Skip to main content

Stepper

Accessible multi-step progress indicator covering: horizontal + vertical, multi-step wizards, linear mode, error steps, click to navigate, keyboard support.

Live Preview

Change orientation, size, and current step to see the Stepper adapt in real time.

  1. Profile
    Tell us about you
  2. Review
    Confirm and submit
1
tsx
1<Stepper2  steps={[3    { label: 'Account', description: 'Basic details' },4    { label: 'Profile', description: 'Tell us about you' },5    { label: 'Preferences', description: 'Configure settings' },6    { label: 'Review', description: 'Confirm and submit' },7  ]}8  current={1}9  orientation="horizontal"10  size="md"11  linear={true}12  onChange={(i) => setCurrent(i)}13/>

Installation

Install the Aidash Components package using your preferred package manager.

$ pnpm add @aidash/components

Import

Import the Stepper component into your file.

tsx
import { Stepper } from '@/components/aidash/stepper';

Basic Usage

A three-step horizontal stepper showing pending, current, and completed states.

  1. Cart
  2. Shipping
  3. Payment
tsx
1<Stepper2  steps={[3    { label: 'Cart' },4    { label: 'Shipping' },5    { label: 'Payment' },6  ]}7  current={1}8/>

Vertical Orientation

Set orientation='vertical' for a stacked column layout that fits sidebars and long-form wizards.

  1. Cart
  2. Shipping
  3. Payment
tsx
1<Stepper2  steps={[3    { label: 'Cart' },4    { label: 'Shipping' },5    { label: 'Payment' },6  ]}7  current={1}8  orientation="vertical"9/>

With Descriptions

Each step can include a short supporting `description` shown under the label.

  1. Account
    Basic details
  2. Profile
    Tell us about you
  3. Review
    Confirm and submit
tsx
1<Stepper2  steps={[3    { label: 'Account', description: 'Basic details' },4    { label: 'Profile', description: 'Tell us about you' },5    { label: 'Review', description: 'Confirm and submit' },6  ]}7  current={1}8/>

Custom Icons

Pass a hugeicons icon per step. Icons render inside pending / current nodes; completed and error states always show their status icon.

  1. Account
  2. Preferences
  3. Done
tsx
1import { UserIcon, Settings01Icon, CheckmarkCircle02Icon } from '@hugeicons/core-free-icons';2 3<Stepper4  steps={[5    { label: 'Account', icon: UserIcon },6    { label: 'Preferences', icon: Settings01Icon },7    { label: 'Done', icon: CheckmarkCircle02Icon },8  ]}9  current={1}10/>

Error State

Force any step into an error state by setting `status: 'error'`. The step turns red and shows an alert icon.

  1. Upload
  2. Verify
  3. Publish
tsx
1<Stepper2  steps={[3    { label: 'Upload' },4    { label: 'Verify', status: 'error' },5    { label: 'Publish' },6  ]}7  current={1}8/>

Sizes

Three sizes to match different layout densities.

  1. One
  2. Two
  3. Three
  1. One
  2. Two
  3. Three
  1. One
  2. Two
  3. Three
tsx
1<Stepper steps={steps} current={1} size="sm" />2<Stepper steps={steps} current={1} size="md" />3<Stepper steps={steps} current={1} size="lg" />

Interactive

Combine `onChange` with Back / Next buttons to power a full wizard. Completed steps can be clicked directly to jump back.

  1. Sign up
  2. Choose plan
  3. Finish
Step 1 of 4
tsx
1const [current, setCurrent] = useState(0);2 3<Stepper4  steps={[5    { label: 'Sign up' },6    { label: 'Verify email' },7    { label: 'Choose plan' },8    { label: 'Finish' },9  ]}10  current={current}11  onChange={setCurrent}12/>13 14<button onClick={() => setCurrent((c) => Math.max(0, c - 1))}>Back</button>15<button onClick={() => setCurrent((c) => c + 1)}>Next</button>

Accessibility

Built-in ARIA semantics and keyboard support for screen-reader and keyboard-only users.

role="list" + aria-current

The outer element uses role="list" and the active step gets aria-current="step" so assistive tech announces progress correctly.

Keyboard Navigation

Tab focuses each navigable step in order. Enter or Space activates the focused step and fires onChange.

Disabled non-navigable steps

Steps that cannot be reached (linear mode past current + 1, or the current step itself) render as plain elements without a button, so they are skipped from the tab order.

Reduced motion

Connector animations are driven by Framer Motion and respect prefers-reduced-motion — the completed portion snaps to its final size instead of animating.

tsx
1<Stepper2  steps={steps}3  current={current}4  onChange={setCurrent}5/>6/* Renders:7   <ol role="list">8     <li aria-current="step">9       <button>...</button>10     </li>11   </ol> */

API Reference

Complete list of props for the Stepper component.

StepperProps
PropTypeDefaultDescription
stepsStepperStep[]Array of steps to render. Each step has a label plus optional description, icon, and status override.
currentnumberZero-based index of the active step.
onChange(index: number) => voidCalled when the user activates a navigable step. When omitted the stepper is display-only.
orientation'horizontal' | 'vertical''horizontal'Layout direction.
size'sm' | 'md' | 'lg''md'Size of the step node circles and typography.
linearbooleantrueWhen true, users cannot jump past `current + 1`. Set false to allow free navigation.
allowClickCompletedbooleantrueWhen true, completed steps remain clickable so users can go back.
numberedbooleantrueWhen true, shows 1..N inside step nodes that have no custom icon.
classNamestring''Additional CSS classes for the outer list element.
Note
By default the Stepper runs in linear mode: users can only click completed steps or the immediate next step. Set linear={false} for free navigation to any step in the flow.

Other components that work well alongside Stepper.