@estiva-app/ui 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/AppShell.d.ts.map +1 -1
- package/dist/AttachmentCard.d.ts.map +1 -1
- package/dist/Banner.d.ts +20 -2
- package/dist/Banner.d.ts.map +1 -1
- package/dist/ContainerHeader.d.ts +25 -0
- package/dist/ContainerHeader.d.ts.map +1 -0
- package/dist/EmptyState.d.ts +10 -1
- package/dist/EmptyState.d.ts.map +1 -1
- package/dist/Form.d.ts.map +1 -1
- package/dist/IconButton.d.ts +9 -1
- package/dist/IconButton.d.ts.map +1 -1
- package/dist/PreviewCard.d.ts +9 -2
- package/dist/PreviewCard.d.ts.map +1 -1
- package/dist/SectionHeader.d.ts +7 -1
- package/dist/SectionHeader.d.ts.map +1 -1
- package/dist/Select.d.ts +11 -3
- package/dist/Select.d.ts.map +1 -1
- package/dist/Tooltip.d.ts +13 -1
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/eslint/index.js +2 -1
- package/dist/eslint/index.js.map +2 -2
- package/dist/eslint/no-restyled-part.d.ts.map +1 -1
- package/dist/gates/app-checks.d.ts.map +1 -1
- package/dist/gates/{chunk-ZGJ2J5NU.js → chunk-EA33NP5B.js} +275 -11
- package/dist/gates/chunk-EA33NP5B.js.map +7 -0
- package/dist/gates/{chunk-AUXD4GCY.js → chunk-GTQZEHPC.js} +15 -1
- package/dist/gates/chunk-GTQZEHPC.js.map +7 -0
- package/dist/gates/cli.js +1 -1
- package/dist/gates/create-app.d.ts +2 -0
- package/dist/gates/create-app.d.ts.map +1 -1
- package/dist/gates/create-app.js +1 -1
- package/dist/gates/index.js +25 -3
- package/dist/gates/index.js.map +2 -2
- package/dist/gates/status.d.ts +2 -0
- package/dist/gates/status.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +196 -156
- package/dist/index.js.map +4 -4
- package/dist/registry/app-DQI6WLHR.js +10 -0
- package/dist/registry/app.d.ts +21 -0
- package/dist/registry/app.d.ts.map +1 -0
- package/dist/registry/build-LGFCCOLR.js +27 -0
- package/dist/registry/build-LGFCCOLR.js.map +7 -0
- package/dist/registry/build.d.ts +68 -2
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/{chunk-MRSBS5OP.js → chunk-E4JNV7PC.js} +68 -12
- package/dist/registry/chunk-E4JNV7PC.js.map +7 -0
- package/dist/registry/{chunk-QDYGB3QN.js → chunk-NJN4MQAM.js} +60 -15
- package/dist/registry/chunk-NJN4MQAM.js.map +7 -0
- package/dist/registry/{chunk-IJNCYVH4.js → chunk-W2B2G7OE.js} +34 -9
- package/dist/registry/chunk-W2B2G7OE.js.map +7 -0
- package/dist/registry/chunk-WMFF3MPP.js +648 -0
- package/dist/registry/chunk-WMFF3MPP.js.map +7 -0
- package/dist/registry/cli.js +81 -26
- package/dist/registry/cli.js.map +3 -3
- package/dist/registry/find.d.ts +12 -1
- package/dist/registry/find.d.ts.map +1 -1
- package/dist/registry/index.d.ts +5 -2
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +11 -3
- package/dist/registry/schema.d.ts +83 -6
- package/dist/registry/schema.d.ts.map +1 -1
- package/package.json +2 -2
- package/registry.json +283 -95
- package/src/AppShell.mdx +10 -0
- package/src/AppShell.test.tsx +16 -0
- package/src/AppShell.tsx +4 -1
- package/src/AttachmentCard.mdx +9 -0
- package/src/AttachmentCard.test.tsx +10 -0
- package/src/AttachmentCard.tsx +8 -5
- package/src/Avatar.mdx +13 -3
- package/src/AvatarGroup.mdx +4 -0
- package/src/Banner.mdx +30 -7
- package/src/Banner.stories.tsx +22 -0
- package/src/Banner.test.tsx +35 -0
- package/src/Banner.tsx +34 -9
- package/src/Breadcrumb.mdx +10 -0
- package/src/Button.mdx +14 -3
- package/src/Card.mdx +9 -0
- package/src/Checkbox.mdx +10 -0
- package/src/Chip.mdx +4 -0
- package/src/ChipInput.mdx +12 -0
- package/src/CollapsibleSection.mdx +9 -0
- package/src/CommandPalette.mdx +14 -2
- package/src/ConfirmDialog.mdx +11 -0
- package/src/ContainerHeader.mdx +60 -0
- package/src/ContainerHeader.stories.tsx +62 -0
- package/src/ContainerHeader.test.tsx +47 -0
- package/src/ContainerHeader.tsx +45 -0
- package/src/DialogShell.mdx +14 -0
- package/src/Divider.mdx +9 -1
- package/src/EditableText.mdx +11 -0
- package/src/EmptyState.mdx +27 -4
- package/src/EmptyState.stories.tsx +6 -1
- package/src/EmptyState.test.tsx +18 -1
- package/src/EmptyState.tsx +14 -1
- package/src/Field.mdx +10 -1
- package/src/FieldLine.mdx +9 -1
- package/src/FilePicker.mdx +8 -0
- package/src/Form.mdx +10 -0
- package/src/Form.test.tsx +26 -0
- package/src/Form.tsx +7 -0
- package/src/IconButton.mdx +16 -2
- package/src/IconButton.stories.tsx +3 -0
- package/src/IconButton.test.tsx +25 -0
- package/src/IconButton.tsx +61 -46
- package/src/IdentityMenu.mdx +9 -0
- package/src/InlineChip.mdx +8 -0
- package/src/Kbd.mdx +4 -0
- package/src/Link.mdx +10 -0
- package/src/Menu.mdx +16 -1
- package/src/MenuItem.mdx +12 -2
- package/src/NavItem.mdx +8 -0
- package/src/Person.mdx +4 -0
- package/src/PersonTrigger.mdx +9 -0
- package/src/Popover.mdx +21 -0
- package/src/PreviewCard.mdx +19 -4
- package/src/PreviewCard.tsx +11 -4
- package/src/ProgressBar.mdx +8 -0
- package/src/Property.mdx +4 -0
- package/src/Rail.mdx +9 -1
- package/src/RailItem.mdx +8 -0
- package/src/Reaction.mdx +9 -0
- package/src/ReactionPicker.mdx +8 -0
- package/src/ScrollArea.mdx +13 -2
- package/src/SearchInput.mdx +9 -0
- package/src/SectionHeader.mdx +13 -0
- package/src/SectionHeader.stories.tsx +9 -0
- package/src/SectionHeader.test.tsx +9 -0
- package/src/SectionHeader.tsx +8 -2
- package/src/SectionLabel.mdx +4 -0
- package/src/Select.mdx +21 -2
- package/src/Select.stories.tsx +4 -1
- package/src/Select.test.tsx +17 -0
- package/src/Select.tsx +34 -13
- package/src/Sidebar.mdx +8 -0
- package/src/Skeleton.mdx +4 -0
- package/src/Tabs.mdx +12 -1
- package/src/TextInput.mdx +8 -0
- package/src/Textarea.mdx +8 -0
- package/src/Toast.mdx +12 -1
- package/src/Toolbar.mdx +11 -0
- package/src/Tooltip.mdx +26 -2
- package/src/Tooltip.stories.tsx +26 -0
- package/src/Tooltip.test.tsx +29 -0
- package/src/Tooltip.tsx +17 -4
- package/src/TopBar.mdx +4 -0
- package/src/eslint/no-rebuilt-behaviour.ts +1 -1
- package/src/eslint/no-restyled-part.ts +1 -0
- package/src/gates/app-checks.ts +23 -1
- package/src/gates/create-app.test.ts +77 -6
- package/src/gates/create-app.ts +288 -15
- package/src/gates/status.ts +16 -0
- package/src/index.ts +1 -0
- package/src/pages.test.ts +142 -0
- package/src/registry/app.test.ts +562 -0
- package/src/registry/app.ts +854 -0
- package/src/registry/build.ts +114 -25
- package/src/registry/cli.ts +105 -42
- package/src/registry/find.ts +45 -8
- package/src/registry/index.ts +8 -1
- package/src/registry/registry.test.ts +5 -5
- package/src/registry/schema.ts +163 -12
- package/tailwind-preset.js +22 -1
- package/dist/gates/chunk-AUXD4GCY.js.map +0 -7
- package/dist/gates/chunk-ZGJ2J5NU.js.map +0 -7
- package/dist/registry/build-GOVLABI6.js +0 -13
- package/dist/registry/chunk-IJNCYVH4.js.map +0 -7
- package/dist/registry/chunk-MRSBS5OP.js.map +0 -7
- package/dist/registry/chunk-QDYGB3QN.js.map +0 -7
- /package/dist/registry/{build-GOVLABI6.js.map → app-DQI6WLHR.js.map} +0 -0
package/dist/eslint/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/eslint/index.ts", "../../src/eslint/has-a-page-and-a-story.ts", "../../src/eslint/escape.ts", "../../src/eslint/no-hand-rolled-behaviour.ts", "../../src/eslint/no-raw-element.ts", "../../src/eslint/no-rebuilt-behaviour.ts", "../../src/eslint/no-restyled-part.ts", "../../src/eslint/raw-element-outside-a-wrapper.ts"],
|
|
4
|
-
"sourcesContent": ["/// <reference types=\"node\" />\n/**\n * `@estiva-app/ui/eslint` \u2014 the UI Guardrails' lint rules, as a plugin (UIG-3,\n * seam S1 in docs/GATES.md \u00A716).\n *\n * A plugin rather than config, so every app \u2014 Peek, Ship, Leaf \u2014 gets a new\n * rule through an ordinary version bump, and an app's editor hook runs the\n * very rule code its CI runs.\n *\n * import estiva from '@estiva-app/ui/eslint'\n * export default [{ files: ['src/**\\/*.tsx'], ...estiva.configs.recommended }]\n *\n * Register it under `estiva` (the configs do): the rule ids are\n * `estiva/<rule>`, and `countGates` counts those ids.\n *\n * Built on its own by build.mjs, for Node, into `dist/eslint/`; nothing here\n * reaches the components' browser bundle.\n */\nimport { createRequire } from 'node:module'\nimport type { ESLint, Linter } from 'eslint'\nimport { componentHasAPage, componentHasAStory } from './has-a-page-and-a-story'\nimport { noHandRolledBehaviour } from './no-hand-rolled-behaviour'\nimport { noRawElement } from './no-raw-element'\nimport { noRebuiltBehaviour } from './no-rebuilt-behaviour'\nimport { noRestyledPart } from './no-restyled-part'\nimport { rawElementOutsideAWrapper } from './raw-element-outside-a-wrapper'\n\nexport { ESCAPE_MARKER, MIN_REASON, SETTINGS_KEY, isEscaped, type EstivaSettings } from './escape'\nexport { OWNED_BEHAVIOURS, type OwnedBehaviour } from './no-rebuilt-behaviour'\nexport { PART_LOOK_PROPS, PLACEMENT } from './no-restyled-part'\n\nconst { version } = createRequire(import.meta.url)('../../package.json') as { version: string }\n\n/** The name the configs register the plugin under, so every rule id is `estiva/<rule>`. */\nexport const PLUGIN_KEY = 'estiva'\n\n/**\n * The rules an **app** runs: they say an app must not build what the package\n * already has \u2014 a raw control (UIG-7), or a behaviour one of its parts owns\n * (UIG-8) \u2014 nor restyle a part it uses (UIG-9). `recommended` and `strict`\n * carry these and only these.\n */\nconst appRules = {\n 'no-raw-element': noRawElement,\n 'no-rebuilt-behaviour': noRebuiltBehaviour,\n 'no-restyled-part': noRestyledPart,\n}\n\n/**\n * The rules the **package itself** runs, pointed inward (UIG-5): don't bury a\n * raw element inside a component, don't rebuild what Base UI owns, don't ship a\n * component without a page or a story.\n *\n * They are in `configs.package`, never in `recommended`, on purpose. Peek and\n * Ship spread `recommended`, so a rule added here must not arrive in an app\n * with the next version bump: an app's components are not primitives, so\n * \"buried inside a component\" means nothing there (`no-raw-element` is the\n * app's version, UIG-7), and an app has no `.mdx` pages at all. `index.test.ts` holds the\n * apps' list to exactly the app rules.\n *\n * One rule is in both sets: `no-restyled-part` (UIG-9). The package restyles\n * none of its own parts either (Katerina, 17 September).\n */\nconst packageRules = {\n 'raw-element-outside-a-wrapper': rawElementOutsideAWrapper,\n 'no-hand-rolled-behaviour': noHandRolledBehaviour,\n 'component-has-a-page': componentHasAPage,\n 'component-has-a-story': componentHasAStory,\n 'no-restyled-part': noRestyledPart,\n}\n\nconst rules = { ...appRules, ...packageRules }\n\nconst plugin = {\n meta: { name: '@estiva-app/ui/eslint', version },\n rules,\n configs: {} as { recommended: Linter.Config; strict: Linter.Config; package: Linter.Config },\n} satisfies ESLint.Plugin\n\n/** The ids `recommended` and `strict` carry \u2014 what an app's gate runs and counts. */\nexport const APP_RULE_IDS = Object.keys(appRules).map((name) => `${PLUGIN_KEY}/${name}`)\n/** The ids `package` carries \u2014 what this package's own gate runs and counts (UIG-5). */\nexport const PACKAGE_RULE_IDS = Object.keys(packageRules).map((name) => `${PLUGIN_KEY}/${name}`)\n\n/**\n * `recommended` switches every **app** rule on at the level it was ruled at: an\n * error blocks, a warning is reported and never blocks. `strict` makes every app\n * rule an error. With every app rule an error, the two are the same today; they part\n * when the first warning-level rule arrives (UIG-25).\n *\n * `package` is the inward set (UIG-5), which only this package runs.\n */\nplugin.configs.recommended = {\n name: '@estiva-app/ui/recommended',\n plugins: { [PLUGIN_KEY]: plugin },\n rules: {\n [`${PLUGIN_KEY}/no-raw-element`]: 'error',\n [`${PLUGIN_KEY}/no-rebuilt-behaviour`]: 'error',\n [`${PLUGIN_KEY}/no-restyled-part`]: 'error',\n },\n}\nplugin.configs.strict = {\n name: '@estiva-app/ui/strict',\n plugins: { [PLUGIN_KEY]: plugin },\n rules: Object.fromEntries(APP_RULE_IDS.map((id) => [id, 'error'])),\n}\nplugin.configs.package = {\n name: '@estiva-app/ui/package',\n plugins: { [PLUGIN_KEY]: plugin },\n rules: Object.fromEntries(PACKAGE_RULE_IDS.map((id) => [id, 'error'])),\n}\n\nexport default plugin\n\nexport interface GateRuleCount {\n errors: number\n warnings: number\n escapes: number\n}\n\nexport interface GateCount {\n /** Per rule id, including rules with nothing to report. */\n rules: Record<string, GateRuleCount>\n /**\n * Reports of these rules that an `eslint-disable` directive silenced. Not\n * an escape: a gate fails on any of these (docs/GATES.md \u00A716, S4).\n */\n disabled: { filePath: string; line: number; ruleId: string }[]\n}\n\n/**\n * Count what a lint of these rules found, for `.gates-count.json` (seam S3).\n *\n * Run the lint with `settings: { estiva: { reportEscapes: true } }` for the\n * escapes to be counted; without it they are silent and count 0. A marker\n * with no reason, or inside a directive, counts as an error of its rule.\n *\n * `seed` is which rules the count lists when they found nothing, and it is the\n * app rules unless a caller says otherwise: an app's count file must not gain\n * rows for the inward rules (UIG-5) that its gate does not run. This package's\n * own count script passes `PACKAGE_RULE_IDS`.\n */\nexport function countGates(results: ESLint.LintResult[], seed: readonly string[] = APP_RULE_IDS): GateCount {\n const counts: Record<string, GateRuleCount> = Object.fromEntries(seed.map((id) => [id, { errors: 0, warnings: 0, escapes: 0 }]))\n const disabled: GateCount['disabled'] = []\n const ours = (ruleId: string | null | undefined): ruleId is string => typeof ruleId === 'string' && ruleId.startsWith(`${PLUGIN_KEY}/`)\n for (const result of results) {\n for (const message of result.messages) {\n // Seeded or not: every rule of this plugin that reported is counted, so a\n // lint of a set the caller did not name is still counted in full.\n if (!ours(message.ruleId)) continue\n const count = (counts[message.ruleId] ??= { errors: 0, warnings: 0, escapes: 0 })\n if (message.messageId === 'escaped') count.escapes += 1\n else if (message.severity === 2) count.errors += 1\n else count.warnings += 1\n }\n for (const message of result.suppressedMessages ?? []) {\n if (ours(message.ruleId)) disabled.push({ filePath: result.filePath, line: message.line, ruleId: message.ruleId })\n }\n }\n return { rules: counts, disabled }\n}\n", "import { existsSync } from 'node:fs'\nimport type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * A component of the package with no page, and one with no story (UIG-5, P2 and\n * P3).\n *\n * A component nobody can read about is a component nobody uses correctly, and\n * one nobody can look at is one nobody reviews. Both were at zero when these\n * were switched on; they are here so the next component cannot arrive without\n * them.\n *\n * The pair is by file name, beside the component, which is how this package is\n * laid out: `Button.tsx`, `Button.mdx`, `Button.stories.tsx`, `Button.test.tsx`\n * side by side in `src/`.\n *\n * **The false positive to avoid** (UIG-1 confirmed it is real): `FieldLine` and\n * `MenuItem` have a page and a story but no `.tsx` of their own \u2014 they are\n * exported from a sibling. These rules read a component file and ask for its\n * page and its story, never the other way round, so a page without a component\n * is not this rule's business.\n *\n * A file that stays without one says why at its top: `// @estiva-escape: <why>`.\n */\ninterface ProgramNode {\n body: { loc?: Rule.Node['loc']; range?: [number, number] }[]\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n}\n\n/** A component file: a `.tsx` in the package's source that is not a story or a test. */\nfunction componentFile(filename: string): boolean {\n return filename.endsWith('.tsx') && !/\\.(stories|test)\\.tsx$/.test(filename)\n}\n\nfunction sibling(filename: string, extension: string): string {\n return filename.replace(/\\.tsx$/, extension)\n}\n\n/**\n * Report on the file's first statement, so the escape is a comment at the top of\n * the file \u2014 the only place a reason for a missing page could go.\n */\nfunction reportOnFile(context: Rule.RuleContext, program: ProgramNode, messageId: string, data: Record<string, string>): void {\n const anchor = program.body[0] ?? program\n if (anchor.loc && anchor.range && isEscaped(context, { loc: anchor.loc, range: anchor.range })) return\n context.report({ loc: anchor.loc ?? program.loc, messageId, data })\n}\n\nexport const componentHasAPage: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Every component of the package has a usage page beside it' },\n schema: [],\n messages: {\n missing: '{{name}} has no page. Write {{page}} beside it \u2014 what it is, when, when not, how, and what it owns \u2014 or say why not at the top of the file.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n Program(node) {\n const filename = context.filename\n if (!componentFile(filename)) return\n const page = sibling(filename, '.mdx')\n if (existsSync(page)) return\n const name = filename.split(/[\\\\/]/).pop() ?? filename\n reportOnFile(context, node as unknown as ProgramNode, 'missing', { name, page: page.split(/[\\\\/]/).pop() ?? page })\n },\n }\n },\n}\n\nexport const componentHasAStory: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Every component of the package has a story beside it' },\n schema: [],\n messages: {\n missing: '{{name}} has no story. Write {{story}} beside it, so it can be seen and reviewed, or say why not at the top of the file.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n Program(node) {\n const filename = context.filename\n if (!componentFile(filename)) return\n const story = sibling(filename, '.stories.tsx')\n if (existsSync(story)) return\n const name = filename.split(/[\\\\/]/).pop() ?? filename\n reportOnFile(context, node as unknown as ProgramNode, 'missing', { name, story: story.split(/[\\\\/]/).pop() ?? story })\n },\n }\n },\n}\n", "import type { AST, Rule } from 'eslint'\n\n/**\n * The escape marker (UIG-3, seam S4 in docs/GATES.md \u00A716): one written reason\n * why one element stays as it is.\n *\n * A line comment directly above the element,\n *\n * // @estiva-escape: <reason>\n *\n * or, where the element is a JSX child, the JSX comment on the line above,\n *\n * {/* @estiva-escape: <reason> *\\/}\n *\n * with at least ten characters of reason, spaces not counted.\n *\n * Not `eslint-disable`. A directive switches a rule off without saying it was\n * meant, and the count of escapes (`.gates-count.json`) could not see it. A\n * marker written inside a directive that switches one of these rules off is\n * reported for that reason.\n *\n * The token lint's older notes (`eslint-disable-next-line <rule> -- @estiva-escape:\n * <reason>`, Katerina's ruling A2 of 15 September) are not read here: they\n * escape the token lint's rules, which are not this plugin's, and they stay as\n * they are (Katerina, 15 September).\n */\nexport const ESCAPE_MARKER = '@estiva-escape'\n\n/** Characters of reason, spaces not counted. */\nexport const MIN_REASON = 10\n\n/** The key under ESLint's `settings` this plugin reads. */\nexport const SETTINGS_KEY = 'estiva'\n\n/**\n * Every rule spreads these into its `meta.messages`, because `isEscaped`\n * reports through the rule that called it.\n */\nexport const ESCAPE_MESSAGES = {\n escapeWithoutReason: `An escape needs its reason, at least ${MIN_REASON} characters: \\`// ${ESCAPE_MARKER}: <why this stays>\\`. An escape with no reason hides nothing.`,\n escapeInDirective: `Write the escape as its own comment on the line above: \\`// ${ESCAPE_MARKER}: <reason>\\`. Inside an eslint-disable comment it switches the rule off instead of recording why.`,\n escaped: 'Escaped: {{reason}}',\n} as const\n\nexport interface EstivaSettings {\n /**\n * Report every sanctioned escape as a message with the id `escaped`, so a\n * count can read them. Off in the lint anyone runs; on only in the count.\n */\n reportEscapes?: boolean\n}\n\ninterface Located {\n loc?: AST.SourceLocation | null\n range?: [number, number]\n}\n\nconst DIRECTIVE = /^\\s*eslint-disable(?:-next-line|-line)?(?=\\s|$)([^]*)$/\n\n/** The rules a directive names: what comes before its ` -- ` description. None means every rule. */\nfunction directiveRules(rest: string): string[] {\n const dashes = rest.search(/(?:^|\\s)--(?:\\s|$)/)\n return (dashes === -1 ? rest : rest.slice(0, dashes)).split(/[\\s,]+/).filter(Boolean)\n}\n\n/** Only spaces and a JSX expression's closing brace between the marker and the element. */\nconst BETWEEN = /^[\\s}]*$/\n\n/**\n * Whether the element at `node` carries a valid escape on the line above.\n *\n * Every rule of this plugin calls it before it reports. It reports, through\n * that rule, a marker with too short a reason and a marker inside an\n * eslint-disable directive for this rule; either way the element is not\n * escaped, so the rule reports it too.\n */\nexport function isEscaped(context: Rule.RuleContext, node: Located): boolean {\n const { sourceCode } = context\n if (!node.loc || !node.range) return false\n const line = node.loc.start.line\n const nodeStart = node.range[0]\n\n const comment = sourceCode\n .getAllComments()\n .find((c) => c.loc && c.range && c.loc.end.line === line - 1 && BETWEEN.test(sourceCode.text.slice(c.range[1], nodeStart)))\n if (!comment?.loc) return false\n\n const at = comment.value.indexOf(ESCAPE_MARKER)\n if (at === -1) return false\n\n const directive = DIRECTIVE.exec(comment.value)\n if (directive) {\n const rules = directiveRules(directive[1])\n // A directive for other rules (the token lint's notes) is not an escape of this one.\n if (rules.length > 0 && !rules.includes(context.id)) return false\n context.report({ loc: comment.loc, messageId: 'escapeInDirective' })\n return false\n }\n\n const reason = comment.value\n .slice(at + ESCAPE_MARKER.length)\n .replace(/^:/, '')\n .trim()\n if (reason.replace(/\\s/g, '').length < MIN_REASON) {\n context.report({ loc: comment.loc, messageId: 'escapeWithoutReason' })\n return false\n }\n\n const settings = context.settings[SETTINGS_KEY] as EstivaSettings | undefined\n if (settings?.reportEscapes) context.report({ loc: comment.loc, messageId: 'escaped', data: { reason } })\n return true\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * Behaviour Base UI already owns, written by hand inside the package (UIG-5,\n * P1 \u2014 the migration's standing rule D6 as a machine).\n *\n * This is the rule with the most to lose. A hand-made portal or a global\n * listener inside `DialogShell` is inherited by every caller in every app, and\n * nobody sees it from there.\n *\n * Two facts, both mechanical, both the signature of a floating part rebuilt by\n * hand:\n *\n * - **`createPortal`**, or importing it from `react-dom`. Base UI's parts carry\n * their own portal.\n * - **a listener on `window` or `document`** for the events a floating part\n * lives on \u2014 resize, scroll, an outside press, a key. Base UI's Positioner\n * follows the anchor and its Root closes on an outside press and on Escape.\n *\n * What it deliberately does not try to read: measuring arithmetic. `Popover`\n * hands Base UI a virtual anchor with a `getBoundingClientRect`, which is the\n * documented way to anchor to a rectangle rather than an element, and a rule\n * that guessed at arithmetic would report it. Anything that shape is caught by\n * a reader, not by this.\n *\n * A place that keeps one says why on the line above: `// @estiva-escape: <why>`.\n */\nconst FLOATING_EVENTS = new Set(['resize', 'scroll', 'mousedown', 'pointerdown', 'keydown', 'keyup', 'focusin', 'focusout', 'click'])\n\ninterface Node {\n type: string\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n}\n\ninterface Identifier extends Node {\n name: string\n}\n\ninterface ImportDeclaration extends Node {\n source: { value: unknown }\n specifiers: { type: string; imported?: { name?: string }; local?: { name?: string }; loc?: Rule.Node['loc']; range?: [number, number] }[]\n}\n\ninterface CallExpression extends Node {\n callee: { type: string; name?: string; object?: { type: string; name?: string }; property?: { type: string; name?: string } }\n arguments: { type: string; value?: unknown }[]\n parent?: { type: string; loc?: Rule.Node['loc']; range?: [number, number]; parent?: CallExpression['parent'] }\n}\n\n/**\n * The statement a call sits in, which is what an escape is written above:\n * `return createPortal(\u2026)` puts the call in the middle of its line, and a\n * comment above the line is above the statement.\n */\nfunction statement(node: { loc: NonNullable<Rule.Node['loc']>; range: [number, number]; parent?: CallExpression['parent'] }): {\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n} {\n for (let p = node.parent; p; p = p.parent) {\n if (!/(Statement|Declaration)$/.test(p.type)) continue\n if (p.loc && p.range) return { loc: p.loc, range: p.range }\n break\n }\n return { loc: node.loc, range: node.range }\n}\n\nexport const noHandRolledBehaviour: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Overlay behaviour written by hand where Base UI has a part (D6)' },\n schema: [],\n messages: {\n portal:\n 'A portal written by hand. Base UI\\'s parts carry their own (Popover, Menu, Select, Tooltip, Dialog, Toast): use the part, or say why this one stays.',\n listener:\n 'A `{{event}}` listener on `{{target}}`. A floating part follows its anchor and closes on an outside press and on Escape by itself (Base UI Positioner and Root): use the part, or say why this one stays.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n ImportDeclaration(node: Rule.Node) {\n const declaration = node as unknown as ImportDeclaration\n if (declaration.source.value !== 'react-dom') return\n for (const specifier of declaration.specifiers) {\n if (specifier.type !== 'ImportSpecifier' || specifier.imported?.name !== 'createPortal') continue\n // The escape goes above the import line, not above the name inside it.\n if (isEscaped(context, declaration)) return\n context.report({ loc: declaration.loc, messageId: 'portal' })\n return\n }\n },\n CallExpression(node: Rule.Node) {\n const call = node as unknown as CallExpression\n const { callee } = call\n\n if (callee.type === 'Identifier' && callee.name === 'createPortal') {\n if (isEscaped(context, statement(call))) return\n context.report({ loc: call.loc, messageId: 'portal' })\n return\n }\n\n if (callee.type !== 'MemberExpression' || callee.property?.name !== 'addEventListener') return\n const target = callee.object?.type === 'Identifier' ? callee.object.name : undefined\n if (target !== 'window' && target !== 'document') return\n const [first] = call.arguments\n const event = first?.type === 'Literal' && typeof first.value === 'string' ? first.value : undefined\n if (!event || !FLOATING_EVENTS.has(event)) return\n if (isEscaped(context, statement(call))) return\n context.report({ loc: call.loc, messageId: 'listener', data: { event, target } })\n },\n }\n },\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\ninterface JSXAttributeValue {\n type: string\n value?: unknown\n expression?: { type: string; value?: unknown; expressions?: unknown[]; quasis?: { value: { cooked: string | null } }[] }\n}\n\ninterface JSXAttribute {\n type: 'JSXAttribute'\n name: { type: string; name?: string }\n value: JSXAttributeValue | null\n}\n\ninterface JSXOpeningElement {\n name: { type: string; name?: string }\n attributes: (JSXAttribute | { type: 'JSXSpreadAttribute' })[]\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n}\n\n/**\n * What the package has instead of one raw element: the component the message\n * names, and where one element does more than one job, the others after it.\n * `null` is an element the package has no part for yet.\n */\nexport interface RawElementPart {\n use: string\n more?: string\n}\n\n/**\n * The mapping (UIG-7), derived from the package's exports: every interactive\n * element in the HTML standard's list (\"interactive content\"), plus `<dialog>`,\n * `<form>` and `<progress>`, which have a part here. docs/GATES.md prints it.\n *\n * Not here, on purpose: `<summary>` (it lives inside a `<details>`, which is\n * reported), `<option>`, `<optgroup>` and `<datalist>` (they live inside a\n * `<select>` or beside an input), `<fieldset>` and `<legend>` (a group's frame,\n * no control of its own), and `<img>` without `usemap`, `<hr>`, `<kbd>`, which\n * are not controls. An `<audio>` or `<video>` is a control only with `controls`.\n */\nexport const RAW_ELEMENT_PARTS: Record<string, RawElementPart | null> = {\n a: { use: 'Link', more: ' For a chip, `InlineChip`; for a whole card, `Card` with `href`.' },\n button: { use: 'Button' },\n textarea: { use: 'Textarea' },\n select: { use: 'Select' },\n dialog: { use: 'DialogShell', more: ' To ask yes or no, `ConfirmDialog`.' },\n label: { use: 'Field', more: ' For words beside a tick box, `Checkbox` with `label`.' },\n details: { use: 'CollapsibleSection' },\n progress: { use: 'ProgressBar' },\n form: { use: 'Form' },\n meter: null,\n iframe: null,\n embed: null,\n object: null,\n audio: null,\n video: null,\n img: null,\n}\n\n/**\n * An `<input>` is as many controls as its `type`. A type missing from here\n * (text, email, password, url, tel, number, or one the browser does not know)\n * is a text box.\n */\nexport const RAW_INPUT_PARTS: Record<string, RawElementPart | null> = {\n search: { use: 'SearchInput' },\n checkbox: { use: 'Checkbox' },\n file: { use: 'FilePicker' },\n submit: { use: 'Button' },\n button: { use: 'Button' },\n reset: { use: 'Button' },\n image: { use: 'Button' },\n radio: null,\n range: null,\n color: null,\n date: null,\n 'datetime-local': null,\n month: null,\n week: null,\n time: null,\n}\n\nconst TEXT_INPUT: RawElementPart = { use: 'TextInput' }\nconst ANY_INPUT: RawElementPart = {\n use: 'TextInput',\n more: ' For a search, `SearchInput`; for a tick box, `Checkbox`; to pick files, `FilePicker`.',\n}\n\nfunction attribute(element: JSXOpeningElement, name: string): JSXAttribute | undefined {\n return element.attributes.find((a): a is JSXAttribute => a.type === 'JSXAttribute' && a.name.name === name)\n}\n\n/** An attribute's value when the code spells it out, `undefined` when it is computed. */\nfunction literal(attr: JSXAttribute): string | boolean | undefined {\n const value = attr.value\n if (value === null) return true\n if (value.type === 'Literal') return typeof value.value === 'string' ? value.value : undefined\n if (value.type !== 'JSXExpressionContainer' || !value.expression) return undefined\n const expression = value.expression\n if (expression.type === 'Literal' && (typeof expression.value === 'string' || typeof expression.value === 'boolean')) return expression.value\n if (expression.type === 'TemplateLiteral' && expression.expressions?.length === 0) return expression.quasis?.[0]?.value.cooked ?? undefined\n return undefined\n}\n\n/** Present, and not written as `={false}`. */\nfunction isOn(element: JSXOpeningElement, name: string): boolean {\n const attr = attribute(element, name)\n return attr !== undefined && literal(attr) !== false\n}\n\ntype Found = { report: 'raw'; element: string; part: RawElementPart } | { report: 'noPart'; element: string } | null\n\n/** What this element is to the rule: a raw element with a part, one with none yet, or none of its business. */\nexport function classify(element: JSXOpeningElement): Found {\n if (element.name.type !== 'JSXIdentifier' || !element.name.name) return null\n const name = element.name.name\n\n if (name === 'input') {\n const attr = attribute(element, 'type')\n const type = attr ? literal(attr) : 'text'\n if (typeof type !== 'string') return { report: 'raw', element: '<input>', part: ANY_INPUT }\n const key = type.toLowerCase()\n // A hidden input draws nothing and takes no focus: it is data, not a control.\n if (key === 'hidden') return null\n if (!(key in RAW_INPUT_PARTS)) return { report: 'raw', element: '<input>', part: TEXT_INPUT }\n const part = RAW_INPUT_PARTS[key]\n const shown = `<input type=\"${key}\">`\n return part ? { report: 'raw', element: shown, part } : { report: 'noPart', element: shown }\n }\n\n if (!Object.hasOwn(RAW_ELEMENT_PARTS, name)) return null\n if ((name === 'audio' || name === 'video') && !isOn(element, 'controls')) return null\n if (name === 'img' && !attribute(element, 'usemap') && !attribute(element, 'useMap')) return null\n\n const part = RAW_ELEMENT_PARTS[name]\n return part ? { report: 'raw', element: `<${name}>`, part } : { report: 'noPart', element: `<${name}>` }\n}\n\n/**\n * A raw interactive element in an app, where the package has a part for it\n * (UIG-3 began it with `<button>`; UIG-7 made it every element). A control\n * the app writes itself has a look, a focus ring and keys that nobody else\n * keeps in step with \u2014 and it looks nearly right, which is why nobody catches\n * it by eye. Every message names the part to use.\n *\n * An element the package has no part for yet is refused too, with a message\n * that says so: the part is made in the package, not by hand in an app\n * (Katerina, 16 September).\n *\n * Only a JSX element written with a lowercase name. `<Button>`,\n * `<Foo.button>` and `createElement('button')` are not this rule's business.\n */\nexport const noRawElement: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'A raw interactive element where @estiva-app/ui has a part, or where it needs one' },\n schema: [],\n messages: {\n raw: 'Use `{{use}}` from @estiva-app/ui instead of a raw {{element}}.{{more}}',\n noPart: '@estiva-app/ui has no part for a raw {{element}} yet. Do not build one here: ask Katerina, and it gets made in @estiva-app/ui.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n // ESLint's types know ESTree's nodes, not JSX's; the parser hands this one over.\n JSXOpeningElement(node: Rule.Node) {\n const element = node as unknown as JSXOpeningElement\n const found = classify(element)\n if (!found) return\n if (isEscaped(context, element)) return\n if (found.report === 'noPart') context.report({ loc: element.loc, messageId: 'noPart', data: { element: found.element } })\n else context.report({ loc: element.loc, messageId: 'raw', data: { element: found.element, use: found.part.use, more: found.part.more ?? '' } })\n },\n }\n },\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * Behaviour the package already owns, rebuilt by hand in an app (UIG-8, \"forbid\n * the reach\"). A hand-made dropdown, dialog, list or scrolling box does not look\n * wrong in review; it shows itself when somebody uses a keyboard, or has 81\n * folders. Every message names the part that already does it.\n *\n * What it reads is derived from the package source: which `@base-ui/react` part\n * each component imports, and so what it owns (`OWNED_BEHAVIOURS`, printed in\n * docs/GATES.md and reused by UIG-12's registry). `no-rebuilt-behaviour.test.ts`\n * holds the tables to the source, so a new part cannot be added without them.\n *\n * What it deliberately does not read, and why:\n *\n * - **A box that should scroll and does not.** A class rule finds the scrolling\n * box built by hand; it cannot find the one that was never built. Peek's\n * Folders column (fixed in peek 3dc663b) had no overflow class at all. Only a\n * check that opens the page can find that.\n * - **Enter and Escape** compared by hand. In a field or an editor they are\n * typing, and `Form` and `EditableText` own the ones that send or cancel.\n * Escape and every other key taken for the whole page are read, through the\n * listener.\n * - **aria-expanded, aria-pressed and the other states** written on a package\n * component: the component is already the package's (UIG-14's usage rules).\n * - **Measuring arithmetic**, for the reason UIG-5 gave: `Popover` takes a\n * rectangle to hang from, and a rule that guessed at arithmetic would report it.\n * - A listener on a variable that happens to hold the document.\n *\n * A place that keeps one says why on the line above: `// @estiva-escape: <why>`.\n * An escape above a statement, an element or an object property covers what the\n * rule found there.\n */\n\n/** The part a message names, and where one behaviour has more owners, the others after it. `null`: no part yet. */\nexport interface OwnerPart {\n use: string\n more?: string\n}\n\n/**\n * Every Base UI module, and the package component built on it. Read from the\n * package's imports (`src/*.tsx`); the test fails if a component imports a\n * module this does not name, or names a component that does not import it.\n * A module no component uses has no part yet, and neither do Base UI's utilities.\n */\nexport const BASE_UI_PARTS: Record<string, OwnerPart | null> = {\n 'alert-dialog': { use: 'DialogShell', more: ' To ask yes or no, `ConfirmDialog`.' },\n autocomplete: { use: 'CommandPalette' },\n avatar: { use: 'Avatar' },\n button: { use: 'Button', more: ' Icon only, `IconButton`.' },\n checkbox: { use: 'Checkbox' },\n collapsible: { use: 'CollapsibleSection' },\n combobox: { use: 'ChipInput' },\n dialog: { use: 'DialogShell', more: ' To search and act, `CommandPalette`.' },\n field: { use: 'Field' },\n fieldset: { use: 'Form' },\n form: { use: 'Form' },\n input: { use: 'TextInput', more: ' For a search, `SearchInput`.' },\n menu: { use: 'Menu' },\n popover: { use: 'Popover' },\n 'preview-card': { use: 'PreviewCard' },\n progress: { use: 'ProgressBar' },\n 'scroll-area': { use: 'ScrollArea' },\n select: { use: 'Select' },\n separator: { use: 'Divider' },\n tabs: { use: 'Tabs' },\n toast: { use: 'Toast' },\n toggle: { use: 'Reaction' },\n toolbar: { use: 'Toolbar' },\n tooltip: { use: 'Tooltip', more: ' Around a control, `WithTooltip`.' },\n accordion: null,\n 'checkbox-group': null,\n 'context-menu': null,\n drawer: null,\n menubar: null,\n meter: null,\n 'navigation-menu': null,\n 'number-field': null,\n 'otp-field': null,\n radio: null,\n 'radio-group': null,\n slider: null,\n switch: null,\n 'toggle-group': null,\n}\n\nconst LIST_PART: OwnerPart = {\n use: 'Select',\n more: ' To pick several, `ChipInput`; to search and act, `CommandPalette`; to tick several in a list, `Checkbox` with `row`.',\n}\n\nconst MESSAGE_PART: OwnerPart = { use: 'FieldLine', more: ' For a notice, `Banner`; for a message that comes and goes, `Toast`.' }\n\n/**\n * A role written by hand, and the part that sets it. Base UI's parts set most of\n * these; `tooltip` (Base UI's Tooltip sets none), `alert`, `status` and `link` are\n * the package's own. A role Base UI has a part for and this package has not got\n * yet is `null`. Not here, on purpose: `img`, `group`, `presentation`, `none`,\n * `region` and every landmark \u2014 they describe, they do not behave.\n */\nexport const ROLE_PARTS: Record<string, { thing: string; part: OwnerPart | null }> = {\n dialog: { thing: 'dialog', part: { use: 'DialogShell', more: ' To ask yes or no, `ConfirmDialog`.' } },\n alertdialog: { thing: 'dialog', part: { use: 'ConfirmDialog' } },\n menu: { thing: 'menu', part: { use: 'Menu' } },\n menuitem: { thing: 'menu', part: { use: 'Menu' } },\n menuitemcheckbox: { thing: 'menu', part: { use: 'Menu' } },\n menuitemradio: { thing: 'menu', part: { use: 'Menu' } },\n listbox: { thing: 'list', part: LIST_PART },\n option: { thing: 'list', part: LIST_PART },\n combobox: { thing: 'list', part: LIST_PART },\n tablist: { thing: 'set of tabs', part: { use: 'Tabs' } },\n tab: { thing: 'set of tabs', part: { use: 'Tabs' } },\n tabpanel: { thing: 'set of tabs', part: { use: 'Tabs' } },\n toolbar: { thing: 'toolbar', part: { use: 'Toolbar' } },\n progressbar: { thing: 'progress bar', part: { use: 'ProgressBar' } },\n checkbox: { thing: 'tick box', part: { use: 'Checkbox' } },\n separator: { thing: 'divider', part: { use: 'Divider' } },\n button: { thing: 'button', part: { use: 'Button', more: ' Icon only, `IconButton`.' } },\n link: { thing: 'link', part: { use: 'Link' } },\n tooltip: { thing: 'tooltip', part: { use: 'Tooltip', more: ' Around a control, `WithTooltip`.' } },\n alert: { thing: 'message', part: MESSAGE_PART },\n status: { thing: 'message', part: MESSAGE_PART },\n menubar: { thing: 'menu bar', part: null },\n switch: { thing: 'switch', part: null },\n radio: { thing: 'radio button', part: null },\n radiogroup: { thing: 'radio group', part: null },\n slider: { thing: 'slider', part: null },\n spinbutton: { thing: 'number field', part: null },\n meter: { thing: 'meter', part: null },\n}\n\n/** The keys a list, a menu, tabs and a toolbar move with. Enter and Escape are not here (see above). */\nexport const WALKING_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'PageUp', 'PageDown']\n\n/**\n * A listener on the whole page, by what it is for. The events Base UI's own\n * parts listen to on the document (useDismiss, FloatingFocusManager, the\n * Positioner's autoUpdate): a floating part closes, holds focus and follows its\n * anchor with these. `focus`, `blur`, `visibilitychange` and `storage` are not\n * here: an app refreshing when the window comes back is not a floating part.\n */\nexport const PAGE_EVENTS: Record<string, 'press' | 'key' | 'focus' | 'follow'> = {\n mousedown: 'press',\n pointerdown: 'press',\n click: 'press',\n touchstart: 'press',\n keydown: 'key',\n keyup: 'key',\n keypress: 'key',\n focusin: 'focus',\n focusout: 'focus',\n scroll: 'follow',\n resize: 'follow',\n}\n\n/** Elements that are reachable with Tab by themselves; `tabIndex` on these is not a Tab stop made by hand. */\nexport const INTERACTIVE_ELEMENTS = new Set(['a', 'button', 'input', 'select', 'textarea', 'summary', 'iframe', 'embed', 'object', 'audio', 'video'])\n\n/** `overflow-auto`, `overflow-y-scroll`\u2026: a box that scrolls with the browser's scrollbar. */\nexport const SCROLL_CLASS = /^overflow(?:-[xy])?-(?:auto|scroll)$/\n\n/** One row of the enumeration (UIG-8's acceptance; the shape UIG-12's registry reads). */\nexport interface OwnedBehaviour {\n id: string\n /** What a person notices the part doing. */\n behaviour: string\n /** The Base UI parts that do it, read from their source (1.8.0). */\n baseUi: string[]\n /** The package components an error names. */\n owners: string[]\n /** What the rule reads in an app to find it rebuilt. */\n reads: string\n}\n\nconst uses = (parts: (OwnerPart | null)[]) => [\n ...new Set(parts.flatMap((p) => (p ? [p.use, ...[...(p.more ?? '').matchAll(/`([A-Z]\\w+)`/g)].map((m) => m[1])] : []))),\n]\n\nexport const OWNED_BEHAVIOURS: OwnedBehaviour[] = [\n {\n id: 'base-ui',\n behaviour: 'Is built on Base UI',\n baseUi: Object.keys(BASE_UI_PARTS),\n owners: uses(Object.values(BASE_UI_PARTS)),\n reads: 'an import from @base-ui/react (and the old @base-ui-components spelling)',\n },\n {\n id: 'portal',\n behaviour: 'Floats on top of the page',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Autocomplete', 'Tooltip', 'PreviewCard', 'Toast'],\n owners: ['DialogShell', 'ConfirmDialog', 'CommandPalette', 'Popover', 'Menu', 'Select', 'ChipInput', 'Tooltip', 'PreviewCard', 'Toast'],\n reads: 'createPortal, called, or imported and never called',\n },\n {\n id: 'press-outside',\n behaviour: 'Closes on a press outside',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Tooltip', 'PreviewCard'],\n owners: ['DialogShell', 'Popover', 'Menu', 'Select', 'PreviewCard'],\n reads: 'a mousedown, pointerdown, click or touchstart listener on window or document',\n },\n {\n id: 'page-keys',\n behaviour: 'Closes on Escape, and takes its keys, by itself',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Tooltip', 'PreviewCard', 'Toast'],\n owners: ['DialogShell', 'Popover', 'Menu', 'Select', 'Tabs', 'Toolbar'],\n reads: 'a keydown, keyup or keypress listener on window or document',\n },\n {\n id: 'focus',\n behaviour: 'Holds focus inside while open, and gives it back',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox'],\n owners: ['DialogShell', 'CommandPalette'],\n reads: 'a focusin or focusout listener on window or document; the Tab key compared by hand',\n },\n {\n id: 'scroll-lock',\n behaviour: 'Stops the page behind it scrolling',\n baseUi: ['Dialog', 'AlertDialog'],\n owners: ['DialogShell'],\n reads: 'overflow written into the style of document.body or document.documentElement',\n },\n {\n id: 'follow',\n behaviour: 'Stays attached to its anchor on scroll and resize',\n baseUi: ['Popover', 'Menu', 'Select', 'Combobox', 'Tooltip', 'PreviewCard', 'Toast'],\n owners: ['Popover', 'Menu', 'Select', 'Tooltip', 'PreviewCard'],\n reads: 'a scroll or resize listener on window or document',\n },\n {\n id: 'walking',\n behaviour: 'Moves through its items with the arrow keys',\n baseUi: ['Menu', 'Select', 'Combobox', 'Autocomplete', 'Tabs', 'Toolbar'],\n owners: ['Menu', 'Select', 'ChipInput', 'CommandPalette', 'Tabs', 'Toolbar'],\n reads: `a key compared by hand with ${WALKING_KEYS.join(', ')}`,\n },\n {\n id: 'role',\n behaviour: 'Says what it is to assistive technology',\n baseUi: ['Dialog', 'AlertDialog', 'Menu', 'Select', 'Combobox', 'Tabs', 'Toolbar', 'Progress', 'Checkbox', 'Separator', 'Button'],\n owners: uses(Object.values(ROLE_PARTS).map((r) => r.part)),\n reads: `role written by hand: ${Object.keys(ROLE_PARTS).join(', ')}`,\n },\n {\n id: 'tab-stop',\n behaviour: 'Is reachable with Tab',\n baseUi: ['Button', 'Toggle', 'Checkbox', 'Tabs', 'Toolbar', 'ScrollArea'],\n owners: ['Button', 'IconButton', 'Link'],\n reads: 'tabIndex that can be 0 or more, on an element that is not a control',\n },\n {\n id: 'scroll',\n behaviour: 'Scrolls with our scrollbar',\n baseUi: ['ScrollArea'],\n owners: ['ScrollArea'],\n reads: 'overflow-auto or overflow-scroll (x or y, behind any variant) in a string, or overflow auto or scroll in a style',\n },\n]\n\ninterface Node {\n type: string\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n parent?: Node\n [key: string]: unknown\n}\n\nconst PAGE_TARGETS = new Set(['window', 'document', 'globalThis', 'self', 'document.body', 'document.documentElement', 'window.document'])\n\n/** Where an escape for this node is written: its object property, its element, its array item, or its statement. */\nfunction anchorOf(node: Node): Node {\n if (node.type === 'FunctionDeclaration') {\n return node.parent && /^Export/.test(node.parent.type) ? node.parent : node\n }\n let child = node\n for (let p = node.parent; p; child = p, p = p.parent) {\n if (p.type === 'JSXOpeningElement' || p.type === 'Property' || p.type === 'MethodDefinition' || p.type === 'PropertyDefinition') return p\n if (p.type === 'ArrayExpression') return child\n if (p.type !== 'BlockStatement' && /(Statement|Declaration)$/.test(p.type)) return p\n }\n return node\n}\n\nfunction enclosingFunction(node: Node): Node | undefined {\n for (let p = node.parent; p; p = p.parent) {\n if (p.type === 'FunctionDeclaration' || p.type === 'FunctionExpression' || p.type === 'ArrowFunctionExpression') return p\n }\n return undefined\n}\n\nfunction stringOf(node: Node | undefined | null): string | undefined {\n if (!node) return undefined\n if (node.type === 'Literal' && typeof node.value === 'string') return node.value\n const quasis = node.quasis as { value: { cooked: string | null } }[] | undefined\n const expressions = node.expressions as unknown[] | undefined\n if (node.type === 'TemplateLiteral' && expressions?.length === 0) return quasis?.[0]?.value.cooked ?? undefined\n return undefined\n}\n\n/** Every string a JSX attribute's value can be: `\"x\"`, `{'x'}`, `{a ? 'x' : 'y'}`, `{a && 'x'}`. */\nfunction stringsOf(node: Node | undefined | null): string[] {\n if (!node) return []\n if (node.type === 'JSXExpressionContainer') return stringsOf(node.expression as Node)\n const s = stringOf(node)\n if (s !== undefined) return [s]\n if (node.type === 'ConditionalExpression') return [...stringsOf(node.consequent as Node), ...stringsOf(node.alternate as Node)]\n if (node.type === 'LogicalExpression') return [...stringsOf(node.left as Node), ...stringsOf(node.right as Node)]\n return []\n}\n\n/** Whether a `tabIndex` value can be 0 or more, as far as the code spells it out. */\nfunction canBeTabStop(node: Node | undefined | null): boolean {\n if (!node) return false\n if (node.type === 'JSXExpressionContainer') return canBeTabStop(node.expression as Node)\n if (node.type === 'Literal') {\n if (typeof node.value === 'number') return node.value >= 0\n if (typeof node.value === 'string') return /^\\s*\\d+\\s*$/.test(node.value)\n return false\n }\n if (node.type === 'ConditionalExpression') return canBeTabStop(node.consequent as Node) || canBeTabStop(node.alternate as Node)\n if (node.type === 'LogicalExpression') return canBeTabStop(node.left as Node) || canBeTabStop(node.right as Node)\n if (node.type === 'TSAsExpression' || node.type === 'TSNonNullExpression') return canBeTabStop(node.expression as Node)\n return false\n}\n\n/** A class token's utility, past its variants: `[&_pre]:overflow-x-auto` \u2192 `overflow-x-auto`. */\nexport function utilityOf(token: string): string {\n let depth = 0\n let last = -1\n for (let i = 0; i < token.length; i++) {\n const c = token[i]\n if (c === '[') depth++\n else if (c === ']') depth--\n else if (c === ':' && depth === 0) last = i\n }\n return token.slice(last + 1).replace(/^!/, '').replace(/!$/, '')\n}\n\n/** The Base UI module an import names, or `undefined` when it is not Base UI. `''` is the package root. */\nexport function baseUiModule(source: string): string | undefined {\n const m = /^@base-ui(?:-components)?\\/([^/]+)(?:\\/(.+))?$/.exec(source)\n if (!m) return undefined\n const [, pkg, sub] = m\n return pkg === 'react' ? (sub ?? '') : `${pkg}${sub ? `/${sub}` : ''}`\n}\n\nfunction isKeySubject(node: Node | undefined): boolean {\n if (!node) return false\n if (node.type === 'Identifier') return node.name === 'key' || node.name === 'code'\n if (node.type !== 'MemberExpression' || node.computed) return false\n const property = node.property as Node\n return property.type === 'Identifier' && (property.name === 'key' || property.name === 'code')\n}\n\nfunction pageTarget(node: Node, text: string): boolean {\n return (node.type === 'Identifier' || node.type === 'MemberExpression') && PAGE_TARGETS.has(text)\n}\n\nexport const noRebuiltBehaviour: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Behaviour @estiva-app/ui already owns, rebuilt by hand in an app' },\n schema: [],\n messages: {\n baseUi: 'Only @estiva-app/ui imports Base UI (`{{module}}`). Use `{{use}}` from @estiva-app/ui.{{more}}',\n baseUiNoPart:\n 'Only @estiva-app/ui imports Base UI (`{{module}}`), and it has no part built on it yet. Do not build one here: ask Katerina, and it gets made in @estiva-app/ui.',\n portal:\n 'A layer put on top of the page by hand (`createPortal`). Every floating part of @estiva-app/ui carries its own: `DialogShell` for a dialog, `Popover` for a panel, `Menu`, `Select`, `Tooltip`, `PreviewCard`, `Toast`.',\n press:\n 'A `{{event}}` listener on `{{target}}`: closing on a press outside, by hand. `Popover`, `Menu`, `Select`, `DialogShell` and `PreviewCard` from @estiva-app/ui close themselves.',\n key: 'A `{{event}}` listener on `{{target}}`: keys taken for the whole page, by hand. `DialogShell`, `Popover`, `Menu` and `Select` from @estiva-app/ui close on Escape themselves; `Menu`, `Select`, `Tabs` and `Toolbar` move with the arrow keys.',\n focus:\n 'A `{{event}}` listener on `{{target}}`: focus held by hand. `DialogShell` and `CommandPalette` from @estiva-app/ui keep focus inside and give it back.',\n follow:\n 'A `{{event}}` listener on `{{target}}`: following an anchor by hand. `Popover`, `Menu`, `Select`, `Tooltip` and `PreviewCard` from @estiva-app/ui stay attached to theirs.',\n scrollLock: \"The page's scroll locked by hand. `DialogShell` from @estiva-app/ui stops the page scrolling while it is open, and gives it back.\",\n walking:\n 'Arrow keys handled by hand (`{{key}}`). `Menu`, `Select`, `ChipInput`, `CommandPalette`, `Tabs` and `Toolbar` from @estiva-app/ui move through their items themselves.',\n tabKey: 'The Tab key handled by hand. `DialogShell` and `CommandPalette` from @estiva-app/ui keep focus inside themselves.',\n role: 'A hand-written `role=\"{{role}}\"` is a hand-made {{thing}}. Use `{{use}}` from @estiva-app/ui.{{more}}',\n roleNoPart:\n 'A hand-written `role=\"{{role}}\"` is a hand-made {{thing}}, and @estiva-app/ui has no part for one yet. Do not build one here: ask Katerina, and it gets made in @estiva-app/ui.',\n tabStop:\n '`tabIndex={{value}}` makes a `<{{element}}>` a Tab stop by hand. Use `Button`, `IconButton` or `Link` from @estiva-app/ui, which are reachable already.',\n scrollClass: \"`{{token}}` scrolls with the browser's scrollbar. Use `ScrollArea` from @estiva-app/ui, which draws ours.\",\n scrollStyle: \"`{{style}}` scrolls with the browser's scrollbar. Use `ScrollArea` from @estiva-app/ui, which draws ours.\",\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n const { sourceCode } = context\n const text = (node: Node) => sourceCode.getText(node as unknown as Rule.Node)\n\n // One escape covers what the rule found at its anchor, and is counted once.\n const escapes = new Map<Node, boolean>()\n const escaped = (anchor: Node) => {\n if (!escapes.has(anchor)) escapes.set(anchor, isEscaped(context, anchor))\n return escapes.get(anchor) === true\n }\n const seen = new Set<string>()\n const report = (anchor: Node, at: Node, messageId: string, data: Record<string, string> = {}, once = `${at.range[0]}`) => {\n const key = `${anchor.range[0]}|${messageId}|${once}`\n if (seen.has(key)) return\n seen.add(key)\n if (escaped(anchor)) return\n context.report({ loc: at.loc, messageId, data })\n }\n\n const importSource = (node: Node, source: Node | undefined | null) => {\n const value = stringOf(source)\n if (value === undefined) return\n const module = baseUiModule(value)\n if (module === undefined) return\n const part = Object.hasOwn(BASE_UI_PARTS, module) ? BASE_UI_PARTS[module] : null\n const anchor = anchorOf(node)\n if (part) report(anchor, node, 'baseUi', { module: value, use: part.use, more: part.more ?? '' })\n else report(anchor, node, 'baseUiNoPart', { module: value })\n }\n\n const keyCompared = (node: Node, key: string | undefined) => {\n if (key === undefined) return\n const fn = enclosingFunction(node)\n const anchor = anchorOf(fn ?? node)\n if (WALKING_KEYS.includes(key)) report(anchor, node, 'walking', { key }, `walking@${fn?.range[0] ?? node.range[0]}`)\n else if (key === 'Tab') report(anchor, node, 'tabKey', {}, `tab@${fn?.range[0] ?? node.range[0]}`)\n }\n\n const classTokens = (node: Node, value: string) => {\n for (const token of value.split(/\\s+/)) {\n if (token && SCROLL_CLASS.test(utilityOf(token))) report(anchorOf(node), node, 'scrollClass', { token }, `class@${token}`)\n }\n }\n\n // `createPortal` imported: reported where it is called, or at the import when it never is.\n const portalImports = new Map<string, Node>()\n let portalCalled = false\n\n return {\n ImportDeclaration(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n importSource(node, node.source as Node)\n if (stringOf(node.source as Node) !== 'react-dom') return\n for (const specifier of node.specifiers as Node[]) {\n const imported = specifier.imported as Node | undefined\n if (specifier.type === 'ImportSpecifier' && imported?.name === 'createPortal') portalImports.set((specifier.local as Node).name as string, node)\n }\n },\n ExportNamedDeclaration(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n if (node.source) importSource(node, node.source as Node)\n },\n ExportAllDeclaration(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n importSource(node, node.source as Node)\n },\n ImportExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n importSource(node, node.source as Node)\n },\n\n CallExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const callee = node.callee as Node\n const args = node.arguments as Node[]\n\n if (callee.type === 'Identifier' && callee.name === 'require') importSource(node, args[0])\n\n if (callee.type === 'Identifier' && portalImports.has(callee.name as string)) {\n portalCalled = true\n report(anchorOf(node), node, 'portal')\n }\n if (callee.type !== 'MemberExpression') return\n const object = callee.object as Node\n const property = callee.property as Node\n if (property.type !== 'Identifier') return\n\n if (property.name === 'createPortal') {\n report(anchorOf(node), node, 'portal')\n return\n }\n\n if (property.name === 'addEventListener') {\n const target = text(object)\n if (!pageTarget(object, target)) return\n const event = stringOf(args[0])\n const group = event === undefined ? undefined : PAGE_EVENTS[event]\n if (!event || !group) return\n report(anchorOf(node), node, group, { event, target })\n return\n }\n\n // ['ArrowUp', 'ArrowDown'].includes(event.key)\n if (property.name === 'includes' && object.type === 'ArrayExpression' && isKeySubject(args[0])) {\n for (const element of object.elements as Node[]) keyCompared(node, stringOf(element))\n }\n },\n\n AssignmentExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const left = node.left as Node\n if (left.type !== 'MemberExpression') return\n const property = left.property as Node\n const object = left.object as Node\n const handler = property.type === 'Identifier' ? /^on([a-z]+)$/.exec(property.name as string) : null\n if (handler && pageTarget(object, text(object)) && PAGE_EVENTS[handler[1]]) {\n report(anchorOf(node), node, PAGE_EVENTS[handler[1]], { event: handler[1], target: text(object) })\n return\n }\n if (/^document\\.(?:body|documentElement)\\.style\\.overflow[XY]?$/.test(text(left))) report(anchorOf(node), node, 'scrollLock')\n },\n\n BinaryExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n if (!['===', '==', '!==', '!='].includes(node.operator as string)) return\n const left = node.left as Node\n const right = node.right as Node\n if (isKeySubject(left)) keyCompared(node, stringOf(right))\n else if (isKeySubject(right)) keyCompared(node, stringOf(left))\n },\n\n SwitchCase(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const statement = node.parent as Node\n if (node.test && isKeySubject(statement.discriminant as Node)) keyCompared(node, stringOf(node.test as Node))\n },\n\n JSXAttribute(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const nameNode = node.name as Node\n if (nameNode.type !== 'JSXIdentifier') return\n const name = nameNode.name as string\n const element = node.parent as Node\n const value = node.value as Node | null\n\n if (name === 'role') {\n for (const role of stringsOf(value).flatMap((v) => v.trim().split(/\\s+/))) {\n if (!Object.hasOwn(ROLE_PARTS, role)) continue\n const { thing, part } = ROLE_PARTS[role]\n if (part) report(element, node, 'role', { role, thing, use: part.use, more: part.more ?? '' })\n else report(element, node, 'roleNoPart', { role, thing })\n return\n }\n return\n }\n\n if (name === 'tabIndex' || name === 'tabindex') {\n const tag = element.name as Node\n if (tag.type !== 'JSXIdentifier' || !/^[a-z]/.test(tag.name as string) || INTERACTIVE_ELEMENTS.has(tag.name as string)) return\n const attributes = element.attributes as Node[]\n const editable = attributes.some((a) => a.type === 'JSXAttribute' && /^contenteditable$/i.test(((a.name as Node).name as string) ?? ''))\n if (editable || !canBeTabStop(value)) return\n report(element, node, 'tabStop', { value: value ? text(value).replace(/^\\{|\\}$/g, '') : '', element: tag.name as string })\n return\n }\n\n if (name === 'style' && value?.type === 'JSXExpressionContainer') {\n const object = value.expression as Node\n if (object.type !== 'ObjectExpression') return\n for (const property of object.properties as Node[]) {\n if (property.type !== 'Property') continue\n const key = property.key as Node\n const keyName = key.type === 'Identifier' ? (key.name as string) : stringOf(key)\n if (!keyName || !/^overflow[XY]?$/.test(keyName)) continue\n const setting = stringOf(property.value as Node)\n if (setting === 'auto' || setting === 'scroll') report(element, property, 'scrollStyle', { style: `${keyName}: '${setting}'` }, `style@${keyName}`)\n }\n }\n },\n\n Literal(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n if (typeof node.value !== 'string') return\n const parent = node.parent\n if (parent && /^(Import|Export)/.test(parent.type)) return\n if (parent?.type === 'TSLiteralType' || parent?.type === 'TSExternalModuleReference') return\n classTokens(node, node.value)\n },\n\n TemplateElement(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const cooked = (node.value as { cooked: string | null }).cooked\n if (cooked && node.parent) classTokens(node.parent, cooked)\n },\n\n 'Program:exit'() {\n if (portalCalled) return\n for (const declaration of new Set(portalImports.values())) report(anchorOf(declaration), declaration, 'portal')\n },\n }\n },\n}\n", "import { existsSync, readFileSync, statSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport type { Rule, Scope } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * A part of the package is placed from outside, never restyled (UIG-9; Katerina's\n * ruling B8 of 13 September, \"only position and spacing pass into our\n * components\").\n *\n * Every part takes `className`, and some take a second class prop for an inner\n * box (`contentClassName`, `bodyClassName`\u2026). Through either, an app could push\n * a colour, a text size or a border into a part and quietly undo it: the token\n * lint only asks whether a class is a real token, never whether the part should\n * take it. This rule reads every class passed into a part and lets through only\n * placement \u2014 where the part sits and how much room it takes.\n *\n * **Which elements are parts: by where they come from, never by name.** No list\n * of names is kept, so a part added to the package later is covered the day it\n * is added.\n *\n * - In an app: anything imported from `@estiva-app/ui`, and anything imported\n * from the app's own files that is one of those \u2014 a re-export (Peek's\n * `components/ui/Button.tsx`), a wrapper that hands its props on to a part\n * (`{...rest}`), or a component that hands its own `className` on to a part\n * (Peek's `ConversationCard` into `Card`). Relative imports and the apps' `@/`\n * alias are followed; `@/` is the `src` folder beside the nearest\n * `package.json`.\n * - Inside the package (Katerina, 17 September): a name `src/index.ts` exports,\n * imported from a sibling file or declared in the same file.\n *\n * **What it reads:** a string, a template, `cn()`/`clsx()` and their arguments,\n * both sides of a condition, a `const` in the same file and the values of a\n * class map read from one. A class the code works out while it runs passes: the\n * rule cannot read it.\n *\n * `EmptyState` takes no padding either (Katerina's ruling 6 of 14 September):\n * its room comes from the box its rows live in.\n */\n\n// ---------------------------------------------------------------- the classes\n\n/** Where a part sits and how much room it takes. Read on the utility, after its variants. */\nexport const PLACEMENT: { what: string; pattern: RegExp }[] = [\n { what: 'space around', pattern: /^m[xytrblse]?-/ },\n { what: 'space inside', pattern: /^p[xytrblse]?-/ },\n { what: 'width and height', pattern: /^(?:w|h|size|min-w|min-h|max-w|max-h)-/ },\n { what: 'shown, and how it lays out', pattern: /^(?:hidden|block|inline|inline-block|inline-flex|inline-grid|flex|grid|contents|flow-root)$/ },\n { what: 'its place in a row or a grid', pattern: /^(?:grow|shrink)$|^(?:flex|basis|grow|shrink|order|gap|gap-x|gap-y|space-x|space-y|col|row|grid-cols|grid-rows|grid-flow|auto-cols|auto-rows)-/ },\n { what: 'alignment', pattern: /^(?:self|justify|justify-items|justify-self|items|place-content|place-items|place-self)-|^content-(?!\\[)/ },\n { what: 'position', pattern: /^(?:static|relative|absolute|fixed|sticky)$|^(?:inset|inset-x|inset-y|top|right|bottom|left|start|end|z)-/ },\n // Draws nothing: it names the part, so what is inside can answer its hover (`group-hover:`).\n { what: 'a name for hover', pattern: /^(?:group|peer)(?:\\/[\\w-]+)?$/ },\n]\n\n/**\n * A variant that draws another box or reaches inside the part: `before:`,\n * `after:`, `[&>*]:`, `*:`\u2026 A placement class behind one of these is not the\n * part's placement.\n */\nconst REACHING_VARIANT = /^\\[|^(?:before|after|placeholder|file|marker|selection|first-letter|first-line|backdrop|\\*|\\*\\*)$/\n\n/** A class list's variants and its utility: `sm:[&>*]:shrink-0` \u2192 `['sm', '[&>*]']`, `shrink-0`. */\nexport function splitClass(token: string): { variants: string[]; utility: string } {\n const variants: string[] = []\n let current = ''\n let depth = 0\n for (const character of token) {\n if (character === '[') depth += 1\n if (character === ']') depth -= 1\n if (character === ':' && depth === 0) {\n variants.push(current)\n current = ''\n } else current += character\n }\n return { variants, utility: current.replace(/^!/, '').replace(/!$/, '').replace(/^-/, '') }\n}\n\n/** Whether a class only places the part. */\nexport function isPlacement(token: string): boolean {\n const { variants, utility } = splitClass(token)\n if (variants.some((variant) => REACHING_VARIANT.test(variant))) return false\n return PLACEMENT.some(({ pattern }) => pattern.test(utility))\n}\n\nconst isPadding = (token: string) => {\n const { variants, utility } = splitClass(token)\n return !variants.some((variant) => REACHING_VARIANT.test(variant)) && /^p[xytrblse]?-/.test(utility)\n}\n\n/**\n * The props a part has for how it looks, named in the message. Held to the\n * package's source by `no-restyled-part.test.ts`: every prop here exists, and\n * every look prop an exported part has is here. A part missing from this table\n * has none, and the message says to ask for one.\n */\nexport const PART_LOOK_PROPS: Record<string, string[]> = {\n AppShell: ['variant'],\n Avatar: ['size'],\n AvatarGroup: ['size'],\n Banner: ['tone'],\n Button: ['variant', 'size'],\n Card: ['fill', 'hover', 'attention', 'selected', 'active', 'hovered', 'quietUntilHover', 'unreadable', 'clip'],\n Checkbox: ['row'],\n Chip: ['type'],\n Divider: ['tone', 'orientation'],\n EmptyState: ['scope'],\n FieldLine: ['tone'],\n IconButton: ['variant', 'pressed', 'glow'],\n InputChip: ['truncate'],\n Link: ['variant', 'truncate'],\n MenuItem: ['size', 'selected', 'destructive'],\n MenuSub: ['selected'],\n NavItem: ['active'],\n Person: ['size'],\n ProgressBar: ['variant'],\n Property: ['layout'],\n RailItem: ['active'],\n Reaction: ['pressed'],\n ReactionPicker: ['surface'],\n SectionLabel: ['tone'],\n Select: ['size'],\n Tabs: ['size'],\n TextInput: ['size'],\n Toast: ['type'],\n Toolbar: ['surface'],\n ToolbarButton: ['variant', 'pressed', 'glow'],\n TopBar: ['variant'],\n}\n\n/** The class props of a part: `className`, and the ones for an inner box. */\nconst CLASS_PROP = /^(?:className|[a-z][A-Za-z]*ClassName)$/\n\n// ---------------------------------------------------------------- the nodes\n\ninterface Node {\n type: string\n range: [number, number]\n loc?: NonNullable<Rule.Node['loc']>\n parent?: Node\n [key: string]: unknown\n}\n\nconst child = (node: Node, key: string) => node[key] as Node | null | undefined\nconst children = (node: Node, key: string) => (node[key] as (Node | null)[] | undefined) ?? []\nconst nameOf = (node: Node | null | undefined): string | undefined =>\n node?.type === 'Identifier' || node?.type === 'JSXIdentifier' ? (node.name as string) : node?.type === 'Literal' && typeof node.value === 'string' ? node.value : undefined\n\n/** Walk every node under `root`, skipping the parser's bookkeeping keys. */\nfunction walk(root: Node, visit: (node: Node) => void): void {\n const stack: Node[] = [root]\n while (stack.length) {\n const node = stack.pop() as Node\n visit(node)\n for (const key of Object.keys(node)) {\n if (key === 'parent' || key === 'loc' || key === 'range' || key === 'tokens' || key === 'comments') continue\n const value = node[key]\n if (Array.isArray(value)) for (const item of value) { if (item && typeof (item as Node).type === 'string') stack.push(item as Node) }\n else if (value && typeof (value as Node).type === 'string') stack.push(value as Node)\n }\n }\n}\n\n// ---------------------------------------------------------------- the parts\n\n/**\n * What a name is to this rule: the part it draws, and which of the caller's\n * class props reach which of the part's (`all` for a part, a re-export or a\n * wrapper; a map for a component that hands on its own `className`). `via` is\n * the app's own component in between, for the message.\n */\nexport interface PartBinding {\n part: string\n props: 'all' | Record<string, string>\n via?: string\n}\n\ninterface Parser {\n parseForESLint?: (code: string, options: unknown) => { ast: Node }\n parse?: (code: string, options: unknown) => Node\n}\n\ninterface ModuleFacts {\n mtime: number\n exports: Map<string, PartBinding>\n}\n\nconst PACKAGE = '@estiva-app/ui'\nconst moduleCache = new Map<string, ModuleFacts>()\nconst packageDirCache = new Map<string, string | null>()\nconst packagePartsCache = new Map<string, { mtime: number; parts: Set<string> }>()\n\nfunction parseFile(parser: Parser, filePath: string): Node | null {\n const code = readFileSync(filePath, 'utf8')\n const options = { filePath, ecmaVersion: 'latest', sourceType: 'module', ecmaFeatures: { jsx: filePath.endsWith('x') }, range: true, loc: true }\n try {\n if (parser.parseForESLint) return parser.parseForESLint(code, options).ast\n if (parser.parse) return parser.parse(code, options)\n } catch {\n // A file that does not parse is its own lint's business; it hands on no parts.\n }\n return null\n}\n\n/** The nearest folder holding a `package.json`, from a file. */\nfunction packageDirOf(file: string): string | null {\n const start = dirname(resolve(file))\n if (packageDirCache.has(start)) return packageDirCache.get(start) ?? null\n let dir = start\n for (;;) {\n if (existsSync(join(dir, 'package.json'))) break\n const up = dirname(dir)\n if (up === dir) {\n dir = ''\n break\n }\n dir = up\n }\n packageDirCache.set(start, dir || null)\n return dir || null\n}\n\nfunction resolveModule(fromFile: string, specifier: string): string | null {\n let base: string\n if (specifier.startsWith('.')) base = resolve(dirname(fromFile), specifier)\n else if (specifier.startsWith('@/')) {\n const dir = packageDirOf(fromFile)\n if (!dir) return null\n base = join(dir, 'src', specifier.slice(2))\n } else return null\n for (const candidate of [base, `${base}.tsx`, `${base}.ts`, join(base, 'index.tsx'), join(base, 'index.ts')]) {\n if (existsSync(candidate) && statSync(candidate).isFile()) return candidate\n }\n return null\n}\n\n/** The names this package's `src/index.ts` exports, when the file lives in `@estiva-app/ui` itself. */\nfunction packagePartsFor(file: string, parser: Parser): Set<string> | null {\n const dir = packageDirOf(file)\n if (!dir) return null\n let name: string | undefined\n try {\n name = (JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as { name?: string }).name\n } catch {\n return null\n }\n if (name !== PACKAGE) return null\n const index = join(dir, 'src', 'index.ts')\n if (!existsSync(index)) return null\n const mtime = statSync(index).mtimeMs\n const cached = packagePartsCache.get(index)\n if (cached && cached.mtime === mtime) return cached.parts\n const parts = new Set<string>()\n const ast = parseFile(parser, index)\n for (const statement of ast ? children(ast, 'body') : []) {\n if (statement?.type !== 'ExportNamedDeclaration' || statement.exportKind === 'type') continue\n for (const specifier of children(statement, 'specifiers')) {\n const exported = nameOf(child(specifier as Node, 'exported'))\n if (specifier?.exportKind !== 'type' && exported && /^[A-Z][a-z]/.test(exported)) parts.add(exported)\n }\n }\n packagePartsCache.set(index, { mtime, parts })\n return parts\n}\n\n/** A function component declared in a module: its name, and the function. */\nfunction functionComponents(program: Node): Map<string, Node> {\n const found = new Map<string, Node>()\n const unwrap = (node: Node | null | undefined): Node | null => {\n let current = node\n while (current?.type === 'CallExpression' && children(current, 'arguments').length) {\n const callee = child(current, 'callee')\n const text = callee?.type === 'Identifier' ? nameOf(callee) : callee?.type === 'MemberExpression' ? nameOf(child(callee, 'property')) : undefined\n if (text !== 'forwardRef' && text !== 'memo') return null\n current = children(current, 'arguments')[0]\n }\n return current?.type === 'ArrowFunctionExpression' || current?.type === 'FunctionExpression' ? current : null\n }\n walk(program, (node) => {\n if (node.type === 'FunctionDeclaration') {\n const name = nameOf(child(node, 'id'))\n if (name && /^[A-Z]/.test(name)) found.set(name, node)\n } else if (node.type === 'VariableDeclarator') {\n const name = nameOf(child(node, 'id'))\n const fn = unwrap(child(node, 'init'))\n if (name && /^[A-Z]/.test(name) && fn) found.set(name, fn)\n }\n })\n return found\n}\n\n/**\n * The parts a module's names stand for. `ownFile` is the file being linted: its\n * imports are read the same way, so a wrapper declared beside its use counts.\n */\nfunction moduleParts(file: string, program: Node, parser: Parser, stack: Set<string>): { locals: Map<string, PartBinding | 'namespace'>; exports: Map<string, PartBinding> } {\n const locals = new Map<string, PartBinding | 'namespace'>()\n const packageParts = packagePartsFor(file, parser)\n const body = children(program, 'body')\n\n const exportsOf = (specifier: string): Map<string, PartBinding> | 'package' | null => {\n if (specifier === PACKAGE) return 'package'\n const target = resolveModule(file, specifier)\n if (!target) return null\n if (packageParts) return 'package'\n return moduleExports(target, parser, stack)\n }\n\n for (const statement of body) {\n if (statement?.type !== 'ImportDeclaration' || statement.importKind === 'type') continue\n const source = exportsOf(String((child(statement, 'source') as Node).value))\n if (!source) continue\n for (const specifier of children(statement, 'specifiers')) {\n if (!specifier || specifier.importKind === 'type') continue\n const local = nameOf(child(specifier, 'local'))\n if (!local) continue\n if (specifier.type === 'ImportNamespaceSpecifier') {\n if (source === 'package' && !packageParts) locals.set(local, 'namespace')\n continue\n }\n const imported = specifier.type === 'ImportDefaultSpecifier' ? 'default' : nameOf(child(specifier, 'imported'))\n if (!imported) continue\n if (source === 'package') {\n const isPart = packageParts ? packageParts.has(imported) : /^[A-Z]/.test(imported)\n if (isPart) locals.set(local, { part: imported, props: 'all' })\n } else if (source.has(imported)) locals.set(local, source.get(imported) as PartBinding)\n }\n }\n\n // Inside the package, a part used in the file that declares it.\n const components = functionComponents(program)\n if (packageParts) for (const name of components.keys()) if (packageParts.has(name) && !locals.has(name)) locals.set(name, { part: name, props: 'all' })\n\n // In an app, a component that hands its props, or its own className, on to a part.\n if (!packageParts) {\n let changed = true\n for (let round = 0; changed && round < 10; round += 1) {\n changed = false\n for (const [name, fn] of components) {\n const binding = handsOnTo(fn, (tag) => bindingOfTag(tag, locals))\n if (!binding) continue\n const next = { ...binding, via: name }\n const previous = locals.get(name)\n if (!previous || JSON.stringify(previous) !== JSON.stringify(next)) {\n if (previous && previous !== 'namespace' && !previous.via) continue\n locals.set(name, next)\n changed = true\n }\n }\n }\n }\n\n const exports = new Map<string, PartBinding>()\n const localBinding = (name: string | undefined) => {\n const binding = name ? locals.get(name) : undefined\n return binding && binding !== 'namespace' ? binding : undefined\n }\n for (const statement of body) {\n if (!statement) continue\n if (statement.type === 'ExportNamedDeclaration') {\n const declaration = child(statement, 'declaration')\n if (declaration?.type === 'FunctionDeclaration') {\n const name = nameOf(child(declaration, 'id'))\n const binding = localBinding(name)\n if (name && binding) exports.set(name, binding)\n } else if (declaration?.type === 'VariableDeclaration') {\n for (const declarator of children(declaration, 'declarations')) {\n const name = nameOf(child(declarator as Node, 'id'))\n const init = child(declarator as Node, 'init')\n const binding = localBinding(name) ?? (init?.type === 'Identifier' ? localBinding(nameOf(init)) : undefined)\n if (name && binding) exports.set(name, binding)\n }\n }\n const source = child(statement, 'source')\n const from = source ? exportsOf(String(source.value)) : null\n for (const specifier of children(statement, 'specifiers')) {\n if (!specifier || specifier.exportKind === 'type') continue\n const local = nameOf(child(specifier, 'local'))\n const exported = nameOf(child(specifier, 'exported'))\n if (!local || !exported) continue\n if (!source) {\n const binding = localBinding(local)\n if (binding) exports.set(exported, binding)\n } else if (from === 'package') {\n if (/^[A-Z]/.test(local)) exports.set(exported, { part: local, props: 'all' })\n } else if (from?.has(local)) exports.set(exported, from.get(local) as PartBinding)\n }\n } else if (statement.type === 'ExportAllDeclaration' && !child(statement, 'exported')) {\n const from = exportsOf(String((child(statement, 'source') as Node).value))\n if (from && from !== 'package') for (const [name, binding] of from) exports.set(name, binding)\n } else if (statement.type === 'ExportDefaultDeclaration') {\n const declaration = child(statement, 'declaration')\n const name = declaration?.type === 'Identifier' ? nameOf(declaration) : nameOf(child(declaration as Node, 'id'))\n const binding = localBinding(name)\n if (binding) exports.set('default', binding)\n }\n }\n return { locals, exports }\n}\n\nfunction moduleExports(file: string, parser: Parser, stack: Set<string>): Map<string, PartBinding> {\n const mtime = statSync(file).mtimeMs\n const cached = moduleCache.get(file)\n if (cached && cached.mtime === mtime) return cached.exports\n if (stack.has(file)) return new Map()\n stack.add(file)\n const program = parseFile(parser, file)\n const exports = program ? moduleParts(file, program, parser, stack).exports : new Map<string, PartBinding>()\n stack.delete(file)\n moduleCache.set(file, { mtime, exports })\n return exports\n}\n\nfunction bindingOfTag(tag: Node | null | undefined, locals: Map<string, PartBinding | 'namespace'>): PartBinding | undefined {\n if (!tag) return undefined\n if (tag.type === 'JSXIdentifier') {\n const binding = locals.get(tag.name as string)\n return binding && binding !== 'namespace' ? binding : undefined\n }\n if (tag.type === 'JSXMemberExpression') {\n const object = child(tag, 'object')\n const property = nameOf(child(tag, 'property'))\n if (object?.type === 'JSXIdentifier' && locals.get(object.name as string) === 'namespace' && property) return { part: property, props: 'all' }\n }\n return undefined\n}\n\n/**\n * Whether a function component hands its props on to a part: its rest or its\n * whole props spread onto one (a wrapper), or its own class props passed into\n * one's class props (a component that places a part by its caller's word).\n */\nfunction handsOnTo(fn: Node, bindingOf: (tag: Node | null | undefined) => PartBinding | undefined): PartBinding | undefined {\n const param = children(fn, 'params')[0]\n if (!param) return undefined\n let restName: string | undefined\n let propsName: string | undefined\n const classParams = new Map<string, string>()\n if (param.type === 'ObjectPattern') {\n for (const property of children(param, 'properties')) {\n if (!property) continue\n if (property.type === 'RestElement') restName = nameOf(child(property, 'argument'))\n else if (property.type === 'Property') {\n const key = nameOf(child(property, 'key'))\n let value = child(property, 'value')\n if (value?.type === 'AssignmentPattern') value = child(value, 'left')\n const local = nameOf(value)\n if (key && local && CLASS_PROP.test(key)) classParams.set(local, key)\n }\n }\n } else if (param.type === 'Identifier') propsName = nameOf(param)\n\n let wrapper: PartBinding | undefined\n const forwarded: { part?: string; props: Record<string, string> } = { props: {} }\n const body = child(fn, 'body')\n if (!body) return undefined\n walk(body, (node) => {\n if (wrapper || node.type !== 'JSXOpeningElement') return\n const binding = bindingOf(child(node, 'name'))\n if (!binding) return\n for (const attribute of children(node, 'attributes')) {\n if (!attribute) continue\n if (attribute.type === 'JSXSpreadAttribute') {\n const argument = nameOf(child(attribute, 'argument'))\n if (argument && (argument === restName || argument === propsName)) wrapper = { part: binding.part, props: binding.props }\n continue\n }\n const prop = nameOf(child(attribute, 'name'))\n if (!prop || !CLASS_PROP.test(prop)) continue\n const partProp = binding.props === 'all' ? prop : binding.props[prop]\n if (!partProp) continue\n walk(attribute, (inner) => {\n let callerProp: string | undefined\n if (inner.type === 'Identifier') callerProp = classParams.get(inner.name as string)\n if (inner.type === 'MemberExpression' && nameOf(child(inner, 'object')) === propsName) {\n const key = nameOf(child(inner, 'property'))\n if (key && CLASS_PROP.test(key)) callerProp = key\n }\n if (!callerProp) return\n if (forwarded.part && forwarded.part !== binding.part) return\n forwarded.part = binding.part\n forwarded.props[callerProp] = partProp\n })\n }\n })\n if (wrapper) return wrapper\n return forwarded.part ? { part: forwarded.part, props: forwarded.props } : undefined\n}\n\n// ---------------------------------------------------------------- reading a class list\n\nconst CLASS_FUNCTIONS = new Set(['cn', 'clsx', 'cx', 'twMerge', 'classNames'])\n\n/** The `const` a name stands for in this file, if it is one. */\nfunction constantOf(identifier: Node, scope: Scope.Scope | null): Node | undefined {\n let current = scope\n while (current) {\n const variable = current.set.get(identifier.name as string)\n if (variable) {\n const definition = variable.defs[0] as unknown as { type: string; node: Node; parent?: Node } | undefined\n if (variable.defs.length !== 1 || definition?.type !== 'Variable') return undefined\n if ((definition.parent as Node | undefined)?.kind !== 'const') return undefined\n return child(definition.node, 'init') ?? undefined\n }\n current = current.upper\n }\n return undefined\n}\n\n/**\n * Every class the code spells out for a value, as far as it can be read in this\n * file. `asMap` reads an object as a class map (its values) rather than as a\n * `clsx` object (its keys).\n */\nexport function classesOf(value: Node | null | undefined, scopeOf: (node: Node) => Scope.Scope | null, asMap = false, seen = new Set<Node>()): string[] {\n if (!value || seen.has(value) || seen.size > 200) return []\n seen.add(value)\n const read = (node: Node | null | undefined, map = false) => classesOf(node, scopeOf, map, seen)\n const words = (text: unknown) => (typeof text === 'string' ? text.split(/\\s+/).filter(Boolean) : [])\n switch (value.type) {\n case 'Literal':\n return words(value.value)\n case 'TemplateLiteral':\n return [...children(value, 'quasis').flatMap((quasi) => words((quasi?.value as { cooked?: string }).cooked)), ...children(value, 'expressions').flatMap((e) => read(e))]\n case 'JSXExpressionContainer':\n case 'TSAsExpression':\n case 'TSSatisfiesExpression':\n case 'TSNonNullExpression':\n case 'ChainExpression':\n return read(child(value, 'expression'), asMap)\n case 'ConditionalExpression':\n return [...read(child(value, 'consequent')), ...read(child(value, 'alternate'))]\n case 'LogicalExpression':\n return value.operator === '&&' ? read(child(value, 'right')) : [...read(child(value, 'left')), ...read(child(value, 'right'))]\n case 'BinaryExpression':\n return value.operator === '+' ? [...read(child(value, 'left')), ...read(child(value, 'right'))] : []\n case 'ArrayExpression':\n return children(value, 'elements').flatMap((e) => read(e))\n case 'ObjectExpression':\n return children(value, 'properties').flatMap((property) => {\n if (property?.type !== 'Property') return []\n return asMap ? read(child(property, 'value'), true) : property.computed ? [] : words(nameOf(child(property, 'key')))\n })\n case 'CallExpression': {\n const callee = child(value, 'callee')\n return callee?.type === 'Identifier' && CLASS_FUNCTIONS.has(callee.name as string) ? children(value, 'arguments').flatMap((a) => read(a)) : []\n }\n case 'Identifier': {\n const constant = constantOf(value, scopeOf(value))\n return constant ? read(constant, asMap) : []\n }\n case 'MemberExpression': {\n const object = child(value, 'object')\n const target = object?.type === 'Identifier' ? constantOf(object, scopeOf(object)) : object\n const map = target?.type === 'TSAsExpression' || target?.type === 'TSSatisfiesExpression' ? child(target, 'expression') : target\n if (map?.type !== 'ObjectExpression') return []\n const property = child(value, 'property')\n const key = value.computed ? (property?.type === 'Literal' ? String(property.value) : undefined) : nameOf(property)\n return children(map, 'properties').flatMap((entry) => {\n if (entry?.type !== 'Property') return []\n if (key !== undefined && nameOf(child(entry, 'key')) !== key) return []\n return read(child(entry, 'value'), true)\n })\n }\n default:\n return []\n }\n}\n\n// ---------------------------------------------------------------- the rule\n\nconst code = (items: string[]) => items.map((item) => `\\`${item}\\``).join(' ')\nconst or = (items: string[]) => (items.length === 1 ? code(items) : `${items.slice(0, -1).map((i) => `\\`${i}\\``).join(', ')} or \\`${items[items.length - 1]}\\``)\n\nexport const noRestyledPart: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Only placement passes into a part of @estiva-app/ui through a class prop' },\n schema: [],\n messages: {\n restyled:\n '{{classes}} on {{where}} changes how it looks. A part of @estiva-app/ui is placed from outside, never restyled: only space, size, flex and grid, and position pass in.{{use}} A look for what is around it goes on your own element around it.',\n emptyStatePadding:\n '{{classes}} pads {{where}}. EmptyState takes no padding (Katerina, 14 September): its room comes from the box its rows live in, so put the padding on that box.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n const parser = (context.languageOptions?.parser ?? {}) as Parser\n const file = context.filename\n const sourceCode = context.sourceCode\n const scopeOf = (node: Node) => sourceCode.getScope(node as unknown as Parameters<typeof sourceCode.getScope>[0])\n let locals: Map<string, PartBinding | 'namespace'> | undefined\n const escapes = new Map<Node, boolean>()\n const escaped = (anchor: Node) => {\n if (!escapes.has(anchor)) escapes.set(anchor, isEscaped(context, anchor))\n return escapes.get(anchor) === true\n }\n\n const check = (element: Node, binding: PartBinding, prop: string, value: Node | null | undefined, at: Node) => {\n const partProp = binding.props === 'all' ? prop : binding.props[prop]\n if (!partProp || !value) return\n const classes = classesOf(value, scopeOf)\n const handedOn = binding.props === 'all' ? 'its props' : `its \\`${prop}\\``\n const via = binding.via && binding.via !== binding.part ? `\\`${binding.via}\\` (it hands ${handedOn} to \\`${binding.part}\\`)` : `\\`${binding.part}\\``\n const where = `${via}${partProp === 'className' ? '' : `'s \\`${partProp}\\``}`\n const restyled = [...new Set(classes.filter((token) => !isPlacement(token)))]\n const padding = binding.part === 'EmptyState' && binding.props === 'all' ? [...new Set(classes.filter(isPadding))] : []\n if (!restyled.length && !padding.length) return\n if (escaped(element)) return\n if (restyled.length) {\n const props = PART_LOOK_PROPS[binding.part]\n const use = props ? ` Use its ${or(props)}.` : ` \\`${binding.part}\\` has no prop for this yet: ask Katerina, and it gets made in @estiva-app/ui.`\n context.report({ loc: at.loc as NonNullable<Rule.Node['loc']>, messageId: 'restyled', data: { classes: code(restyled), where, use } })\n }\n if (padding.length) context.report({ loc: at.loc as NonNullable<Rule.Node['loc']>, messageId: 'emptyStatePadding', data: { classes: code(padding), where } })\n }\n\n return {\n Program(program) {\n locals = moduleParts(file, program as unknown as Node, parser, new Set([file])).locals\n },\n JSXOpeningElement(ruleNode: Rule.Node) {\n const element = ruleNode as unknown as Node\n const binding = locals && bindingOfTag(child(element, 'name'), locals)\n if (!binding) return\n for (const attribute of children(element, 'attributes')) {\n if (!attribute) continue\n if (attribute.type === 'JSXAttribute') {\n const prop = nameOf(child(attribute, 'name'))\n if (prop && CLASS_PROP.test(prop)) check(element, binding, prop, child(attribute, 'value'), attribute)\n continue\n }\n // `{...{ className }}`, or a `const` object spread onto the part.\n let spread = child(attribute, 'argument')\n if (spread?.type === 'Identifier') spread = constantOf(spread, scopeOf(spread))\n while (spread?.type === 'TSAsExpression' || spread?.type === 'TSSatisfiesExpression') spread = child(spread, 'expression')\n if (spread?.type !== 'ObjectExpression') continue\n for (const property of children(spread, 'properties')) {\n const key = property?.type === 'Property' && !property.computed ? nameOf(child(property, 'key')) : undefined\n if (key && CLASS_PROP.test(key)) check(element, binding, key, child(property as Node, 'value'), property as Node)\n }\n }\n },\n }\n },\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\ninterface JSXOpeningElement {\n type: string\n name: { type: string; name?: string }\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n parent?: Parent\n}\n\ninterface Parent {\n type: string\n name?: { name?: string }\n openingElement?: unknown\n parent?: Parent\n}\n\n/**\n * The elements this package writes by hand. The set the count used (UIG-1,\n * docs/GATES.md \u00A75 and \u00A77): every element that carries behaviour or a role of\n * its own. A `div` or a `span` is layout and is nobody's business here.\n */\nexport const RAW_ELEMENTS = new Set(['a', 'button', 'input', 'textarea', 'select', 'dialog', 'form', 'label'])\n\n/**\n * A raw element nested inside another element, in the package itself (UIG-5,\n * the inward tracer).\n *\n * The package is allowed to write raw elements \u2014 that is what a primitive is.\n * Two shapes are right, and both are facts about the code rather than a\n * judgement:\n *\n * - **the component's own outermost element.** `NavItem` is an `<a>`, `Link` is\n * an `<a>`, a `MenuItem` outside a `Menu` is a `<button>`. A primitive owning\n * its element is the whole point of it.\n * - **handed to a Base UI `render` prop.** `render={<button type=\"button\" />}`\n * tells a Base UI part which element to be; the behaviour stays Base UI's.\n *\n * Anything else is an element buried inside a bigger component, where its look\n * and its behaviour are kept in step by nobody \u2014 the package's own version of\n * the rule the apps get from UIG-3 and UIG-7.\n *\n * It keeps its reason on the line above if it stays: `// @estiva-escape: <why>`.\n */\nexport const rawElementOutsideAWrapper: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'A raw element nested inside a component, rather than the component itself' },\n schema: [],\n messages: {\n nested:\n 'A raw <{{name}}> inside another element. In this package a raw element is either the component\\'s own outermost element or handed to a Base UI `render` prop; one buried inside belongs in a component of its own (Link, Button, MenuItem...).',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n // ESLint's types know ESTree's nodes, not JSX's; the parser hands this one over.\n JSXOpeningElement(node: Rule.Node) {\n const element = node as unknown as JSXOpeningElement\n const name = element.name.name\n if (element.name.type !== 'JSXIdentifier' || !name || !RAW_ELEMENTS.has(name)) return\n\n // An opening tag's own parent is its JSXElement: that is this element,\n // not an element around it.\n let parent = element.parent\n if (parent?.type === 'JSXElement' && parent.openingElement === (element as unknown)) parent = parent.parent\n\n // Whichever comes first going outward decides: an element around it\n // means it is nested; a `render` prop means Base UI draws it.\n for (let p = parent; p; p = p.parent) {\n if (p.type === 'JSXAttribute') {\n if (p.name?.name === 'render') return\n continue\n }\n if (p.type !== 'JSXElement' && p.type !== 'JSXFragment') continue\n if (isEscaped(context, element)) return\n context.report({ loc: element.loc, messageId: 'nested', data: { name } })\n return\n }\n },\n }\n },\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/// <reference types=\"node\" />\n/**\n * `@estiva-app/ui/eslint` \u2014 the UI Guardrails' lint rules, as a plugin (UIG-3,\n * seam S1 in docs/GATES.md \u00A716).\n *\n * A plugin rather than config, so every app \u2014 Peek, Ship, Leaf \u2014 gets a new\n * rule through an ordinary version bump, and an app's editor hook runs the\n * very rule code its CI runs.\n *\n * import estiva from '@estiva-app/ui/eslint'\n * export default [{ files: ['src/**\\/*.tsx'], ...estiva.configs.recommended }]\n *\n * Register it under `estiva` (the configs do): the rule ids are\n * `estiva/<rule>`, and `countGates` counts those ids.\n *\n * Built on its own by build.mjs, for Node, into `dist/eslint/`; nothing here\n * reaches the components' browser bundle.\n */\nimport { createRequire } from 'node:module'\nimport type { ESLint, Linter } from 'eslint'\nimport { componentHasAPage, componentHasAStory } from './has-a-page-and-a-story'\nimport { noHandRolledBehaviour } from './no-hand-rolled-behaviour'\nimport { noRawElement } from './no-raw-element'\nimport { noRebuiltBehaviour } from './no-rebuilt-behaviour'\nimport { noRestyledPart } from './no-restyled-part'\nimport { rawElementOutsideAWrapper } from './raw-element-outside-a-wrapper'\n\nexport { ESCAPE_MARKER, MIN_REASON, SETTINGS_KEY, isEscaped, type EstivaSettings } from './escape'\nexport { OWNED_BEHAVIOURS, type OwnedBehaviour } from './no-rebuilt-behaviour'\nexport { PART_LOOK_PROPS, PLACEMENT } from './no-restyled-part'\n\nconst { version } = createRequire(import.meta.url)('../../package.json') as { version: string }\n\n/** The name the configs register the plugin under, so every rule id is `estiva/<rule>`. */\nexport const PLUGIN_KEY = 'estiva'\n\n/**\n * The rules an **app** runs: they say an app must not build what the package\n * already has \u2014 a raw control (UIG-7), or a behaviour one of its parts owns\n * (UIG-8) \u2014 nor restyle a part it uses (UIG-9). `recommended` and `strict`\n * carry these and only these.\n */\nconst appRules = {\n 'no-raw-element': noRawElement,\n 'no-rebuilt-behaviour': noRebuiltBehaviour,\n 'no-restyled-part': noRestyledPart,\n}\n\n/**\n * The rules the **package itself** runs, pointed inward (UIG-5): don't bury a\n * raw element inside a component, don't rebuild what Base UI owns, don't ship a\n * component without a page or a story.\n *\n * They are in `configs.package`, never in `recommended`, on purpose. Peek and\n * Ship spread `recommended`, so a rule added here must not arrive in an app\n * with the next version bump: an app's components are not primitives, so\n * \"buried inside a component\" means nothing there (`no-raw-element` is the\n * app's version, UIG-7), and an app has no `.mdx` pages at all. `index.test.ts` holds the\n * apps' list to exactly the app rules.\n *\n * One rule is in both sets: `no-restyled-part` (UIG-9). The package restyles\n * none of its own parts either (Katerina, 17 September).\n */\nconst packageRules = {\n 'raw-element-outside-a-wrapper': rawElementOutsideAWrapper,\n 'no-hand-rolled-behaviour': noHandRolledBehaviour,\n 'component-has-a-page': componentHasAPage,\n 'component-has-a-story': componentHasAStory,\n 'no-restyled-part': noRestyledPart,\n}\n\nconst rules = { ...appRules, ...packageRules }\n\nconst plugin = {\n meta: { name: '@estiva-app/ui/eslint', version },\n rules,\n configs: {} as { recommended: Linter.Config; strict: Linter.Config; package: Linter.Config },\n} satisfies ESLint.Plugin\n\n/** The ids `recommended` and `strict` carry \u2014 what an app's gate runs and counts. */\nexport const APP_RULE_IDS = Object.keys(appRules).map((name) => `${PLUGIN_KEY}/${name}`)\n/** The ids `package` carries \u2014 what this package's own gate runs and counts (UIG-5). */\nexport const PACKAGE_RULE_IDS = Object.keys(packageRules).map((name) => `${PLUGIN_KEY}/${name}`)\n\n/**\n * `recommended` switches every **app** rule on at the level it was ruled at: an\n * error blocks, a warning is reported and never blocks. `strict` makes every app\n * rule an error. With every app rule an error, the two are the same today; they part\n * when the first warning-level rule arrives (UIG-25).\n *\n * `package` is the inward set (UIG-5), which only this package runs.\n */\nplugin.configs.recommended = {\n name: '@estiva-app/ui/recommended',\n plugins: { [PLUGIN_KEY]: plugin },\n rules: {\n [`${PLUGIN_KEY}/no-raw-element`]: 'error',\n [`${PLUGIN_KEY}/no-rebuilt-behaviour`]: 'error',\n [`${PLUGIN_KEY}/no-restyled-part`]: 'error',\n },\n}\nplugin.configs.strict = {\n name: '@estiva-app/ui/strict',\n plugins: { [PLUGIN_KEY]: plugin },\n rules: Object.fromEntries(APP_RULE_IDS.map((id) => [id, 'error'])),\n}\nplugin.configs.package = {\n name: '@estiva-app/ui/package',\n plugins: { [PLUGIN_KEY]: plugin },\n rules: Object.fromEntries(PACKAGE_RULE_IDS.map((id) => [id, 'error'])),\n}\n\nexport default plugin\n\nexport interface GateRuleCount {\n errors: number\n warnings: number\n escapes: number\n}\n\nexport interface GateCount {\n /** Per rule id, including rules with nothing to report. */\n rules: Record<string, GateRuleCount>\n /**\n * Reports of these rules that an `eslint-disable` directive silenced. Not\n * an escape: a gate fails on any of these (docs/GATES.md \u00A716, S4).\n */\n disabled: { filePath: string; line: number; ruleId: string }[]\n}\n\n/**\n * Count what a lint of these rules found, for `.gates-count.json` (seam S3).\n *\n * Run the lint with `settings: { estiva: { reportEscapes: true } }` for the\n * escapes to be counted; without it they are silent and count 0. A marker\n * with no reason, or inside a directive, counts as an error of its rule.\n *\n * `seed` is which rules the count lists when they found nothing, and it is the\n * app rules unless a caller says otherwise: an app's count file must not gain\n * rows for the inward rules (UIG-5) that its gate does not run. This package's\n * own count script passes `PACKAGE_RULE_IDS`.\n */\nexport function countGates(results: ESLint.LintResult[], seed: readonly string[] = APP_RULE_IDS): GateCount {\n const counts: Record<string, GateRuleCount> = Object.fromEntries(seed.map((id) => [id, { errors: 0, warnings: 0, escapes: 0 }]))\n const disabled: GateCount['disabled'] = []\n const ours = (ruleId: string | null | undefined): ruleId is string => typeof ruleId === 'string' && ruleId.startsWith(`${PLUGIN_KEY}/`)\n for (const result of results) {\n for (const message of result.messages) {\n // Seeded or not: every rule of this plugin that reported is counted, so a\n // lint of a set the caller did not name is still counted in full.\n if (!ours(message.ruleId)) continue\n const count = (counts[message.ruleId] ??= { errors: 0, warnings: 0, escapes: 0 })\n if (message.messageId === 'escaped') count.escapes += 1\n else if (message.severity === 2) count.errors += 1\n else count.warnings += 1\n }\n for (const message of result.suppressedMessages ?? []) {\n if (ours(message.ruleId)) disabled.push({ filePath: result.filePath, line: message.line, ruleId: message.ruleId })\n }\n }\n return { rules: counts, disabled }\n}\n", "import { existsSync } from 'node:fs'\nimport type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * A component of the package with no page, and one with no story (UIG-5, P2 and\n * P3).\n *\n * A component nobody can read about is a component nobody uses correctly, and\n * one nobody can look at is one nobody reviews. Both were at zero when these\n * were switched on; they are here so the next component cannot arrive without\n * them.\n *\n * The pair is by file name, beside the component, which is how this package is\n * laid out: `Button.tsx`, `Button.mdx`, `Button.stories.tsx`, `Button.test.tsx`\n * side by side in `src/`.\n *\n * **The false positive to avoid** (UIG-1 confirmed it is real): `FieldLine` and\n * `MenuItem` have a page and a story but no `.tsx` of their own \u2014 they are\n * exported from a sibling. These rules read a component file and ask for its\n * page and its story, never the other way round, so a page without a component\n * is not this rule's business.\n *\n * A file that stays without one says why at its top: `// @estiva-escape: <why>`.\n */\ninterface ProgramNode {\n body: { loc?: Rule.Node['loc']; range?: [number, number] }[]\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n}\n\n/** A component file: a `.tsx` in the package's source that is not a story or a test. */\nfunction componentFile(filename: string): boolean {\n return filename.endsWith('.tsx') && !/\\.(stories|test)\\.tsx$/.test(filename)\n}\n\nfunction sibling(filename: string, extension: string): string {\n return filename.replace(/\\.tsx$/, extension)\n}\n\n/**\n * Report on the file's first statement, so the escape is a comment at the top of\n * the file \u2014 the only place a reason for a missing page could go.\n */\nfunction reportOnFile(context: Rule.RuleContext, program: ProgramNode, messageId: string, data: Record<string, string>): void {\n const anchor = program.body[0] ?? program\n if (anchor.loc && anchor.range && isEscaped(context, { loc: anchor.loc, range: anchor.range })) return\n context.report({ loc: anchor.loc ?? program.loc, messageId, data })\n}\n\nexport const componentHasAPage: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Every component of the package has a usage page beside it' },\n schema: [],\n messages: {\n missing: '{{name}} has no page. Write {{page}} beside it \u2014 what it is, when, when not, how, and what it owns \u2014 or say why not at the top of the file.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n Program(node) {\n const filename = context.filename\n if (!componentFile(filename)) return\n const page = sibling(filename, '.mdx')\n if (existsSync(page)) return\n const name = filename.split(/[\\\\/]/).pop() ?? filename\n reportOnFile(context, node as unknown as ProgramNode, 'missing', { name, page: page.split(/[\\\\/]/).pop() ?? page })\n },\n }\n },\n}\n\nexport const componentHasAStory: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Every component of the package has a story beside it' },\n schema: [],\n messages: {\n missing: '{{name}} has no story. Write {{story}} beside it, so it can be seen and reviewed, or say why not at the top of the file.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n Program(node) {\n const filename = context.filename\n if (!componentFile(filename)) return\n const story = sibling(filename, '.stories.tsx')\n if (existsSync(story)) return\n const name = filename.split(/[\\\\/]/).pop() ?? filename\n reportOnFile(context, node as unknown as ProgramNode, 'missing', { name, story: story.split(/[\\\\/]/).pop() ?? story })\n },\n }\n },\n}\n", "import type { AST, Rule } from 'eslint'\n\n/**\n * The escape marker (UIG-3, seam S4 in docs/GATES.md \u00A716): one written reason\n * why one element stays as it is.\n *\n * A line comment directly above the element,\n *\n * // @estiva-escape: <reason>\n *\n * or, where the element is a JSX child, the JSX comment on the line above,\n *\n * {/* @estiva-escape: <reason> *\\/}\n *\n * with at least ten characters of reason, spaces not counted.\n *\n * Not `eslint-disable`. A directive switches a rule off without saying it was\n * meant, and the count of escapes (`.gates-count.json`) could not see it. A\n * marker written inside a directive that switches one of these rules off is\n * reported for that reason.\n *\n * The token lint's older notes (`eslint-disable-next-line <rule> -- @estiva-escape:\n * <reason>`, Katerina's ruling A2 of 15 September) are not read here: they\n * escape the token lint's rules, which are not this plugin's, and they stay as\n * they are (Katerina, 15 September).\n */\nexport const ESCAPE_MARKER = '@estiva-escape'\n\n/** Characters of reason, spaces not counted. */\nexport const MIN_REASON = 10\n\n/** The key under ESLint's `settings` this plugin reads. */\nexport const SETTINGS_KEY = 'estiva'\n\n/**\n * Every rule spreads these into its `meta.messages`, because `isEscaped`\n * reports through the rule that called it.\n */\nexport const ESCAPE_MESSAGES = {\n escapeWithoutReason: `An escape needs its reason, at least ${MIN_REASON} characters: \\`// ${ESCAPE_MARKER}: <why this stays>\\`. An escape with no reason hides nothing.`,\n escapeInDirective: `Write the escape as its own comment on the line above: \\`// ${ESCAPE_MARKER}: <reason>\\`. Inside an eslint-disable comment it switches the rule off instead of recording why.`,\n escaped: 'Escaped: {{reason}}',\n} as const\n\nexport interface EstivaSettings {\n /**\n * Report every sanctioned escape as a message with the id `escaped`, so a\n * count can read them. Off in the lint anyone runs; on only in the count.\n */\n reportEscapes?: boolean\n}\n\ninterface Located {\n loc?: AST.SourceLocation | null\n range?: [number, number]\n}\n\nconst DIRECTIVE = /^\\s*eslint-disable(?:-next-line|-line)?(?=\\s|$)([^]*)$/\n\n/** The rules a directive names: what comes before its ` -- ` description. None means every rule. */\nfunction directiveRules(rest: string): string[] {\n const dashes = rest.search(/(?:^|\\s)--(?:\\s|$)/)\n return (dashes === -1 ? rest : rest.slice(0, dashes)).split(/[\\s,]+/).filter(Boolean)\n}\n\n/** Only spaces and a JSX expression's closing brace between the marker and the element. */\nconst BETWEEN = /^[\\s}]*$/\n\n/**\n * Whether the element at `node` carries a valid escape on the line above.\n *\n * Every rule of this plugin calls it before it reports. It reports, through\n * that rule, a marker with too short a reason and a marker inside an\n * eslint-disable directive for this rule; either way the element is not\n * escaped, so the rule reports it too.\n */\nexport function isEscaped(context: Rule.RuleContext, node: Located): boolean {\n const { sourceCode } = context\n if (!node.loc || !node.range) return false\n const line = node.loc.start.line\n const nodeStart = node.range[0]\n\n const comment = sourceCode\n .getAllComments()\n .find((c) => c.loc && c.range && c.loc.end.line === line - 1 && BETWEEN.test(sourceCode.text.slice(c.range[1], nodeStart)))\n if (!comment?.loc) return false\n\n const at = comment.value.indexOf(ESCAPE_MARKER)\n if (at === -1) return false\n\n const directive = DIRECTIVE.exec(comment.value)\n if (directive) {\n const rules = directiveRules(directive[1])\n // A directive for other rules (the token lint's notes) is not an escape of this one.\n if (rules.length > 0 && !rules.includes(context.id)) return false\n context.report({ loc: comment.loc, messageId: 'escapeInDirective' })\n return false\n }\n\n const reason = comment.value\n .slice(at + ESCAPE_MARKER.length)\n .replace(/^:/, '')\n .trim()\n if (reason.replace(/\\s/g, '').length < MIN_REASON) {\n context.report({ loc: comment.loc, messageId: 'escapeWithoutReason' })\n return false\n }\n\n const settings = context.settings[SETTINGS_KEY] as EstivaSettings | undefined\n if (settings?.reportEscapes) context.report({ loc: comment.loc, messageId: 'escaped', data: { reason } })\n return true\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * Behaviour Base UI already owns, written by hand inside the package (UIG-5,\n * P1 \u2014 the migration's standing rule D6 as a machine).\n *\n * This is the rule with the most to lose. A hand-made portal or a global\n * listener inside `DialogShell` is inherited by every caller in every app, and\n * nobody sees it from there.\n *\n * Two facts, both mechanical, both the signature of a floating part rebuilt by\n * hand:\n *\n * - **`createPortal`**, or importing it from `react-dom`. Base UI's parts carry\n * their own portal.\n * - **a listener on `window` or `document`** for the events a floating part\n * lives on \u2014 resize, scroll, an outside press, a key. Base UI's Positioner\n * follows the anchor and its Root closes on an outside press and on Escape.\n *\n * What it deliberately does not try to read: measuring arithmetic. `Popover`\n * hands Base UI a virtual anchor with a `getBoundingClientRect`, which is the\n * documented way to anchor to a rectangle rather than an element, and a rule\n * that guessed at arithmetic would report it. Anything that shape is caught by\n * a reader, not by this.\n *\n * A place that keeps one says why on the line above: `// @estiva-escape: <why>`.\n */\nconst FLOATING_EVENTS = new Set(['resize', 'scroll', 'mousedown', 'pointerdown', 'keydown', 'keyup', 'focusin', 'focusout', 'click'])\n\ninterface Node {\n type: string\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n}\n\ninterface Identifier extends Node {\n name: string\n}\n\ninterface ImportDeclaration extends Node {\n source: { value: unknown }\n specifiers: { type: string; imported?: { name?: string }; local?: { name?: string }; loc?: Rule.Node['loc']; range?: [number, number] }[]\n}\n\ninterface CallExpression extends Node {\n callee: { type: string; name?: string; object?: { type: string; name?: string }; property?: { type: string; name?: string } }\n arguments: { type: string; value?: unknown }[]\n parent?: { type: string; loc?: Rule.Node['loc']; range?: [number, number]; parent?: CallExpression['parent'] }\n}\n\n/**\n * The statement a call sits in, which is what an escape is written above:\n * `return createPortal(\u2026)` puts the call in the middle of its line, and a\n * comment above the line is above the statement.\n */\nfunction statement(node: { loc: NonNullable<Rule.Node['loc']>; range: [number, number]; parent?: CallExpression['parent'] }): {\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n} {\n for (let p = node.parent; p; p = p.parent) {\n if (!/(Statement|Declaration)$/.test(p.type)) continue\n if (p.loc && p.range) return { loc: p.loc, range: p.range }\n break\n }\n return { loc: node.loc, range: node.range }\n}\n\nexport const noHandRolledBehaviour: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Overlay behaviour written by hand where Base UI has a part (D6)' },\n schema: [],\n messages: {\n portal:\n 'A portal written by hand. Base UI\\'s parts carry their own (Popover, Menu, Select, Tooltip, Dialog, Toast): use the part, or say why this one stays.',\n listener:\n 'A `{{event}}` listener on `{{target}}`. A floating part follows its anchor and closes on an outside press and on Escape by itself (Base UI Positioner and Root): use the part, or say why this one stays.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n ImportDeclaration(node: Rule.Node) {\n const declaration = node as unknown as ImportDeclaration\n if (declaration.source.value !== 'react-dom') return\n for (const specifier of declaration.specifiers) {\n if (specifier.type !== 'ImportSpecifier' || specifier.imported?.name !== 'createPortal') continue\n // The escape goes above the import line, not above the name inside it.\n if (isEscaped(context, declaration)) return\n context.report({ loc: declaration.loc, messageId: 'portal' })\n return\n }\n },\n CallExpression(node: Rule.Node) {\n const call = node as unknown as CallExpression\n const { callee } = call\n\n if (callee.type === 'Identifier' && callee.name === 'createPortal') {\n if (isEscaped(context, statement(call))) return\n context.report({ loc: call.loc, messageId: 'portal' })\n return\n }\n\n if (callee.type !== 'MemberExpression' || callee.property?.name !== 'addEventListener') return\n const target = callee.object?.type === 'Identifier' ? callee.object.name : undefined\n if (target !== 'window' && target !== 'document') return\n const [first] = call.arguments\n const event = first?.type === 'Literal' && typeof first.value === 'string' ? first.value : undefined\n if (!event || !FLOATING_EVENTS.has(event)) return\n if (isEscaped(context, statement(call))) return\n context.report({ loc: call.loc, messageId: 'listener', data: { event, target } })\n },\n }\n },\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\ninterface JSXAttributeValue {\n type: string\n value?: unknown\n expression?: { type: string; value?: unknown; expressions?: unknown[]; quasis?: { value: { cooked: string | null } }[] }\n}\n\ninterface JSXAttribute {\n type: 'JSXAttribute'\n name: { type: string; name?: string }\n value: JSXAttributeValue | null\n}\n\ninterface JSXOpeningElement {\n name: { type: string; name?: string }\n attributes: (JSXAttribute | { type: 'JSXSpreadAttribute' })[]\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n}\n\n/**\n * What the package has instead of one raw element: the component the message\n * names, and where one element does more than one job, the others after it.\n * `null` is an element the package has no part for yet.\n */\nexport interface RawElementPart {\n use: string\n more?: string\n}\n\n/**\n * The mapping (UIG-7), derived from the package's exports: every interactive\n * element in the HTML standard's list (\"interactive content\"), plus `<dialog>`,\n * `<form>` and `<progress>`, which have a part here. docs/GATES.md prints it.\n *\n * Not here, on purpose: `<summary>` (it lives inside a `<details>`, which is\n * reported), `<option>`, `<optgroup>` and `<datalist>` (they live inside a\n * `<select>` or beside an input), `<fieldset>` and `<legend>` (a group's frame,\n * no control of its own), and `<img>` without `usemap`, `<hr>`, `<kbd>`, which\n * are not controls. An `<audio>` or `<video>` is a control only with `controls`.\n */\nexport const RAW_ELEMENT_PARTS: Record<string, RawElementPart | null> = {\n a: { use: 'Link', more: ' For a chip, `InlineChip`; for a whole card, `Card` with `href`.' },\n button: { use: 'Button' },\n textarea: { use: 'Textarea' },\n select: { use: 'Select' },\n dialog: { use: 'DialogShell', more: ' To ask yes or no, `ConfirmDialog`.' },\n label: { use: 'Field', more: ' For words beside a tick box, `Checkbox` with `label`.' },\n details: { use: 'CollapsibleSection' },\n progress: { use: 'ProgressBar' },\n form: { use: 'Form' },\n meter: null,\n iframe: null,\n embed: null,\n object: null,\n audio: null,\n video: null,\n img: null,\n}\n\n/**\n * An `<input>` is as many controls as its `type`. A type missing from here\n * (text, email, password, url, tel, number, or one the browser does not know)\n * is a text box.\n */\nexport const RAW_INPUT_PARTS: Record<string, RawElementPart | null> = {\n search: { use: 'SearchInput' },\n checkbox: { use: 'Checkbox' },\n file: { use: 'FilePicker' },\n submit: { use: 'Button' },\n button: { use: 'Button' },\n reset: { use: 'Button' },\n image: { use: 'Button' },\n radio: null,\n range: null,\n color: null,\n date: null,\n 'datetime-local': null,\n month: null,\n week: null,\n time: null,\n}\n\nconst TEXT_INPUT: RawElementPart = { use: 'TextInput' }\nconst ANY_INPUT: RawElementPart = {\n use: 'TextInput',\n more: ' For a search, `SearchInput`; for a tick box, `Checkbox`; to pick files, `FilePicker`.',\n}\n\nfunction attribute(element: JSXOpeningElement, name: string): JSXAttribute | undefined {\n return element.attributes.find((a): a is JSXAttribute => a.type === 'JSXAttribute' && a.name.name === name)\n}\n\n/** An attribute's value when the code spells it out, `undefined` when it is computed. */\nfunction literal(attr: JSXAttribute): string | boolean | undefined {\n const value = attr.value\n if (value === null) return true\n if (value.type === 'Literal') return typeof value.value === 'string' ? value.value : undefined\n if (value.type !== 'JSXExpressionContainer' || !value.expression) return undefined\n const expression = value.expression\n if (expression.type === 'Literal' && (typeof expression.value === 'string' || typeof expression.value === 'boolean')) return expression.value\n if (expression.type === 'TemplateLiteral' && expression.expressions?.length === 0) return expression.quasis?.[0]?.value.cooked ?? undefined\n return undefined\n}\n\n/** Present, and not written as `={false}`. */\nfunction isOn(element: JSXOpeningElement, name: string): boolean {\n const attr = attribute(element, name)\n return attr !== undefined && literal(attr) !== false\n}\n\ntype Found = { report: 'raw'; element: string; part: RawElementPart } | { report: 'noPart'; element: string } | null\n\n/** What this element is to the rule: a raw element with a part, one with none yet, or none of its business. */\nexport function classify(element: JSXOpeningElement): Found {\n if (element.name.type !== 'JSXIdentifier' || !element.name.name) return null\n const name = element.name.name\n\n if (name === 'input') {\n const attr = attribute(element, 'type')\n const type = attr ? literal(attr) : 'text'\n if (typeof type !== 'string') return { report: 'raw', element: '<input>', part: ANY_INPUT }\n const key = type.toLowerCase()\n // A hidden input draws nothing and takes no focus: it is data, not a control.\n if (key === 'hidden') return null\n if (!(key in RAW_INPUT_PARTS)) return { report: 'raw', element: '<input>', part: TEXT_INPUT }\n const part = RAW_INPUT_PARTS[key]\n const shown = `<input type=\"${key}\">`\n return part ? { report: 'raw', element: shown, part } : { report: 'noPart', element: shown }\n }\n\n if (!Object.hasOwn(RAW_ELEMENT_PARTS, name)) return null\n if ((name === 'audio' || name === 'video') && !isOn(element, 'controls')) return null\n if (name === 'img' && !attribute(element, 'usemap') && !attribute(element, 'useMap')) return null\n\n const part = RAW_ELEMENT_PARTS[name]\n return part ? { report: 'raw', element: `<${name}>`, part } : { report: 'noPart', element: `<${name}>` }\n}\n\n/**\n * A raw interactive element in an app, where the package has a part for it\n * (UIG-3 began it with `<button>`; UIG-7 made it every element). A control\n * the app writes itself has a look, a focus ring and keys that nobody else\n * keeps in step with \u2014 and it looks nearly right, which is why nobody catches\n * it by eye. Every message names the part to use.\n *\n * An element the package has no part for yet is refused too, with a message\n * that says so: the part is made in the package, not by hand in an app\n * (Katerina, 16 September).\n *\n * Only a JSX element written with a lowercase name. `<Button>`,\n * `<Foo.button>` and `createElement('button')` are not this rule's business.\n */\nexport const noRawElement: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'A raw interactive element where @estiva-app/ui has a part, or where it needs one' },\n schema: [],\n messages: {\n raw: 'Use `{{use}}` from @estiva-app/ui instead of a raw {{element}}.{{more}}',\n noPart: '@estiva-app/ui has no part for a raw {{element}} yet. Do not build one here: ask Katerina, and it gets made in @estiva-app/ui.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n // ESLint's types know ESTree's nodes, not JSX's; the parser hands this one over.\n JSXOpeningElement(node: Rule.Node) {\n const element = node as unknown as JSXOpeningElement\n const found = classify(element)\n if (!found) return\n if (isEscaped(context, element)) return\n if (found.report === 'noPart') context.report({ loc: element.loc, messageId: 'noPart', data: { element: found.element } })\n else context.report({ loc: element.loc, messageId: 'raw', data: { element: found.element, use: found.part.use, more: found.part.more ?? '' } })\n },\n }\n },\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * Behaviour the package already owns, rebuilt by hand in an app (UIG-8, \"forbid\n * the reach\"). A hand-made dropdown, dialog, list or scrolling box does not look\n * wrong in review; it shows itself when somebody uses a keyboard, or has 81\n * folders. Every message names the part that already does it.\n *\n * What it reads is derived from the package source: which `@base-ui/react` part\n * each component imports, and so what it owns (`OWNED_BEHAVIOURS`, printed in\n * docs/GATES.md and reused by UIG-12's registry). `no-rebuilt-behaviour.test.ts`\n * holds the tables to the source, so a new part cannot be added without them.\n *\n * What it deliberately does not read, and why:\n *\n * - **A box that should scroll and does not.** A class rule finds the scrolling\n * box built by hand; it cannot find the one that was never built. Peek's\n * Folders column (fixed in peek 3dc663b) had no overflow class at all. Only a\n * check that opens the page can find that.\n * - **Enter and Escape** compared by hand. In a field or an editor they are\n * typing, and `Form` and `EditableText` own the ones that send or cancel.\n * Escape and every other key taken for the whole page are read, through the\n * listener.\n * - **aria-expanded, aria-pressed and the other states** written on a package\n * component: the component is already the package's (UIG-14's usage rules).\n * - **Measuring arithmetic**, for the reason UIG-5 gave: `Popover` takes a\n * rectangle to hang from, and a rule that guessed at arithmetic would report it.\n * - A listener on a variable that happens to hold the document.\n *\n * A place that keeps one says why on the line above: `// @estiva-escape: <why>`.\n * An escape above a statement, an element or an object property covers what the\n * rule found there.\n */\n\n/** The part a message names, and where one behaviour has more owners, the others after it. `null`: no part yet. */\nexport interface OwnerPart {\n use: string\n more?: string\n}\n\n/**\n * Every Base UI module, and the package component built on it. Read from the\n * package's imports (`src/*.tsx`); the test fails if a component imports a\n * module this does not name, or names a component that does not import it.\n * A module no component uses has no part yet, and neither do Base UI's utilities.\n */\nexport const BASE_UI_PARTS: Record<string, OwnerPart | null> = {\n 'alert-dialog': { use: 'DialogShell', more: ' To ask yes or no, `ConfirmDialog`.' },\n autocomplete: { use: 'CommandPalette' },\n avatar: { use: 'Avatar' },\n button: { use: 'Button', more: ' Icon only, `IconButton`.' },\n checkbox: { use: 'Checkbox' },\n collapsible: { use: 'CollapsibleSection' },\n combobox: { use: 'ChipInput' },\n dialog: { use: 'DialogShell', more: ' To search and act, `CommandPalette`.' },\n field: { use: 'Field' },\n fieldset: { use: 'Form' },\n form: { use: 'Form' },\n input: { use: 'TextInput', more: ' For a search, `SearchInput`.' },\n menu: { use: 'Menu' },\n popover: { use: 'Popover' },\n 'preview-card': { use: 'PreviewCard' },\n progress: { use: 'ProgressBar' },\n 'scroll-area': { use: 'ScrollArea' },\n select: { use: 'Select' },\n separator: { use: 'Divider' },\n tabs: { use: 'Tabs' },\n toast: { use: 'Toast' },\n toggle: { use: 'Reaction' },\n toolbar: { use: 'Toolbar' },\n tooltip: { use: 'Tooltip', more: ' Around a control, `WithTooltip`.' },\n accordion: null,\n 'checkbox-group': null,\n 'context-menu': null,\n drawer: null,\n menubar: null,\n meter: null,\n 'navigation-menu': null,\n 'number-field': null,\n 'otp-field': null,\n radio: null,\n 'radio-group': null,\n slider: null,\n switch: null,\n 'toggle-group': null,\n}\n\nconst LIST_PART: OwnerPart = {\n use: 'Select',\n more: ' To pick several, `ChipInput`; to search and act, `CommandPalette`; to tick several in a list, `Checkbox` with `row`.',\n}\n\nconst MESSAGE_PART: OwnerPart = { use: 'FieldLine', more: ' For a notice, `Banner`; for a message that comes and goes, `Toast`.' }\n\n/**\n * A role written by hand, and the part that sets it. Base UI's parts set most of\n * these; `tooltip` (Base UI's Tooltip sets none), `alert`, `status` and `link` are\n * the package's own. A role Base UI has a part for and this package has not got\n * yet is `null`. Not here, on purpose: `img`, `group`, `presentation`, `none`,\n * `region` and every landmark \u2014 they describe, they do not behave.\n */\nexport const ROLE_PARTS: Record<string, { thing: string; part: OwnerPart | null }> = {\n dialog: { thing: 'dialog', part: { use: 'DialogShell', more: ' To ask yes or no, `ConfirmDialog`.' } },\n alertdialog: { thing: 'dialog', part: { use: 'ConfirmDialog' } },\n menu: { thing: 'menu', part: { use: 'Menu' } },\n menuitem: { thing: 'menu', part: { use: 'Menu' } },\n menuitemcheckbox: { thing: 'menu', part: { use: 'Menu' } },\n menuitemradio: { thing: 'menu', part: { use: 'Menu' } },\n listbox: { thing: 'list', part: LIST_PART },\n option: { thing: 'list', part: LIST_PART },\n combobox: { thing: 'list', part: LIST_PART },\n tablist: { thing: 'set of tabs', part: { use: 'Tabs' } },\n tab: { thing: 'set of tabs', part: { use: 'Tabs' } },\n tabpanel: { thing: 'set of tabs', part: { use: 'Tabs' } },\n toolbar: { thing: 'toolbar', part: { use: 'Toolbar' } },\n progressbar: { thing: 'progress bar', part: { use: 'ProgressBar' } },\n checkbox: { thing: 'tick box', part: { use: 'Checkbox' } },\n separator: { thing: 'divider', part: { use: 'Divider' } },\n button: { thing: 'button', part: { use: 'Button', more: ' Icon only, `IconButton`.' } },\n link: { thing: 'link', part: { use: 'Link' } },\n tooltip: { thing: 'tooltip', part: { use: 'Tooltip', more: ' Around a control, `WithTooltip`.' } },\n alert: { thing: 'message', part: MESSAGE_PART },\n status: { thing: 'message', part: MESSAGE_PART },\n menubar: { thing: 'menu bar', part: null },\n switch: { thing: 'switch', part: null },\n radio: { thing: 'radio button', part: null },\n radiogroup: { thing: 'radio group', part: null },\n slider: { thing: 'slider', part: null },\n spinbutton: { thing: 'number field', part: null },\n meter: { thing: 'meter', part: null },\n}\n\n/** The keys a list, a menu, tabs and a toolbar move with. Enter and Escape are not here (see above). */\nexport const WALKING_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'PageUp', 'PageDown']\n\n/**\n * A listener on the whole page, by what it is for. The events Base UI's own\n * parts listen to on the document (useDismiss, FloatingFocusManager, the\n * Positioner's autoUpdate): a floating part closes, holds focus and follows its\n * anchor with these. `focus`, `blur`, `visibilitychange` and `storage` are not\n * here: an app refreshing when the window comes back is not a floating part.\n */\nexport const PAGE_EVENTS: Record<string, 'press' | 'key' | 'focus' | 'follow'> = {\n mousedown: 'press',\n pointerdown: 'press',\n click: 'press',\n touchstart: 'press',\n keydown: 'key',\n keyup: 'key',\n keypress: 'key',\n focusin: 'focus',\n focusout: 'focus',\n scroll: 'follow',\n resize: 'follow',\n}\n\n/** Elements that are reachable with Tab by themselves; `tabIndex` on these is not a Tab stop made by hand. */\nexport const INTERACTIVE_ELEMENTS = new Set(['a', 'button', 'input', 'select', 'textarea', 'summary', 'iframe', 'embed', 'object', 'audio', 'video'])\n\n/** `overflow-auto`, `overflow-y-scroll`\u2026: a box that scrolls with the browser's scrollbar. */\nexport const SCROLL_CLASS = /^overflow(?:-[xy])?-(?:auto|scroll)$/\n\n/** One row of the enumeration (UIG-8's acceptance; the shape UIG-12's registry reads). */\nexport interface OwnedBehaviour {\n id: string\n /** What a person notices the part doing. */\n behaviour: string\n /** The Base UI parts that do it, read from their source (1.8.0). */\n baseUi: string[]\n /** The package components an error names. */\n owners: string[]\n /** What the rule reads in an app to find it rebuilt. */\n reads: string\n}\n\nconst uses = (parts: (OwnerPart | null)[]) => [\n ...new Set(parts.flatMap((p) => (p ? [p.use, ...[...(p.more ?? '').matchAll(/`([A-Z]\\w+)`/g)].map((m) => m[1])] : []))),\n]\n\nexport const OWNED_BEHAVIOURS: OwnedBehaviour[] = [\n {\n id: 'base-ui',\n behaviour: 'Is built on Base UI',\n baseUi: Object.keys(BASE_UI_PARTS),\n owners: uses(Object.values(BASE_UI_PARTS)),\n reads: 'an import from @base-ui/react (and the old @base-ui-components spelling)',\n },\n {\n id: 'portal',\n behaviour: 'Floats on top of the page',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Autocomplete', 'Tooltip', 'PreviewCard', 'Toast'],\n owners: ['DialogShell', 'ConfirmDialog', 'CommandPalette', 'Popover', 'Menu', 'Select', 'ChipInput', 'Tooltip', 'PreviewCard', 'Toast'],\n reads: 'createPortal, called, or imported and never called',\n },\n {\n id: 'press-outside',\n behaviour: 'Closes on a press outside',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Tooltip', 'PreviewCard'],\n owners: ['DialogShell', 'Popover', 'Menu', 'Select', 'PreviewCard'],\n reads: 'a mousedown, pointerdown, click or touchstart listener on window or document',\n },\n {\n id: 'page-keys',\n behaviour: 'Takes its keys by itself',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox', 'Tooltip', 'PreviewCard', 'Toast'],\n owners: ['DialogShell', 'Popover', 'Menu', 'Select', 'Tabs', 'Toolbar'],\n reads: 'a keydown, keyup or keypress listener on window or document',\n },\n {\n id: 'focus',\n behaviour: 'Holds focus inside while open, and gives it back',\n baseUi: ['Dialog', 'AlertDialog', 'Popover', 'Menu', 'Select', 'Combobox'],\n owners: ['DialogShell', 'CommandPalette'],\n reads: 'a focusin or focusout listener on window or document; the Tab key compared by hand',\n },\n {\n id: 'scroll-lock',\n behaviour: 'Stops the page behind it scrolling',\n baseUi: ['Dialog', 'AlertDialog'],\n owners: ['DialogShell'],\n reads: 'overflow written into the style of document.body or document.documentElement',\n },\n {\n id: 'follow',\n behaviour: 'Stays attached to its anchor on scroll and resize',\n baseUi: ['Popover', 'Menu', 'Select', 'Combobox', 'Tooltip', 'PreviewCard', 'Toast'],\n owners: ['Popover', 'Menu', 'Select', 'Tooltip', 'PreviewCard'],\n reads: 'a scroll or resize listener on window or document',\n },\n {\n id: 'walking',\n behaviour: 'Moves through its items with the arrow keys',\n baseUi: ['Menu', 'Select', 'Combobox', 'Autocomplete', 'Tabs', 'Toolbar'],\n owners: ['Menu', 'Select', 'ChipInput', 'CommandPalette', 'Tabs', 'Toolbar'],\n reads: `a key compared by hand with ${WALKING_KEYS.join(', ')}`,\n },\n {\n id: 'role',\n behaviour: 'Says what it is to assistive technology',\n baseUi: ['Dialog', 'AlertDialog', 'Menu', 'Select', 'Combobox', 'Tabs', 'Toolbar', 'Progress', 'Checkbox', 'Separator', 'Button'],\n owners: uses(Object.values(ROLE_PARTS).map((r) => r.part)),\n reads: `role written by hand: ${Object.keys(ROLE_PARTS).join(', ')}`,\n },\n {\n id: 'tab-stop',\n behaviour: 'Is reachable with Tab',\n baseUi: ['Button', 'Toggle', 'Checkbox', 'Tabs', 'Toolbar', 'ScrollArea'],\n owners: ['Button', 'IconButton', 'Link'],\n reads: 'tabIndex that can be 0 or more, on an element that is not a control',\n },\n {\n id: 'scroll',\n behaviour: 'Scrolls with our scrollbar',\n baseUi: ['ScrollArea'],\n owners: ['ScrollArea'],\n reads: 'overflow-auto or overflow-scroll (x or y, behind any variant) in a string, or overflow auto or scroll in a style',\n },\n]\n\ninterface Node {\n type: string\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n parent?: Node\n [key: string]: unknown\n}\n\nconst PAGE_TARGETS = new Set(['window', 'document', 'globalThis', 'self', 'document.body', 'document.documentElement', 'window.document'])\n\n/** Where an escape for this node is written: its object property, its element, its array item, or its statement. */\nfunction anchorOf(node: Node): Node {\n if (node.type === 'FunctionDeclaration') {\n return node.parent && /^Export/.test(node.parent.type) ? node.parent : node\n }\n let child = node\n for (let p = node.parent; p; child = p, p = p.parent) {\n if (p.type === 'JSXOpeningElement' || p.type === 'Property' || p.type === 'MethodDefinition' || p.type === 'PropertyDefinition') return p\n if (p.type === 'ArrayExpression') return child\n if (p.type !== 'BlockStatement' && /(Statement|Declaration)$/.test(p.type)) return p\n }\n return node\n}\n\nfunction enclosingFunction(node: Node): Node | undefined {\n for (let p = node.parent; p; p = p.parent) {\n if (p.type === 'FunctionDeclaration' || p.type === 'FunctionExpression' || p.type === 'ArrowFunctionExpression') return p\n }\n return undefined\n}\n\nfunction stringOf(node: Node | undefined | null): string | undefined {\n if (!node) return undefined\n if (node.type === 'Literal' && typeof node.value === 'string') return node.value\n const quasis = node.quasis as { value: { cooked: string | null } }[] | undefined\n const expressions = node.expressions as unknown[] | undefined\n if (node.type === 'TemplateLiteral' && expressions?.length === 0) return quasis?.[0]?.value.cooked ?? undefined\n return undefined\n}\n\n/** Every string a JSX attribute's value can be: `\"x\"`, `{'x'}`, `{a ? 'x' : 'y'}`, `{a && 'x'}`. */\nfunction stringsOf(node: Node | undefined | null): string[] {\n if (!node) return []\n if (node.type === 'JSXExpressionContainer') return stringsOf(node.expression as Node)\n const s = stringOf(node)\n if (s !== undefined) return [s]\n if (node.type === 'ConditionalExpression') return [...stringsOf(node.consequent as Node), ...stringsOf(node.alternate as Node)]\n if (node.type === 'LogicalExpression') return [...stringsOf(node.left as Node), ...stringsOf(node.right as Node)]\n return []\n}\n\n/** Whether a `tabIndex` value can be 0 or more, as far as the code spells it out. */\nfunction canBeTabStop(node: Node | undefined | null): boolean {\n if (!node) return false\n if (node.type === 'JSXExpressionContainer') return canBeTabStop(node.expression as Node)\n if (node.type === 'Literal') {\n if (typeof node.value === 'number') return node.value >= 0\n if (typeof node.value === 'string') return /^\\s*\\d+\\s*$/.test(node.value)\n return false\n }\n if (node.type === 'ConditionalExpression') return canBeTabStop(node.consequent as Node) || canBeTabStop(node.alternate as Node)\n if (node.type === 'LogicalExpression') return canBeTabStop(node.left as Node) || canBeTabStop(node.right as Node)\n if (node.type === 'TSAsExpression' || node.type === 'TSNonNullExpression') return canBeTabStop(node.expression as Node)\n return false\n}\n\n/** A class token's utility, past its variants: `[&_pre]:overflow-x-auto` \u2192 `overflow-x-auto`. */\nexport function utilityOf(token: string): string {\n let depth = 0\n let last = -1\n for (let i = 0; i < token.length; i++) {\n const c = token[i]\n if (c === '[') depth++\n else if (c === ']') depth--\n else if (c === ':' && depth === 0) last = i\n }\n return token.slice(last + 1).replace(/^!/, '').replace(/!$/, '')\n}\n\n/** The Base UI module an import names, or `undefined` when it is not Base UI. `''` is the package root. */\nexport function baseUiModule(source: string): string | undefined {\n const m = /^@base-ui(?:-components)?\\/([^/]+)(?:\\/(.+))?$/.exec(source)\n if (!m) return undefined\n const [, pkg, sub] = m\n return pkg === 'react' ? (sub ?? '') : `${pkg}${sub ? `/${sub}` : ''}`\n}\n\nfunction isKeySubject(node: Node | undefined): boolean {\n if (!node) return false\n if (node.type === 'Identifier') return node.name === 'key' || node.name === 'code'\n if (node.type !== 'MemberExpression' || node.computed) return false\n const property = node.property as Node\n return property.type === 'Identifier' && (property.name === 'key' || property.name === 'code')\n}\n\nfunction pageTarget(node: Node, text: string): boolean {\n return (node.type === 'Identifier' || node.type === 'MemberExpression') && PAGE_TARGETS.has(text)\n}\n\nexport const noRebuiltBehaviour: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Behaviour @estiva-app/ui already owns, rebuilt by hand in an app' },\n schema: [],\n messages: {\n baseUi: 'Only @estiva-app/ui imports Base UI (`{{module}}`). Use `{{use}}` from @estiva-app/ui.{{more}}',\n baseUiNoPart:\n 'Only @estiva-app/ui imports Base UI (`{{module}}`), and it has no part built on it yet. Do not build one here: ask Katerina, and it gets made in @estiva-app/ui.',\n portal:\n 'A layer put on top of the page by hand (`createPortal`). Every floating part of @estiva-app/ui carries its own: `DialogShell` for a dialog, `Popover` for a panel, `Menu`, `Select`, `Tooltip`, `PreviewCard`, `Toast`.',\n press:\n 'A `{{event}}` listener on `{{target}}`: closing on a press outside, by hand. `Popover`, `Menu`, `Select`, `DialogShell` and `PreviewCard` from @estiva-app/ui close themselves.',\n key: 'A `{{event}}` listener on `{{target}}`: keys taken for the whole page, by hand. `DialogShell`, `Popover`, `Menu` and `Select` from @estiva-app/ui close on Escape themselves; `Menu`, `Select`, `Tabs` and `Toolbar` move with the arrow keys.',\n focus:\n 'A `{{event}}` listener on `{{target}}`: focus held by hand. `DialogShell` and `CommandPalette` from @estiva-app/ui keep focus inside and give it back.',\n follow:\n 'A `{{event}}` listener on `{{target}}`: following an anchor by hand. `Popover`, `Menu`, `Select`, `Tooltip` and `PreviewCard` from @estiva-app/ui stay attached to theirs.',\n scrollLock: \"The page's scroll locked by hand. `DialogShell` from @estiva-app/ui stops the page scrolling while it is open, and gives it back.\",\n walking:\n 'Arrow keys handled by hand (`{{key}}`). `Menu`, `Select`, `ChipInput`, `CommandPalette`, `Tabs` and `Toolbar` from @estiva-app/ui move through their items themselves.',\n tabKey: 'The Tab key handled by hand. `DialogShell` and `CommandPalette` from @estiva-app/ui keep focus inside themselves.',\n role: 'A hand-written `role=\"{{role}}\"` is a hand-made {{thing}}. Use `{{use}}` from @estiva-app/ui.{{more}}',\n roleNoPart:\n 'A hand-written `role=\"{{role}}\"` is a hand-made {{thing}}, and @estiva-app/ui has no part for one yet. Do not build one here: ask Katerina, and it gets made in @estiva-app/ui.',\n tabStop:\n '`tabIndex={{value}}` makes a `<{{element}}>` a Tab stop by hand. Use `Button`, `IconButton` or `Link` from @estiva-app/ui, which are reachable already.',\n scrollClass: \"`{{token}}` scrolls with the browser's scrollbar. Use `ScrollArea` from @estiva-app/ui, which draws ours.\",\n scrollStyle: \"`{{style}}` scrolls with the browser's scrollbar. Use `ScrollArea` from @estiva-app/ui, which draws ours.\",\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n const { sourceCode } = context\n const text = (node: Node) => sourceCode.getText(node as unknown as Rule.Node)\n\n // One escape covers what the rule found at its anchor, and is counted once.\n const escapes = new Map<Node, boolean>()\n const escaped = (anchor: Node) => {\n if (!escapes.has(anchor)) escapes.set(anchor, isEscaped(context, anchor))\n return escapes.get(anchor) === true\n }\n const seen = new Set<string>()\n const report = (anchor: Node, at: Node, messageId: string, data: Record<string, string> = {}, once = `${at.range[0]}`) => {\n const key = `${anchor.range[0]}|${messageId}|${once}`\n if (seen.has(key)) return\n seen.add(key)\n if (escaped(anchor)) return\n context.report({ loc: at.loc, messageId, data })\n }\n\n const importSource = (node: Node, source: Node | undefined | null) => {\n const value = stringOf(source)\n if (value === undefined) return\n const module = baseUiModule(value)\n if (module === undefined) return\n const part = Object.hasOwn(BASE_UI_PARTS, module) ? BASE_UI_PARTS[module] : null\n const anchor = anchorOf(node)\n if (part) report(anchor, node, 'baseUi', { module: value, use: part.use, more: part.more ?? '' })\n else report(anchor, node, 'baseUiNoPart', { module: value })\n }\n\n const keyCompared = (node: Node, key: string | undefined) => {\n if (key === undefined) return\n const fn = enclosingFunction(node)\n const anchor = anchorOf(fn ?? node)\n if (WALKING_KEYS.includes(key)) report(anchor, node, 'walking', { key }, `walking@${fn?.range[0] ?? node.range[0]}`)\n else if (key === 'Tab') report(anchor, node, 'tabKey', {}, `tab@${fn?.range[0] ?? node.range[0]}`)\n }\n\n const classTokens = (node: Node, value: string) => {\n for (const token of value.split(/\\s+/)) {\n if (token && SCROLL_CLASS.test(utilityOf(token))) report(anchorOf(node), node, 'scrollClass', { token }, `class@${token}`)\n }\n }\n\n // `createPortal` imported: reported where it is called, or at the import when it never is.\n const portalImports = new Map<string, Node>()\n let portalCalled = false\n\n return {\n ImportDeclaration(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n importSource(node, node.source as Node)\n if (stringOf(node.source as Node) !== 'react-dom') return\n for (const specifier of node.specifiers as Node[]) {\n const imported = specifier.imported as Node | undefined\n if (specifier.type === 'ImportSpecifier' && imported?.name === 'createPortal') portalImports.set((specifier.local as Node).name as string, node)\n }\n },\n ExportNamedDeclaration(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n if (node.source) importSource(node, node.source as Node)\n },\n ExportAllDeclaration(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n importSource(node, node.source as Node)\n },\n ImportExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n importSource(node, node.source as Node)\n },\n\n CallExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const callee = node.callee as Node\n const args = node.arguments as Node[]\n\n if (callee.type === 'Identifier' && callee.name === 'require') importSource(node, args[0])\n\n if (callee.type === 'Identifier' && portalImports.has(callee.name as string)) {\n portalCalled = true\n report(anchorOf(node), node, 'portal')\n }\n if (callee.type !== 'MemberExpression') return\n const object = callee.object as Node\n const property = callee.property as Node\n if (property.type !== 'Identifier') return\n\n if (property.name === 'createPortal') {\n report(anchorOf(node), node, 'portal')\n return\n }\n\n if (property.name === 'addEventListener') {\n const target = text(object)\n if (!pageTarget(object, target)) return\n const event = stringOf(args[0])\n const group = event === undefined ? undefined : PAGE_EVENTS[event]\n if (!event || !group) return\n report(anchorOf(node), node, group, { event, target })\n return\n }\n\n // ['ArrowUp', 'ArrowDown'].includes(event.key)\n if (property.name === 'includes' && object.type === 'ArrayExpression' && isKeySubject(args[0])) {\n for (const element of object.elements as Node[]) keyCompared(node, stringOf(element))\n }\n },\n\n AssignmentExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const left = node.left as Node\n if (left.type !== 'MemberExpression') return\n const property = left.property as Node\n const object = left.object as Node\n const handler = property.type === 'Identifier' ? /^on([a-z]+)$/.exec(property.name as string) : null\n if (handler && pageTarget(object, text(object)) && PAGE_EVENTS[handler[1]]) {\n report(anchorOf(node), node, PAGE_EVENTS[handler[1]], { event: handler[1], target: text(object) })\n return\n }\n if (/^document\\.(?:body|documentElement)\\.style\\.overflow[XY]?$/.test(text(left))) report(anchorOf(node), node, 'scrollLock')\n },\n\n BinaryExpression(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n if (!['===', '==', '!==', '!='].includes(node.operator as string)) return\n const left = node.left as Node\n const right = node.right as Node\n if (isKeySubject(left)) keyCompared(node, stringOf(right))\n else if (isKeySubject(right)) keyCompared(node, stringOf(left))\n },\n\n SwitchCase(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const statement = node.parent as Node\n if (node.test && isKeySubject(statement.discriminant as Node)) keyCompared(node, stringOf(node.test as Node))\n },\n\n JSXAttribute(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const nameNode = node.name as Node\n if (nameNode.type !== 'JSXIdentifier') return\n const name = nameNode.name as string\n const element = node.parent as Node\n const value = node.value as Node | null\n\n if (name === 'role') {\n for (const role of stringsOf(value).flatMap((v) => v.trim().split(/\\s+/))) {\n if (!Object.hasOwn(ROLE_PARTS, role)) continue\n const { thing, part } = ROLE_PARTS[role]\n if (part) report(element, node, 'role', { role, thing, use: part.use, more: part.more ?? '' })\n else report(element, node, 'roleNoPart', { role, thing })\n return\n }\n return\n }\n\n if (name === 'tabIndex' || name === 'tabindex') {\n const tag = element.name as Node\n if (tag.type !== 'JSXIdentifier' || !/^[a-z]/.test(tag.name as string) || INTERACTIVE_ELEMENTS.has(tag.name as string)) return\n const attributes = element.attributes as Node[]\n const editable = attributes.some((a) => a.type === 'JSXAttribute' && /^contenteditable$/i.test(((a.name as Node).name as string) ?? ''))\n if (editable || !canBeTabStop(value)) return\n report(element, node, 'tabStop', { value: value ? text(value).replace(/^\\{|\\}$/g, '') : '', element: tag.name as string })\n return\n }\n\n if (name === 'style' && value?.type === 'JSXExpressionContainer') {\n const object = value.expression as Node\n if (object.type !== 'ObjectExpression') return\n for (const property of object.properties as Node[]) {\n if (property.type !== 'Property') continue\n const key = property.key as Node\n const keyName = key.type === 'Identifier' ? (key.name as string) : stringOf(key)\n if (!keyName || !/^overflow[XY]?$/.test(keyName)) continue\n const setting = stringOf(property.value as Node)\n if (setting === 'auto' || setting === 'scroll') report(element, property, 'scrollStyle', { style: `${keyName}: '${setting}'` }, `style@${keyName}`)\n }\n }\n },\n\n Literal(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n if (typeof node.value !== 'string') return\n const parent = node.parent\n if (parent && /^(Import|Export)/.test(parent.type)) return\n if (parent?.type === 'TSLiteralType' || parent?.type === 'TSExternalModuleReference') return\n classTokens(node, node.value)\n },\n\n TemplateElement(ruleNode: Rule.Node) {\n const node = ruleNode as unknown as Node\n const cooked = (node.value as { cooked: string | null }).cooked\n if (cooked && node.parent) classTokens(node.parent, cooked)\n },\n\n 'Program:exit'() {\n if (portalCalled) return\n for (const declaration of new Set(portalImports.values())) report(anchorOf(declaration), declaration, 'portal')\n },\n }\n },\n}\n", "import { existsSync, readFileSync, statSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport type { Rule, Scope } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\n/**\n * A part of the package is placed from outside, never restyled (UIG-9; Katerina's\n * ruling B8 of 13 September, \"only position and spacing pass into our\n * components\").\n *\n * Every part takes `className`, and some take a second class prop for an inner\n * box (`contentClassName`, `bodyClassName`\u2026). Through either, an app could push\n * a colour, a text size or a border into a part and quietly undo it: the token\n * lint only asks whether a class is a real token, never whether the part should\n * take it. This rule reads every class passed into a part and lets through only\n * placement \u2014 where the part sits and how much room it takes.\n *\n * **Which elements are parts: by where they come from, never by name.** No list\n * of names is kept, so a part added to the package later is covered the day it\n * is added.\n *\n * - In an app: anything imported from `@estiva-app/ui`, and anything imported\n * from the app's own files that is one of those \u2014 a re-export (Peek's\n * `components/ui/Button.tsx`), a wrapper that hands its props on to a part\n * (`{...rest}`), or a component that hands its own `className` on to a part\n * (Peek's `ConversationCard` into `Card`). Relative imports and the apps' `@/`\n * alias are followed; `@/` is the `src` folder beside the nearest\n * `package.json`.\n * - Inside the package (Katerina, 17 September): a name `src/index.ts` exports,\n * imported from a sibling file or declared in the same file.\n *\n * **What it reads:** a string, a template, `cn()`/`clsx()` and their arguments,\n * both sides of a condition, a `const` in the same file and the values of a\n * class map read from one. A class the code works out while it runs passes: the\n * rule cannot read it.\n *\n * `EmptyState` takes no padding either (Katerina's ruling 6 of 14 September):\n * its room comes from the box its rows live in.\n */\n\n// ---------------------------------------------------------------- the classes\n\n/** Where a part sits and how much room it takes. Read on the utility, after its variants. */\nexport const PLACEMENT: { what: string; pattern: RegExp }[] = [\n { what: 'space around', pattern: /^m[xytrblse]?-/ },\n { what: 'space inside', pattern: /^p[xytrblse]?-/ },\n { what: 'width and height', pattern: /^(?:w|h|size|min-w|min-h|max-w|max-h)-/ },\n { what: 'shown, and how it lays out', pattern: /^(?:hidden|block|inline|inline-block|inline-flex|inline-grid|flex|grid|contents|flow-root)$/ },\n { what: 'its place in a row or a grid', pattern: /^(?:grow|shrink)$|^(?:flex|basis|grow|shrink|order|gap|gap-x|gap-y|space-x|space-y|col|row|grid-cols|grid-rows|grid-flow|auto-cols|auto-rows)-/ },\n { what: 'alignment', pattern: /^(?:self|justify|justify-items|justify-self|items|place-content|place-items|place-self)-|^content-(?!\\[)/ },\n { what: 'position', pattern: /^(?:static|relative|absolute|fixed|sticky)$|^(?:inset|inset-x|inset-y|top|right|bottom|left|start|end|z)-/ },\n // Draws nothing: it names the part, so what is inside can answer its hover (`group-hover:`).\n { what: 'a name for hover', pattern: /^(?:group|peer)(?:\\/[\\w-]+)?$/ },\n]\n\n/**\n * A variant that draws another box or reaches inside the part: `before:`,\n * `after:`, `[&>*]:`, `*:`\u2026 A placement class behind one of these is not the\n * part's placement.\n */\nconst REACHING_VARIANT = /^\\[|^(?:before|after|placeholder|file|marker|selection|first-letter|first-line|backdrop|\\*|\\*\\*)$/\n\n/** A class list's variants and its utility: `sm:[&>*]:shrink-0` \u2192 `['sm', '[&>*]']`, `shrink-0`. */\nexport function splitClass(token: string): { variants: string[]; utility: string } {\n const variants: string[] = []\n let current = ''\n let depth = 0\n for (const character of token) {\n if (character === '[') depth += 1\n if (character === ']') depth -= 1\n if (character === ':' && depth === 0) {\n variants.push(current)\n current = ''\n } else current += character\n }\n return { variants, utility: current.replace(/^!/, '').replace(/!$/, '').replace(/^-/, '') }\n}\n\n/** Whether a class only places the part. */\nexport function isPlacement(token: string): boolean {\n const { variants, utility } = splitClass(token)\n if (variants.some((variant) => REACHING_VARIANT.test(variant))) return false\n return PLACEMENT.some(({ pattern }) => pattern.test(utility))\n}\n\nconst isPadding = (token: string) => {\n const { variants, utility } = splitClass(token)\n return !variants.some((variant) => REACHING_VARIANT.test(variant)) && /^p[xytrblse]?-/.test(utility)\n}\n\n/**\n * The props a part has for how it looks, named in the message. Held to the\n * package's source by `no-restyled-part.test.ts`: every prop here exists, and\n * every look prop an exported part has is here. A part missing from this table\n * has none, and the message says to ask for one.\n */\nexport const PART_LOOK_PROPS: Record<string, string[]> = {\n AppShell: ['variant'],\n Avatar: ['size'],\n AvatarGroup: ['size'],\n Banner: ['tone'],\n Button: ['variant', 'size'],\n Card: ['fill', 'hover', 'attention', 'selected', 'active', 'hovered', 'quietUntilHover', 'unreadable', 'clip'],\n Checkbox: ['row'],\n Chip: ['type'],\n Divider: ['tone', 'orientation'],\n EmptyState: ['scope'],\n FieldLine: ['tone'],\n IconButton: ['variant', 'pressed', 'glow'],\n InputChip: ['truncate'],\n Link: ['variant', 'truncate'],\n MenuItem: ['size', 'selected', 'destructive'],\n MenuSub: ['selected'],\n NavItem: ['active'],\n Person: ['size'],\n ProgressBar: ['variant'],\n Property: ['layout'],\n RailItem: ['active'],\n Reaction: ['pressed'],\n ReactionPicker: ['surface'],\n SectionHeader: ['hover'],\n SectionLabel: ['tone'],\n Select: ['size'],\n Tabs: ['size'],\n TextInput: ['size'],\n Toast: ['type'],\n Toolbar: ['surface'],\n ToolbarButton: ['variant', 'pressed', 'glow'],\n TopBar: ['variant'],\n}\n\n/** The class props of a part: `className`, and the ones for an inner box. */\nconst CLASS_PROP = /^(?:className|[a-z][A-Za-z]*ClassName)$/\n\n// ---------------------------------------------------------------- the nodes\n\ninterface Node {\n type: string\n range: [number, number]\n loc?: NonNullable<Rule.Node['loc']>\n parent?: Node\n [key: string]: unknown\n}\n\nconst child = (node: Node, key: string) => node[key] as Node | null | undefined\nconst children = (node: Node, key: string) => (node[key] as (Node | null)[] | undefined) ?? []\nconst nameOf = (node: Node | null | undefined): string | undefined =>\n node?.type === 'Identifier' || node?.type === 'JSXIdentifier' ? (node.name as string) : node?.type === 'Literal' && typeof node.value === 'string' ? node.value : undefined\n\n/** Walk every node under `root`, skipping the parser's bookkeeping keys. */\nfunction walk(root: Node, visit: (node: Node) => void): void {\n const stack: Node[] = [root]\n while (stack.length) {\n const node = stack.pop() as Node\n visit(node)\n for (const key of Object.keys(node)) {\n if (key === 'parent' || key === 'loc' || key === 'range' || key === 'tokens' || key === 'comments') continue\n const value = node[key]\n if (Array.isArray(value)) for (const item of value) { if (item && typeof (item as Node).type === 'string') stack.push(item as Node) }\n else if (value && typeof (value as Node).type === 'string') stack.push(value as Node)\n }\n }\n}\n\n// ---------------------------------------------------------------- the parts\n\n/**\n * What a name is to this rule: the part it draws, and which of the caller's\n * class props reach which of the part's (`all` for a part, a re-export or a\n * wrapper; a map for a component that hands on its own `className`). `via` is\n * the app's own component in between, for the message.\n */\nexport interface PartBinding {\n part: string\n props: 'all' | Record<string, string>\n via?: string\n}\n\ninterface Parser {\n parseForESLint?: (code: string, options: unknown) => { ast: Node }\n parse?: (code: string, options: unknown) => Node\n}\n\ninterface ModuleFacts {\n mtime: number\n exports: Map<string, PartBinding>\n}\n\nconst PACKAGE = '@estiva-app/ui'\nconst moduleCache = new Map<string, ModuleFacts>()\nconst packageDirCache = new Map<string, string | null>()\nconst packagePartsCache = new Map<string, { mtime: number; parts: Set<string> }>()\n\nfunction parseFile(parser: Parser, filePath: string): Node | null {\n const code = readFileSync(filePath, 'utf8')\n const options = { filePath, ecmaVersion: 'latest', sourceType: 'module', ecmaFeatures: { jsx: filePath.endsWith('x') }, range: true, loc: true }\n try {\n if (parser.parseForESLint) return parser.parseForESLint(code, options).ast\n if (parser.parse) return parser.parse(code, options)\n } catch {\n // A file that does not parse is its own lint's business; it hands on no parts.\n }\n return null\n}\n\n/** The nearest folder holding a `package.json`, from a file. */\nfunction packageDirOf(file: string): string | null {\n const start = dirname(resolve(file))\n if (packageDirCache.has(start)) return packageDirCache.get(start) ?? null\n let dir = start\n for (;;) {\n if (existsSync(join(dir, 'package.json'))) break\n const up = dirname(dir)\n if (up === dir) {\n dir = ''\n break\n }\n dir = up\n }\n packageDirCache.set(start, dir || null)\n return dir || null\n}\n\nfunction resolveModule(fromFile: string, specifier: string): string | null {\n let base: string\n if (specifier.startsWith('.')) base = resolve(dirname(fromFile), specifier)\n else if (specifier.startsWith('@/')) {\n const dir = packageDirOf(fromFile)\n if (!dir) return null\n base = join(dir, 'src', specifier.slice(2))\n } else return null\n for (const candidate of [base, `${base}.tsx`, `${base}.ts`, join(base, 'index.tsx'), join(base, 'index.ts')]) {\n if (existsSync(candidate) && statSync(candidate).isFile()) return candidate\n }\n return null\n}\n\n/** The names this package's `src/index.ts` exports, when the file lives in `@estiva-app/ui` itself. */\nfunction packagePartsFor(file: string, parser: Parser): Set<string> | null {\n const dir = packageDirOf(file)\n if (!dir) return null\n let name: string | undefined\n try {\n name = (JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as { name?: string }).name\n } catch {\n return null\n }\n if (name !== PACKAGE) return null\n const index = join(dir, 'src', 'index.ts')\n if (!existsSync(index)) return null\n const mtime = statSync(index).mtimeMs\n const cached = packagePartsCache.get(index)\n if (cached && cached.mtime === mtime) return cached.parts\n const parts = new Set<string>()\n const ast = parseFile(parser, index)\n for (const statement of ast ? children(ast, 'body') : []) {\n if (statement?.type !== 'ExportNamedDeclaration' || statement.exportKind === 'type') continue\n for (const specifier of children(statement, 'specifiers')) {\n const exported = nameOf(child(specifier as Node, 'exported'))\n if (specifier?.exportKind !== 'type' && exported && /^[A-Z][a-z]/.test(exported)) parts.add(exported)\n }\n }\n packagePartsCache.set(index, { mtime, parts })\n return parts\n}\n\n/** A function component declared in a module: its name, and the function. */\nfunction functionComponents(program: Node): Map<string, Node> {\n const found = new Map<string, Node>()\n const unwrap = (node: Node | null | undefined): Node | null => {\n let current = node\n while (current?.type === 'CallExpression' && children(current, 'arguments').length) {\n const callee = child(current, 'callee')\n const text = callee?.type === 'Identifier' ? nameOf(callee) : callee?.type === 'MemberExpression' ? nameOf(child(callee, 'property')) : undefined\n if (text !== 'forwardRef' && text !== 'memo') return null\n current = children(current, 'arguments')[0]\n }\n return current?.type === 'ArrowFunctionExpression' || current?.type === 'FunctionExpression' ? current : null\n }\n walk(program, (node) => {\n if (node.type === 'FunctionDeclaration') {\n const name = nameOf(child(node, 'id'))\n if (name && /^[A-Z]/.test(name)) found.set(name, node)\n } else if (node.type === 'VariableDeclarator') {\n const name = nameOf(child(node, 'id'))\n const fn = unwrap(child(node, 'init'))\n if (name && /^[A-Z]/.test(name) && fn) found.set(name, fn)\n }\n })\n return found\n}\n\n/**\n * The parts a module's names stand for. `ownFile` is the file being linted: its\n * imports are read the same way, so a wrapper declared beside its use counts.\n */\nfunction moduleParts(file: string, program: Node, parser: Parser, stack: Set<string>): { locals: Map<string, PartBinding | 'namespace'>; exports: Map<string, PartBinding> } {\n const locals = new Map<string, PartBinding | 'namespace'>()\n const packageParts = packagePartsFor(file, parser)\n const body = children(program, 'body')\n\n const exportsOf = (specifier: string): Map<string, PartBinding> | 'package' | null => {\n if (specifier === PACKAGE) return 'package'\n const target = resolveModule(file, specifier)\n if (!target) return null\n if (packageParts) return 'package'\n return moduleExports(target, parser, stack)\n }\n\n for (const statement of body) {\n if (statement?.type !== 'ImportDeclaration' || statement.importKind === 'type') continue\n const source = exportsOf(String((child(statement, 'source') as Node).value))\n if (!source) continue\n for (const specifier of children(statement, 'specifiers')) {\n if (!specifier || specifier.importKind === 'type') continue\n const local = nameOf(child(specifier, 'local'))\n if (!local) continue\n if (specifier.type === 'ImportNamespaceSpecifier') {\n if (source === 'package' && !packageParts) locals.set(local, 'namespace')\n continue\n }\n const imported = specifier.type === 'ImportDefaultSpecifier' ? 'default' : nameOf(child(specifier, 'imported'))\n if (!imported) continue\n if (source === 'package') {\n const isPart = packageParts ? packageParts.has(imported) : /^[A-Z]/.test(imported)\n if (isPart) locals.set(local, { part: imported, props: 'all' })\n } else if (source.has(imported)) locals.set(local, source.get(imported) as PartBinding)\n }\n }\n\n // Inside the package, a part used in the file that declares it.\n const components = functionComponents(program)\n if (packageParts) for (const name of components.keys()) if (packageParts.has(name) && !locals.has(name)) locals.set(name, { part: name, props: 'all' })\n\n // In an app, a component that hands its props, or its own className, on to a part.\n if (!packageParts) {\n let changed = true\n for (let round = 0; changed && round < 10; round += 1) {\n changed = false\n for (const [name, fn] of components) {\n const binding = handsOnTo(fn, (tag) => bindingOfTag(tag, locals))\n if (!binding) continue\n const next = { ...binding, via: name }\n const previous = locals.get(name)\n if (!previous || JSON.stringify(previous) !== JSON.stringify(next)) {\n if (previous && previous !== 'namespace' && !previous.via) continue\n locals.set(name, next)\n changed = true\n }\n }\n }\n }\n\n const exports = new Map<string, PartBinding>()\n const localBinding = (name: string | undefined) => {\n const binding = name ? locals.get(name) : undefined\n return binding && binding !== 'namespace' ? binding : undefined\n }\n for (const statement of body) {\n if (!statement) continue\n if (statement.type === 'ExportNamedDeclaration') {\n const declaration = child(statement, 'declaration')\n if (declaration?.type === 'FunctionDeclaration') {\n const name = nameOf(child(declaration, 'id'))\n const binding = localBinding(name)\n if (name && binding) exports.set(name, binding)\n } else if (declaration?.type === 'VariableDeclaration') {\n for (const declarator of children(declaration, 'declarations')) {\n const name = nameOf(child(declarator as Node, 'id'))\n const init = child(declarator as Node, 'init')\n const binding = localBinding(name) ?? (init?.type === 'Identifier' ? localBinding(nameOf(init)) : undefined)\n if (name && binding) exports.set(name, binding)\n }\n }\n const source = child(statement, 'source')\n const from = source ? exportsOf(String(source.value)) : null\n for (const specifier of children(statement, 'specifiers')) {\n if (!specifier || specifier.exportKind === 'type') continue\n const local = nameOf(child(specifier, 'local'))\n const exported = nameOf(child(specifier, 'exported'))\n if (!local || !exported) continue\n if (!source) {\n const binding = localBinding(local)\n if (binding) exports.set(exported, binding)\n } else if (from === 'package') {\n if (/^[A-Z]/.test(local)) exports.set(exported, { part: local, props: 'all' })\n } else if (from?.has(local)) exports.set(exported, from.get(local) as PartBinding)\n }\n } else if (statement.type === 'ExportAllDeclaration' && !child(statement, 'exported')) {\n const from = exportsOf(String((child(statement, 'source') as Node).value))\n if (from && from !== 'package') for (const [name, binding] of from) exports.set(name, binding)\n } else if (statement.type === 'ExportDefaultDeclaration') {\n const declaration = child(statement, 'declaration')\n const name = declaration?.type === 'Identifier' ? nameOf(declaration) : nameOf(child(declaration as Node, 'id'))\n const binding = localBinding(name)\n if (binding) exports.set('default', binding)\n }\n }\n return { locals, exports }\n}\n\nfunction moduleExports(file: string, parser: Parser, stack: Set<string>): Map<string, PartBinding> {\n const mtime = statSync(file).mtimeMs\n const cached = moduleCache.get(file)\n if (cached && cached.mtime === mtime) return cached.exports\n if (stack.has(file)) return new Map()\n stack.add(file)\n const program = parseFile(parser, file)\n const exports = program ? moduleParts(file, program, parser, stack).exports : new Map<string, PartBinding>()\n stack.delete(file)\n moduleCache.set(file, { mtime, exports })\n return exports\n}\n\nfunction bindingOfTag(tag: Node | null | undefined, locals: Map<string, PartBinding | 'namespace'>): PartBinding | undefined {\n if (!tag) return undefined\n if (tag.type === 'JSXIdentifier') {\n const binding = locals.get(tag.name as string)\n return binding && binding !== 'namespace' ? binding : undefined\n }\n if (tag.type === 'JSXMemberExpression') {\n const object = child(tag, 'object')\n const property = nameOf(child(tag, 'property'))\n if (object?.type === 'JSXIdentifier' && locals.get(object.name as string) === 'namespace' && property) return { part: property, props: 'all' }\n }\n return undefined\n}\n\n/**\n * Whether a function component hands its props on to a part: its rest or its\n * whole props spread onto one (a wrapper), or its own class props passed into\n * one's class props (a component that places a part by its caller's word).\n */\nfunction handsOnTo(fn: Node, bindingOf: (tag: Node | null | undefined) => PartBinding | undefined): PartBinding | undefined {\n const param = children(fn, 'params')[0]\n if (!param) return undefined\n let restName: string | undefined\n let propsName: string | undefined\n const classParams = new Map<string, string>()\n if (param.type === 'ObjectPattern') {\n for (const property of children(param, 'properties')) {\n if (!property) continue\n if (property.type === 'RestElement') restName = nameOf(child(property, 'argument'))\n else if (property.type === 'Property') {\n const key = nameOf(child(property, 'key'))\n let value = child(property, 'value')\n if (value?.type === 'AssignmentPattern') value = child(value, 'left')\n const local = nameOf(value)\n if (key && local && CLASS_PROP.test(key)) classParams.set(local, key)\n }\n }\n } else if (param.type === 'Identifier') propsName = nameOf(param)\n\n let wrapper: PartBinding | undefined\n const forwarded: { part?: string; props: Record<string, string> } = { props: {} }\n const body = child(fn, 'body')\n if (!body) return undefined\n walk(body, (node) => {\n if (wrapper || node.type !== 'JSXOpeningElement') return\n const binding = bindingOf(child(node, 'name'))\n if (!binding) return\n for (const attribute of children(node, 'attributes')) {\n if (!attribute) continue\n if (attribute.type === 'JSXSpreadAttribute') {\n const argument = nameOf(child(attribute, 'argument'))\n if (argument && (argument === restName || argument === propsName)) wrapper = { part: binding.part, props: binding.props }\n continue\n }\n const prop = nameOf(child(attribute, 'name'))\n if (!prop || !CLASS_PROP.test(prop)) continue\n const partProp = binding.props === 'all' ? prop : binding.props[prop]\n if (!partProp) continue\n walk(attribute, (inner) => {\n let callerProp: string | undefined\n if (inner.type === 'Identifier') callerProp = classParams.get(inner.name as string)\n if (inner.type === 'MemberExpression' && nameOf(child(inner, 'object')) === propsName) {\n const key = nameOf(child(inner, 'property'))\n if (key && CLASS_PROP.test(key)) callerProp = key\n }\n if (!callerProp) return\n if (forwarded.part && forwarded.part !== binding.part) return\n forwarded.part = binding.part\n forwarded.props[callerProp] = partProp\n })\n }\n })\n if (wrapper) return wrapper\n return forwarded.part ? { part: forwarded.part, props: forwarded.props } : undefined\n}\n\n// ---------------------------------------------------------------- reading a class list\n\nconst CLASS_FUNCTIONS = new Set(['cn', 'clsx', 'cx', 'twMerge', 'classNames'])\n\n/** The `const` a name stands for in this file, if it is one. */\nfunction constantOf(identifier: Node, scope: Scope.Scope | null): Node | undefined {\n let current = scope\n while (current) {\n const variable = current.set.get(identifier.name as string)\n if (variable) {\n const definition = variable.defs[0] as unknown as { type: string; node: Node; parent?: Node } | undefined\n if (variable.defs.length !== 1 || definition?.type !== 'Variable') return undefined\n if ((definition.parent as Node | undefined)?.kind !== 'const') return undefined\n return child(definition.node, 'init') ?? undefined\n }\n current = current.upper\n }\n return undefined\n}\n\n/**\n * Every class the code spells out for a value, as far as it can be read in this\n * file. `asMap` reads an object as a class map (its values) rather than as a\n * `clsx` object (its keys).\n */\nexport function classesOf(value: Node | null | undefined, scopeOf: (node: Node) => Scope.Scope | null, asMap = false, seen = new Set<Node>()): string[] {\n if (!value || seen.has(value) || seen.size > 200) return []\n seen.add(value)\n const read = (node: Node | null | undefined, map = false) => classesOf(node, scopeOf, map, seen)\n const words = (text: unknown) => (typeof text === 'string' ? text.split(/\\s+/).filter(Boolean) : [])\n switch (value.type) {\n case 'Literal':\n return words(value.value)\n case 'TemplateLiteral':\n return [...children(value, 'quasis').flatMap((quasi) => words((quasi?.value as { cooked?: string }).cooked)), ...children(value, 'expressions').flatMap((e) => read(e))]\n case 'JSXExpressionContainer':\n case 'TSAsExpression':\n case 'TSSatisfiesExpression':\n case 'TSNonNullExpression':\n case 'ChainExpression':\n return read(child(value, 'expression'), asMap)\n case 'ConditionalExpression':\n return [...read(child(value, 'consequent')), ...read(child(value, 'alternate'))]\n case 'LogicalExpression':\n return value.operator === '&&' ? read(child(value, 'right')) : [...read(child(value, 'left')), ...read(child(value, 'right'))]\n case 'BinaryExpression':\n return value.operator === '+' ? [...read(child(value, 'left')), ...read(child(value, 'right'))] : []\n case 'ArrayExpression':\n return children(value, 'elements').flatMap((e) => read(e))\n case 'ObjectExpression':\n return children(value, 'properties').flatMap((property) => {\n if (property?.type !== 'Property') return []\n return asMap ? read(child(property, 'value'), true) : property.computed ? [] : words(nameOf(child(property, 'key')))\n })\n case 'CallExpression': {\n const callee = child(value, 'callee')\n return callee?.type === 'Identifier' && CLASS_FUNCTIONS.has(callee.name as string) ? children(value, 'arguments').flatMap((a) => read(a)) : []\n }\n case 'Identifier': {\n const constant = constantOf(value, scopeOf(value))\n return constant ? read(constant, asMap) : []\n }\n case 'MemberExpression': {\n const object = child(value, 'object')\n const target = object?.type === 'Identifier' ? constantOf(object, scopeOf(object)) : object\n const map = target?.type === 'TSAsExpression' || target?.type === 'TSSatisfiesExpression' ? child(target, 'expression') : target\n if (map?.type !== 'ObjectExpression') return []\n const property = child(value, 'property')\n const key = value.computed ? (property?.type === 'Literal' ? String(property.value) : undefined) : nameOf(property)\n return children(map, 'properties').flatMap((entry) => {\n if (entry?.type !== 'Property') return []\n if (key !== undefined && nameOf(child(entry, 'key')) !== key) return []\n return read(child(entry, 'value'), true)\n })\n }\n default:\n return []\n }\n}\n\n// ---------------------------------------------------------------- the rule\n\nconst code = (items: string[]) => items.map((item) => `\\`${item}\\``).join(' ')\nconst or = (items: string[]) => (items.length === 1 ? code(items) : `${items.slice(0, -1).map((i) => `\\`${i}\\``).join(', ')} or \\`${items[items.length - 1]}\\``)\n\nexport const noRestyledPart: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'Only placement passes into a part of @estiva-app/ui through a class prop' },\n schema: [],\n messages: {\n restyled:\n '{{classes}} on {{where}} changes how it looks. A part of @estiva-app/ui is placed from outside, never restyled: only space, size, flex and grid, and position pass in.{{use}} A look for what is around it goes on your own element around it.',\n emptyStatePadding:\n '{{classes}} pads {{where}}. EmptyState takes no padding (Katerina, 14 September): its room comes from the box its rows live in, so put the padding on that box.',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n const parser = (context.languageOptions?.parser ?? {}) as Parser\n const file = context.filename\n const sourceCode = context.sourceCode\n const scopeOf = (node: Node) => sourceCode.getScope(node as unknown as Parameters<typeof sourceCode.getScope>[0])\n let locals: Map<string, PartBinding | 'namespace'> | undefined\n const escapes = new Map<Node, boolean>()\n const escaped = (anchor: Node) => {\n if (!escapes.has(anchor)) escapes.set(anchor, isEscaped(context, anchor))\n return escapes.get(anchor) === true\n }\n\n const check = (element: Node, binding: PartBinding, prop: string, value: Node | null | undefined, at: Node) => {\n const partProp = binding.props === 'all' ? prop : binding.props[prop]\n if (!partProp || !value) return\n const classes = classesOf(value, scopeOf)\n const handedOn = binding.props === 'all' ? 'its props' : `its \\`${prop}\\``\n const via = binding.via && binding.via !== binding.part ? `\\`${binding.via}\\` (it hands ${handedOn} to \\`${binding.part}\\`)` : `\\`${binding.part}\\``\n const where = `${via}${partProp === 'className' ? '' : `'s \\`${partProp}\\``}`\n const restyled = [...new Set(classes.filter((token) => !isPlacement(token)))]\n const padding = binding.part === 'EmptyState' && binding.props === 'all' ? [...new Set(classes.filter(isPadding))] : []\n if (!restyled.length && !padding.length) return\n if (escaped(element)) return\n if (restyled.length) {\n const props = PART_LOOK_PROPS[binding.part]\n const use = props ? ` Use its ${or(props)}.` : ` \\`${binding.part}\\` has no prop for this yet: ask Katerina, and it gets made in @estiva-app/ui.`\n context.report({ loc: at.loc as NonNullable<Rule.Node['loc']>, messageId: 'restyled', data: { classes: code(restyled), where, use } })\n }\n if (padding.length) context.report({ loc: at.loc as NonNullable<Rule.Node['loc']>, messageId: 'emptyStatePadding', data: { classes: code(padding), where } })\n }\n\n return {\n Program(program) {\n locals = moduleParts(file, program as unknown as Node, parser, new Set([file])).locals\n },\n JSXOpeningElement(ruleNode: Rule.Node) {\n const element = ruleNode as unknown as Node\n const binding = locals && bindingOfTag(child(element, 'name'), locals)\n if (!binding) return\n for (const attribute of children(element, 'attributes')) {\n if (!attribute) continue\n if (attribute.type === 'JSXAttribute') {\n const prop = nameOf(child(attribute, 'name'))\n if (prop && CLASS_PROP.test(prop)) check(element, binding, prop, child(attribute, 'value'), attribute)\n continue\n }\n // `{...{ className }}`, or a `const` object spread onto the part.\n let spread = child(attribute, 'argument')\n if (spread?.type === 'Identifier') spread = constantOf(spread, scopeOf(spread))\n while (spread?.type === 'TSAsExpression' || spread?.type === 'TSSatisfiesExpression') spread = child(spread, 'expression')\n if (spread?.type !== 'ObjectExpression') continue\n for (const property of children(spread, 'properties')) {\n const key = property?.type === 'Property' && !property.computed ? nameOf(child(property, 'key')) : undefined\n if (key && CLASS_PROP.test(key)) check(element, binding, key, child(property as Node, 'value'), property as Node)\n }\n }\n },\n }\n },\n}\n", "import type { Rule } from 'eslint'\nimport { ESCAPE_MESSAGES, isEscaped } from './escape'\n\ninterface JSXOpeningElement {\n type: string\n name: { type: string; name?: string }\n loc: NonNullable<Rule.Node['loc']>\n range: [number, number]\n parent?: Parent\n}\n\ninterface Parent {\n type: string\n name?: { name?: string }\n openingElement?: unknown\n parent?: Parent\n}\n\n/**\n * The elements this package writes by hand. The set the count used (UIG-1,\n * docs/GATES.md \u00A75 and \u00A77): every element that carries behaviour or a role of\n * its own. A `div` or a `span` is layout and is nobody's business here.\n */\nexport const RAW_ELEMENTS = new Set(['a', 'button', 'input', 'textarea', 'select', 'dialog', 'form', 'label'])\n\n/**\n * A raw element nested inside another element, in the package itself (UIG-5,\n * the inward tracer).\n *\n * The package is allowed to write raw elements \u2014 that is what a primitive is.\n * Two shapes are right, and both are facts about the code rather than a\n * judgement:\n *\n * - **the component's own outermost element.** `NavItem` is an `<a>`, `Link` is\n * an `<a>`, a `MenuItem` outside a `Menu` is a `<button>`. A primitive owning\n * its element is the whole point of it.\n * - **handed to a Base UI `render` prop.** `render={<button type=\"button\" />}`\n * tells a Base UI part which element to be; the behaviour stays Base UI's.\n *\n * Anything else is an element buried inside a bigger component, where its look\n * and its behaviour are kept in step by nobody \u2014 the package's own version of\n * the rule the apps get from UIG-3 and UIG-7.\n *\n * It keeps its reason on the line above if it stays: `// @estiva-escape: <why>`.\n */\nexport const rawElementOutsideAWrapper: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: { description: 'A raw element nested inside a component, rather than the component itself' },\n schema: [],\n messages: {\n nested:\n 'A raw <{{name}}> inside another element. In this package a raw element is either the component\\'s own outermost element or handed to a Base UI `render` prop; one buried inside belongs in a component of its own (Link, Button, MenuItem...).',\n ...ESCAPE_MESSAGES,\n },\n },\n create(context) {\n return {\n // ESLint's types know ESTree's nodes, not JSX's; the parser hands this one over.\n JSXOpeningElement(node: Rule.Node) {\n const element = node as unknown as JSXOpeningElement\n const name = element.name.name\n if (element.name.type !== 'JSXIdentifier' || !name || !RAW_ELEMENTS.has(name)) return\n\n // An opening tag's own parent is its JSXElement: that is this element,\n // not an element around it.\n let parent = element.parent\n if (parent?.type === 'JSXElement' && parent.openingElement === (element as unknown)) parent = parent.parent\n\n // Whichever comes first going outward decides: an element around it\n // means it is nested; a `render` prop means Base UI draws it.\n for (let p = parent; p; p = p.parent) {\n if (p.type === 'JSXAttribute') {\n if (p.name?.name === 'render') return\n continue\n }\n if (p.type !== 'JSXElement' && p.type !== 'JSXFragment') continue\n if (isEscaped(context, element)) return\n context.report({ loc: element.loc, messageId: 'nested', data: { name } })\n return\n }\n },\n }\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["rules", "part", "child", "statement", "existsSync", "code", "existsSync", "statement", "attribute"]
|
|
7
7
|
}
|