Skip to content

feat(Stepper): theme targets for the step label and description - #5728

Merged
cixzhang merged 1 commit into
mainfrom
feat/stepper-text-theme-targets
Sep 3, 2026
Merged

feat(Stepper): theme targets for the step label and description#5728
cixzhang merged 1 commit into
mainfrom
feat/stepper-text-theme-targets

Conversation

@freddymeta

@freddymeta freddymeta commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Why

A Step label and description declare their own typography and color, so themes cannot reach them through the existing step target by inheritance. Stable targets replace brittle structural selectors on the existing painted spans.

#5495 has now merged the current Stepper contract, Connector anatomy, --step-connector-gap, and DEC-1. This PR is rebased on that authority and no longer carries a competing full Stepper record.

What

  • Adds step-label and step-description in both indicator positions.
  • Both targets reflect progress and status; step-label alone reflects disabled, because only the label owns disabled text paint.
  • Amends the current spec with FR9–FR11 and DEC-2. Connector semantics are unchanged, and the merged DEC-1 text is byte-for-byte preserved; there are no new open questions.
  • Drops the duplicate RTL target already supplied by feat(Stepper): --step-connector-gap, so a theme can stop the on-track connector short of the indicator #5495 and keeps the generated probe diff scoped to the two Stepper targets.

The spec is 218 → 245 lines (+27 net). The existing record already exceeded the soft 200-line target; shrinking it further would rewrite settled #5495 authority rather than make this amendment smaller.

Dependency

#5953 separately owns two pre-existing generated readonly selectors from #5805. After it lands, this PR needs one final main rebase and probe regeneration; its generated diff will remain Stepper-only while the standard probe check becomes clean.

Compatibility

Additive. Existing label and description spans gain stable classes and state attributes. No element, prop, export, default style, or Connector behavior changes.

Validation

  • Focused Vitest: 2 files, 471 tests passed (61 Stepper + 410 theming-target tests)
  • @astryxdesign/core typecheck and build passed
  • Storybook production build passed
  • check:knowledge, check:repo, and git diff --check passed
  • Chromium + generated probe theme passed in separated and on-track layouts: Step rgb(5, 56, 29), Label rgb(58, 3, 37), Description rgb(9, 19, 52); removing the two text target classes restored their own component colors rather than inheriting Step
  • Chromium confirmed disabled only on Label and status on both text targets
  • Full probe generation produced 274 targets / 885 selectors. The committed Stepper-only delta is +2 targets / +2 selectors; chore: synchronize readonly probe selectors #5953 carries the unrelated +2 selector drift from main

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Sep 3, 2026 1:03am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Aug 31, 2026
@github-actions github-actions Bot added community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge needs:design-review Affects visuals — Design should review labels Aug 31, 2026
github-actions Bot added a commit that referenced this pull request Aug 31, 2026
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

Modified Components

