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
The free tier covers the two examples below (Dots and Sizes); the rest render the Pro overlay and are marked with a Pro badge.
Dots
StepperDots renders a compact progress row. Set count and defaultActiveIndex (or a controlled activeIndex), and pick a shape: circle, pill (the active dot stretches), or bar.
Sizes
size on the root scales the whole stepper. The free badge layout at sm and md: padding, type, and icon size all move together.
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.
Content and actions
Each step can carry a StepperTitle, a StepperDescription, and a StepperActions row (usually Buttons on the active step) inside StepperContent.
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.
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">.