Overview
Horizontal or vertical step indicator for multi-step wizards and onboarding flows.
Usage
Interactive steps
A step is static text by default. Give a StepItem an href or an onclick
and its body (label + description) becomes a focusable control — an <a> for
href, a <button> for onclick. The marker circle and the connector line
stay decorative, so only the body region is clickable and the marker never
joins the accessible name.
When a step has both href and onclick, it renders as a link and still runs
the callback on click — the consumer decides whether to preventDefault (for
SPA routing interception, analytics, or confirmation). For the current step,
aria-current="step" moves onto the interactive element; static steps keep it
on the list item.
Skipped steps
By default, state is derived from currentStep: earlier steps are complete,
the matching index is current, and later steps are upcoming. Set
state: 'skipped' on a StepItem when a flow advances past a step without
completing it. Skipped steps keep their numeric marker, use neutral styling,
and announce the skippedLabel text instead of the completed label.
When to use
- Walking the user through a multi-step wizard or checkout flow with strict ordering.
- Showing how far the user has advanced through a known number of stages.
- Switching between independent peer views with no order — use tabs instead.
- Showing ancestor hierarchy of the current page — use breadcrumbs instead.
Examples
Completed (terminal state)
Passing `currentStep={steps.length}` advances past the final step, marking every step complete — the terminal "done" state shown after a flow finishes.
Interactive steps
A step becomes navigable when its `StepItem` carries an `href` (renders the body as a link) or an `onclick` (renders it as a button). The marker and connector stay decorative — only the body region is the focusable, clickable target.
Skipped step
Use `state: "skipped"` when a flow advances past a step without completing it.
Vertical orientation
Set `orientation="vertical"` to stack the steps top-to-bottom with the connector running down the side — useful in narrow side panels or wizards.
Props
| Name | Type | Default | Required | Bindable | Description |
|---|---|---|---|---|---|
steps | StepItem[] | req | Ordered list of step entries from first to last. | ||
currentStep | number | req | Zero-based index of the active step. Steps with index < currentStep are
"completed". Pass steps.length to mark every step as complete (terminal
"done" state). | ||
orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout direction. Defaults to 'horizontal'. | ||
label | text | 'Progress' | Accessible name for the wrapping nav landmark. Defaults to 'Progress'. | ||
completedLabel | text | 'Completed' | Visually-hidden text prepended to completed steps so screen readers announce state + label. Defaults to 'Completed'. | ||
skippedLabel | text | 'Skipped' | Visually-hidden text prepended to skipped steps so screen readers announce state + label. Defaults to 'Skipped'. |