@estiva-app/ui 0.36.0 → 0.37.1
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/dist/Panel.d.ts +47 -0
- package/dist/Panel.d.ts.map +1 -0
- package/dist/ScrollArea.d.ts +7 -2
- package/dist/ScrollArea.d.ts.map +1 -1
- package/dist/eslint/index.js +16 -3
- package/dist/eslint/index.js.map +3 -3
- package/dist/eslint/no-handmade-header.d.ts +5 -0
- package/dist/eslint/no-handmade-header.d.ts.map +1 -1
- package/dist/eslint/no-native-title.d.ts +1 -1
- package/dist/eslint/no-native-title.d.ts.map +1 -1
- package/dist/gates/app-checks.d.ts +1 -1
- package/dist/gates/app-checks.d.ts.map +1 -1
- package/dist/gates/index.js +5 -2
- package/dist/gates/index.js.map +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +63 -36
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/registry.json +77 -3
- package/src/Panel.mdx +78 -0
- package/src/Panel.stories.tsx +111 -0
- package/src/Panel.tsx +83 -0
- package/src/ScrollArea.mdx +2 -2
- package/src/ScrollArea.stories.tsx +1 -1
- package/src/ScrollArea.tsx +9 -4
- package/src/eslint/no-handmade-header.test.ts +9 -0
- package/src/eslint/no-handmade-header.ts +24 -2
- package/src/eslint/no-native-title.ts +1 -1
- package/src/gates/app-checks.ts +5 -3
- package/src/index.ts +1 -0
- package/src/registry/app.test.ts +3 -1
- package/src/registry/registry.test.ts +4 -4
- package/stories/Choosing.mdx +4 -3
|
@@ -12,6 +12,11 @@ import type { Rule } from 'eslint';
|
|
|
12
12
|
* What it leaves alone, on purpose: a group heading inside a list (the row one
|
|
13
13
|
* section starts with), a label strip on a card, and a row a person presses.
|
|
14
14
|
* Only a lowercase element is judged: a part is already a part.
|
|
15
|
+
*
|
|
16
|
+
* And the package's `ContainerHeader` on its own in an app (26 September): a
|
|
17
|
+
* header over a box of the app's own is a panel made by hand, and the box is
|
|
18
|
+
* what forgot to scroll — Peek's widget panel cut off a long description. The
|
|
19
|
+
* message names `Panel`, whose body always scrolls.
|
|
15
20
|
*/
|
|
16
21
|
export declare const noHandmadeHeader: Rule.RuleModule;
|
|
17
22
|
//# sourceMappingURL=no-handmade-header.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-handmade-header.d.ts","sourceRoot":"","sources":["../../src/eslint/no-handmade-header.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AA8GlC
|
|
1
|
+
{"version":3,"file":"no-handmade-header.d.ts","sourceRoot":"","sources":["../../src/eslint/no-handmade-header.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AA8GlC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,EAAE,IAAI,CAAC,UA6CnC,CAAA"}
|
|
@@ -5,7 +5,7 @@ import type { Rule } from 'eslint';
|
|
|
5
5
|
* the browser shows it as its tooltip. `no-native-title.test.ts` holds this
|
|
6
6
|
* list to the catalogue: a part that gains a `title` of its own joins it.
|
|
7
7
|
*/
|
|
8
|
-
export declare const PARTS_WITH_A_TITLE: readonly ["CollapsibleSection", "ConfirmDialog", "ContainerHeader", "DialogShell", "ListColumn", "SectionHeader"];
|
|
8
|
+
export declare const PARTS_WITH_A_TITLE: readonly ["CollapsibleSection", "ConfirmDialog", "ContainerHeader", "DialogShell", "ListColumn", "Panel", "SectionHeader"];
|
|
9
9
|
/**
|
|
10
10
|
* UIG-24: the browser's tooltip where ours belongs.
|
|
11
11
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-native-title.d.ts","sourceRoot":"","sources":["../../src/eslint/no-native-title.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAIlC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"no-native-title.d.ts","sourceRoot":"","sources":["../../src/eslint/no-native-title.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAIlC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,4HAA6H,CAAA;AAM5J;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa,EAAE,IAAI,CAAC,UAkChC,CAAA"}
|
|
@@ -32,7 +32,7 @@ export interface AppCheckOptions {
|
|
|
32
32
|
};
|
|
33
33
|
/** The token lint configs the app has, relative to the app. */
|
|
34
34
|
tokenConfigs?: string[];
|
|
35
|
-
/** The part a hand-made column header should name (UIG-22): `ContainerHeader
|
|
35
|
+
/** The part a hand-made column header should name (UIG-22): `Panel` since 0.37.0, `ContainerHeader` before. */
|
|
36
36
|
headers?: string[];
|
|
37
37
|
}
|
|
38
38
|
export declare const APP_TICKET_TITLES: Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-checks.d.ts","sourceRoot":"","sources":["../../src/gates/app-checks.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAA0B,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE/E,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAA;IACZ,8GAA8G;IAC9G,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IACvC,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB
|
|
1
|
+
{"version":3,"file":"app-checks.d.ts","sourceRoot":"","sources":["../../src/gates/app-checks.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAA0B,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE/E,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAA;IACZ,8GAA8G;IAC9G,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IACvC,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,+GAA+G;IAC/G,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsBpD,CAAA;AAaD,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,GAAS,EAAE,IAAI,EAAE,KAAsC,EAAE,YAA8D,EAAE,OAAmB,EAAE,EAAE,eAAe,GAAG,UAAU,EAAE,CAkNzN"}
|
package/dist/gates/index.js
CHANGED
|
@@ -100,7 +100,7 @@ function all(h, steps, label) {
|
|
|
100
100
|
return h.PASS(label);
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
function appChecks(h, { app = ".", page, chain = { ref: "UIG-3", owner: false }, tokenConfigs = ["eslint.tokens.config.js", "eslint.config.js"], headers = ["
|
|
103
|
+
function appChecks(h, { app = ".", page, chain = { ref: "UIG-3", owner: false }, tokenConfigs = ["eslint.tokens.config.js", "eslint.config.js"], headers = ["Panel"] }) {
|
|
104
104
|
const WEB = app === "." ? "" : `${app.replace(/\/$/, "")}/`;
|
|
105
105
|
const cwd = app === "." ? void 0 : app;
|
|
106
106
|
const PROBE = "src/components/__gates_probe__.tsx";
|
|
@@ -259,7 +259,10 @@ export function Probe() {
|
|
|
259
259
|
]),
|
|
260
260
|
ticket("UIG-22", [
|
|
261
261
|
// The Folders pane's own row, at the commit before peek 3dc663b.
|
|
262
|
-
{ what:
|
|
262
|
+
{ what: `a hand-made column header is an error naming ${headers.join(" or ")}`, run: all(h, headers.map((name) => probe(component('<div className="flex h-full flex-col"><div className="flex items-center gap-2 px-3 py-2"><span>Folders</span></div><div /></div>'), "error", name)), `a hand-made column header is an error naming ${headers.join(" or ")}`) },
|
|
263
|
+
// 26 September: the package's header on its own is a panel made by hand, whose box forgot to scroll.
|
|
264
|
+
{ what: "the package's ContainerHeader on its own is an error naming Panel", run: probe(`import { ContainerHeader } from '@estiva-app/ui'
|
|
265
|
+
${component('<div className="flex flex-col"><ContainerHeader title="Details" /><div className="px-4">x</div></div>')}`, "error", "`Panel`") },
|
|
263
266
|
{ what: "a group heading inside a list is left alone", run: probe(component('<section className="flex flex-col gap-px"><h3 className="flex h-8 items-center gap-2 px-3"><span>Todo</span></h3><div /></section>'), "none") }
|
|
264
267
|
]),
|
|
265
268
|
ticket("UIG-23", [
|
package/dist/gates/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/gates/gate-config.ts", "../../src/gates/app-checks.ts"],
|
|
4
|
-
"sourcesContent": ["/// <reference types=\"node\" />\n/**\n * Where the UI Guardrails' rules apply, written once (docs/GATES.md \u00A723).\n *\n * Until UIG-10 every repo wrote this itself: `eslint.gates.js` (the rules and\n * where they apply) and `eslint.gates.config.js` (the gate: those rules alone)\n * in Peek, in Ship, and here pointed inward. The rules were always the\n * package's; these two files were copies. Now they are two functions.\n *\n * Where: every `.ts` and `.tsx` under `src`, stories included (a story is what\n * people read and copy), tests not (a test mounts markup to test it) \u2014\n * Katerina's rulings of 13 September; `.ts` since UIG-8. This package's own\n * inward set reads `.tsx` only, as it always has.\n *\n * A place that keeps something says why, on the line above:\n * `// @estiva-escape: <reason>`, or `{/* @estiva-escape: <reason> *\\/}` as a\n * JSX child. Never `eslint-disable`: the count refuses it.\n */\nimport type { ESLint, Linter } from 'eslint'\nimport betterTailwindcss from 'eslint-plugin-better-tailwindcss'\nimport { parser as typescriptParser } from 'typescript-eslint'\nimport estiva from '../eslint/index'\nimport { KNOWN_PLUGINS, TOKEN_LINT_IGNORES } from './token-lint'\nimport { tokenStylePlugin } from './token-style'\n\nexport interface GateConfigOptions {\n /** `app` (the default) runs `configs.recommended`; `package` runs this package's inward set. */\n audience?: 'app' | 'package'\n /**\n * Plugins whose `eslint-disable` directives appear in the source, registered\n * here with every rule off. ESLint refuses a directive for a rule it does not\n * know, so without them the gate would fail on another lint's comments.\n * The token lint's names and TypeScript's are registered already (UIG-37).\n */\n quiet?: Record<string, ESLint.Plugin>\n /** Folders the gate never reads, beside build output. */\n ignores?: string[]\n}\n\n/**\n * The rules and where they apply \u2014 one config object, to add beside\n * everything else an app's `eslint.config.js` runs, so an editor shows a\n * refusal where the element is typed.\n */\nexport function gateLint({ audience = 'app' }: Pick<GateConfigOptions, 'audience'> = {}): Linter.Config {\n return {\n ...(audience === 'package' ? estiva.configs.package : estiva.configs.recommended),\n // An app's every script type: a raw <button> in a .jsx, or a key listener in a .mts,\n // passed while only .ts and .tsx were read (the re-review after the audit before UIG-26).\n files: audience === 'package' ? ['src/**/*.tsx'] : ['src/**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}'],\n ignores: ['**/*.test.*'],\n languageOptions: {\n parser: typescriptParser,\n parserOptions: { ecmaFeatures: { jsx: true } },\n },\n }\n}\n\n/**\n * The gate: the rules on their own \u2014 `npm run lint:rules`, CI's job `gate`, and\n * the config the editor hook lints a proposed write with. It fails on a gate\n * rule and on nothing else, so a backlog in the full lint never blocks it.\n */\nexport function gateConfig({ audience = 'app', quiet = {}, ignores = [] }: GateConfigOptions = {}): Linter.Config[] {\n return [\n { ignores: [...TOKEN_LINT_IGNORES, ...ignores] },\n {\n plugins: {\n ...KNOWN_PLUGINS,\n ...quiet,\n 'better-tailwindcss': betterTailwindcss,\n 'token-values': betterTailwindcss,\n 'token-spacing': betterTailwindcss,\n 'token-style': tokenStylePlugin,\n },\n // Every other config's directives are unused here, because their rules are\n // off here. Reporting them would be this config complaining about the\n // others' business.\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n },\n gateLint({ audience }),\n ]\n}\n", "/// <reference types=\"node\" />\n/**\n * The gate checks every app runs, written once (docs/GATES.md \u00A723).\n *\n * Until UIG-10 Peek and Ship each wrote them into their own\n * `scripts/gates-checks.mjs`. 65 different checks for finished tickets, counted\n * on 17 September: 28 were identical in both, 21 were the same check written two\n * ways, 2 read each app's real page, and 14 read code only one app has. This is\n * the first three groups as one list. The fourth stays in the app's own checks\n * file, beside this list.\n *\n * Where Peek and Ship wrote one check two ways, the check here runs both, so it\n * passes wherever either did: the raw-link probe with both of their texts, the\n * token probes against each token config the app has.\n *\n * `scripts/gates-compare.mjs` holds this list to Peek's and Ship's: every check\n * of theirs must be here, or be about code only that app has, or the comparison\n * fails and names it.\n *\n * A check for a ticket not built yet is a first guess at the evidence, taken\n * from the ticket's own text; the ticket that builds it changes it here.\n */\nimport type { CheckResult, GateCheck, GateHelpers, GateTicket } from './status'\n\nexport interface AppCheckOptions {\n /** Where the app is inside the repository: `.` unless it sits in a folder of its own. */\n app?: string\n /** A real page of the app, relative to the app, full of elements that are not controls. */\n page: string\n /** The ticket the gate chain is listed under, and whether this repo owns it: UIG-3 in Peek, UIG-4 in Ship. */\n chain?: { ref: string; owner: boolean }\n /** The token lint configs the app has, relative to the app. */\n tokenConfigs?: string[]\n /** The part a hand-made column header should name (UIG-22): `ContainerHeader`. */\n headers?: string[]\n}\n\nexport const APP_TICKET_TITLES: Record<string, string> = {\n 'UIG-2': 'The tracking rails \u2014 GATES.md, the status script, the guide committed',\n 'UIG-3': 'Tracer bullet \u2014 one rule, end to end, blocking in Peek',\n 'UIG-4': 'The same chain, blocking in Ship',\n 'UIG-6': 'Branch protection \u2014 the backstop, all three repos',\n 'UIG-7': 'Lint rule \u2014 every remaining raw element',\n 'UIG-8': 'Lint rule \u2014 forbid the reach',\n 'UIG-9': 'Lint rule \u2014 the className allow-list',\n 'UIG-10': 'create-app \u2014 a command that makes a new Estiva app that runs',\n 'UIG-13': \"The registry widens to Peek's 115 and Ship's 74, with classification\",\n 'UIG-19': 'Lock the contract in CI',\n 'UIG-20': 'The Claude skill, reading the registry',\n 'UIG-21': 'CLAUDE.md becomes an index, not a lecture',\n 'UIG-22': 'Fingerprint \u2014 a hand-made header row',\n 'UIG-23': 'Fingerprint \u2014 a hand-made empty state',\n 'UIG-24': 'Fingerprint \u2014 a browser tooltip where ours belongs',\n 'UIG-25': 'Fingerprint \u2014 a component copied out by hand',\n 'UIG-27': 'The components the apps had to build themselves \u2014 Link, ProgressBar, EmptyState padding',\n 'UIG-28': 'Close the two holes in the token contract \u2014 arbitrary values, and inline style',\n 'UIG-30': 'RichText \u2014 one component that draws a message\\'s text, for both apps',\n 'UIG-32': 'Peek and Ship take their gate pieces from the package',\n 'UIG-37': 'The gates refuse a TypeScript eslint-disable comment \u2014 know the rule names, rules off',\n}\n\n/** Run several checks as one: the first that does not pass is the answer. */\nfunction all(h: GateHelpers, steps: (() => CheckResult | Promise<CheckResult>)[], label: string): () => Promise<CheckResult> {\n return async () => {\n for (const step of steps) {\n const r = await step()\n if (r.result !== 'pass') return r\n }\n return h.PASS(label)\n }\n}\n\nexport function appChecks(h: GateHelpers, { app = '.', page, chain = { ref: 'UIG-3', owner: false }, tokenConfigs = ['eslint.tokens.config.js', 'eslint.config.js'], headers = ['ContainerHeader'] }: AppCheckOptions): GateTicket[] {\n const WEB = app === '.' ? '' : `${app.replace(/\\/$/, '')}/`\n const cwd = app === '.' ? undefined : app\n const PROBE = 'src/components/__gates_probe__.tsx'\n const GATES = 'eslint.gates.config.js'\n const at = (rel: string) => `${WEB}${rel}`\n const probe = (code: string, expect: 'error' | 'warning' | 'none', mentions?: string, file = PROBE, config = GATES) => () =>\n h.lint({ ...(cwd ? { cwd } : {}), config, file, code, expect, mentions })\n const component = (body: string) => `export function Probe() {\\n return ${body}\\n}\\n`\n const installed = at('node_modules/@estiva-app/ui/dist/index.d.ts')\n const realPage = (): Promise<CheckResult> => h.lint({ ...(cwd ? { cwd } : {}), config: GATES, file: page, code: h.read(at(page)), expect: 'none' })\n const button = component('<button type=\"button\">x</button>')\n /** A line TypeScript's own lint writes; ESLint refuses it where TypeScript's plugin is unknown (UIG-37). */\n const typescriptDirective = '// eslint-disable-next-line @typescript-eslint/no-explicit-any\\nexport const probe: any = 1\\n'\n const ticket = (ref: string, checks: GateCheck[], owner = false): GateTicket => ({ ref, title: APP_TICKET_TITLES[ref], owner, checks })\n\n const tokenProbe = (code: string, expect: 'error' | 'warning' | 'none', mentions?: string, file = PROBE) =>\n all(h, tokenConfigs.map((config) => probe(code, expect, mentions, file, config)), `${tokenConfigs.join(' and ')}: as expected`)\n\n return [\n ticket('UIG-2', [\n { what: 'npm run gates:status is wired', run: () => h.script('package.json', 'gates:status') },\n ]),\n ticket(chain.ref, [\n { what: 'the gate lint config loads', run: () => h.loads(at(GATES)) },\n { what: `${at('package.json')} has lint:rules`, run: () => h.script(at('package.json'), 'lint:rules') },\n { what: 'CI runs lint:rules', run: () => h.ci('lint:rules') },\n { what: 'the committed hook runs the gate lint', run: () => h.hook('.claude/settings.json', 'gates') },\n { what: '.gates-count.json is committed and parses', run: () => h.json(h.exists('.gates-count.json') ? '.gates-count.json' : at('.gates-count.json')) },\n { what: 'a raw <button> is an error naming Button', run: probe(button, 'error', 'Button') },\n { what: 'the same in a story', run: probe(button, 'error', 'Button', 'src/stories/__gates_probe__.stories.tsx') },\n { what: 'a test file is not checked, while source is', run: async () => {\n const source = await probe(button, 'error', 'Button')()\n if (source.result !== 'pass') return h.FAIL(`source is not checked yet, so this proves nothing: ${source.detail}`)\n return probe(button, 'none', undefined, 'src/components/__gates_probe__.test.tsx')()\n } },\n { what: 'the debt list exists', run: () => h.file('docs/GATES-DEBT.md') },\n ], chain.owner),\n ticket('UIG-6', [\n { what: 'GitHub requires the check gate to merge into main', run: () => h.protectedBranch(/^gate$/) },\n { what: \"CI's job gate runs lint:rules\", run: () => h.ciJob('gate', 'lint:rules') },\n ]),\n ticket('UIG-7', [\n { what: 'a raw <input> is an error naming TextInput', run: probe(component('<input />'), 'error', 'TextInput') },\n { what: 'a clickable <div> is an error naming Button (R5)', run: probe(component('<div onClick={() => history.back()}>Back</div>'), 'error', '`Button`') },\n { what: 'a raw <a> is an error naming Link', run: all(h, [probe(component('<a href=\"/topics\">Topics</a>'), 'error', 'Link'), probe(component('<a href=\"/issues\">Issues</a>'), 'error', 'Link')], 'a raw <a> is an error naming Link') },\n { what: 'a raw <form> is an error naming Form, and a file input one naming FilePicker', run: async () => {\n const form = await probe(component('<form />'), 'error', '`Form`')()\n if (form.result !== 'pass') return form\n return probe(component('<input type=\"file\" />'), 'error', 'FilePicker')()\n } },\n { what: '<textarea>, <select>, <dialog> and <label> name Textarea, Select, DialogShell and Field', run: async () => {\n for (const [element, part] of [['textarea', 'Textarea'], ['select', 'Select'], ['dialog', 'DialogShell'], ['label', 'Field']]) {\n const one = await probe(component(`<${element} />`), 'error', `\\`${part}\\``)()\n if (one.result !== 'pass') return one\n }\n return h.PASS('all four are errors, each naming its part')\n } },\n { what: 'an element the package has no part for is an error that says to ask for one', run: probe(component('<iframe title=\"Map\" />'), 'error', 'ask Katerina') },\n { what: 'an escaped element is not an error, while the same element is', run: async () => {\n const raw = await probe(component('<form />'), 'error')()\n if (raw.result !== 'pass') return h.FAIL(`a raw <form> is not caught yet, so this proves nothing: ${raw.detail}`)\n return probe('export function Probe() {\\n return (\\n // @estiva-escape(no-raw-element): a probe that keeps its element on purpose\\n <form />\\n )\\n}\\n', 'none')()\n } },\n { what: 'a real page, full of elements that are not controls, gets no error', run: realPage },\n ]),\n ticket('UIG-8', [\n { what: 'a Base UI import is an error naming the part built on it', run: probe(\"import { Popover } from '@base-ui/react/popover'\\nexport const Probe = Popover\\n\", 'error', '`Popover`') },\n { what: 'createPortal is an error naming the floating parts', run: probe(\"import { createPortal } from 'react-dom'\\nexport const Probe = (to: HTMLElement) => createPortal(<span />, to)\\n\", 'error', '`DialogShell`') },\n { what: 'a key listener on the whole page is an error, in a .ts file too', run: probe(\"export function listen() {\\n window.addEventListener('keydown', () => {})\\n}\\n\", 'error', '`DialogShell`', 'src/lib/__gates_probe__.ts') },\n { what: 'arrow keys by hand are an error; Enter in a field is not', run: async () => {\n const arrows = await probe(\"export const onKeyDown = (e: KeyboardEvent) => e.key === 'ArrowDown'\\n\", 'error', '`Menu`', 'src/lib/__gates_probe__.ts')()\n if (arrows.result !== 'pass') return arrows\n return probe(\"export const onKeyDown = (e: KeyboardEvent) => e.key === 'Enter'\\n\", 'none', undefined, 'src/lib/__gates_probe__.ts')()\n } },\n { what: 'a hand-written role=\"option\" is an error naming Select', run: probe(component('<div role=\"option\" />'), 'error', '`Select`') },\n { what: 'tabIndex={0} on a div is an error; tabIndex={-1} is not', run: async () => {\n const zero = await probe(component('<div tabIndex={0} />'), 'error', '`Button`')()\n if (zero.result !== 'pass') return h.FAIL(`tabIndex={0} is not caught yet, so this proves nothing: ${zero.detail}`)\n return probe(component('<div tabIndex={-1} />'), 'none')()\n } },\n { what: 'overflow-y-auto is an error naming ScrollArea', run: probe(component('<div className=\"h-64 overflow-y-auto\" />'), 'error', '`ScrollArea`') },\n { what: 'an escaped listener is not an error, while the same listener is', run: async () => {\n const raw = await probe(\"export function listen() {\\n document.addEventListener('mousedown', () => {})\\n}\\n\", 'error', undefined, 'src/lib/__gates_probe__.ts')()\n if (raw.result !== 'pass') return h.FAIL(`a page listener is not caught yet, so this proves nothing: ${raw.detail}`)\n return probe(\"export function listen() {\\n // @estiva-escape(no-rebuilt-behaviour): a probe that keeps its listener on purpose\\n document.addEventListener('mousedown', () => {})\\n}\\n\", 'none', undefined, 'src/lib/__gates_probe__.ts')()\n } },\n { what: 'a real page gets no error', run: realPage },\n ]),\n ticket('UIG-9', [\n { what: 'a border passed into Button is an error naming Button', run: probe(`import { Button } from '@estiva-app/ui'\\n${component('<Button className=\"border\">x</Button>')}`, 'error', 'on `Button` changes how it looks') },\n { what: 'placement passed into Button is not', run: probe(`import { Button } from '@estiva-app/ui'\\n${component('<Button className=\"mt-2 w-full flex-1 relative\">x</Button>')}`, 'none') },\n { what: 'an escaped look is not an error, while the same look is', run: async () => {\n const raw = await probe(`import { Link } from '@estiva-app/ui'\\n${component('<Link href=\"/x\" className=\"after:absolute after:inset-0\">x</Link>')}`, 'error', '`Link`')()\n if (raw.result !== 'pass') return h.FAIL(`a restyled part is not caught yet, so this proves nothing: ${raw.detail}`)\n return probe(`import { Link } from '@estiva-app/ui'\\nexport function Probe() {\\n return (\\n // @estiva-escape(no-restyled-part): a probe that keeps its row link on purpose\\n <Link href=\"/x\" className=\"after:absolute after:inset-0\">x</Link>\\n )\\n}\\n`, 'none')()\n } },\n { what: 'a real page gets no error', run: realPage },\n ]),\n // UIG-10, reopened 18 September: a tab holds one relay client, the way Peek and Ship hold\n // theirs and a made app is written to. Measured on both mains that day: one each, and no\n // socket opened any other way. A second holder, or a socket of the app's own, is a second\n // connection the relay signs in and budgets separately.\n ticket('UIG-10', [\n { what: 'the app holds one relay client, at module level, and opens no socket of its own', run: () => {\n const sources = h.listFiles(at('src'), (n) => /\\.tsx?$/.test(n) && !/\\.(test|stories)\\.tsx?$/.test(n))\n const own = sources.filter((f) => /\\bcreateLiveClient\\(|\\bcreateLiveRelay\\(|\\bnew WebSocket\\(/.test(h.read(f)))\n if (own.length) return h.FAIL(`opens a socket of its own (${own.join(', ')}): hold one client from createLiveClientHolder()`)\n const holders = sources.filter((f) => /^\\s*(?:export\\s+)?const\\s+\\w+\\s*=\\s*createLiveClientHolder\\(\\)/m.test(h.read(f)))\n if (holders.length !== 1) return h.FAIL(holders.length ? `${holders.length} client holders (${holders.join(', ')}): a tab holds one` : 'no module-level createLiveClientHolder(): the app has no relay client')\n return h.PASS(`one client for the tab, held in ${holders[0]}`)\n } },\n ]),\n // Built by UIG-13, 18 September. An app's catalogue is built fresh from its code\n // and never committed: the package is public and the apps are private (Katerina).\n ticket('UIG-13', [\n { what: \"npm run ui:find is the package's search, over the package and this app\", run: () => h.contains(at('package.json'), /\"ui:find\":\\s*\"estiva-ui find\\b/, \"ui:find runs the package's estiva-ui find\") },\n { what: \"npm run registry:check is the package's check\", run: () => h.contains(at('package.json'), /\"registry:check\":\\s*\"estiva-ui check\\b/, 'registry:check runs estiva-ui check') },\n { what: \"CI's job gate refuses a part with no description\", run: () => h.ciJob('gate', 'registry:check') },\n // In the .gitignore of the app's own folder, where `estiva-ui build` would write it.\n { what: 'the catalogue is never committed: git ignores registry.json', run: () => h.contains(at('.gitignore'), /^\\/?registry\\.json\\r?$/m, `${at('.gitignore')} ignores registry.json`) },\n { what: 'every part is described and sorted, and every file is accounted for', run: () => h.catalogue(at('.')) },\n ]),\n ticket('UIG-19', [\n // The contract runs inside `estiva-ui check`, which the gate job already runs\n // (UIG-13), so an app changes no script: it takes the package that has it.\n { what: 'the installed package checks the usage-page contract and the story links', run: () => h.contains(at('node_modules/@estiva-app/ui/dist/registry/cli.js'), 'the usage-page contract', \"the installed estiva-ui check runs the contract\") },\n { what: \"CI's job gate runs it\", run: () => h.ciJob('gate', 'registry:check') },\n { what: 'the app keeps no copy of it in its own gates-checks.mjs', run: () => h.exists(at('scripts/gates-checks.mjs')) ? h.lacks(at('scripts/gates-checks.mjs'), '\"When not\"', 'the app checks no page sections itself') : h.PASS('the app has no gates-checks.mjs') },\n ]),\n // The Claude skill (UIG-20): its text is the installed package's, read in by a\n // loader `estiva-ui skill` writes; the app commits the loader and the settings.\n ticket('UIG-20', [\n { what: \"the skill's loader reads the installed package's text\", run: () => h.contains('.claude/skills/estiva-ui/SKILL.md', `!\\`cat \"\\${CLAUDE_PROJECT_DIR}/${at('node_modules/@estiva-app/ui/skill/estiva-ui.md')}\"\\``, 'the loader reads the package\u2019s skill') },\n { what: 'the search runs without a prompt', run: () => h.contains('.claude/settings.json', 'Bash(npm run ui:find *)', '.claude/settings.json allows npm run ui:find') },\n { what: 'ui:find searches every app beside this one: it names none', run: () => h.lacks(at('package.json'), /\"ui:find\":[^\\n]*--also/, 'ui:find names no neighbour, so it finds them all') },\n ...(WEB ? [{ what: 'ui:find runs from the top folder too', run: () => h.contains('package.json', /\"ui:find\":/, 'the top folder has ui:find') }] : []),\n { what: \"CI's job gate refuses a loader that differs\", run: () => (h.exists(at('node_modules/@estiva-app/ui/dist/registry/cli.js')) && /claude skill:/.test(h.read(at('node_modules/@estiva-app/ui/dist/registry/cli.js'))) ? h.ciJob('gate', 'registry:check') : h.FAIL('the installed package does not check the loader: take a version that does')) },\n ]),\n // What loads into every Claude session (UIG-21): CLAUDE.md is an index, the\n // rest loads where it applies, and a rule a check can hold is a check.\n ticket('UIG-21', [\n { what: 'CLAUDE.md with its imports is under 200 lines, and every rule file is scoped', run: () => h.instructions(200) },\n { what: \"CI's job gate runs the token lint\", run: () => {\n const tokens = h.ciJob('gate', 'lint:tokens')\n return tokens.result === 'pass' ? tokens : h.ciJob('gate', 'lint')\n } },\n { what: \"a plain tailwind-merge is an error naming the package's cn()\", run: tokenProbe(\"import { twMerge } from 'tailwind-merge'\\nexport const merged = twMerge('p-2', 'p-3')\\n\", 'error', 'cn()', 'src/lib/__gates_probe__.ts') },\n ]),\n ticket('UIG-22', [\n // The Folders pane's own row, at the commit before peek 3dc663b.\n { what: 'a hand-made column header is an error naming ContainerHeader', run: all(h, headers.map((name) => probe(component('<div className=\"flex h-full flex-col\"><div className=\"flex items-center gap-2 px-3 py-2\"><span>Folders</span></div><div /></div>'), 'error', name)), 'a hand-made column header is an error naming ContainerHeader') },\n { what: 'a group heading inside a list is left alone', run: probe(component('<section className=\"flex flex-col gap-px\"><h3 className=\"flex h-8 items-center gap-2 px-3\"><span>Todo</span></h3><div /></section>'), 'none') },\n ]),\n ticket('UIG-23', [\n { what: 'a hand-made empty line is an error naming EmptyState', run: probe(\"export function Probe({ items }: { items: string[] }) {\\n return <div>{items.length === 0 ? <p className=\\\"text-text-secondary\\\">Nothing here</p> : items.map((i) => <span key={i}>{i}</span>)}</div>\\n}\\n\", 'error', 'EmptyState') },\n ]),\n ticket('UIG-24', [\n { what: 'a title= is an error naming WithTooltip', run: probe(`import { Button } from '@estiva-app/ui'\\n${component('<Button title=\"Delete\">x</Button>')}`, 'error', 'WithTooltip') },\n ]),\n ticket('UIG-25', [\n { what: \"SectionLabel's class list, typed by hand, is a warning\", run: probe(component('<span className=\"text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-secondary\">Label</span>'), 'warning', 'SectionLabel') },\n ]),\n ticket('UIG-27', [\n { what: 'the installed package has Link', run: () => h.contains(installed, /\\bLink\\b/, 'the installed @estiva-app/ui exports Link') },\n { what: 'the installed package has ProgressBar', run: () => h.contains(installed, /\\bProgressBar\\b/, 'the installed @estiva-app/ui exports ProgressBar') },\n ]),\n ticket('UIG-28', [\n { what: 'text-[14px] is an error', run: tokenProbe(component('<div className=\"text-[14px]\">x</div>'), 'error') },\n { what: 'a colour in an inline style is an error', run: tokenProbe(component(\"<div style={{ backgroundColor: '#ff0000' }}>x</div>\"), 'error') },\n { what: 'h-[240px] is a warning', run: tokenProbe(component('<div className=\"h-[240px]\">x</div>'), 'warning') },\n { what: 'h-[240px] is not an error', run: tokenProbe(component('<div className=\"h-[240px]\">x</div>'), 'none') },\n { what: 'a hand-written line height behind an arbitrary variant is an error', run: tokenProbe(component('<div className=\"[&_p]:leading-[1.4]\">x</div>'), 'error') },\n { what: 'a raw colour in a class is an error (the pattern that matched nothing, R1)', run: tokenProbe(component('<div className=\"bg-[#5c69dc]\">x</div>'), 'error', 'raw colour') },\n { what: 'a width and height from a prop pass', run: tokenProbe(\"export function Probe({ size }: { size: number }) {\\n return <div style={{ width: size, height: size }}>x</div>\\n}\\n\", 'none') },\n { what: 'a test file is not checked for hand-written values, while source is', run: all(h, tokenConfigs.map((config) => async () => {\n const code = component(\"<div className=\\\"text-[14px]\\\" style={{ color: 'red' }}>x</div>\")\n const source = await probe(code, 'error', undefined, PROBE, config)()\n if (source.result !== 'pass') return h.FAIL(`source is not checked yet, so this proves nothing: ${source.detail}`)\n return probe(code, 'none', undefined, 'src/components/__gates_probe__.test.tsx', config)()\n }), 'a test file is not checked for hand-written values, while source is') },\n ]),\n ticket('UIG-30', [\n { what: 'the installed package has RichText', run: () => h.contains(installed, /\\bRichText\\b/, 'the installed @estiva-app/ui exports RichText') },\n ]),\n // Katerina's ruling of 17 September (docs/GATES.md \u00A723): one copy, in the package. An app made\n // by create-estiva-app passes this from its first commit; Peek and Ship do once UIG-32 lands.\n ticket('UIG-32', [\n { what: 'the gate pieces come from the package, and no repo keeps a copy', run: all(h, [\n () => h.contains(at('eslint.gates.config.js'), /from '@estiva-app\\/ui\\/gates'/, 'the gate config imports @estiva-app/ui/gates'),\n () => h.hook('.claude/settings.json', '@estiva-app/ui/dist/gates/cli.js'),\n // `estiva-gates status` where npm can find the command; by path where it cannot,\n // because the install is in the app's folder and the script is in the repo's top one (Ship).\n () => h.contains('package.json', /\"gates:status\":\\s*\"[^\"]*(?:estiva-gates|@estiva-app\\/ui\\/dist\\/gates\\/cli\\.js)[^\"]*status/, \"gates:status runs the package's engine\"),\n () => (h.exists('scripts/gates-status.mjs') ? h.FAIL('scripts/gates-status.mjs is a copy of the status engine: run estiva-gates status instead') : h.PASS('no copy of the status engine')),\n ], 'the gate config, the hook and gates:status are the package\\'s; no copy of the engine') },\n ]),\n ticket('UIG-37', [\n { what: 'a TypeScript eslint-disable comment breaks neither the gate nor the token lint', run: all(h, [\n probe(typescriptDirective, 'none'),\n tokenProbe(typescriptDirective, 'none'),\n ], `${[GATES, ...tokenConfigs].join(', ')}: a TypeScript directive is no error`) },\n { what: 'a token lint on its own is the package\\'s tokenConfig, not built by hand', run: () =>\n (h.exists(at('eslint.tokens.config.js'))\n ? h.contains(at('eslint.tokens.config.js'), /\\btokenConfig\\(/, 'eslint.tokens.config.js runs tokenConfig from @estiva-app/ui/gates')\n : h.PASS('no token lint on its own')) },\n ]),\n ]\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/// <reference types=\"node\" />\n/**\n * Where the UI Guardrails' rules apply, written once (docs/GATES.md \u00A723).\n *\n * Until UIG-10 every repo wrote this itself: `eslint.gates.js` (the rules and\n * where they apply) and `eslint.gates.config.js` (the gate: those rules alone)\n * in Peek, in Ship, and here pointed inward. The rules were always the\n * package's; these two files were copies. Now they are two functions.\n *\n * Where: every `.ts` and `.tsx` under `src`, stories included (a story is what\n * people read and copy), tests not (a test mounts markup to test it) \u2014\n * Katerina's rulings of 13 September; `.ts` since UIG-8. This package's own\n * inward set reads `.tsx` only, as it always has.\n *\n * A place that keeps something says why, on the line above:\n * `// @estiva-escape: <reason>`, or `{/* @estiva-escape: <reason> *\\/}` as a\n * JSX child. Never `eslint-disable`: the count refuses it.\n */\nimport type { ESLint, Linter } from 'eslint'\nimport betterTailwindcss from 'eslint-plugin-better-tailwindcss'\nimport { parser as typescriptParser } from 'typescript-eslint'\nimport estiva from '../eslint/index'\nimport { KNOWN_PLUGINS, TOKEN_LINT_IGNORES } from './token-lint'\nimport { tokenStylePlugin } from './token-style'\n\nexport interface GateConfigOptions {\n /** `app` (the default) runs `configs.recommended`; `package` runs this package's inward set. */\n audience?: 'app' | 'package'\n /**\n * Plugins whose `eslint-disable` directives appear in the source, registered\n * here with every rule off. ESLint refuses a directive for a rule it does not\n * know, so without them the gate would fail on another lint's comments.\n * The token lint's names and TypeScript's are registered already (UIG-37).\n */\n quiet?: Record<string, ESLint.Plugin>\n /** Folders the gate never reads, beside build output. */\n ignores?: string[]\n}\n\n/**\n * The rules and where they apply \u2014 one config object, to add beside\n * everything else an app's `eslint.config.js` runs, so an editor shows a\n * refusal where the element is typed.\n */\nexport function gateLint({ audience = 'app' }: Pick<GateConfigOptions, 'audience'> = {}): Linter.Config {\n return {\n ...(audience === 'package' ? estiva.configs.package : estiva.configs.recommended),\n // An app's every script type: a raw <button> in a .jsx, or a key listener in a .mts,\n // passed while only .ts and .tsx were read (the re-review after the audit before UIG-26).\n files: audience === 'package' ? ['src/**/*.tsx'] : ['src/**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}'],\n ignores: ['**/*.test.*'],\n languageOptions: {\n parser: typescriptParser,\n parserOptions: { ecmaFeatures: { jsx: true } },\n },\n }\n}\n\n/**\n * The gate: the rules on their own \u2014 `npm run lint:rules`, CI's job `gate`, and\n * the config the editor hook lints a proposed write with. It fails on a gate\n * rule and on nothing else, so a backlog in the full lint never blocks it.\n */\nexport function gateConfig({ audience = 'app', quiet = {}, ignores = [] }: GateConfigOptions = {}): Linter.Config[] {\n return [\n { ignores: [...TOKEN_LINT_IGNORES, ...ignores] },\n {\n plugins: {\n ...KNOWN_PLUGINS,\n ...quiet,\n 'better-tailwindcss': betterTailwindcss,\n 'token-values': betterTailwindcss,\n 'token-spacing': betterTailwindcss,\n 'token-style': tokenStylePlugin,\n },\n // Every other config's directives are unused here, because their rules are\n // off here. Reporting them would be this config complaining about the\n // others' business.\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n },\n gateLint({ audience }),\n ]\n}\n", "/// <reference types=\"node\" />\n/**\n * The gate checks every app runs, written once (docs/GATES.md \u00A723).\n *\n * Until UIG-10 Peek and Ship each wrote them into their own\n * `scripts/gates-checks.mjs`. 65 different checks for finished tickets, counted\n * on 17 September: 28 were identical in both, 21 were the same check written two\n * ways, 2 read each app's real page, and 14 read code only one app has. This is\n * the first three groups as one list. The fourth stays in the app's own checks\n * file, beside this list.\n *\n * Where Peek and Ship wrote one check two ways, the check here runs both, so it\n * passes wherever either did: the raw-link probe with both of their texts, the\n * token probes against each token config the app has.\n *\n * `scripts/gates-compare.mjs` holds this list to Peek's and Ship's: every check\n * of theirs must be here, or be about code only that app has, or the comparison\n * fails and names it.\n *\n * A check for a ticket not built yet is a first guess at the evidence, taken\n * from the ticket's own text; the ticket that builds it changes it here.\n */\nimport type { CheckResult, GateCheck, GateHelpers, GateTicket } from './status'\n\nexport interface AppCheckOptions {\n /** Where the app is inside the repository: `.` unless it sits in a folder of its own. */\n app?: string\n /** A real page of the app, relative to the app, full of elements that are not controls. */\n page: string\n /** The ticket the gate chain is listed under, and whether this repo owns it: UIG-3 in Peek, UIG-4 in Ship. */\n chain?: { ref: string; owner: boolean }\n /** The token lint configs the app has, relative to the app. */\n tokenConfigs?: string[]\n /** The part a hand-made column header should name (UIG-22): `Panel` since 0.37.0, `ContainerHeader` before. */\n headers?: string[]\n}\n\nexport const APP_TICKET_TITLES: Record<string, string> = {\n 'UIG-2': 'The tracking rails \u2014 GATES.md, the status script, the guide committed',\n 'UIG-3': 'Tracer bullet \u2014 one rule, end to end, blocking in Peek',\n 'UIG-4': 'The same chain, blocking in Ship',\n 'UIG-6': 'Branch protection \u2014 the backstop, all three repos',\n 'UIG-7': 'Lint rule \u2014 every remaining raw element',\n 'UIG-8': 'Lint rule \u2014 forbid the reach',\n 'UIG-9': 'Lint rule \u2014 the className allow-list',\n 'UIG-10': 'create-app \u2014 a command that makes a new Estiva app that runs',\n 'UIG-13': \"The registry widens to Peek's 115 and Ship's 74, with classification\",\n 'UIG-19': 'Lock the contract in CI',\n 'UIG-20': 'The Claude skill, reading the registry',\n 'UIG-21': 'CLAUDE.md becomes an index, not a lecture',\n 'UIG-22': 'Fingerprint \u2014 a hand-made header row',\n 'UIG-23': 'Fingerprint \u2014 a hand-made empty state',\n 'UIG-24': 'Fingerprint \u2014 a browser tooltip where ours belongs',\n 'UIG-25': 'Fingerprint \u2014 a component copied out by hand',\n 'UIG-27': 'The components the apps had to build themselves \u2014 Link, ProgressBar, EmptyState padding',\n 'UIG-28': 'Close the two holes in the token contract \u2014 arbitrary values, and inline style',\n 'UIG-30': 'RichText \u2014 one component that draws a message\\'s text, for both apps',\n 'UIG-32': 'Peek and Ship take their gate pieces from the package',\n 'UIG-37': 'The gates refuse a TypeScript eslint-disable comment \u2014 know the rule names, rules off',\n}\n\n/** Run several checks as one: the first that does not pass is the answer. */\nfunction all(h: GateHelpers, steps: (() => CheckResult | Promise<CheckResult>)[], label: string): () => Promise<CheckResult> {\n return async () => {\n for (const step of steps) {\n const r = await step()\n if (r.result !== 'pass') return r\n }\n return h.PASS(label)\n }\n}\n\nexport function appChecks(h: GateHelpers, { app = '.', page, chain = { ref: 'UIG-3', owner: false }, tokenConfigs = ['eslint.tokens.config.js', 'eslint.config.js'], headers = ['Panel'] }: AppCheckOptions): GateTicket[] {\n const WEB = app === '.' ? '' : `${app.replace(/\\/$/, '')}/`\n const cwd = app === '.' ? undefined : app\n const PROBE = 'src/components/__gates_probe__.tsx'\n const GATES = 'eslint.gates.config.js'\n const at = (rel: string) => `${WEB}${rel}`\n const probe = (code: string, expect: 'error' | 'warning' | 'none', mentions?: string, file = PROBE, config = GATES) => () =>\n h.lint({ ...(cwd ? { cwd } : {}), config, file, code, expect, mentions })\n const component = (body: string) => `export function Probe() {\\n return ${body}\\n}\\n`\n const installed = at('node_modules/@estiva-app/ui/dist/index.d.ts')\n const realPage = (): Promise<CheckResult> => h.lint({ ...(cwd ? { cwd } : {}), config: GATES, file: page, code: h.read(at(page)), expect: 'none' })\n const button = component('<button type=\"button\">x</button>')\n /** A line TypeScript's own lint writes; ESLint refuses it where TypeScript's plugin is unknown (UIG-37). */\n const typescriptDirective = '// eslint-disable-next-line @typescript-eslint/no-explicit-any\\nexport const probe: any = 1\\n'\n const ticket = (ref: string, checks: GateCheck[], owner = false): GateTicket => ({ ref, title: APP_TICKET_TITLES[ref], owner, checks })\n\n const tokenProbe = (code: string, expect: 'error' | 'warning' | 'none', mentions?: string, file = PROBE) =>\n all(h, tokenConfigs.map((config) => probe(code, expect, mentions, file, config)), `${tokenConfigs.join(' and ')}: as expected`)\n\n return [\n ticket('UIG-2', [\n { what: 'npm run gates:status is wired', run: () => h.script('package.json', 'gates:status') },\n ]),\n ticket(chain.ref, [\n { what: 'the gate lint config loads', run: () => h.loads(at(GATES)) },\n { what: `${at('package.json')} has lint:rules`, run: () => h.script(at('package.json'), 'lint:rules') },\n { what: 'CI runs lint:rules', run: () => h.ci('lint:rules') },\n { what: 'the committed hook runs the gate lint', run: () => h.hook('.claude/settings.json', 'gates') },\n { what: '.gates-count.json is committed and parses', run: () => h.json(h.exists('.gates-count.json') ? '.gates-count.json' : at('.gates-count.json')) },\n { what: 'a raw <button> is an error naming Button', run: probe(button, 'error', 'Button') },\n { what: 'the same in a story', run: probe(button, 'error', 'Button', 'src/stories/__gates_probe__.stories.tsx') },\n { what: 'a test file is not checked, while source is', run: async () => {\n const source = await probe(button, 'error', 'Button')()\n if (source.result !== 'pass') return h.FAIL(`source is not checked yet, so this proves nothing: ${source.detail}`)\n return probe(button, 'none', undefined, 'src/components/__gates_probe__.test.tsx')()\n } },\n { what: 'the debt list exists', run: () => h.file('docs/GATES-DEBT.md') },\n ], chain.owner),\n ticket('UIG-6', [\n { what: 'GitHub requires the check gate to merge into main', run: () => h.protectedBranch(/^gate$/) },\n { what: \"CI's job gate runs lint:rules\", run: () => h.ciJob('gate', 'lint:rules') },\n ]),\n ticket('UIG-7', [\n { what: 'a raw <input> is an error naming TextInput', run: probe(component('<input />'), 'error', 'TextInput') },\n { what: 'a clickable <div> is an error naming Button (R5)', run: probe(component('<div onClick={() => history.back()}>Back</div>'), 'error', '`Button`') },\n { what: 'a raw <a> is an error naming Link', run: all(h, [probe(component('<a href=\"/topics\">Topics</a>'), 'error', 'Link'), probe(component('<a href=\"/issues\">Issues</a>'), 'error', 'Link')], 'a raw <a> is an error naming Link') },\n { what: 'a raw <form> is an error naming Form, and a file input one naming FilePicker', run: async () => {\n const form = await probe(component('<form />'), 'error', '`Form`')()\n if (form.result !== 'pass') return form\n return probe(component('<input type=\"file\" />'), 'error', 'FilePicker')()\n } },\n { what: '<textarea>, <select>, <dialog> and <label> name Textarea, Select, DialogShell and Field', run: async () => {\n for (const [element, part] of [['textarea', 'Textarea'], ['select', 'Select'], ['dialog', 'DialogShell'], ['label', 'Field']]) {\n const one = await probe(component(`<${element} />`), 'error', `\\`${part}\\``)()\n if (one.result !== 'pass') return one\n }\n return h.PASS('all four are errors, each naming its part')\n } },\n { what: 'an element the package has no part for is an error that says to ask for one', run: probe(component('<iframe title=\"Map\" />'), 'error', 'ask Katerina') },\n { what: 'an escaped element is not an error, while the same element is', run: async () => {\n const raw = await probe(component('<form />'), 'error')()\n if (raw.result !== 'pass') return h.FAIL(`a raw <form> is not caught yet, so this proves nothing: ${raw.detail}`)\n return probe('export function Probe() {\\n return (\\n // @estiva-escape(no-raw-element): a probe that keeps its element on purpose\\n <form />\\n )\\n}\\n', 'none')()\n } },\n { what: 'a real page, full of elements that are not controls, gets no error', run: realPage },\n ]),\n ticket('UIG-8', [\n { what: 'a Base UI import is an error naming the part built on it', run: probe(\"import { Popover } from '@base-ui/react/popover'\\nexport const Probe = Popover\\n\", 'error', '`Popover`') },\n { what: 'createPortal is an error naming the floating parts', run: probe(\"import { createPortal } from 'react-dom'\\nexport const Probe = (to: HTMLElement) => createPortal(<span />, to)\\n\", 'error', '`DialogShell`') },\n { what: 'a key listener on the whole page is an error, in a .ts file too', run: probe(\"export function listen() {\\n window.addEventListener('keydown', () => {})\\n}\\n\", 'error', '`DialogShell`', 'src/lib/__gates_probe__.ts') },\n { what: 'arrow keys by hand are an error; Enter in a field is not', run: async () => {\n const arrows = await probe(\"export const onKeyDown = (e: KeyboardEvent) => e.key === 'ArrowDown'\\n\", 'error', '`Menu`', 'src/lib/__gates_probe__.ts')()\n if (arrows.result !== 'pass') return arrows\n return probe(\"export const onKeyDown = (e: KeyboardEvent) => e.key === 'Enter'\\n\", 'none', undefined, 'src/lib/__gates_probe__.ts')()\n } },\n { what: 'a hand-written role=\"option\" is an error naming Select', run: probe(component('<div role=\"option\" />'), 'error', '`Select`') },\n { what: 'tabIndex={0} on a div is an error; tabIndex={-1} is not', run: async () => {\n const zero = await probe(component('<div tabIndex={0} />'), 'error', '`Button`')()\n if (zero.result !== 'pass') return h.FAIL(`tabIndex={0} is not caught yet, so this proves nothing: ${zero.detail}`)\n return probe(component('<div tabIndex={-1} />'), 'none')()\n } },\n { what: 'overflow-y-auto is an error naming ScrollArea', run: probe(component('<div className=\"h-64 overflow-y-auto\" />'), 'error', '`ScrollArea`') },\n { what: 'an escaped listener is not an error, while the same listener is', run: async () => {\n const raw = await probe(\"export function listen() {\\n document.addEventListener('mousedown', () => {})\\n}\\n\", 'error', undefined, 'src/lib/__gates_probe__.ts')()\n if (raw.result !== 'pass') return h.FAIL(`a page listener is not caught yet, so this proves nothing: ${raw.detail}`)\n return probe(\"export function listen() {\\n // @estiva-escape(no-rebuilt-behaviour): a probe that keeps its listener on purpose\\n document.addEventListener('mousedown', () => {})\\n}\\n\", 'none', undefined, 'src/lib/__gates_probe__.ts')()\n } },\n { what: 'a real page gets no error', run: realPage },\n ]),\n ticket('UIG-9', [\n { what: 'a border passed into Button is an error naming Button', run: probe(`import { Button } from '@estiva-app/ui'\\n${component('<Button className=\"border\">x</Button>')}`, 'error', 'on `Button` changes how it looks') },\n { what: 'placement passed into Button is not', run: probe(`import { Button } from '@estiva-app/ui'\\n${component('<Button className=\"mt-2 w-full flex-1 relative\">x</Button>')}`, 'none') },\n { what: 'an escaped look is not an error, while the same look is', run: async () => {\n const raw = await probe(`import { Link } from '@estiva-app/ui'\\n${component('<Link href=\"/x\" className=\"after:absolute after:inset-0\">x</Link>')}`, 'error', '`Link`')()\n if (raw.result !== 'pass') return h.FAIL(`a restyled part is not caught yet, so this proves nothing: ${raw.detail}`)\n return probe(`import { Link } from '@estiva-app/ui'\\nexport function Probe() {\\n return (\\n // @estiva-escape(no-restyled-part): a probe that keeps its row link on purpose\\n <Link href=\"/x\" className=\"after:absolute after:inset-0\">x</Link>\\n )\\n}\\n`, 'none')()\n } },\n { what: 'a real page gets no error', run: realPage },\n ]),\n // UIG-10, reopened 18 September: a tab holds one relay client, the way Peek and Ship hold\n // theirs and a made app is written to. Measured on both mains that day: one each, and no\n // socket opened any other way. A second holder, or a socket of the app's own, is a second\n // connection the relay signs in and budgets separately.\n ticket('UIG-10', [\n { what: 'the app holds one relay client, at module level, and opens no socket of its own', run: () => {\n const sources = h.listFiles(at('src'), (n) => /\\.tsx?$/.test(n) && !/\\.(test|stories)\\.tsx?$/.test(n))\n const own = sources.filter((f) => /\\bcreateLiveClient\\(|\\bcreateLiveRelay\\(|\\bnew WebSocket\\(/.test(h.read(f)))\n if (own.length) return h.FAIL(`opens a socket of its own (${own.join(', ')}): hold one client from createLiveClientHolder()`)\n const holders = sources.filter((f) => /^\\s*(?:export\\s+)?const\\s+\\w+\\s*=\\s*createLiveClientHolder\\(\\)/m.test(h.read(f)))\n if (holders.length !== 1) return h.FAIL(holders.length ? `${holders.length} client holders (${holders.join(', ')}): a tab holds one` : 'no module-level createLiveClientHolder(): the app has no relay client')\n return h.PASS(`one client for the tab, held in ${holders[0]}`)\n } },\n ]),\n // Built by UIG-13, 18 September. An app's catalogue is built fresh from its code\n // and never committed: the package is public and the apps are private (Katerina).\n ticket('UIG-13', [\n { what: \"npm run ui:find is the package's search, over the package and this app\", run: () => h.contains(at('package.json'), /\"ui:find\":\\s*\"estiva-ui find\\b/, \"ui:find runs the package's estiva-ui find\") },\n { what: \"npm run registry:check is the package's check\", run: () => h.contains(at('package.json'), /\"registry:check\":\\s*\"estiva-ui check\\b/, 'registry:check runs estiva-ui check') },\n { what: \"CI's job gate refuses a part with no description\", run: () => h.ciJob('gate', 'registry:check') },\n // In the .gitignore of the app's own folder, where `estiva-ui build` would write it.\n { what: 'the catalogue is never committed: git ignores registry.json', run: () => h.contains(at('.gitignore'), /^\\/?registry\\.json\\r?$/m, `${at('.gitignore')} ignores registry.json`) },\n { what: 'every part is described and sorted, and every file is accounted for', run: () => h.catalogue(at('.')) },\n ]),\n ticket('UIG-19', [\n // The contract runs inside `estiva-ui check`, which the gate job already runs\n // (UIG-13), so an app changes no script: it takes the package that has it.\n { what: 'the installed package checks the usage-page contract and the story links', run: () => h.contains(at('node_modules/@estiva-app/ui/dist/registry/cli.js'), 'the usage-page contract', \"the installed estiva-ui check runs the contract\") },\n { what: \"CI's job gate runs it\", run: () => h.ciJob('gate', 'registry:check') },\n { what: 'the app keeps no copy of it in its own gates-checks.mjs', run: () => h.exists(at('scripts/gates-checks.mjs')) ? h.lacks(at('scripts/gates-checks.mjs'), '\"When not\"', 'the app checks no page sections itself') : h.PASS('the app has no gates-checks.mjs') },\n ]),\n // The Claude skill (UIG-20): its text is the installed package's, read in by a\n // loader `estiva-ui skill` writes; the app commits the loader and the settings.\n ticket('UIG-20', [\n { what: \"the skill's loader reads the installed package's text\", run: () => h.contains('.claude/skills/estiva-ui/SKILL.md', `!\\`cat \"\\${CLAUDE_PROJECT_DIR}/${at('node_modules/@estiva-app/ui/skill/estiva-ui.md')}\"\\``, 'the loader reads the package\u2019s skill') },\n { what: 'the search runs without a prompt', run: () => h.contains('.claude/settings.json', 'Bash(npm run ui:find *)', '.claude/settings.json allows npm run ui:find') },\n { what: 'ui:find searches every app beside this one: it names none', run: () => h.lacks(at('package.json'), /\"ui:find\":[^\\n]*--also/, 'ui:find names no neighbour, so it finds them all') },\n ...(WEB ? [{ what: 'ui:find runs from the top folder too', run: () => h.contains('package.json', /\"ui:find\":/, 'the top folder has ui:find') }] : []),\n { what: \"CI's job gate refuses a loader that differs\", run: () => (h.exists(at('node_modules/@estiva-app/ui/dist/registry/cli.js')) && /claude skill:/.test(h.read(at('node_modules/@estiva-app/ui/dist/registry/cli.js'))) ? h.ciJob('gate', 'registry:check') : h.FAIL('the installed package does not check the loader: take a version that does')) },\n ]),\n // What loads into every Claude session (UIG-21): CLAUDE.md is an index, the\n // rest loads where it applies, and a rule a check can hold is a check.\n ticket('UIG-21', [\n { what: 'CLAUDE.md with its imports is under 200 lines, and every rule file is scoped', run: () => h.instructions(200) },\n { what: \"CI's job gate runs the token lint\", run: () => {\n const tokens = h.ciJob('gate', 'lint:tokens')\n return tokens.result === 'pass' ? tokens : h.ciJob('gate', 'lint')\n } },\n { what: \"a plain tailwind-merge is an error naming the package's cn()\", run: tokenProbe(\"import { twMerge } from 'tailwind-merge'\\nexport const merged = twMerge('p-2', 'p-3')\\n\", 'error', 'cn()', 'src/lib/__gates_probe__.ts') },\n ]),\n ticket('UIG-22', [\n // The Folders pane's own row, at the commit before peek 3dc663b.\n { what: `a hand-made column header is an error naming ${headers.join(' or ')}`, run: all(h, headers.map((name) => probe(component('<div className=\"flex h-full flex-col\"><div className=\"flex items-center gap-2 px-3 py-2\"><span>Folders</span></div><div /></div>'), 'error', name)), `a hand-made column header is an error naming ${headers.join(' or ')}`) },\n // 26 September: the package's header on its own is a panel made by hand, whose box forgot to scroll.\n { what: \"the package's ContainerHeader on its own is an error naming Panel\", run: probe(`import { ContainerHeader } from '@estiva-app/ui'\\n${component('<div className=\"flex flex-col\"><ContainerHeader title=\"Details\" /><div className=\"px-4\">x</div></div>')}`, 'error', '`Panel`') },\n { what: 'a group heading inside a list is left alone', run: probe(component('<section className=\"flex flex-col gap-px\"><h3 className=\"flex h-8 items-center gap-2 px-3\"><span>Todo</span></h3><div /></section>'), 'none') },\n ]),\n ticket('UIG-23', [\n { what: 'a hand-made empty line is an error naming EmptyState', run: probe(\"export function Probe({ items }: { items: string[] }) {\\n return <div>{items.length === 0 ? <p className=\\\"text-text-secondary\\\">Nothing here</p> : items.map((i) => <span key={i}>{i}</span>)}</div>\\n}\\n\", 'error', 'EmptyState') },\n ]),\n ticket('UIG-24', [\n { what: 'a title= is an error naming WithTooltip', run: probe(`import { Button } from '@estiva-app/ui'\\n${component('<Button title=\"Delete\">x</Button>')}`, 'error', 'WithTooltip') },\n ]),\n ticket('UIG-25', [\n { what: \"SectionLabel's class list, typed by hand, is a warning\", run: probe(component('<span className=\"text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest text-text-secondary\">Label</span>'), 'warning', 'SectionLabel') },\n ]),\n ticket('UIG-27', [\n { what: 'the installed package has Link', run: () => h.contains(installed, /\\bLink\\b/, 'the installed @estiva-app/ui exports Link') },\n { what: 'the installed package has ProgressBar', run: () => h.contains(installed, /\\bProgressBar\\b/, 'the installed @estiva-app/ui exports ProgressBar') },\n ]),\n ticket('UIG-28', [\n { what: 'text-[14px] is an error', run: tokenProbe(component('<div className=\"text-[14px]\">x</div>'), 'error') },\n { what: 'a colour in an inline style is an error', run: tokenProbe(component(\"<div style={{ backgroundColor: '#ff0000' }}>x</div>\"), 'error') },\n { what: 'h-[240px] is a warning', run: tokenProbe(component('<div className=\"h-[240px]\">x</div>'), 'warning') },\n { what: 'h-[240px] is not an error', run: tokenProbe(component('<div className=\"h-[240px]\">x</div>'), 'none') },\n { what: 'a hand-written line height behind an arbitrary variant is an error', run: tokenProbe(component('<div className=\"[&_p]:leading-[1.4]\">x</div>'), 'error') },\n { what: 'a raw colour in a class is an error (the pattern that matched nothing, R1)', run: tokenProbe(component('<div className=\"bg-[#5c69dc]\">x</div>'), 'error', 'raw colour') },\n { what: 'a width and height from a prop pass', run: tokenProbe(\"export function Probe({ size }: { size: number }) {\\n return <div style={{ width: size, height: size }}>x</div>\\n}\\n\", 'none') },\n { what: 'a test file is not checked for hand-written values, while source is', run: all(h, tokenConfigs.map((config) => async () => {\n const code = component(\"<div className=\\\"text-[14px]\\\" style={{ color: 'red' }}>x</div>\")\n const source = await probe(code, 'error', undefined, PROBE, config)()\n if (source.result !== 'pass') return h.FAIL(`source is not checked yet, so this proves nothing: ${source.detail}`)\n return probe(code, 'none', undefined, 'src/components/__gates_probe__.test.tsx', config)()\n }), 'a test file is not checked for hand-written values, while source is') },\n ]),\n ticket('UIG-30', [\n { what: 'the installed package has RichText', run: () => h.contains(installed, /\\bRichText\\b/, 'the installed @estiva-app/ui exports RichText') },\n ]),\n // Katerina's ruling of 17 September (docs/GATES.md \u00A723): one copy, in the package. An app made\n // by create-estiva-app passes this from its first commit; Peek and Ship do once UIG-32 lands.\n ticket('UIG-32', [\n { what: 'the gate pieces come from the package, and no repo keeps a copy', run: all(h, [\n () => h.contains(at('eslint.gates.config.js'), /from '@estiva-app\\/ui\\/gates'/, 'the gate config imports @estiva-app/ui/gates'),\n () => h.hook('.claude/settings.json', '@estiva-app/ui/dist/gates/cli.js'),\n // `estiva-gates status` where npm can find the command; by path where it cannot,\n // because the install is in the app's folder and the script is in the repo's top one (Ship).\n () => h.contains('package.json', /\"gates:status\":\\s*\"[^\"]*(?:estiva-gates|@estiva-app\\/ui\\/dist\\/gates\\/cli\\.js)[^\"]*status/, \"gates:status runs the package's engine\"),\n () => (h.exists('scripts/gates-status.mjs') ? h.FAIL('scripts/gates-status.mjs is a copy of the status engine: run estiva-gates status instead') : h.PASS('no copy of the status engine')),\n ], 'the gate config, the hook and gates:status are the package\\'s; no copy of the engine') },\n ]),\n ticket('UIG-37', [\n { what: 'a TypeScript eslint-disable comment breaks neither the gate nor the token lint', run: all(h, [\n probe(typescriptDirective, 'none'),\n tokenProbe(typescriptDirective, 'none'),\n ], `${[GATES, ...tokenConfigs].join(', ')}: a TypeScript directive is no error`) },\n { what: 'a token lint on its own is the package\\'s tokenConfig, not built by hand', run: () =>\n (h.exists(at('eslint.tokens.config.js'))\n ? h.contains(at('eslint.tokens.config.js'), /\\btokenConfig\\(/, 'eslint.tokens.config.js runs tokenConfig from @estiva-app/ui/gates')\n : h.PASS('no token lint on its own')) },\n ]),\n ]\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ export { Reaction, type ReactionProps } from './Reaction';
|
|
|
60
60
|
export { SearchInput, type SearchInputProps } from './SearchInput';
|
|
61
61
|
export { SectionHeader, type SectionAction, type SectionHeaderProps } from './SectionHeader';
|
|
62
62
|
export { ContainerHeader, type ContainerHeaderProps } from './ContainerHeader';
|
|
63
|
+
export { Panel, type PanelProps } from './Panel';
|
|
63
64
|
export { ListColumn, type ListColumnProps } from './ListColumn';
|
|
64
65
|
export { CollapsibleSection, type CollapsibleSectionProps } from './CollapsibleSection';
|
|
65
66
|
export { SectionLabel } from './SectionLabel';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACrG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC1F,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AACxF,OAAO,EAAE,IAAI,EAAE,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAA;AAChG,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,GAChC,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,UAAU,EACV,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACvF,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAC5H,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACtI,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AACpG,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACtE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACrE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAC3F,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,KAAK,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAA;AACvL,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAChG,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC1L,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAC9E,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAA;AAC5G,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -56,8 +56,8 @@ function ScrollArea({ orientation = "vertical", className, viewportClassName, co
|
|
|
56
56
|
children: /* @__PURE__ */ jsx(BaseScrollArea.Content, { className: contentClassName, style: horizontal ? void 0 : { minWidth: 0 }, children })
|
|
57
57
|
}
|
|
58
58
|
),
|
|
59
|
-
vertical && /* @__PURE__ */ jsx(BaseScrollArea.Scrollbar, { orientation: "vertical", className: cn(BAR, "w-1.5 justify-center py-0.5 pr-0.5"), children: /* @__PURE__ */ jsx(BaseScrollArea.Thumb, { className: cn(THUMB, "w-full") }) }),
|
|
60
|
-
horizontal && /* @__PURE__ */ jsx(BaseScrollArea.Scrollbar, { orientation: "horizontal", className: cn(BAR, "h-1.5 flex-col justify-center px-0.5 pb-0.5"), children: /* @__PURE__ */ jsx(BaseScrollArea.Thumb, { className: cn(THUMB, "h-full") }) }),
|
|
59
|
+
vertical && /* @__PURE__ */ jsx(BaseScrollArea.Scrollbar, { orientation: "vertical", className: cn(BAR, "w-1.5 justify-center py-0.5 pr-0.5 data-[has-overflow-y]:opacity-100"), children: /* @__PURE__ */ jsx(BaseScrollArea.Thumb, { className: cn(THUMB, "w-full") }) }),
|
|
60
|
+
horizontal && /* @__PURE__ */ jsx(BaseScrollArea.Scrollbar, { orientation: "horizontal", className: cn(BAR, "h-1.5 flex-col justify-center px-0.5 pb-0.5 data-[has-overflow-x]:opacity-100"), children: /* @__PURE__ */ jsx(BaseScrollArea.Thumb, { className: cn(THUMB, "h-full") }) }),
|
|
61
61
|
vertical && horizontal && /* @__PURE__ */ jsx(BaseScrollArea.Corner, {})
|
|
62
62
|
] });
|
|
63
63
|
}
|
|
@@ -2999,10 +2999,36 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2999
2999
|
);
|
|
3000
3000
|
}
|
|
3001
3001
|
|
|
3002
|
-
// src/
|
|
3002
|
+
// src/Panel.tsx
|
|
3003
3003
|
import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3004
|
+
function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
|
|
3005
|
+
return /* @__PURE__ */ jsxs36("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
|
|
3006
|
+
/* @__PURE__ */ jsx53(ContainerHeader, { title, chevron, actions }),
|
|
3007
|
+
broken ? (
|
|
3008
|
+
// The message takes the room the body had and centres itself in it.
|
|
3009
|
+
/* @__PURE__ */ jsx53("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
|
|
3010
|
+
) : /* @__PURE__ */ jsx53(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
|
|
3011
|
+
!broken && footer && /* @__PURE__ */ jsx53("div", { className: "shrink-0", children: footer })
|
|
3012
|
+
] });
|
|
3013
|
+
}
|
|
3014
|
+
function Panel(props) {
|
|
3015
|
+
return /* @__PURE__ */ jsx53(
|
|
3016
|
+
ErrorBoundary,
|
|
3017
|
+
{
|
|
3018
|
+
label: "panel",
|
|
3019
|
+
frame: (message) => (
|
|
3020
|
+
// Only the name comes back with the message: the actions and the footer may be what threw.
|
|
3021
|
+
/* @__PURE__ */ jsx53(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
|
|
3022
|
+
),
|
|
3023
|
+
children: /* @__PURE__ */ jsx53(Frame, { ...props })
|
|
3024
|
+
}
|
|
3025
|
+
);
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
// src/ListColumn.tsx
|
|
3029
|
+
import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3004
3030
|
function Column({ title, chevron = false, actions, above, collapsed = false, children, className, broken = false }) {
|
|
3005
|
-
return /* @__PURE__ */
|
|
3031
|
+
return /* @__PURE__ */ jsxs37(
|
|
3006
3032
|
"div",
|
|
3007
3033
|
{
|
|
3008
3034
|
className: cn(
|
|
@@ -3013,26 +3039,26 @@ function Column({ title, chevron = false, actions, above, collapsed = false, chi
|
|
|
3013
3039
|
),
|
|
3014
3040
|
"data-collapsed": collapsed || void 0,
|
|
3015
3041
|
children: [
|
|
3016
|
-
/* @__PURE__ */
|
|
3042
|
+
/* @__PURE__ */ jsx54(ContainerHeader, { title, chevron, actions }),
|
|
3017
3043
|
above,
|
|
3018
3044
|
broken ? (
|
|
3019
3045
|
// The message takes the room the list had and centres itself in it (Katerina, 19 September).
|
|
3020
|
-
/* @__PURE__ */
|
|
3021
|
-
) : /* @__PURE__ */
|
|
3046
|
+
/* @__PURE__ */ jsx54("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
|
|
3047
|
+
) : /* @__PURE__ */ jsx54(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
|
|
3022
3048
|
]
|
|
3023
3049
|
}
|
|
3024
3050
|
);
|
|
3025
3051
|
}
|
|
3026
3052
|
function ListColumn(props) {
|
|
3027
|
-
return /* @__PURE__ */
|
|
3053
|
+
return /* @__PURE__ */ jsx54(
|
|
3028
3054
|
ErrorBoundary,
|
|
3029
3055
|
{
|
|
3030
3056
|
label: "list panel",
|
|
3031
3057
|
frame: (message) => (
|
|
3032
3058
|
// Only the name comes back with the message: the actions and the row above may be what threw.
|
|
3033
|
-
/* @__PURE__ */
|
|
3059
|
+
/* @__PURE__ */ jsx54(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
|
|
3034
3060
|
),
|
|
3035
|
-
children: /* @__PURE__ */
|
|
3061
|
+
children: /* @__PURE__ */ jsx54(Column, { ...props })
|
|
3036
3062
|
}
|
|
3037
3063
|
);
|
|
3038
3064
|
}
|
|
@@ -3040,7 +3066,7 @@ function ListColumn(props) {
|
|
|
3040
3066
|
// src/CollapsibleSection.tsx
|
|
3041
3067
|
import { useState as useState7 } from "react";
|
|
3042
3068
|
import { Collapsible } from "@base-ui/react/collapsible";
|
|
3043
|
-
import { jsx as
|
|
3069
|
+
import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3044
3070
|
var OPEN = "open";
|
|
3045
3071
|
var CLOSED = "closed";
|
|
3046
3072
|
function readStored(key) {
|
|
@@ -3067,14 +3093,14 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
3067
3093
|
writeStored(storageKey, next);
|
|
3068
3094
|
onOpenChange?.(next);
|
|
3069
3095
|
};
|
|
3070
|
-
return /* @__PURE__ */
|
|
3071
|
-
/* @__PURE__ */
|
|
3072
|
-
/* @__PURE__ */
|
|
3096
|
+
return /* @__PURE__ */ jsxs38(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
3097
|
+
/* @__PURE__ */ jsx55(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx55(Collapsible.Trigger, {}) }),
|
|
3098
|
+
/* @__PURE__ */ jsx55(
|
|
3073
3099
|
Collapsible.Panel,
|
|
3074
3100
|
{
|
|
3075
3101
|
hiddenUntilFound: true,
|
|
3076
3102
|
className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0",
|
|
3077
|
-
children: /* @__PURE__ */
|
|
3103
|
+
children: /* @__PURE__ */ jsx55("div", { className: cn("flex flex-col", contentClassName), children })
|
|
3078
3104
|
}
|
|
3079
3105
|
)
|
|
3080
3106
|
] });
|
|
@@ -3082,9 +3108,9 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
3082
3108
|
|
|
3083
3109
|
// src/Tabs.tsx
|
|
3084
3110
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
3085
|
-
import { jsx as
|
|
3111
|
+
import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3086
3112
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
3087
|
-
return /* @__PURE__ */
|
|
3113
|
+
return /* @__PURE__ */ jsx56(
|
|
3088
3114
|
BaseTabs.Root,
|
|
3089
3115
|
{
|
|
3090
3116
|
value: active,
|
|
@@ -3092,14 +3118,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3092
3118
|
if (details.reason === "none") onChange(value);
|
|
3093
3119
|
},
|
|
3094
3120
|
className,
|
|
3095
|
-
children: /* @__PURE__ */
|
|
3121
|
+
children: /* @__PURE__ */ jsx56(
|
|
3096
3122
|
BaseTabs.List,
|
|
3097
3123
|
{
|
|
3098
3124
|
activateOnFocus: true,
|
|
3099
3125
|
"aria-label": aria["aria-label"],
|
|
3100
3126
|
"aria-labelledby": aria["aria-labelledby"],
|
|
3101
3127
|
className: "flex items-center gap-2",
|
|
3102
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
3128
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs39(
|
|
3103
3129
|
BaseTabs.Tab,
|
|
3104
3130
|
{
|
|
3105
3131
|
value: tab.id,
|
|
@@ -3112,9 +3138,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3112
3138
|
),
|
|
3113
3139
|
children: [
|
|
3114
3140
|
tab.icon,
|
|
3115
|
-
/* @__PURE__ */
|
|
3141
|
+
/* @__PURE__ */ jsxs39("span", { className: "flex items-baseline", children: [
|
|
3116
3142
|
tab.label,
|
|
3117
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
3143
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx56("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
3118
3144
|
] })
|
|
3119
3145
|
]
|
|
3120
3146
|
},
|
|
@@ -3130,7 +3156,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3130
3156
|
import { createContext as createContext5, useContext as useContext5, useMemo as useMemo4 } from "react";
|
|
3131
3157
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
3132
3158
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
3133
|
-
import { jsx as
|
|
3159
|
+
import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3134
3160
|
var SURFACE_STYLES = {
|
|
3135
3161
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
3136
3162
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
@@ -3166,16 +3192,16 @@ var pillClassName = (type, hasAction, className) => cn(
|
|
|
3166
3192
|
);
|
|
3167
3193
|
function LeadingIcon({ type }) {
|
|
3168
3194
|
const Icon = ICONS[type];
|
|
3169
|
-
return /* @__PURE__ */
|
|
3195
|
+
return /* @__PURE__ */ jsx57(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
|
|
3170
3196
|
}
|
|
3171
3197
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
3172
3198
|
const hasAction = !!(actionLabel && onAction);
|
|
3173
|
-
return /* @__PURE__ */
|
|
3174
|
-
/* @__PURE__ */
|
|
3175
|
-
leadingIcon && /* @__PURE__ */
|
|
3176
|
-
/* @__PURE__ */
|
|
3199
|
+
return /* @__PURE__ */ jsxs40("div", { className: pillClassName(type, hasAction, className), children: [
|
|
3200
|
+
/* @__PURE__ */ jsxs40("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3201
|
+
leadingIcon && /* @__PURE__ */ jsx57(LeadingIcon, { type }),
|
|
3202
|
+
/* @__PURE__ */ jsx57("span", { className: LABEL_CLASSES, children: label })
|
|
3177
3203
|
] }),
|
|
3178
|
-
hasAction && /* @__PURE__ */
|
|
3204
|
+
hasAction && /* @__PURE__ */ jsx57(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
3179
3205
|
] });
|
|
3180
3206
|
}
|
|
3181
3207
|
var ToastContext = createContext5(null);
|
|
@@ -3196,9 +3222,9 @@ function ToastProvider({ children }) {
|
|
|
3196
3222
|
}),
|
|
3197
3223
|
[manager]
|
|
3198
3224
|
);
|
|
3199
|
-
return /* @__PURE__ */
|
|
3225
|
+
return /* @__PURE__ */ jsx57(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs40(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
|
|
3200
3226
|
children,
|
|
3201
|
-
/* @__PURE__ */
|
|
3227
|
+
/* @__PURE__ */ jsx57(BaseToast.Portal, { children: /* @__PURE__ */ jsx57(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx57(ToastList, {}) }) })
|
|
3202
3228
|
] }) });
|
|
3203
3229
|
}
|
|
3204
3230
|
function ToastList() {
|
|
@@ -3206,25 +3232,25 @@ function ToastList() {
|
|
|
3206
3232
|
return toasts.map((toast) => {
|
|
3207
3233
|
const type = toast.type ?? "neutral";
|
|
3208
3234
|
const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
|
|
3209
|
-
return /* @__PURE__ */
|
|
3235
|
+
return /* @__PURE__ */ jsxs40(
|
|
3210
3236
|
BaseToast.Root,
|
|
3211
3237
|
{
|
|
3212
3238
|
toast,
|
|
3213
3239
|
swipeDirection: ["left", "down"],
|
|
3214
3240
|
className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
|
|
3215
3241
|
children: [
|
|
3216
|
-
/* @__PURE__ */
|
|
3217
|
-
leadingIcon && /* @__PURE__ */
|
|
3218
|
-
/* @__PURE__ */
|
|
3242
|
+
/* @__PURE__ */ jsxs40("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3243
|
+
leadingIcon && /* @__PURE__ */ jsx57(LeadingIcon, { type }),
|
|
3244
|
+
/* @__PURE__ */ jsx57(BaseToast.Title, { render: /* @__PURE__ */ jsx57("span", {}), className: LABEL_CLASSES })
|
|
3219
3245
|
] }),
|
|
3220
|
-
actionLabel && /* @__PURE__ */
|
|
3246
|
+
actionLabel && /* @__PURE__ */ jsx57(
|
|
3221
3247
|
BaseToast.Action,
|
|
3222
3248
|
{
|
|
3223
3249
|
onClick: () => {
|
|
3224
3250
|
onAction?.();
|
|
3225
3251
|
close(toast.id);
|
|
3226
3252
|
},
|
|
3227
|
-
render: /* @__PURE__ */
|
|
3253
|
+
render: /* @__PURE__ */ jsx57(Button, { variant: "outlined", size: "small", children: actionLabel })
|
|
3228
3254
|
}
|
|
3229
3255
|
)
|
|
3230
3256
|
]
|
|
@@ -3288,6 +3314,7 @@ export {
|
|
|
3288
3314
|
MenuSeparator,
|
|
3289
3315
|
MenuSub,
|
|
3290
3316
|
NavItem,
|
|
3317
|
+
Panel,
|
|
3291
3318
|
Person,
|
|
3292
3319
|
PersonTrigger,
|
|
3293
3320
|
Popover,
|