Stepper
A text-based stepper component for multi-step workflows. Displays numbered steps with labels, support for complete/active/default states, and optional navigation.
Basic Usage
import { SimpleStepper } from '@/components'
<SimpleStepper
steps={[
{ label: 'Account' },
{ label: 'Details' },
{ label: 'Confirm' }
]}
currentStep={1}
/>Horizontal States
Steps before the current step show as "complete" (green checkmark), the current step is "active" (blue), and future steps are "default" (gray).
Step 1 (Active)
Step 2 (Step 1 Complete)
Step 3 (Steps 1-2 Complete)
Vertical Orientation
Use orientation="vertical" for a vertical layout with optional descriptions.
<SimpleStepper
orientation="vertical"
steps={[
{ label: 'Account', description: 'Create your account' },
{ label: 'Details', description: 'Add your information' },
{ label: 'Confirm', description: 'Review and submit' },
]}
currentStep={1}
/>Vertical Step States
Each step state has distinct styling:
Complete State
Active State
Default State
- Complete: Green checkmark icon, strong text color
- Active: Blue numbered circle, medium weight label
- Default: Gray bordered circle, subdued text colors
Connector Position
In vertical mode, you can show or hide the connector line using connectorPosition. Options are "left" (default) or "none".
With Connector (default)
Without Connector
// With connector (default)
<SimpleStepper orientation="vertical" steps={steps} currentStep={1} />
// Without connector
<SimpleStepper orientation="vertical" steps={steps} currentStep={1} connectorPosition="none" />Interactive Stepper
Add onStepClick to make steps clickable for navigation.
Click on any step to navigate, or use the buttons below.
const [currentStep, setCurrentStep] = useState(0)
<SimpleStepper
steps={[
{ label: 'Account' },
{ label: 'Details' },
{ label: 'Confirm' }
]}
currentStep={currentStep}
onStepClick={setCurrentStep}
/>Many Steps
The stepper handles many steps gracefully with horizontal scrolling when needed.
Compound Component API
For maximum flexibility, use the compound component API with Stepper.Root, Stepper.Step, etc.
import { Stepper } from '@/components'
<Stepper.Root orientation="horizontal" currentStep={1}>
<Stepper.Step index={0} isLast={false}>
<Stepper.Indicator />
<Stepper.Label>Account</Stepper.Label>
<Stepper.Separator />
</Stepper.Step>
<Stepper.Step index={1} isLast={false}>
<Stepper.Indicator />
<Stepper.Label>Details</Stepper.Label>
<Stepper.Separator />
</Stepper.Step>
<Stepper.Step index={2} isLast={true}>
<Stepper.Indicator />
<Stepper.Label>Confirm</Stepper.Label>
</Stepper.Step>
</Stepper.Root>Vertical Compound
<Stepper.Root orientation="vertical" currentStep={1}>
<Stepper.Step index={0} isLast={false}>
<Stepper.Indicator />
<div className="flex flex-col gap-0.5">
<Stepper.Label>Account</Stepper.Label>
<Stepper.Description>Create your account</Stepper.Description>
</div>
<Stepper.Separator />
</Stepper.Step>
{/* ... more steps */}
</Stepper.Root>Accessibility
- Uses
<nav>element witharia-label="Progress" - Steps are rendered in an
<ol>ordered list - Active step has
aria-current="step" - Clickable steps are focusable and keyboard-accessible
- Separators are hidden from screen readers with
aria-hidden="true"
API Reference
SimpleStepper Props
| Prop | Type | Default | Description |
|---|---|---|---|
| steps | SimpleStepperStep[] | required | Array of step definitions |
| currentStep | number | required | Current active step (0-indexed) |
| orientation | "horizontal" | "vertical" | "horizontal" | Layout orientation |
| connectorPosition | "left" | "none" | "left" | Show/hide connector line (vertical only) |
| onStepClick | (index: number) => void | - | Callback when a step is clicked |
| className | string | - | Additional CSS classes |
SimpleStepperStep Type
interface SimpleStepperStep {
label: string // Step title
description?: string // Optional description (vertical only)
}Compound Components
| Component | Description |
|---|---|
Stepper.Root | Container that provides context |
Stepper.Step | Individual step wrapper |
Stepper.Indicator | Numbered circle or checkmark |
Stepper.Label | Step title text |
Stepper.Description | Step description text |
Stepper.Separator | Arrow (horizontal) or line (vertical) |
Stepper.Root Props
| Prop | Type | Default | Description |
|---|---|---|---|
| orientation | "horizontal" | "vertical" | "horizontal" | Layout orientation |
| currentStep | number | required | Current active step (0-indexed) |
| connectorPosition | "left" | "none" | "left" | Show/hide connector line (vertical only) |
| onStepClick | (index: number) => void | - | Click handler for steps |
Stepper.Step Props
| Prop | Type | Default | Description |
|---|---|---|---|
| index | number | required | Step index (0-indexed) |
| state | "complete" | "active" | "default" | auto | Override computed state |
| isLast | boolean | false | Whether this is the last step |