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 with aria-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

PropTypeDefaultDescription
stepsSimpleStepperStep[]requiredArray of step definitions
currentStepnumberrequiredCurrent 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
classNamestring-Additional CSS classes

SimpleStepperStep Type

interface SimpleStepperStep {
  label: string        // Step title
  description?: string // Optional description (vertical only)
}

Compound Components

ComponentDescription
Stepper.RootContainer that provides context
Stepper.StepIndividual step wrapper
Stepper.IndicatorNumbered circle or checkmark
Stepper.LabelStep title text
Stepper.DescriptionStep description text
Stepper.SeparatorArrow (horizontal) or line (vertical)

Stepper.Root Props

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Layout orientation
currentStepnumberrequiredCurrent 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

PropTypeDefaultDescription
indexnumberrequiredStep index (0-indexed)
state"complete" | "active" | "default"autoOverride computed state
isLastbooleanfalseWhether this is the last step