Steps
Step trail for multi-step flows: numbered badge, connector, label. Same
anatomy in both orientations — horizontal on desktop, vertical below md
(badges stacked, connectors vertical, each label beside its badge).
When to use
| ✅ Use when… | 🚫 Avoid when… |
|---|---|
|
|
Basic
Status comes from position and flags: before currentIndex (or
isComplete) → complete; at currentIndex → current; disabled →
locked; otherwise next — actionable when it has href, to or onClick.
<Steps
currentIndex={2}
steps={[
{ title: 'Dados pessoais' },
{ title: 'Documentos' },
{ title: 'Comprovante de renda' },
{ title: 'Revisão', href: '/onboarding/review' },
]}
/>Level ladder (current + CTA + locked)
<Steps
currentIndex={0}
steps={[{ title: 'Não verificado' }, { title: 'Silver', href: '/user/verify' }, { title: 'Gold', disabled: true }]}
/>Router links
Steps with to render through linkAs (the framework Link); steps with
href are native anchors.
import { Link as RouterLink } from 'react-router-dom';
<Steps linkAs={RouterLink} currentIndex={1} steps={[{ title: 'A' }, { title: 'B' }, { title: 'C', to: '/c' }]} />;Mobile
Below md (or with layout="mobile") the trail runs vertical — the same
badges and labels, stacked, with vertical connectors and each label beside
its badge. It resolves by the slot's width via container query (ADR-025),
so a Steps embedded in a narrow column goes vertical even on a wide screen.
<Steps layout="mobile" currentIndex={1} steps={steps} />StepsBadge
The numbered circle is exported for custom layouts.
Accessibility
The trail is a <nav> named by label. The current step carries
aria-current="step", locked steps aria-disabled. The actionable step is
a real link or button — keyboard reachable, focus ring on its badge.
Properties
Prop | Type | Default | Description |
|---|---|---|---|
color | string | — | Theme token (`theme.colors`) used as `color`. Has lower precedence than
`contrast`: when both are provided, the contrast calculation wins.
Stays `string` (not the typed union): `color` is also an HTML attribute
(`<li color>`, etc.) and interfaces extending native props require
identical types on the name collision. |
containment | string | — | Containment marker for the `cq` channel: emits
`container-type` (+ `container-name` when the string form carries one,
e.g. `'inline-size card'`). Apply on the immediate wrapper of the
adapting component — NEVER on page-level shells. |
counterLabel | ((current: number, total: number) => string) | — | @deprecated No longer rendered. The mobile layout is now the vertical
trail (badge + connector + label), not a progress bar with a counter, so
there is no counter string to localize. Accepted and ignored for source
compatibility; drop it — it will be removed in the next major. |
currentIndex | number | 0 | 0-based index of the current step. |
label | string | Etapas | Accessible name of the trail (`<nav aria-label>`). |
layout | "auto" | "desktop" | "mobile" | auto | Force one orientation instead of following the `md` container size.
`mobile` is the vertical trail. |
legibility | "on-photo" | — | Reading-shadow preset for text over a photographic background
(`on-photo`). Replaces the inline `style={{ textShadow }}` in the
consumer (brasil_2030 radar, gap A3). Token emission is deferred until a
2nd consumer asks for the raw var (see backlog). |
linkAs | ElementType<any, keyof IntrinsicElements> | — | Component rendered for steps with `to` (a router `Link`). Steps with
`href` always render a native `<a>`. |
pageShell | boolean | — | Centers the element and caps the width at `theme.layout.pageMaxWidth`.
The page shell of a classic centered layout. |
readable | number | boolean | — | Makes the `color` legible against the page surface: `true` = WCAG AA
(4.5), a number sets a custom floor. Ignored with `contrast`.
See the Layout Props concept page for the full semantics. |
steps * | StepItem[] | — | Steps, in order. |
transform | string | — | CSS `transform` value (e.g. `translate(-50%, -33px)`). Never leaks
to the DOM as an attribute. |
Besides the props above, every component accepts the layout props (spacing, color, flex/grid, sizing, border) — not repeated here.
See also
- Storybook story: Components / Data Display / Steps
- Percentage only:
ProgressBar