// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // A screen is a declaration: data from `load`, columns, actions and labels, handed to the kit's patterns // (docs/how-to/compose-a-page.md in the platform's documentation). So a screen has no styling of its own: no `className`, no // colour value. React Aria is out of a screen's reach too, by the `ui-comes-from-the-kit` rule of // scripts/dep-rules.cjs. A screen that is truly domain-specific says so, and why, in its first lines: // `// kit:custom-ui `. `pnpm boundaries` and this suite read the same marker. import { readFileSync } from "node:fs" import { createRequire } from "node:module" import { join } from "node:path" import { describe, expect, it } from "vitest" const require = createRequire(import.meta.url) const { buildForbidden, listCustomScreens, listScreens } = require("../scripts/dep-rules.cjs") as { buildForbidden( moduleIds: string[], custom?: string[], ): { name: string; from: { path?: string; pathNot?: string | string[] }; to: { path?: string | string[] } }[] listCustomScreens(root: string): string[] listScreens(root: string): string[] } const root = new URL("..", import.meta.url).pathname const COLOUR = /["'`](?:#[0-9a-fA-F]{3,8}|rgba?\(|hsla?\(|oklch\()/ /** What a declared screen may not hold, by file, with the way out in the message. */ function styling(source: string): string[] { const found: string[] = [] if (/<(?:button|input|select|textarea|table)(?:\s|>)/.test(source)) found.push("raw control: compose kit primitives or patterns") if (/\bclassName=/.test(source)) found.push("className: use a pattern's slot, or a variant") if (COLOUR.test(source)) found.push("a colour value: the kit's roles carry every colour") return found } describe("a screen is a declaration", () => { const custom = new Set(listCustomScreens(root)) it("holds no styling of its own unless it declares itself custom", () => { const problems = listScreens(root) .filter((file) => !custom.has(file)) .flatMap((file) => styling(readFileSync(join(root, file), "utf8")).map( (problem) => `${file}: ${problem}, or \`// kit:custom-ui \``, ), ) expect(problems).toEqual([]) }) it("catches what it means to", () => { expect(styling(`

`)).toHaveLength(1) expect(styling(`const c = "#123abc"`)).toHaveLength(1) expect(styling(`const c = "oklch(0.5 0 0)"`)).toHaveLength(1) expect(styling(``)).toEqual([]) expect(styling(`