Stepper (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 1318 -
Complexity N/A Very High (139) -

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.8KB 1.2KB

Accessibility Audit

Status: 1 accessibility violation(s) found — 1 serious.

Stepper - 1 issue(s)
  • 🟠 serious: Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds
    • Rule: color-contrast · Affects 1/28 stories · Learn more
    • WCAG: 1.4.3 (Level AA)

Visual Regression

12 added · 0 removed. View the report

A repository maintainer can accept these exact frames: /accept-visual 33701835979/1 <why every changed frame is correct>

Added — After
Added — After visual regression frame

Added — After
Added — After visual regression frame

Added — After
Added — After visual regression frame


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

@github-actions github-actions Bot removed the needs:design-review Affects visuals — Design should review label Sep 1, 2026
github-actions Bot added a commit that referenced this pull request Sep 1, 2026
@freddymeta

Copy link
Copy Markdown
Contributor Author

Pushed a conformance follow-up (314a5644) after merging main. Nothing about the two targets changed — the audit says they were the right call — but the record they have to be written into was missing.

The targets are correctly component-owned. INV5 asks whether a shared primitive renders the part. Stepper imports no Text; the label and description are local spans styled by Step.tsx, so delegatesTo: component:Text would describe a composition that does not exist. (Contrast Pagination, which does render <Text> and so delegates.) inherits: step is also unavailable, which is the point of the change.

Measured in Chromium, built Storybook, astryxTheme:probe — the real compiler, the generated probe theme, both indicator positions:

tree .astryx-step-label present label colour description colour step colour
this branch yes rgb(58,3,37) rgb(9,19,52) rgb(5,56,29)
Step.tsx reverted no rgb(240,255,0) element unreachable rgb(5,56,29)

The negative control is the load-bearing row: with step themed to rgb(5,56,29) the label sits at the value it declares itself, not the inherited one. The cascade does not carry, so inherits would be a false disposition.

What the follow-up adds

  • Stepper.spec.md (draft, approved_by: null, like 35 of the 42 existing component specs) with a ### Theming anatomy block. architecture:component-theming-surface couples a target addition to that map, and the checker is bidirectional, so completing it needed anatomy rows for the stepper root, the step and the on-track connector — all three carried targets but had no row. Progress bar becomes required: false, since the on-track position renders the connector in its place.
  • Regenerated probe theme. pnpm visual:probe-theme:check was failing on this branch: the new targets were invisible to the visual gate. Worth flagging that regeneration is whole-file, so it also picks up two readonly selectors that were already stale on main (verified against a clean worktree: 272 → 273 targets there before this branch). Happy to drop those two hunks if you would rather they land separately.

Gates, all on the merged tree: core build ✅ · vitest packages/core/src packages/lab/src 316 files / 8951 tests ✅ · core typecheck ✅ · typecheck:docs ✅ · check:repo ✅ · lint:strict 0 errors ✅ · visual:probe-theme:check ✅ (274 targets, 885 selectors).

@freddymeta

Copy link
Copy Markdown
Contributor Author

pr-rtl on this PR is a coverage gap, not a failure: every dimension returns N/A for Stepper, and the audit counts unexplained all-N/A as unmeasured.

It is already closed by #5885, which adds a curated D2 target over core-stepper--default-horizontal. I verified that against this branch's head rather than assuming — main's targets.json plus #5885's Stepper entry, built and run here:

pnpm rtl:audit -- --filter Stepper
CUR  RTL-ready  core/stepper  {"D2":"pass"}
COV : 1 measured / 0 verified N-A / 0 gap / 0 stale

So the theme targets in this PR introduce no RTL regression, and I have not duplicated the target here — it would collide with #5885. This check goes green once that lands.

(pr-rtl is continue-on-error in ci.yml, so it is a scorecard rather than a blocker either way.)

@freddymeta

Copy link
Copy Markdown
Contributor Author

Closed the RTL coverage gap here rather than waiting on #5885 — that PR is still under review, so this check would stay red until it lands.

Stepper returned N/A on every dimension, which the audit counts as unmeasured. Steps run along the inline axis, so first and last must swap under RTL; a curated D2 target measures that:

pnpm rtl:audit -- --filter Stepper
CUR  RTL-ready  core/stepper  {"D2":"pass"}
COV : 1 measured / 0 verified N-A / 0 gap / 0 stale

Probe verified, not assumed: pointing prev and next at the same element gives D2 fail.

This is the same target #5885 proposes in its bulk sweep — whichever lands second should drop it. Happy to remove it here instead if you would rather it went in with that PR.

@cixzhang cixzhang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the text targets and the real consumer proof. Two things need fixing before this lands:

  • A theme author cannot write a disabled-label rule through step-label: it omits component-owned disabled. The current target contract requires that state on its owning target. Please reflect and document it, with a focused theme test.
  • Builders browsing Toast docs would get a new LogicalPlacement example that this Stepper-only PR never motivates. Please move or drop it.

It also needs a merge with main for the RTL registry conflict.

[Reviewed by Robohands]

@cixzhang cixzhang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the merged head clears the unrelated conflicts and Toast-doc issue. The label target still omits disabled, even though disabled styling is owned by the label itself. Please reflect and document disabled on step-label, with a focused theme test.

[Reviewed by Robohands]

github-actions Bot added a commit that referenced this pull request Sep 2, 2026
@freddymeta
freddymeta force-pushed the feat/stepper-text-theme-targets branch from b1a22c8 to 42bc832 Compare September 2, 2026 13:38
@freddymeta

Copy link
Copy Markdown
Contributor Author

Addressed the final disabled ask on clean head 42bc832b9.

  • step-label now reflects disabled: disabled in themeProps, beside its existing progress/status selectors.
  • step-description deliberately does not: the label owns styles.labelDisabled; the description does not change under disabled. The selector follows paint ownership rather than being copied across targets for vocabulary symmetry.
  • Both consumer-doc entries now record disabled on astryx-step-label.
  • Stepper.spec.md no longer calls this an unresolved gap. FR5, compatibility, ownership, verification, Decision DEC-1 and the remaining open question now describe the approved narrower contract.
  • The changeset says the same thing.

The focused test holds both halves:

  1. a disabled Step emits data-disabled="disabled" / .disabled on .astryx-step-label, and emits neither on .astryx-step-description;
  2. the real defineThemegenerateThemeCSS path emits .astryx-step-label.disabled for disabled:disabled.

Negative control: removed only the new disabled entry from themeProps; the focused test failed. Restored it; the test passes.

I also rewrote the PR as one commit on current main. The old public commit message and changeset included private implementation context; the final diff and commit message are now public-boundary clean rather than merely editing the PR body around them.

Full preflight on the exact pushed tree:

  • no conflicts with main (0 behind)
  • no private names/paths in diff or commit messages
  • typecheck + lint clean
  • core: 8642 tests pass
  • core + Storybook build pass
  • RTL: 1 measured / 0 N-A / 0 gap / 0 stale
  • Chromium guards pass
  • knowledge records aligned; changeset valid

The Astryx CLI now reports:

astryx-step-label | data-progress, data-status, data-disabled | progress, status, disabled
astryx-step-description | data-progress, data-status | progress, status

…lectors

A Step label and description declare their own typography and color, so a theme cannot reach them through the step target by inheritance. Add direct targets to the painted spans in both indicator positions.

Both targets reflect progress and status. The label also reflects disabled because it owns disabled text paint; the description deliberately does not.

Amend the current Stepper contract with only this text-part ownership decision while preserving the merged Connector contract and DEC-1. Focused tests cover target placement, selector state, both layouts, and the generated defineTheme selector.
@cixzhang
cixzhang force-pushed the feat/stepper-text-theme-targets branch from ba90779 to d6b7b02 Compare September 3, 2026 00:59
github-actions Bot added a commit that referenced this pull request Sep 3, 2026
@cixzhang

cixzhang commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

/approve-spec

@cixzhang cixzhang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requested disabled state, unrelated-doc cleanup, main refresh, and spec deduplication are complete at this exact head. Approved.

@github-actions github-actions Bot removed needs:code-review High-risk change (new package/component/API) — needs human code review before merge needs:spec-owner-review Current knowledge records await owner approval labels Sep 3, 2026
@cixzhang
cixzhang merged commit a5333b2 into main Sep 3, 2026
27 of 28 checks passed
@github-actions
github-actions Bot deleted the feat/stepper-text-theme-targets branch September 3, 2026 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. community Authored by a community contributor (not on the eng/design team)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants