Stepper
The linear progress header of a multi-step flow: numbered pills joined by 40x2 dividers, one label per step. Built for the connection setup wizard (Set up credentials → Set up accounts) and any other sequence where the merchant needs to know where they are and what is left. Four step states and three orientations, all straight from the Figma. Purely display — it reports progress, it does not navigate.
Anatomy
A flex row of steps separated by dividers. Each step pairs an indicator (the BadgeNumber atom, or a filled CheckCircle once complete) with its label. The current step is the only one in bold, so the eye lands on it first.
- Set up credentials
- 2Set up costs
- 3Set up accounts
- 1Container
flex items-center justify-center gap-2 (or flex-col gap-4 in the mobile orientation).
- 2Indicator
BadgeNumber (h-5 min-w-5 rounded-full px-1 text-xs) carrying the step number. Swapped for a size-5 filled CheckCircle in primary once the step is complete.
- 3Label
text-sm. Bold with leading-none on the current step, regular everywhere else. Muted at 60% opacity when disabled.
- 4Divider
h-0.5 w-10 between consecutive steps. Turns bg-primary once the step behind it is complete, so the filled run of line shows the ground already covered; bg-border otherwise. Absent in the mobile orientation.
Step states
Where the merchant is right now. Primary BadgeNumber plus the only bold label in the row — the single strongest signal in the component.
- 1Set up credentials
- 2Set up accounts
<Stepper steps={["Set up credentials", "Set up accounts"]} current={0} />Already done. The badge is replaced by a filled CheckCircle in primary — the number is no longer useful once the step is behind you. Label stays regular.
- Set up credentials
- 2Set up accounts
<Stepper steps={["Set up credentials", "Set up accounts"]} current={1} />Ahead of the current step and reachable. Secondary BadgeNumber, regular label at full contrast. This is the default for everything after the current step.
- 1Set up credentials
- 2Set up costs
- 3Set up accounts
<Stepper steps={["Set up credentials", "Set up costs", "Set up accounts"]} current={0} />Not reachable yet (a step gated by an earlier choice). Secondary BadgeNumber with the number and label muted at 60% opacity. Pin it with status on the step object — it is never derived from current.
- 1Set up credentials
- 2Set up costs
- 3Set up accounts
<Stepper
steps={[
"Set up credentials",
{ label: "Set up costs", status: "disabled" },
"Set up accounts",
]}
current={0}
/>Orientations
Careful with the names: they come from the Figma and they describe how each STEP lays out, not the direction the stepper runs. Only mobile actually stacks the flow.
Steps in a row, each badge beside its label. What the setup wizard uses.
- Set up credentials
- 2Set up costs
- 3Set up accounts
<Stepper steps={steps} current={1} />Steps still run left to right, but each badge sits above its label, centered. Useful when labels are long and you want a narrower row.
- Set up credentials
- 2Set up costs
- 3Set up accounts
<Stepper steps={steps} current={1} orientation="vertical" />Steps stacked in a column with gap-4 and no dividers. For narrow viewports where a row would wrap.
- Set up credentials
- 2Set up costs
- 3Set up accounts
<Stepper steps={steps} current={1} orientation="mobile" />Import
Copy this import line at the top of the file where you compose this atom.
import { Stepper } from "@/components/ui/stepper";Props
Everything else from the underlying HTML or Radix primitive is forwarded via ...props.
Stepper
| Prop | Type | Default | Description |
|---|---|---|---|
| steps | (string | StepperStep)[] (required) | — | Steps in order. Pass plain labels for the common case, or objects when a step needs a pinned status. |
| current | number | 0 | Zero-based index of the current step. Everything before it reads as complete, everything after as active. |
| orientation | "horizontal" | "vertical" | "mobile" | "horizontal" | How each step lays out. These are the Figma's names — only mobile stacks the flow into a column. |
| className | string | — | Extra classes on the <ol> container. |
StepperStep
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string (required) | — | Step name shown next to (or under) the indicator. |
| status | "complete" | "current" | "active" | "disabled" | — | Overrides the status derived from current. Required to mark a step disabled — that state is never derived. |
Related
Cross-links to atoms and patterns you may reach for next.
- BadgeShips BadgeNumber, the pill the Stepper uses as its indicator. Same h-5 / rounded-full / text-xs anatomy.
- SeparatorThe general-purpose divider. The Stepper draws its own 40x2 connector instead, so it can sit inline between steps.
- ProgressUse this instead when progress is continuous (a percentage) rather than a set of named steps.