Stepper
A progress indicator for sequential flows: onboarding, checkout and multi-step dialogs. Each step derives its state from a single active value, and the connecting line fills as you advance.
Installation#
Usage#
"use client"
import * as React from "react"
import {
Stepper,
StepperItem,
StepperTrigger,
StepperIndicator,
StepperTitle,
StepperSeparator,
} from "@/components/ui/stepper"
export function Example() {
const [step, setStep] = React.useState(1)
return (
<Stepper value={step} onValueChange={setStep}>
<StepperItem step={1}>
<StepperTrigger>
<StepperIndicator />
<StepperTitle>Account</StepperTitle>
</StepperTrigger>
<StepperSeparator />
</StepperItem>
<StepperItem step={2}>
<StepperTrigger>
<StepperIndicator />
<StepperTitle>Confirm</StepperTitle>
</StepperTrigger>
</StepperItem>
</Stepper>
)
}Orientation#
Orientation is set on the root. horizontal lays steps in a row with a flexible connector; vertical stacks them with the connector running down the indicator column.
With descriptions#
Pair each StepperTitle with a StepperDescription in a vertical stack. Vertical orientation gives the supporting copy room to breathe.
Density#
Density retunes the indicator size, connector geometry, and text, without touching color or radius. comfortable suits onboarding; compact fits dense app UI and dialogs.
Loading & disabled#
Set loading on the active step to swap its number for a spinner while it validates or submits. Mark unreachable steps disabled to block selection and mute them.
In a dialog#
The headline use case. Reach for DialogStepper (from @/components/ui/dialog). It places the stepper full-bleed with a divider beneath and inherits the dialog's density. Drive its value from the dialog's own step state and swap the body per step; future steps are disabled so the user can't skip ahead.