VisorVisor
ComponentsNavigation

Stepper

A multi-step progress indicator with horizontal and vertical orientations. Auto-derives step status from activeStep with accessible ARIA roles — copy it into your project and own it completely.

Horizontal (Default)

Account
Profile
Review

With Descriptions

Account

Create your account

Profile

Set up your profile

Review

Confirm details

Vertical

Account
Profile
Review

Prominent Variant

The prominent variant turns the Stepper into a primary-navigation surface: the active row gets a primary-soft tint, the active bullet renders a concentric halo plus a filled pulse dot (replacing the step number), and complete-to-next rails render in a primary-line tint. Use it vertically — it's designed for derivation spines and side-column step navigation.

Start

name · public

Essence

working on it now

Personality

brand-as-person

Locked Step

Account
Profile
Review

All Steps Complete

Account
Profile
Review

Installation

npx visor add stepper

This copies two files into your project:

  • components/ui/stepper/stepper.tsx — the component
  • components/ui/stepper/stepper.module.css — the styles

Usage

import {
  Stepper,
  StepperItem,
  StepperTrigger,
  StepperTitle,
  StepperSeparator,
} from '@/components/ui/stepper/stepper';

export default function Example() {
  return (
    <Stepper activeStep={1}>
      <StepperItem step={0}>
        <StepperTrigger step={0} />
        <StepperTitle>Account</StepperTitle>
      </StepperItem>
      <StepperSeparator complete />
      <StepperItem step={1}>
        <StepperTrigger step={1} />
        <StepperTitle>Profile</StepperTitle>
      </StepperItem>
      <StepperSeparator />
      <StepperItem step={2}>
        <StepperTrigger step={2} />
        <StepperTitle>Review</StepperTitle>
      </StepperItem>
    </Stepper>
  );
}

Choosing a Variant

SituationVariant
Multi-step form, checkout, onboarding wizarddefault
Vertical derivation spine, primary side-column navigationprominent
Stepper is a supporting element on a pagedefault
Stepper is the primary surface of a pageprominent

The prominent variant uses --interactive-primary-soft for the active-row tint and concentric halo, --interactive-primary-bg for the bullet border, pulse dot, and check fill, and a color-mix tint of --interactive-primary-bg at 34% for the complete-to-next rail. All values resolve against the active theme — monochromatic themes (e.g., Blackout) stay restrained while colorful ones get the full pop.

API Reference

StepperProps

PropTypeDefaultDescription
activeStepnumber0Zero-based index of the currently active step. All steps before this index are considered complete.
orientation'horizontal' | 'vertical''horizontal'Layout direction of the stepper. "vertical" stacks steps top-to-bottom.
variant'default' | 'prominent''default'Visual treatment. "default" is the standard step indicator for multi-step forms. "prominent" adds a primary-soft active-row tint, a concentric halo, a filled pulse dot in the active bullet, and a primary-tinted complete rail — use it vertically as a primary derivation spine or navigation surface.
step*numberZero-based step index passed to StepperItem and StepperTrigger. Used to auto-derive status.
status'complete' | 'active' | 'upcoming' | 'locked'Explicit status override for StepperItem or StepperTrigger. Auto-derived from activeStep if omitted; "locked" is never auto-derived and must be set explicitly.
completebooleanfalseWhether the StepperSeparator line renders in its completed style.
classNamestringAdditional CSS class names to merge onto the element.

Sub-components

ComponentElementPurpose
Stepper<div>Root container with context provider
StepperItem<div>Step wrapper, auto-derives status from activeStep
StepperTrigger<button>Clickable step indicator circle
StepperTitle<div>Step label
StepperDescription<p>Step description
StepperSeparator<div>Connecting line between steps

Accessibility

  • Stepper renders with role="group" and aria-label="Progress" to group the steps as a meaningful unit.
  • StepperItem sets aria-current="step" on the currently active step.
  • StepperTrigger is a <button> element and includes a visually hidden label ("Completed", "Step N", or "Step N, locked") for screen readers.
  • The check icon in completed triggers and the lock icon in locked triggers both have aria-hidden="true" since the status is communicated via the button's text content.
  • Step status (complete, active, upcoming, locked) is also exposed as a data-status attribute for custom CSS targeting.
  • Locked triggers set aria-disabled="true" and tabIndex={-1} — they are non-interactive and removed from the tab order. The onClick handler is suppressed regardless of what is passed.
  • When steps are clickable (navigating back), ensure StepperTrigger has a meaningful onClick handler. For read-only steppers, pass disabled or tabIndex={-1} to prevent interaction.