Stepper
Compound component that tracks progress through an ordered sequence of steps, with a status per step.
Description
Stepper is a compound component that renders an ordered list (<ol>) of steps and marks each one as completed, active, error, or locked. The root hands orientation, size, and layout down through context, so the sub-parts style themselves from the step's status without per-element wiring.
Reach for it in multi-step flows where the user needs to see where they are and what is left: onboarding, checkout, account setup wizards, and long forms split into stages. It works vertically or horizontally, and ships a dots progress indicator and a status-tinted badge layout for tighter surfaces.
This component is tiered. The free tier ships the dots progress (StepperDots) and the status-badge steps (StepperBadgeItem). The signature numbered-icon layout with connector lines, per-step content, descriptions, actions, and the compact layout is Pro: run add stepper with a seat to swap in the richer overlay (same API, extra exports). If the flow only swaps a panel in place, use Tabs. For an indeterminate "working" state with no discrete steps, use Progress or Spinner. For hierarchical path navigation, use Breadcrumb.
Installation
Anatomy
Stepper provides a context (orientation, size, layout) that every sub-part reads. Each StepperItem owns a status and passes it to the icon, line, and text inside it.
The free tier composes two shorthands instead of the full item tree: StepperDots for a dot progress row, and StepperBadgeItem for status-tinted step bars (<Stepper layout="badge">).
Usage
Examples
Stepper is tiered. The free tier ships the dot progress row (StepperDots) and the status-tinted badge steps (StepperBadgeItem, under <Stepper layout="badge">). A developer seat swaps in the Pro overlay, which adds the full numbered-icon step tree; StepperItem → StepperIndicator (StepperIcon + StepperLine) + StepperContent (StepperTitle / StepperDescription / StepperActions) — plus the compact layout. The root API (orientation, size, layout) is identical across tiers, so upgrading is an import swap, not a rewrite. Pro examples below are marked with a Pro badge.
Status badges
<Stepper layout="badge"> with StepperBadgeItem is the free-tier step list: each step is a status-tinted bar with an optional leadIcon, a number, a title, and an auto status glyph (check / arrow / warning). Pass onClick to make a step navigable. This one is fully interactive click any step to jump to it.
Sizes
size on the root (sm or md) scales the whole stepper - padding, type, and icon size all move together. Set it once on Stepper; every step reads it from context.
Dots
StepperDots renders a compact progress row. Set count and defaultActiveIndex (or a controlled activeIndex), and pick a shape: circle, pill (only the active dot stretches), or bar. It is interactive by default (clickable buttons); pass interactive={false} for a read-only progress bar.
Numbered steps
The Pro overlay is a compound tree. Each StepperItem owns a status and composes an indicator column (StepperIcon) with a text column (StepperContent → StepperContentHead → StepperTitle + StepperDescription), plus an optional StepperActions row on the active step.
Interactive flow
Stepper never tracks a current index you derive each step's status from your own state. Here Continue / Back advance and rewind the flow, completed steps recolor, and a completed title jumps back to it. Drive it with a StepperTrigger (a real <button>) and StepperActions.
Statuses
Each step is completed, active, error, or locked, and the icon, connector line, and text all recolor from it. An empty StepperIcon on a completed step renders a check; on an error step it renders a warning glyph.
Horizontal
Set orientation="horizontal" on the root to lay steps left to right, with the connector line running between each StepperIcon.
Compact
StepperCompactItem (inside <Stepper layout="compact">) is a condensed step: an icon plus a short label. Use alignment (top, left, right) to place the label relative to the icon.
Step icons
StepperIcon is the step marker. variant sets the color, appearance picks the fill (soft, outline, solid), and an empty success or error icon auto-renders a check or warning glyph.
Connector lines
StepperLine is the rule between steps. variant sets the color and appearance (solid / soft) its weight; inside a StepperItem it derives both from the step status. Pass fill to animate a progress fill as the flow advances.
Accessibility
The root is an ordered list (<ol>), so steps are announced in order. The active step (and its StepperTrigger) sets aria-current="step". Interactive steps use a real StepperTrigger (<button>); static steps are not focusable.
ARIA notes:
- The root sets
aria-label="Progress"by default. Pass your ownaria-labeloraria-labelledbywhen the surrounding context already names the flow. - The active item and
StepperTriggersetaria-current="step"; completed and error icons add ansr-only"Completed" / "Error" label so state is not conveyed by color alone. StepperDotswithinteractive(the default) is arole="group"of per-dot<button>s, each with its ownaria-labelandaria-current. Withinteractive={false}it becomes arole="progressbar"and setsaria-valuemin,aria-valuemax,aria-valuenow, andaria-valuetext.StepperLineis decorative (role="presentation",aria-hidden); it carries no meaning for assistive tech.- Disabled steps skip their click handler and set
aria-disabled.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's CVA classes (via cn()):
Data slots and attributes: the component sets these for CSS targeting.
data-slot="stepper"on the root<ol>.data-slot="stepper-item"on each step.data-slot="stepper-trigger"on the interactive step button.data-slot="stepper-indicator"on the icon + line column.data-slot="stepper-icon"on the step marker.data-slot="stepper-line"on the connector, withdata-slot="stepper-line-fill"on its animated fill.data-slot="stepper-dot"on a single dot,data-slot="stepper-dots"on the dots row.data-slot="stepper-content",data-slot="stepper-content-head",data-slot="stepper-heading"on the text column wrappers.data-slot="stepper-title",data-slot="stepper-description",data-slot="stepper-actions"on the text and actions.data-status="active" | "completed" | "error" | "locked",data-orientation,data-size, anddata-layouton the root, items, and text.data-variant,data-appearance,data-shape,data-active,data-highlighted, anddata-disabledon the icon, dot, and line.
Target a step's status in CSS:
Related Components
- Tabs: use this when each option swaps a content panel within the same surface, not a linear flow.
- Progress: use this for a single indeterminate or percentage bar with no discrete steps.
- Breadcrumb: use this for hierarchical path navigation rather than sequential progress.
- Pagination: use this for moving through pages of content.
API Reference
Stepper
Root ordered list that owns the orientation / size / layout context. Extends React.ComponentProps<"ol">, so standard list attributes (id, aria-label, aria-labelledby, etc.) are accepted.
Props
StepperItem
One step in the full (Pro) layout. Extends React.ComponentProps<"li"> and provides the per-step status context.
Props
StepperTrigger
Interactive step target. Extends React.ComponentProps<"button">; renders a <button> by default, or any element via asChild (Radix Slot).
Props
StepperIndicator
Column that holds the step's icon and its trailing connector line. Extends React.ComponentProps<"div">.
Props
StepperIcon
Step marker rendered as a <span>. Extends React.ComponentProps<"span">. An empty success or error icon auto-renders a check or warning glyph.
Props
StepperDot
A single dot. Extends React.ComponentProps<"span">. Used by StepperDots, or on its own.
Props
StepperDots
Dot progress row. Extends React.ComponentProps<"div">. Interactive by default (each dot is a button); pass interactive={false} for a read-only progress bar.
Props
StepperLine
Connector line between steps, rendered as a decorative <span> (role="presentation"). Extends React.ComponentProps<"span">. Pass fill to animate a progress fill.
Props
StepperContent
Text column beside the indicator. Extends React.ComponentProps<"div">. Takes className and children (a StepperContentHead and optional StepperActions).
StepperContentHead
Wrapper for the title and description. Extends React.ComponentProps<"div">. Takes className and children.
StepperHeading
Row that lays out a title next to trailing content (e.g. a badge). Extends React.ComponentProps<"div">. Takes className and children.
StepperTitle
Step title rendered as a <span>. Extends React.ComponentProps<"span">.
Props
StepperDescription
Secondary line under the title, rendered as a <p>. Extends React.ComponentProps<"p">.
Props
StepperActions
Row for step buttons. Extends React.ComponentProps<"div">. Takes className and children (usually Buttons).
StepperCompactItem
Condensed step (icon + label) for the compact layout. Extends Omit<React.ComponentProps<"li">, "onClick">.
Props
StepperBadgeItem
Status-tinted step bar (free layout). Extends Omit<React.ComponentProps<"li">, "onClick">.