Repository navigation
feat(anatomy): anatomy standard, presentIn, SPEC-073 to 075 and flowed-box painting (4/6) - #1580
Merged
Merged
Conversation
added 19 commits
October 31, 2026 17:47
- label: required -> optional (hidden by isLabelHidden and while pending) - focus-indicator: mark state-only (states: [focus]) - progress: description generalised; kept, button styles it and isPending drives it - add anatomyReview: reviewed
- focus-indicator: mark state-only (states: [keyboard-focus]) - progress: description generalised; kept - hold-icon: kept (registry term, own style) - add anatomyReview: reviewed
- no part changes; icon and label already optional, not focusable - add anatomyReview: reviewed
- focus-indicator: mark state-only; no longer nested in control - box: required (always drawn) - control: kept but flagged; it is a render-only wrapper (flowed boxes cannot paint) - anatomyReview stays draft until control can be removed
- focus-indicator: mark state-only; no longer nested in control - track: required (always drawn) - control: kept but flagged; it is a render-only wrapper (flowed boxes cannot paint) - anatomyReview stays draft until control can be removed
…natomy view The anatomy callouts filtered out every ring node, so the focus indicator never appeared even with the focus state selected. Rings now get a callout while their state is active, placed below on the ring's bottom edge so the other labels keep their alternation. Fit and compact/large labels are unchanged.
…anatomy One info diagnostic lists components that have relationships but no anatomy and components whose anatomy is still draft. Adds the rule catalog entry, spec table row, conformance fixture and changeset.
… part A box placed directly in a row only read width, height and corner radius, so a painted box had to nest inside a sized wrapper. The renderer and the JS runtime now read fill, stroke and strokeWidth on a flowed box. - checkbox: control removed; box carries the size and holds the checkmark and dash - switch: control removed; track carries the size and holds the handle - relationships that named control now name box or track - anatomyReview is reviewed for both - snapshots and golden SVGs regenerated; 1536 old and new scene renders match in geometry, paint, token traces and press scale, minus the empty control node
… review design-data anatomy-suggest [COMPONENT...] [--format markdown|json] reads relationship scope.part and context text, token name.anatomy and component options, and prints candidate parts with their evidence. It never writes component files and every result is a draft. Candidates are checked against the anatomy definition: - registry terms are marked, custom names are flagged with the nearest term - platform words, layout helpers, measurements, variants and compound phrases are listed as not proposed, with the reason - spacing-only evidence, repeated component names and plurals are flagged - the focus indicator gets the component's declared focus state for `states`
…required parts presentIn says a part is present only in the listed states (drawn when any is active). State-dependent styling is not presence and stays off the part. - anatomy-format.md: definition of presentIn, checklist item 7 - anatomy-part and component schemas: rename, and a Layer 1 condition that rejects required: true together with presentIn - button, action-button, checkbox, switch: focus-indicator uses presentIn - anatomy-suggest: candidates carry presentIn - schema tests cover valid, required-with-presentIn and the old field name
name_states now delegates one state name to state_ids, so validation rules can normalize a state name the same way the renderer does. No behavior change.
A part that lists a state the component does not declare is a dangling reference, the anatomy version of SPEC-054. States are compared after the engine's normalization, so focus, key-focus and keyboard-focus are one state. A part with presentIn on a component that declares no states is also reported. Warning while anatomy is unreviewed; it should become an error after the review pass. Adds the rules.yaml entry, spec table row, conformance fixture, unit tests and a changeset update.
The fixture harness read relationships but not visual recipes, so rules that check a recipe against component data could not have a conformance fixture. A dataset.json may now carry a visuals array of recipes.
…ee on states A recipe part's visibleWhen.states should match the presentIn of the anatomy part of the same name, so the focus indicator's visibility cannot drift between the two. States are compared after normalization. visibleWhen.states means all listed states and presentIn means any, so a difference is a warning only when neither side lists more than one state; otherwise it is reported at info level. Adds the rules.yaml entry, spec rows, a conformance fixture that uses the new visuals support, unit tests and a changeset update.
SPEC-060 to 063 and SPEC-066 to 071 only had unit tests. Each rule now has an invalid fixture with a dataset (recipes in the visuals key) and the expected diagnostic, matched on severity and message. SPEC-070 expects both of its diagnostics. The README table lists the new fixtures, including SPEC-072 to 075, which were missing from it.
An alias pinned to colorScheme dark that resolves to a light token now has an invalid fixture and a README row.
The five components with anatomy are reviewed and the dataset is clean, so an undeclared presentIn state (SPEC-074) and a recipe whose visibleWhen.states disagrees with presentIn (SPEC-075) are now errors. SPEC-075 stays at info level when either side lists more than one state, because visibleWhen.states means all and presentIn means any. Updates the rule catalog, spec wording and tables, fixtures, unit tests and the changeset.
🦋 Changeset detectedLatest commit: cd8d71a The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
Run report for cd8d71a0Total time: 8m 56s | Comparison time: 23m 5s | Estimated savings: 14m 9s (61.3% faster)
Expanded report
Changed files |
Contributor
🧩 Component Schema Changes ReportComponent Schemas Changed (0 added, 0 deleted, 5 updated)Original Branch: ✅ No Breaking ChangesThis PR contains only non-breaking changes to component schemas. 🔄 Non-Breaking Updatesaction-button badge button checkbox switch This diff was generated automatically and contains only backward-compatible changes. This comment was automatically generated by the component schema diff tool. 🤖 |
Contributor
🎨 Token Changes ReportTokens Changed (0)Original Branch: This comment was automatically generated by the token diff tool. 🤖 |
This was referenced Nov 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Squash merge is fine; the next slice is rebased onto the result.
Description
Slice 4 of 6 from #1569, into
next/visual-recipes, now rebased onto the merged 3b (#1579). It defines what an anatomy part is and enforces it, then reviews the first five components against that definition.anatomy-format.mddefines parts, naming, nesting, required parts, non-anatomy, and a review checklist. New optionalpresentInon a part (states it is present in; not allowed on a required part). New optionalanatomyReview(draftorreviewed) on a component.presentInstates must be declared on the component), SPEC-075 (error: a recipe'svisibleWhen.statesmust agree withpresentIn). Conformance fixtures for SPEC-059 to SPEC-063, SPEC-066 to SPEC-071 and SPEC-073 to SPEC-075.design-data anatomy-suggestproposes candidate parts for a component. State-name normalization is shared asstate_ids. The site shows state-only parts such as the focus indicator.labelis optional. The focus indicator is state-only.fill,strokeandstrokeWidthitself, so checkbox and switch drop the render-onlycontrolpart. Relationships move tobox/track. Rendered geometry, colors and press scale are unchanged (measured below).Changesets:
anatomy-definition-and-review(button, action-button, badge review and the standard) andflowed-box-paints(flowed-box painting; checkbox and switch review).Related Issue
Part of #1569. Tracked in bead
spectrum-design-data-p6ga.9.Motivation and Context
Anatomy was loosely defined, so each component's parts were ad hoc and recipes could disagree with them. A written standard plus rules makes the data checkable. The flowed-box change removes a part that existed only for rendering, which the new standard calls out as not anatomy.
How Has This Been Tested?
Run in a clean worktree on the rebased branch (macOS):
cargo fmt --check,cargo clippy --workspace --all-targets -- -D warningsmoon run sdk:test sdk-wasm:test design-data:validate design-data:validate-dataset tokens:verifyLegacyOutput --force: 1691 Rust tests passed, 2 skipped; the working tree was clean afterward, so no snapshot, golden or legacy output drifted beyond what the commits below commit on purposenode tools/changeset-linter/src/cli.js check --fail-on-warningsnode .github/scripts/check-ci-coverage.mjs,pnpm ai:checkpnpm-lock.yamldiff is emptyRendered output before and after (checkbox, switch). I rendered both components on the integration branch (
bf40d547, old data) and on this branch (new data) over the same full sweep: every option set the recipe uses (booleans and declared values; combinations anerrorconstraint excludes are skipped) across every size, interaction state, color scheme (light, dark, wireframe) and scale (desktop, mobile). Each pair of scenes was compared as SVG text, with the old data-partcontrolmapped tobox(checkbox) ortrack(switch):How the mapping works. The old SVG has an unpainted
controlrect (fill="none") with the same x, y, width and height as the part that paints the box. The comparison drops that rect, after checking that its geometry equals the newbox/trackrect and that it was unpainted. Then the SVGs must be identical, withdata-tokensstripped. Fordata-tokens, the newbox/tracklist must equal the union of the oldcontrolandbox/tracklists (the order differs). The press info (part,nested, scale, center) must match withcontrolmapped tobox(checkbox:nestedlosesbox). Diagnostics must match. Nothing else differed. Switch press was already onhandleand is unchanged.The committed goldens and
recipe-snapshots.jsonchange only because of that removal ofcontroland thedata-tokensorder. The scratch test that produced the numbers is not committed.sdk/core/tests/recipe_snapshots.rsand the visual goldens guard this output from now on.Screenshots (if appropriate):
None. Checkbox and switch render the same geometry and colors.
Types of changes
Checklist:
Review guide (reading order)
packages/design-data-spec/spec/anatomy-format.md,schemas/anatomy-part.schema.json,rules/rules.yaml: the standard and rule entries.sdk/core/src/validate/rules/spec073.rs,spec074.rs,spec075.rs, plusschema.rs,lib.rs: the rules.packages/design-data-spec/conformance/invalid/:SPEC-059,SPEC-060,SPEC-061,SPEC-062,SPEC-063,SPEC-066,SPEC-067,SPEC-068,SPEC-069,SPEC-070,SPEC-071,SPEC-073,SPEC-074,SPEC-075.sdk/core/src/anatomy_suggest.rs,sdk/cli/src/main.rs: the suggester (largest new file, self-contained).packages/design-data/components/{button,action-button,badge,checkbox,switch}.json: the per-component reviews (one commit per component).sdk/core/src/visual.rs,sdk/plugins/site/assets/visual-runtime.js,index.html, thenvisuals/andrelationships/for checkbox and switch: flowed-box painting..changeset/anatomy-definition-and-review.md,.changeset/flowed-box-paints.md.