Skip to content

Navigation Menu

Sign in
Sign up

fix(Stepper): define the public context boundary and deprecate useStepperContext - #6074

Open
Alif416 wants to merge 3 commits into
facebook:main from
Alif416:fix/stepper-context-public-surface
Open

fix(Stepper): define the public context boundary and deprecate useStepperContext #6074
Alif416 wants to merge 3 commits into
facebook:main from
Alif416:fix/stepper-context-public-surface

Conversation

@Alif416

@Alif416 Alif416 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Decision

useStepperContext and StepperContextValue are not a supported extension point. Three things settled it:

  1. The hook returns nothing the caller lacks. A Stepper builds its context entirely from props the caller passed it — activeStep, orientation, density, indicatorPosition, onStepClick. The only fields genuinely new to it were previousActiveStep and registerStep, which are exactly the private coordination.
  2. Custom step composition cannot work through it. The connector fill is choreographed inside Step, so a hand-rolled step reading the context still cannot draw a correct track. The export advertised a capability it could not fulfill.
  3. No consumers. Nothing in Storybook, the CLI showcase blocks, docs, or tests calls it. The StepperCustomContent block already threads active from its own state — the idiomatic pattern.

Custom composition is supported through <Step> and its children, indicator, and endContent slots.

Approach

Follows the doctrine already stated in Typeahead/busyIndicatorLane.tsx: an @internal tag is a note to a reader, not a boundary. The seam is closed by module boundary instead.

  • StepperContext.ts splits the shape. Public StepperContextValue keeps the six safe reads; StepperCoordination extends it with previousActiveStep and registerStep. One object on the wire — the split governs which declaration a consumer can reach, not a second allocation per render.
  • StepperCoordination and useStepperCoordination are never re-exported from the barrel.
  • useStepperContext and StepperContextValue stay exported and @deprecated, so removal lands at an explicit major rather than in a patch.

Acceptance criteria

Criterion Where
Intended public use case is explicit @deprecated blocks in StepperContext.ts + the rationale block in index.ts
Private coordination off the required public interface StepperCoordination split, internal to the module
Compatibility/type test protects the surface Stepper.public.test.ts
Consumer docs match the decision Stepper.doc.mjs — all three locale blocks (full, --dense, --zh)

Testing

Stepper.public.test.ts follows the existing *.public.test.ts precedent: expectTypeOf locks the private fields off both the public type and the hook's return, asserts the deprecated names are still exported, and asserts the barrel's code never references the internal names.

The guard was verified to bite, not assumed: re-widening StepperContextValue with registerStep made exactly the two matching assertions fail typecheck, while the previousActiveStep ones correctly stayed silent.

One caveat documented in the file header — these assertions are enforced by pnpm -F @astryxdesign/core typecheck, not by the test run, and a failure surfaces as the cryptic TS2554: Expected 2 arguments, but got 1.

  • pnpm -F @astryxdesign/core typecheck — clean
  • Core suite — 9009 tests / 308 files passing
  • pnpm check:repo — green
  • astryx component Stepper --dense renders the new guidance

Notes for review

No runtime behavior changes — this is a type-surface and documentation change. The one non-type edit is Stepper.tsx annotating its provider value with the wider type, and Step.tsx switching to useStepperCoordination.

It should fixes #6060

alif416 added 2 commits September 5, 2026 14:38
`@astryxdesign/core/Stepper` exported `useStepperContext` and the full
`StepperContextValue`, which named Stepper's own coordination —
`previousActiveStep` (connector-fill choreography) and `registerStep`
(dev-mode duplicate-index registry). Both are described in-source as
internal, and `Step` is their only consumer in the repo, but exporting
them put them in the installable type surface: changing how the fill is
choreographed could land as a consumer type break.
Records the decision: the hook is NOT a supported extension point.
A Stepper builds its context entirely from the props the caller passed
it, so the hook returns nothing the call site already lacks — the
custom-content showcase block already threads `active` from its own
state rather than reading it back. Custom step composition is not
supported through it either: the fill is choreographed inside `Step`, so
a hand-rolled step reading the context still cannot draw a correct
connector track. `<Step>`'s `children`, `indicator`, and `endContent`
slots are the composition surface.
- Split the context into the deprecated public `StepperContextValue` and
 a wider `StepperCoordination` that carries the private fields. One
 object on the wire; the split is about which declaration a consumer
 can reach.
- `StepperCoordination` and `useStepperCoordination` are not re-exported
 from the barrel, closing the seam by module boundary rather than by an
 `@internal` tag — the same reasoning as Typeahead's `BusyIndicatorLane`.
- `useStepperContext` and `StepperContextValue` stay exported, so the
 removal lands at an explicit compatibility boundary rather than in a
 patch.
- Adds `Stepper.public.test.ts`, following the `*.public.test.ts`
 precedent: `expectTypeOf` locks the private fields off the public type
 and off the hook's return, asserts the deprecated names are still
 exported, and asserts the barrel's code never references the internal
 ones. Verified to bite by re-widening the type and watching exactly the
 matching lines fail typecheck.
- Consumer guidance in all three Stepper.doc.mjs locale blocks.

vercel Bot commented Sep 5, 2026
edited
Loading

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 5, 2026 9:21am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Sep 5, 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 labels Sep 5, 2026

github-actions Bot commented Sep 5, 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 1615 -
Complexity N/A Very High (191) -

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/30 stories · Learn more
    • WCAG: 1.4.3 (Level AA)

Visual Regression

Status: No visual change across 2 compared shot(s).


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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cixzhang cixzhang Awaiting requested review from cixzhang cixzhang is a code owner
@imdreamrunner imdreamrunner Awaiting requested review from imdreamrunner imdreamrunner is a code owner
@josephfarina josephfarina Awaiting requested review from josephfarina josephfarina is a code owner

Assignees

No one assigned

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) needs:code-review High-risk change (new package/component/API) — needs human code review before merge

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Stepper: define the public boundary for context exports

1 participant

AltStyle によって変換されたページ (->オリジナル) /