Skip to content
WANCRAFT

D.135Navigation & Menus

Step Indicator

A horizontal or vertical wizard stepper whose connectors fill as you advance, with clickable completed steps and a narrow-width summary.

NewReactCSSTailwindintermediate

Overview

Step Indicator shows where someone is in a multi-step flow. Steps carry a title, an optional description and a status that is derived from the current index (complete, current, upcoming) or set explicitly (error), and any step can be marked optional. Connectors fill with the accent as you move forward and drain as you move back, one after another, while completed markers draw their check mark in. Pass onStepClick to let people jump back to finished steps; linear mode keeps future steps locked, and non-linear mode opens them all. Laid out as an ordered list inside a navigation landmark, it marks the current step with aria-current="step" and spells out each status for screen readers, and in narrow containers the horizontal list collapses to a compact "Step 2 of 5 · Title" summary through container queries.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/step-indicator.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/step-indicator.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/step-indicator.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { StepIndicator, type StepIndicatorStep } from "@/components/ui/step-indicator";
import { useState } from "react";

export function StepIndicatorExample() {
  const steps: StepIndicatorStep[] = [
    { title: "Account", description: "Name and email" },
    { title: "Workspace", description: "Team and region" },
    { title: "Integrations", optional: true },
    { title: "Review" },
  ];
  const [current, setCurrent] = useState(1);

  return (
    <div className="w-full max-w-2xl">
      <StepIndicator steps={steps} current={current} onStepClick={setCurrent} />
    </div>
  );
}

03Props

PropTypeDefaultDescription
stepsStepIndicatorStep[]—Required. { id?, title, description?, status?, optional? }; status overrides the derived one (e.g. "error").
currentnumber—Required. Zero-based index of the current step; earlier steps are complete.
orientation"horizontal" | "vertical""horizontal"Row or column layout.
onStepClick(index: number) => void—Makes steps buttons. Without it the indicator is display only.
linearbooleantrueOnly completed steps and the current one are clickable; false makes every step clickable.
showDescriptionsbooleantrueRender step descriptions.
fillDurationnumber450Connector fill time in ms; several connectors fill in sequence.
collapseBelow"none" | "24rem" | "32rem" | "42rem""32rem"Horizontal only: container width below which the list collapses to a summary.
accentstring"#FF7448"Fill, current ring and focus colour.
labelstring"Progress"Accessible name of the <nav> landmark.
...propsHTMLAttributes<HTMLElement>—Forwarded to the <nav> root.

04Features

  • 01Horizontal and vertical layouts from one ordered list
  • 02Statuses: complete, current, upcoming and error, plus optional steps
  • 03Connectors fill forward and drain backward one after another; checks draw in
  • 04Clickable completed steps through onStepClick, with a linear or free mode
  • 05Container-query collapse to "Step 2 of 5 · Title" with a segmented progress bar
  • 06No dependencies: CSS transitions only
motion · tweeninput · clickinput · keyboard

05Accessibility

  • A <nav> landmark ("Progress") wraps an <ol>, so position and count come from list semantics.
  • The current step has aria-current="step"; each step ends with screen-reader text for its status (Completed, Current step, Not started, Needs attention) and "optional".
  • Clickable steps are real <button> elements with visible focus rings; locked steps are plain text, not disabled buttons.
  • Markers, connectors and the collapsed progress bar are aria-hidden; status is never conveyed by colour alone (check mark, exclamation mark, ring).
  • prefers-reduced-motion sets the fill and check animations to instant.

06Limitations

  • Collapse breakpoints are a fixed set of container widths so Tailwind can generate the classes.
  • Long titles wrap under their marker; keep horizontal titles short or use the vertical layout.