@motion-proto/live-tokens 0.78.0 → 0.79.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/.claude/skills/live-tokens-check-compliance/SKILL.md +60 -31
- package/.claude/skills/live-tokens-create-component/SKILL.md +23 -28
- package/.claude/skills/live-tokens-create-component/references/contract-tests.md +61 -0
- package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +2 -2
- package/.claude/skills/live-tokens-create-component/references/token-naming.md +6 -15
- package/.claude/skills/live-tokens-create-page/SKILL.md +6 -4
- package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
- package/.claude/skills/live-tokens-pick-component/SKILL.md +3 -3
- package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +1 -1
- package/.claude/skills/live-tokens-set-geometry/SKILL.md +1 -1
- package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +1 -1
- package/CHANGELOG.md +231 -0
- package/README.md +9 -15
- package/bin/check-component.mjs +152 -551
- package/bin/check-page.mjs +55 -541
- package/bin/cli.mjs +59 -13
- package/bin/contractRunner.mjs +37 -91
- package/bin/lib/catalogue.mjs +161 -34
- package/bin/lib/componentSource.mjs +152 -0
- package/bin/lib/cssValues.mjs +9 -0
- package/bin/lib/dataDir.mjs +126 -0
- package/bin/lib/findings.mjs +103 -12
- package/bin/lib/fixers.mjs +64 -0
- package/bin/lib/geometry.mjs +92 -0
- package/bin/lib/pageSource.mjs +230 -0
- package/bin/lib/report.mjs +57 -59
- package/bin/lib/tokenVocabulary.mjs +104 -34
- package/bin/rules/componentStructure.mjs +344 -0
- package/bin/rules/componentUse.mjs +313 -0
- package/bin/rules/importsAndRoutes.mjs +136 -0
- package/bin/rules/testRuns.mjs +122 -0
- package/bin/rules/tokens.mjs +363 -0
- package/bin/setup-claude.mjs +1 -2
- package/dist-plugin/{chunk-PDNL4NC5.js → chunk-D4WRIKEZ.js} +7 -2
- package/dist-plugin/{chunk-SWXRVZKT.js → chunk-REBHE3ZM.js} +414 -1
- package/dist-plugin/index.cjs +432 -15
- package/dist-plugin/index.js +8 -9
- package/dist-plugin/migrateData/index.cjs +422 -4
- package/dist-plugin/migrateData/index.js +2 -2
- package/dist-plugin/setColors/index.cjs +414 -1
- package/dist-plugin/setColors/index.d.cts +1 -1
- package/dist-plugin/setColors/index.d.ts +1 -1
- package/dist-plugin/setColors/index.js +1 -1
- package/dist-plugin/setGeometry/index.cjs +423 -13
- package/dist-plugin/setGeometry/index.d.cts +3 -3
- package/dist-plugin/setGeometry/index.d.ts +3 -3
- package/dist-plugin/setGeometry/index.js +10 -13
- package/dist-plugin/setType/index.d.cts +1 -1
- package/dist-plugin/setType/index.d.ts +1 -1
- package/dist-plugin/{themeTypes-BxRtuN5V.d.cts → themeTypes-B8_Idrp4.d.cts} +2 -2
- package/dist-plugin/{themeTypes-BxRtuN5V.d.ts → themeTypes-B8_Idrp4.d.ts} +2 -2
- package/package.json +2 -2
- package/src/editor/component-editor/CalloutEditor.svelte +2 -2
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +14 -15
- package/src/editor/component-editor/CornerBadgeEditor.svelte +14 -14
- package/src/editor/component-editor/DialogEditor.svelte +5 -5
- package/src/editor/component-editor/InlineEditActionsEditor.svelte +2 -2
- package/src/editor/component-editor/RadioButtonEditor.svelte +21 -21
- package/src/editor/component-editor/SectionDividerEditor.svelte +7 -7
- package/src/editor/component-editor/SegmentedControlEditor.svelte +5 -5
- package/src/editor/component-editor/SideNavigationEditor.svelte +25 -25
- package/src/editor/component-editor/TabBarEditor.svelte +6 -6
- package/src/editor/component-editor/TableEditor.svelte +6 -6
- package/src/editor/component-editor/ToggleEditor.svelte +2 -2
- package/src/editor/component-editor/index.ts +3 -0
- package/src/editor/component-editor/registry.ts +57 -1
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +14 -14
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +3 -0
- package/src/editor/component-editor/scaffolding/types.ts +15 -0
- package/src/editor/core/components/adjustAliases.ts +4 -4
- package/src/editor/core/components/aliasKinds.ts +20 -19
- package/src/editor/core/sketch/sketchLayer.ts +3 -3
- package/src/editor/core/themes/migrateComponentConfig.ts +14 -6
- package/src/editor/core/themes/migrations/2026-09-13-badge-brand.ts +42 -0
- package/src/editor/core/themes/migrations/2026-09-13-collapsiblesection-open.ts +33 -0
- package/src/editor/core/themes/migrations/2026-09-13-cornerbadge-prefix.ts +70 -0
- package/src/editor/core/themes/migrations/2026-09-13-hairline.ts +92 -0
- package/src/editor/core/themes/migrations/2026-09-13-indicator.ts +54 -0
- package/src/editor/core/themes/migrations/2026-09-13-sectiondivider-surface.ts +36 -0
- package/src/editor/core/themes/migrations/2026-09-13-selected-state.ts +124 -0
- package/src/editor/core/themes/migrations/2026-09-13-toggle-label.ts +31 -0
- package/src/editor/core/themes/migrations/index.ts +16 -0
- package/src/editor/core/themes/themeService.ts +3 -3
- package/src/editor/core/themes/themeTypes.ts +13 -15
- package/src/editor/docs/Docs.svelte +1 -1
- package/src/editor/docs/content/light-and-dark.md +3 -3
- package/src/editor/docs/content.generated.ts +1 -1
- package/src/editor/index.ts +1 -0
- package/src/editor/overlay/LiveEditorOverlay.svelte +15 -0
- package/src/editor/skill-atlas/SkillAtlas.svelte +4 -4
- package/src/editor/skill-atlas/TreeNodeCard.svelte +4 -4
- package/src/editor/skill-atlas/skillSources.generated.ts +11 -14
- package/src/editor/skill-atlas/skillTrees.ts +1 -3
- package/src/editor/skill-atlas/trees/check-compliance.ts +258 -93
- package/src/editor/skill-atlas/trees/create-component.ts +73 -62
- package/src/editor/skill-atlas/trees/create-page.ts +38 -17
- package/src/editor/skill-atlas/trees/pick-component.ts +3 -3
- package/src/editor/skill-atlas/trees/set-geometry.ts +1 -1
- package/src/editor/ui/UIPaletteSelector.svelte +11 -15
- package/src/editor/ui/variantScales.ts +8 -8
- package/src/live-tokens/data/themes/autumn.json +188 -188
- package/src/live-tokens/data/themes/halloween.json +188 -188
- package/src/live-tokens/data/themes/midnight-study.json +245 -245
- package/src/live-tokens/data/themes/ocean.json +188 -188
- package/src/live-tokens/data/themes/royal-velvet.json +188 -188
- package/src/live-tokens/data/themes/sketchy.json +188 -188
- package/src/live-tokens/data/themes/spring-meadow.json +188 -188
- package/src/live-tokens/data/themes/sunset.json +188 -188
- package/src/system/components/Badge.svelte +27 -23
- package/src/system/components/Button.svelte +13 -7
- package/src/system/components/Callout.svelte +16 -11
- package/src/system/components/Card.svelte +22 -15
- package/src/system/components/CodeSnippet.svelte +10 -6
- package/src/system/components/CollapsibleSection.svelte +68 -63
- package/src/system/components/CornerBadge.svelte +78 -72
- package/src/system/components/Dialog.svelte +21 -18
- package/src/system/components/IconButton.svelte +13 -9
- package/src/system/components/Image.svelte +14 -8
- package/src/system/components/ImageLightbox.svelte +10 -6
- package/src/system/components/InlineEditActions.svelte +17 -14
- package/src/system/components/Input.svelte +13 -7
- package/src/system/components/MenuSelect.svelte +13 -7
- package/src/system/components/Notification.svelte +17 -11
- package/src/system/components/Panel.svelte +13 -6
- package/src/system/components/ProgressBar.svelte +10 -5
- package/src/system/components/RadioButton.svelte +33 -30
- package/src/system/components/SectionDivider.svelte +28 -21
- package/src/system/components/SegmentedControl.svelte +27 -23
- package/src/system/components/SideNavigation.svelte +175 -171
- package/src/system/components/Slider.svelte +11 -7
- package/src/system/components/TabBar.svelte +53 -49
- package/src/system/components/Table.svelte +20 -15
- package/src/system/components/Toggle.svelte +14 -10
- package/src/system/components/Tooltip.svelte +10 -6
- package/src/system/styles/CONVENTIONS.md +3 -4
- package/src/testing-js/chunk-3UKGXCDL.js +48 -0
- package/src/testing-js/chunk-3UKGXCDL.js.map +1 -0
- package/src/testing-js/{chunk-FAFOAWYL.js → chunk-Q3YIAAG3.js} +17 -3
- package/src/testing-js/chunk-Q3YIAAG3.js.map +1 -0
- package/src/testing-js/{chunk-GNIUPIU2.js → chunk-U7OJE5DU.js} +18 -18
- package/src/testing-js/chunk-U7OJE5DU.js.map +1 -0
- package/src/testing-js/{chunk-4JQX6WWL.js → chunk-ZMZQZ33J.js} +474 -166
- package/src/testing-js/chunk-ZMZQZ33J.js.map +1 -0
- package/src/testing-js/component-behavior.contract.js +155 -0
- package/src/testing-js/component-behavior.contract.js.map +1 -0
- package/src/testing-js/component-editor.contract.js +6 -4
- package/src/testing-js/component-editor.contract.js.map +1 -1
- package/src/testing-js/component-render.contract.js +14 -10
- package/src/testing-js/component-render.contract.js.map +1 -1
- package/src/testing-js/index.d.ts +44 -4
- package/src/testing-js/index.js +13 -7
- package/src/testing-js/index.js.map +1 -1
- package/src/testing-js/page-compliance.contract.js +48 -10
- package/src/testing-js/page-compliance.contract.js.map +1 -1
- package/src/testing-js/registry.contract.js +5 -3
- package/src/testing-js/registry.contract.js.map +1 -1
- package/src/testing-js/{vitest-C-wNWcoA.d.ts → vitest-BMLIbDs2.d.ts} +8 -2
- package/src/testing-js/vitest.d.ts +1 -1
- package/src/testing-js/vitest.js +2 -1
- package/template/package.json +1 -1
- package/.claude/skills/live-tokens-create-component/SKILL copy.md +0 -196
- package/.claude/skills/live-tokens-fix-findings/SKILL.md +0 -105
- package/src/editor/skill-atlas/trees/fix-findings.ts +0 -504
- package/src/testing-js/chunk-4JQX6WWL.js.map +0 -1
- package/src/testing-js/chunk-FAFOAWYL.js.map +0 -1
- package/src/testing-js/chunk-GNIUPIU2.js.map +0 -1
|
@@ -1,47 +1,76 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: live-tokens-check-compliance
|
|
3
|
-
description:
|
|
3
|
+
description: Check an existing @motion-proto/live-tokens project against the design system and fix it until check-page and check-component both exit 0. Checks for correct use of components, properties, and tokens. Reads the whole project from one run of npx live-tokens report, runs the token migrations, then runs both checkers, which apply every auto repair and return each remaining finding with its own guidance, repair level, and details. Use when the user asks to check, audit, or review the project. Use when the user asks to fix the project or to make check:design pass. Edits the files the checkers name. Updates tokens.css only through the migration command.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Checking a project's adherence to live-tokens
|
|
6
|
+
# Checking and fixing a project's adherence to live-tokens
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Check the project, then fix every finding of `check-page` and `check-component` until both exit 0. `check-page` checks pages. Every component comes from the catalogue, every prop is declared, and every value in page CSS is a design token. `check-component` checks the project's own components. Every token names a semantic property, and its default is the design token that property reads. Every finding carries its own `guidance`, and the repair follows it.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
`report` stays static for pages too. The `check-page` test run is what live-tokens-create-page calls for a rendered page, in a browser against the project's own route, and it reports `page-component-paint`, `page-text-style`, `page-contrast`, `page-grid`, and `page-overflow` findings the same way `report`'s static findings read: by rule, with a fix.
|
|
10
|
+
The report and both checkers are static. They read the project's source, never open a browser, and never mount a runtime. `npx live-tokens check-page <file> --tests` proves a page's rendered paint, and `npx live-tokens check-component <id> --tests` proves a component's declared behavior. **live-tokens-create-page** and **live-tokens-create-component** run those, one file or one id at a time, and their findings carry guidance the same way.
|
|
13
11
|
|
|
14
12
|
## Workflow
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
1. Run `npx live-tokens report --json`. Read it in its own key order: `project`, `migrations`, `components`, `findings.pages`, `findings.components`, `usage`, per Report sections below.
|
|
15
|
+
2. Run `npx live-tokens migrate --check` to see the plan, then `npx live-tokens migrate` to apply it. The command brings `tokens.css` up to the installed package and heals the data tree. With `--write` it also rewrites the route references it lists. `--tokens <path>` names a tokens.css in an unusual place.
|
|
16
|
+
3. Run both checkers with `--json`. Each first applies every finding whose `repair` is `auto`, checks again, and returns the fixes it applied in `fix.applied` beside the findings that remain. A fix in `fix.skipped` found its text moved, and the next run applies it. `--no-fix` reports without editing, for a build or CI.
|
|
17
|
+
```sh
|
|
18
|
+
npx live-tokens check-page --json
|
|
19
|
+
npx live-tokens check-component --json
|
|
20
|
+
```
|
|
21
|
+
4. Read what remains. Each finding carries the fields under Finding fields, with a `repair` of `choice` or `authored`.
|
|
22
|
+
5. Group the findings by rule. Take the largest error group first, then the remaining errors. Take warnings only when the repair scope includes warnings.
|
|
23
|
+
6. Make every repair in the group from its `guidance`, within Scope below.
|
|
24
|
+
7. Run both checkers again. When repairable findings remain in scope, return to step 5. When no token fits a remaining finding, leave it and continue to the reply with its reason.
|
|
25
|
+
8. When the errors are clear, run both checkers with `--strict`. Report what `--strict` adds. Clear warnings within the existing request. Otherwise ask whether to clear the warnings now.
|
|
26
|
+
9. When the repair scope includes warnings, return to step 5 with `--strict`. When strict checks pass or the user defers warnings, set up the build script.
|
|
27
|
+
10. Add `check:design` to the build, per Build script below.
|
|
28
|
+
11. Reply with:
|
|
29
|
+
- the report's picture: pending migrations, component facts, and usage
|
|
30
|
+
- the fixes the checkers applied, each with its count and any visible shift
|
|
31
|
+
- the remaining changes by rule, each with its count and any visible shift
|
|
32
|
+
- the findings left, each with its reason and any config entry the user chose
|
|
33
|
+
- both checker commands with their exit codes
|
|
25
34
|
|
|
26
|
-
|
|
35
|
+
`check-page <path>` scopes a run to one page. `check-component <id>` scopes a run to one component: its runtime, its editor, and its registration. The checkers read tokens.css from its default location.
|
|
27
36
|
|
|
28
37
|
## Report sections
|
|
29
38
|
|
|
30
|
-
| Section | Contents |
|
|
31
|
-
| --- | --- |
|
|
32
|
-
| Pending token migrations (`migrations`) | Whether `tokens.css` is behind the installed package. `status` is `pending`, `none pending`, `no tokens.css`, or `unavailable`. A stale file shows downstream as unknown tokens
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
| Section | Contents |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| Pending token migrations (`migrations`) | Whether `tokens.css` is behind the installed package. `status` is `pending`, `none pending`, `no tokens.css`, or `unavailable`. A stale file shows downstream as unknown tokens, so step 2 runs the migrations before either checker. |
|
|
42
|
+
| Component facts (`components[]`) | Every component the project has, each with `id`, `origin`, `file`, `registered`, and `tokens` (the count of semantic properties it declares). A component's unread tokens, missing description, and missing registration are the `unread-token`, `missing-description`, and `missing-registration` findings. |
|
|
43
|
+
| Checker findings by rule (`findings.pages`, `findings.components`) | Both checkers' findings by rule under the project's severities, and one strict total with every warning as an error. Errors fail the build today. The strict total is what a fully tokenized project would fail. |
|
|
44
|
+
| Components each page renders (`usage.byPage`) | Which component each page imports, and how many times the page renders it. When a page renders none, say whether it is chrome or markup that a shipped component covers. |
|
|
45
|
+
| Shipped components no page renders (`usage.unusedShipped`) | Information only. |
|
|
46
|
+
| Project components unused (`usage.customUnused`) | The project's own components no page renders. |
|
|
47
|
+
|
|
48
|
+
## Finding fields
|
|
49
|
+
|
|
50
|
+
Every finding from both checkers, under `report --json` and under each checker's `--json`:
|
|
51
|
+
|
|
52
|
+
| Field | Value |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `rule`, `severity`, `file`, `line`, `message` | What the finding is and where. |
|
|
55
|
+
| `guidance` | How to make the repair: the token for the role or the scale step, the command that prints the candidates, or the section of a create skill that owns the fix. |
|
|
56
|
+
| `repair` | `auto`, `choice`, or `authored`. See Repair levels. |
|
|
57
|
+
| `exception` | The narrower config entry that records a decision to leave the finding as it is: `{ "checks": { "exclude": ["<file>"] } }` for a page or CSS file, otherwise `{ "checks": { "rules": { "<rule>": "warn" } } }`. Applying it steps the rule down one level, error to warn and warn to off. |
|
|
58
|
+
| `details` | Per-rule data the message already states in prose, such as the accepted values behind `unknown-prop-value` or the nearest design-token candidates behind `dimension-literal`. Absent when a rule has nothing to add. |
|
|
59
|
+
|
|
60
|
+
## Repair levels
|
|
61
|
+
|
|
62
|
+
Every finding's `repair` says what moving it costs.
|
|
63
|
+
|
|
64
|
+
- **`auto`.** The value determines the fix, such as a spacing literal with one nearest design-token step. The checkers apply it and list it in `fix.applied`.
|
|
65
|
+
- **`choice`.** A role or an ambiguous value determines the fix, such as a color literal and the role it plays, or a spacing literal tied between two steps. `details` lists the candidates, and `guidance` says how to pick one.
|
|
66
|
+
- **`authored`.** New code is the fix: a runtime that has to start behaving, an editor schema that has to name a token, a route that has to move. `guidance` names what to write. No candidate list applies.
|
|
67
|
+
|
|
68
|
+
## Scope
|
|
40
69
|
|
|
41
|
-
|
|
70
|
+
- Add no token to `tokens.css`. Map a literal with no matching token to the nearest existing token by role. When no token fits, leave the finding and say so.
|
|
71
|
+
- When the nearest token differs from the literal, use the token and name the shift in the reply, such as `14px` to `--space-16`.
|
|
72
|
+
- Any finding, at any repair level, can stay as a deliberate exception when the user chooses to keep it. Record that decision in the config entry its `exception` field names, and prefer the narrower entry. When the user has chosen to lower a rule's severity, record it in `live-tokens.config.json` under `"checks": { "rules": { "<rule>": "warn" } }`. `--off=<rule>` silences a rule for one run only.
|
|
42
73
|
|
|
43
|
-
|
|
74
|
+
## Build script
|
|
44
75
|
|
|
45
|
-
|
|
46
|
-
- **Judgement.** A role determines the token, such as a color literal and the role it plays. Say what the options are. Ask the user to choose.
|
|
47
|
-
- **Deliberate.** The finding records a decision, such as a layout size the project owns. Name the config entry that would record the decision. Leave the decision to the user. To lower a rule's severity everywhere, the entry is `"checks": { "rules": { "<rule>": "warn" } }` in `live-tokens.config.json`. To drop one file that is not a themed surface, the entry is `"checks": { "exclude": ["src/art/hero.css"] }`. The path is project-relative, and a directory covers what is under it. Prefer the narrower entry.
|
|
76
|
+
When `package.json` has no `check:design` script, add `"check:design": "live-tokens check-page --no-fix && live-tokens check-component --no-fix"`. `--no-fix` keeps the build from editing files. When both checkers exit 0, prepend `npm run check:design &&` to the existing build command. Preserve its other build steps.
|
|
@@ -11,10 +11,10 @@ Create a component whose structure and behavior serve the user's purpose. Give e
|
|
|
11
11
|
|
|
12
12
|
1. Read the project: `package.json`, `live-tokens.config.json`, `src/main.ts`, the catalogue, the token scales the component will use, a shipped runtime and editor pair, and the property suffixes.
|
|
13
13
|
2. Design the properties: separate the component's parts, variants, and states, then write one row per editable role with its token and the CSS it controls, named the way the shipped components name the same role.
|
|
14
|
-
3. Write the runtime file: the
|
|
14
|
+
3. Write the runtime file: the catalogue export and the `:global(:root)` block. A structural choice is an intrinsic. Every component joins the sketch layer, and a fixed overlay portals to `<body>`.
|
|
15
15
|
4. Write the editor file: the schema, the preview props, and the markup. Variants that share a value are linked.
|
|
16
16
|
5. Register the component in the module `src/main.ts` and `live-tokens.testing.ts` both name, and write its contract in the module `contractsModule` names.
|
|
17
|
-
6. Run
|
|
17
|
+
6. Run `npx live-tokens check-component <id> --tests --strict --json` until it exits 0 with complete applicable coverage, then the Svelte check and the build.
|
|
18
18
|
7. Reply with the files, the id, the props, and each check's result. Then place the component on a page with **live-tokens-create-page**.
|
|
19
19
|
|
|
20
20
|
## Design model
|
|
@@ -34,12 +34,14 @@ A component is distinct in its anatomy, its proportions, its content hierarchy,
|
|
|
34
34
|
|
|
35
35
|
Props carry content and behavior: a value, a label, a callback. Properties carry the editable appearance. When a variant is a choice the page makes, expose it as a prop.
|
|
36
36
|
|
|
37
|
+
Prop names follow the shipped components. `label` names a control, `title` heads content, `text` is body copy. `open` is the one prop for an open state. `value` holds a selection's id. A size prop's values are `default` and `small`. A callback prop is `on` followed by the event name, all lowercase, as in `onchange`, `onclose`, and `onsave`.
|
|
38
|
+
|
|
37
39
|
## Source inspection
|
|
38
40
|
|
|
39
41
|
Before writing a file:
|
|
40
42
|
|
|
41
43
|
1. Read the project's `package.json`, `live-tokens.config.json`, and `src/main.ts`.
|
|
42
|
-
2. Run `npx live-tokens components`. The list holds every component the project has, with its variants and
|
|
44
|
+
2. Run `npx live-tokens components`. The list holds every component the project has, with its variants and catalogue entry. `npx live-tokens components <id>` prints one component's props.
|
|
43
45
|
3. Run `npx live-tokens tokens --scale <name>` for each token scale the component will use. Those names are the tokens a property can reference.
|
|
44
46
|
4. Read a shipped runtime and editor pair: `Toggle` for interaction states, `Badge` for variants and linked values, `Card` for text and container parts.
|
|
45
47
|
5. Read `references/token-naming.md` for the suffixes that select editor controls.
|
|
@@ -53,7 +55,7 @@ A component has three kinds of division. Keep them apart in the props, the names
|
|
|
53
55
|
| Kind | Meaning | Example |
|
|
54
56
|
|---|---|---|
|
|
55
57
|
| Part | Regions present at once | Dialog's overlay, header, body, footer |
|
|
56
|
-
| Variant | Alternative presentations the page chooses | Badge's
|
|
58
|
+
| Variant | Alternative presentations the page chooses | Badge's brand, danger |
|
|
57
59
|
| State | A runtime condition | Toggle's on, hover, disabled |
|
|
58
60
|
|
|
59
61
|
States have two axes. A component state is one of a set that excludes the others: default, selected (or on), disabled. An interaction state layers on a component state: default, hover, and later focus or active. `disabled` is terminal: no other state layers on it, in the names or in the editor.
|
|
@@ -95,20 +97,24 @@ A property name starts with the component id and ends with the property suffix.
|
|
|
95
97
|
|
|
96
98
|
For a state that affects several parts, follow Toggle: `--toggle-on-hover-track-surface`. State segments precede the affected part.
|
|
97
99
|
|
|
98
|
-
Name a role as the shipped component that paints the same thing names it. A fill is `-surface` in every shipped component. A knob is `-thumb`. A text role's color sits on the role's own name, `-title`, `-body`, `-label`, `-value`, and its typography hangs off that name: `--card-default-title-font-size`. A component with one text role uses `-text`: `--badge-
|
|
100
|
+
Name a role as the shipped component that paints the same thing names it. A fill is `-surface` in every shipped component. A knob is `-thumb`. A text role's color sits on the role's own name, `-title`, `-body`, `-label`, `-value`, and its typography hangs off that name: `--card-default-title-font-size`. A component with one text role uses `-text`: `--badge-brand-text`.
|
|
99
101
|
|
|
100
102
|
## Runtime component
|
|
101
103
|
|
|
102
104
|
Create `src/system/components/StatCard.svelte`. `check-component` finds a runtime there only. A component in another directory is listed by `components` and `report` when that directory is named in `"componentDirs"` in `live-tokens.config.json`, and `check-component` does not check it. Use Svelte 5 props and snippets, semantic HTML, and the behavior the task requires.
|
|
103
105
|
|
|
104
|
-
Open the file with
|
|
106
|
+
Open the file with a `<script module lang="ts">` block that exports a `catalogue` entry in the shape every shipped component carries. `npx live-tokens components` prints it beside the id, and `components <id>` prints it with the props. Each field is `key: <string literal>`, in single, double, or backtick quotes; no `${}` interpolation, no concatenation, no identifier reference. An optional `props` map adds one line per prop whose values carry a choice, such as `variant`; each key names a prop the file declares, and the text says what the values mean.
|
|
105
107
|
|
|
106
108
|
```svelte
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
<script module lang="ts">
|
|
110
|
+
import type { CatalogueEntry } from '@motion-proto/live-tokens';
|
|
111
|
+
|
|
112
|
+
export const catalogue = {
|
|
113
|
+
description: 'A figure with its label.',
|
|
114
|
+
useFor: 'one number the reader takes in at a glance.',
|
|
115
|
+
notFor: 'a set of records (Table); a titled block of content (Card).',
|
|
116
|
+
} satisfies CatalogueEntry;
|
|
117
|
+
</script>
|
|
112
118
|
```
|
|
113
119
|
|
|
114
120
|
Declare every editable property in a literal `:global(:root)` block, each assigned a token. The plugin parses the Svelte source to seed `component-configs/<id>/default.json`, so the block holds plain declarations with no SCSS loop or interpolation.
|
|
@@ -192,6 +198,7 @@ Register the component in `src/registerComponents.ts`, a registration-only modul
|
|
|
192
198
|
```ts
|
|
193
199
|
// src/registerComponents.ts
|
|
194
200
|
import { registerComponent } from '@motion-proto/live-tokens';
|
|
201
|
+
import { catalogue } from './system/components/StatCard.svelte';
|
|
195
202
|
import StatCardEditor, { allTokens as statCardTokens } from './system/components/StatCardEditor.svelte';
|
|
196
203
|
|
|
197
204
|
registerComponent({
|
|
@@ -201,6 +208,7 @@ registerComponent({
|
|
|
201
208
|
sourceFile: 'src/system/components/StatCard.svelte',
|
|
202
209
|
editorComponent: StatCardEditor,
|
|
203
210
|
schema: statCardTokens,
|
|
211
|
+
catalogue,
|
|
204
212
|
});
|
|
205
213
|
```
|
|
206
214
|
|
|
@@ -218,23 +226,10 @@ A fixed overlay portals to `<body>`: read `references/fixed-overlays.md`. A cont
|
|
|
218
226
|
|
|
219
227
|
## Verification
|
|
220
228
|
|
|
221
|
-
1. Run
|
|
222
|
-
2.
|
|
223
|
-
3.
|
|
224
|
-
|
|
225
|
-
Every finding carries a `fix` slug naming the section that fixes it.
|
|
226
|
-
|
|
227
|
-
| `fix` | Section |
|
|
228
|
-
|---|---|
|
|
229
|
-
| `property-name` | Property design, the name |
|
|
230
|
-
| `property-token` | Property design, the assigned token |
|
|
231
|
-
| `runtime` | Runtime component |
|
|
232
|
-
| `runtime-defaults` | Runtime component, the `:global(:root)` defaults |
|
|
233
|
-
| `editor` | Component editor |
|
|
234
|
-
| `registration` | Registration |
|
|
235
|
-
| `sketch` | Sketch mode and overlays |
|
|
236
|
-
| `tooling` | The message names the missing tool or the broken path; fix it and rerun |
|
|
237
|
-
| `coverage` | Add the missing contract, or complete the run the message names |
|
|
229
|
+
1. Run `npx live-tokens check-component <id> --tests --strict --json`. Inside the live-tokens repository, run `node bin/cli.mjs check-component <id> --tests --strict --json`. It applies every `auto` repair, runs the registry contract and, for a component with a contract in the module `contractsModule` names, the component contract suites, and returns the fixes it applied, the findings that remain, and coverage by rule. `--off=<rule>` silences a rule for one run, and `--no-fix` reports without editing.
|
|
230
|
+
2. Each remaining finding carries a rule id, a line, and its `guidance`. Make each repair from its guidance, and run the command again until it exits 0 with complete applicable coverage and no disabled checks.
|
|
231
|
+
3. Run the project's Svelte check and its build.
|
|
232
|
+
4. Reply with the files, the component id, the props, and the result of each check, naming any check the environment prevented.
|
|
238
233
|
|
|
239
234
|
`--tests` covers every line a reviewer once checked by eye: the component's listing, its controls and preview, persistence and reset, theme projection, linked properties, and Sketch mode.
|
|
240
235
|
|
|
@@ -152,10 +152,71 @@ Each obligation and what it needs from the project:
|
|
|
152
152
|
to under it.
|
|
153
153
|
- `interaction`: the interactive part's role and its cases. `applicable:
|
|
154
154
|
false` for a component with no interactive role.
|
|
155
|
+
- `behavior`: what a callback prop does. See Behavior below.
|
|
155
156
|
- `sketch`: a sketch style id and the fill and stroke each reserved-class part
|
|
156
157
|
resolves to under it. `applicable: false` only for a component
|
|
157
158
|
`references/sketch-mode.md` exempts.
|
|
158
159
|
|
|
160
|
+
## Behavior
|
|
161
|
+
|
|
162
|
+
`behavior` runs under Vitest with `mount` from Svelte and happy-dom, not in
|
|
163
|
+
the editor preview, because a controlled component's callback prop has
|
|
164
|
+
nothing driving it there: the preview edits the token, not the prop. One
|
|
165
|
+
case names the props the runtime mounts with, the action a user takes, and
|
|
166
|
+
what that should do.
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
behavior: {
|
|
170
|
+
cases: [
|
|
171
|
+
{
|
|
172
|
+
name: 'clicking an off toggle asks for on',
|
|
173
|
+
props: { checked: false },
|
|
174
|
+
action: { kind: 'click', part: 'root' },
|
|
175
|
+
expect: { kind: 'callback', prop: 'onchange', args: [true] },
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'clicking leaves the switch where the prop put it',
|
|
179
|
+
props: { checked: false },
|
|
180
|
+
action: { kind: 'click', part: 'root' },
|
|
181
|
+
expect: { kind: 'attribute', part: 'root', name: 'aria-checked', value: 'false' },
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: 'checked drives aria-checked',
|
|
185
|
+
props: { checked: true },
|
|
186
|
+
expect: { kind: 'attribute', part: 'root', name: 'aria-checked', value: 'true' },
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: 'a disabled toggle stays silent',
|
|
190
|
+
props: { checked: false, disabled: true },
|
|
191
|
+
action: { kind: 'click', part: 'root' },
|
|
192
|
+
expect: { kind: 'no-callback', prop: 'onchange' },
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Toggle is controlled: it never flips `checked` itself, so the click case
|
|
199
|
+
that asks for `on` and the mount case that reads `checked` are two separate
|
|
200
|
+
cases, not one. The disabled case pins that a disabled toggle calls nothing
|
|
201
|
+
back: the prop reaches the DOM as a real `disabled` attribute on the part,
|
|
202
|
+
and happy-dom withholds a dispatched click from a disabled `<button>`. A
|
|
203
|
+
component that reports through `input` rather than `click`, such as Slider,
|
|
204
|
+
gets no disabled case, because happy-dom delivers a dispatched `input` event
|
|
205
|
+
to a disabled control and the case would assert the environment rather than
|
|
206
|
+
the component.
|
|
207
|
+
|
|
208
|
+
A component with no callback prop declares the obligation inapplicable, in
|
|
209
|
+
one line:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
behavior: { applicable: false, reason: 'a table wrapper declares no callback prop; its rows arrive as a snippet' },
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The fault this suite catches is a callback that fires with the wrong
|
|
216
|
+
argument, fires when a case says it should stay silent, or never fires at
|
|
217
|
+
all. `check-component <id> --tests` reports it as `contract-behavior`,
|
|
218
|
+
naming the case.
|
|
219
|
+
|
|
159
220
|
## Running vitest yourself
|
|
160
221
|
|
|
161
222
|
`check-component --tests` covers the shipped path. Run vitest directly only
|
|
@@ -138,8 +138,8 @@ Make the rule an element, give it `sketch-rule`, and name its ink as the fill.
|
|
|
138
138
|
```css
|
|
139
139
|
.mywidget-rule {
|
|
140
140
|
height: var(--border-width-2);
|
|
141
|
-
background: var(--mywidget-
|
|
142
|
-
--sketch-fill: var(--mywidget-
|
|
141
|
+
background: var(--mywidget-hairline-color);
|
|
142
|
+
--sketch-fill: var(--mywidget-hairline-color);
|
|
143
143
|
}
|
|
144
144
|
```
|
|
145
145
|
|
|
@@ -17,15 +17,12 @@ to that list, so the two cannot drift apart.
|
|
|
17
17
|
| `-icon` | Icon color |
|
|
18
18
|
| `-label` | Label text color |
|
|
19
19
|
| `-fill` | Inner fill (distinct from outer surface) |
|
|
20
|
-
| `-
|
|
21
|
-
| `-color` | Generic color, when none of the above name the role |
|
|
20
|
+
| `-color` | A hairline rule's colour, or a color no role word above names |
|
|
22
21
|
| `-shadow` | Box-shadow |
|
|
23
22
|
| `-opacity` | Opacity (0–1) |
|
|
24
23
|
| `-blur` | Backdrop or filter blur radius |
|
|
25
24
|
| `-tint` | A wash over the surface, aliasing a `--tint-*` stop |
|
|
26
|
-
| `-
|
|
27
|
-
| `-accent` | An accent bar or indicator's colour |
|
|
28
|
-
| `-indicator` | A selection indicator's colour |
|
|
25
|
+
| `-indicator` | The colour of the bar or stripe that marks an item |
|
|
29
26
|
| `-thumb` | A scrollbar or slider thumb's colour |
|
|
30
27
|
| `-title` | Title text colour |
|
|
31
28
|
| `-body` | Body text colour |
|
|
@@ -42,21 +39,15 @@ to that list, so the two cannot drift apart.
|
|
|
42
39
|
|-----------------|---------------------------------------------------------------|
|
|
43
40
|
| `-radius` | Corner radius |
|
|
44
41
|
| `-border-width` | Stroke thickness (used even when CSS uses `outline:`) |
|
|
45
|
-
| `-
|
|
46
|
-
| `-
|
|
47
|
-
| `-indicator-width` | An indicator's thickness, moved with `-accent-width` |
|
|
48
|
-
| `-hairline-thickness` | A hairline rule's thickness |
|
|
42
|
+
| `-indicator-width` | An indicator's thickness |
|
|
43
|
+
| `-hairline-width` | A hairline rule's thickness |
|
|
49
44
|
| `-dot-size` | A dot indicator's diameter |
|
|
50
|
-
| `-
|
|
51
|
-
| `-divider-thickness` | Alternative to `-divider-width` |
|
|
52
|
-
| `-divider-height` | A divider's length |
|
|
53
|
-
| `-divider-inset` | Inset trimmed from a stretched divider |
|
|
45
|
+
| `-hairline-inset` | Inset trimmed from a stretched hairline |
|
|
54
46
|
| `-track-height` | A track's height (progress bar, slider) |
|
|
55
47
|
| `-icon-size` | An icon's rendered size |
|
|
56
48
|
| `-thumb-size` | A thumb's rendered size |
|
|
57
49
|
| `-height` | A measured height (a track, a panel) |
|
|
58
50
|
| `-margin` | Outer spacing, moved on the same scale as `-padding` |
|
|
59
|
-
| `-inset` | Inset trimmed from a stretched element |
|
|
60
51
|
| `-duration` | Motion duration |
|
|
61
52
|
| `-easing` | Motion easing curve |
|
|
62
53
|
| `-scale` | A transform scale factor |
|
|
@@ -67,7 +58,7 @@ to that list, so the two cannot drift apart.
|
|
|
67
58
|
|
|
68
59
|
`-width`, `-height` and `-size` are the fall-through: any dimension with no
|
|
69
60
|
more specific name behind it. They read the `--space-*` scale through the same
|
|
70
|
-
picker `-gap` uses, and they match last, so `-border-width`, `-
|
|
61
|
+
picker `-gap` uses, and they match last, so `-border-width`, `-hairline-width`,
|
|
71
62
|
`-icon-size` and the rest claim their token first. Reach for the specific name
|
|
72
63
|
when one fits; a stroke is `-border-width` even where the CSS says `outline:`.
|
|
73
64
|
|
|
@@ -17,8 +17,8 @@ Assemble the page from the shipped components at their defaults and the theme's
|
|
|
17
17
|
6. Write the page CSS in design tokens.
|
|
18
18
|
7. Set the hierarchy: one text style per element, the shipped size on every control, one primary action, and one space step per position.
|
|
19
19
|
8. Add the route, with a lazy import and the source path.
|
|
20
|
-
9. Run
|
|
21
|
-
10. Reply with the sections and the layout each took, the components placed, the route, and the
|
|
20
|
+
9. Run `npx live-tokens check-page <file> --tests --strict --json` until it exits 0, then check the rendered page.
|
|
21
|
+
10. Reply with the sections and the layout each took, the components placed, the route, and the check-page result.
|
|
22
22
|
|
|
23
23
|
## Layout
|
|
24
24
|
|
|
@@ -85,7 +85,7 @@ Show related items side by side when the width permits. A line of copy runs 45 t
|
|
|
85
85
|
## Components
|
|
86
86
|
|
|
87
87
|
- Use a shipped component when one fits. Import it from `@motion-proto/live-tokens/components/<Name>.svelte`.
|
|
88
|
-
- `npx live-tokens components <id>` prints the declared props, the values each union accepts, and the
|
|
88
|
+
- `npx live-tokens components <id>` prints the declared props, the values each union accepts, and the catalogue entry. `--json` prints the same as data. The list includes the project's own components.
|
|
89
89
|
- Pass only the props a component declares.
|
|
90
90
|
- A shipped component fills its parent. To size one, size the element the page wraps it in.
|
|
91
91
|
- A native element with no chrome of its own needs no component: an `<input type="file">` behind a Button, a `<canvas>`, an `<img>` inside a stage.
|
|
@@ -165,7 +165,9 @@ const pages = {
|
|
|
165
165
|
|
|
166
166
|
## Verify
|
|
167
167
|
|
|
168
|
-
Run
|
|
168
|
+
Run `npx live-tokens check-page <file> --tests --strict --json`. It applies every `auto` repair, runs the Playwright suite against the page's own route, and returns the fixes it applied and the findings that remain. The suite proves what only a rendered page can: the cascade leaves every component painting from its semantic properties, every run of text sits in one shipped text style, every text and surface pair meets AA, sections sit on the page grid, and nothing overflows. `--off=<rule>` silences a rule for one run, and `--no-fix` reports without editing.
|
|
169
|
+
|
|
170
|
+
Each remaining finding carries a rule id, a line, and its `guidance`. Make each remaining repair from its guidance, and run the command again until it exits 0.
|
|
169
171
|
|
|
170
172
|
The checkers cannot see a layout. Open the page at the width it is built for and check each line below.
|
|
171
173
|
|
|
@@ -88,7 +88,7 @@ rather than only on the buttons.
|
|
|
88
88
|
| Christmas | red and green with gold, one of the two owning the ground |
|
|
89
89
|
| Halloween | pumpkin, violet, and poison green, dark either way |
|
|
90
90
|
| St. Patrick's | green with gold over a pale ground |
|
|
91
|
-
| Ocean | blues held to one narrow
|
|
91
|
+
| Ocean | blues held to one narrow range |
|
|
92
92
|
| Sunset | a hue sweep through red, falling in lightness |
|
|
93
93
|
| Autumn | parchment under rust, gold, and moss |
|
|
94
94
|
| Spring | pastels, greens and pinks over a mint ground |
|
|
@@ -9,7 +9,7 @@ When more than one shipped component could fit, find the family below that names
|
|
|
9
9
|
|
|
10
10
|
## Catalogue
|
|
11
11
|
|
|
12
|
-
Before choosing, run `npx live-tokens components`. The list holds every component the project has, shipped and custom, with each one's variants and
|
|
12
|
+
Before choosing, run `npx live-tokens components`. The list holds every component the project has, shipped and custom, with each one's variants and catalogue entry. The family tests below name the shipped set only. Weigh a custom component by the same tests.
|
|
13
13
|
|
|
14
14
|
## Action family
|
|
15
15
|
|
|
@@ -38,7 +38,7 @@ The test is whether the answer comes from a predefined list of options.
|
|
|
38
38
|
- A predefined list (a status, a currency, a size, a country): the single-selection family, by its own test. Up to four options sit in a row; more go in a `MenuSelect`, which scrolls.
|
|
39
39
|
- No list (a name, a search string, an amount, a message, a street address): `Input`. Validation keeps a typed answer well-formed.
|
|
40
40
|
- A long list the reader would rather filter by typing (a city): no shipped component filters a list. Use `Input` with validation, or author a filtering select with **live-tokens-create-component**.
|
|
41
|
-
- A number where the position on a track carries the meaning (a volume, a price
|
|
41
|
+
- A number where the position on a track carries the meaning (a volume, a price range, a percentage): `Slider`. A number the reader knows and would rather type: `Input` with `type="number"`.
|
|
42
42
|
|
|
43
43
|
## On and off
|
|
44
44
|
|
|
@@ -93,4 +93,4 @@ Each pair holds a block the reader views and one the reader interacts with. The
|
|
|
93
93
|
|
|
94
94
|
A native element with no chrome of its own needs no component: an `<input type="file">` behind a Button, a `<canvas>`, an `<img>` inside a stage. When nothing in the catalogue fits a piece with chrome (a `DatePicker`, a `Stepper`), author the component with **live-tokens-create-component**. Size, emphasis, and placement are **live-tokens-create-page**'s.
|
|
95
95
|
|
|
96
|
-
`npx live-tokens components <id>` prints one component's
|
|
96
|
+
`npx live-tokens components <id>` prints one component's catalogue entry, its declared props, and the values each union accepts. `--json` returns the same as data.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Color anchors: feelings, idioms, and occasions
|
|
2
2
|
|
|
3
3
|
Read this when the color intent names one of these. Entries are starting
|
|
4
|
-
points: apply the chroma budget, the per-role
|
|
4
|
+
points: apply the chroma budget, the per-role ranges, and the canvas commitment
|
|
5
5
|
rules from SKILL.md on top of them.
|
|
6
6
|
|
|
7
7
|
An idiom sets constraints and overrides the generic defaults in SKILL.md. The
|
|
@@ -37,7 +37,7 @@ Targeted, absolute:
|
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
- `target` (optional): a component id, one of the folder names under `src/live-tokens/data/component-configs/`. "Windows" or "modals" is `dialog`, "cards" is `card`, "tabs" is `tabbar`. "The UI", "everything", or no noun means global, so omit `target`.
|
|
40
|
-
- `kind`: `radius | padding | gap | border-width |
|
|
40
|
+
- `kind`: `radius | padding | gap | border-width | hairline-width | indicator-width`. `border-width` moves `-border-width` aliases. `hairline-width` moves `-hairline-width` aliases. `indicator-width` moves the bar or stripe an indicator draws.
|
|
41
41
|
- `set` or `shift`, one of the two. `set` takes a token on that kind's scale. `shift` is a whole number of steps and stops at the ends of the scale.
|
|
42
42
|
- `full` (radius shifts only): admits `--radius-full` as the top of the scale. A pill request is `set: "--radius-full"` with no `full` flag.
|
|
43
43
|
|
|
@@ -7,7 +7,7 @@ came from, and a style's geometry is often targeted rather than global.
|
|
|
7
7
|
Entries are written in the ops vocabulary. "radius +2" is a radius shift of 2.
|
|
8
8
|
"borders +1" is a border-width shift of 1. "padding +1" is a padding and gap
|
|
9
9
|
shift of 1. "hairline borders" is border-width `set: "--border-width-1"`, and
|
|
10
|
-
"no borders" is `set: "--border-width-0"`. "hairline rules" is
|
|
10
|
+
"no borders" is `set: "--border-width-0"`. "hairline rules" is hairline-width
|
|
11
11
|
`set: "--border-width-1"`. A named component means a targeted op. Controls squeeze before containers,
|
|
12
12
|
so a compaction of more than one step still spends its extra steps on
|
|
13
13
|
containers by name.
|