Steps React component for Tailwind CSS v4
v1.0.0Added in 1.0.0
A React stepper for checkouts, onboarding and KYC: circles, bars or dots, with complete, error and loading states and a phone header.
Move forward and the connectors fill one after another on a smooth spring, the new current marker pops and the check draws itself in. Click a completed step to go back to it (or any step with clickable="all"). With the keyboard, Tab reaches each clickable step, Left / Right (Up / Down when vertical) move between them and Home / End jump to the first and last. Below 640px a horizontal stepper turns into a compact header: "Step 2 of 4", the step title, what comes next and a progress bar. Dots variant: tap or click a dot to jump (with clickable steps). Clickable markers and dots get a 44px hit area on touch.
Steps is a Pro React component in the React navigation components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add steps, together with Spinner, useControllableState, Motion presets, Navigation, Tones and 1 more and the npm package motion.
Add to a project
Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup
npx wingo-ui@latest add stepsSteps is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans
Usage
Import Steps from @/components/ui/steps.
import { useState } from "react"
import { Steps, type StepItem } from "@/components/ui/steps"
const STEPS: StepItem[] = [
{ id: "cart", title: "Cart", description: "3 items" },
{ id: "shipping", title: "Shipping", description: "FedEx" },
{ id: "payment", title: "Payment" },
{ id: "review", title: "Review" },
]
export function CheckoutSteps() {
const [step, setStep] = useState("shipping")
return (
<Steps
steps={STEPS}
value={step}
onValueChange={setStep}
/>
)
}Props
steps*StepItem[]{ id: string; title: ReactNode; description?: ReactNode; icon?: ReactNode; status?: StepStatus; optional?: boolean; disabled?: boolean; href?: string }. status overrides the derived one (complete before value, current at it, upcoming after); errors and loading are always explicit.
valuestringThe current step id, controlled. An id that is not among the steps leaves every step upcoming.
defaultValuedefault""stringThe starting step id while uncontrolled. Empty starts on the first step; an id that is not among the steps leaves them all upcoming. The playground takes cart, shipping, payment or review.
onValueChange(id: string, step: StepItem) => voidFires when a clickable step is clicked.
orientationdefault"horizontal""horizontal" | "vertical"Vertical stacks the steps with their descriptions beside a column of markers; it works at any width.
variantdefault"circles""circles" | "bars" | "dots"circles: numbered markers joined by connectors (the form-wizard look). bars: one segment per step with the title under it (checkout). dots: small dots, the current one widened (onboarding).
sizedefault"md""sm" | "md" | "lg"Markers 24 / 28 / 32px, titles 13 / 14 / 15px, descriptions 12 / 13 / 13px.
tonedefault"neutral""neutral" | "brand" | "success" | "warning" | "danger" | "info"Paints the current marker, the tint of completed markers and the connector fill.
colordefault""stringAny CSS color. Replaces the tone; text on the current marker turns black or white by lightness.
labelPlacementdefault"bottom""bottom" | "end"Horizontal circles: titles centered under the markers (clamped to two lines), or beside them with the connector after the text.
clickabledefault"completed""none" | "completed" | "all"Which steps are buttons: none, the ones already done (plus the current one and ones marked with an error), or every enabled step. Disabled steps never are.
connectordefault"solid""solid" | "dashed"dashed draws the connectors (and bar segments) still ahead as dashes.
mobileVariantdefault"compact""compact" | "same"Below 640px a horizontal circles or bars stepper becomes the compact header ("Step 2 of 5", title, next step, progress bar). Pure CSS: both are rendered, so the server HTML is right on a phone.
compactdefaultfalsebooleanAlways shows the compact header, at every width: phone screen headers, narrow cards, sheets. Horizontal circles and bars only (vertical and dots keep their layout).
showDescriptiondefaulttruebooleanDescriptions under the titles. Vertical steppers always show them.
linkComponent(props: LinkComponentProps) => ReactNodeThe link component for href steps (a router Link, or "a"). Default: the one set by LinkProvider, a plain <a> without one.
labels{ progress?: string; step?: (position: number, count: number) => string; next?: (title: ReactNode) => ReactNode; complete?: string; current?: string; error?: string; loading?: string; optional?: string }Text for screen readers and the compact header. Defaults: "Progress", "Step 2 of 5", "Next: …", "Completed", "Current step", "Needs attention", "In progress", "Optional".
classNamesPartial<Record<"list" | "item" | "trigger" | "marker" | "title" | "description" | "connector" | "compact", string>>Extra classes for the inner parts.
classNamestringExtra classes for the root, merged last.
Parts
StepItem
typeOne step: id, title, description, icon (replaces the number), status (overrides the derived one; error and loading are always set here), optional, disabled and href (renders the step as a link).
StepStatus
type"complete" | "current" | "upcoming" | "error" | "loading".
Examples
Vertical with descriptions
Icons stand in for the numbers; an optional step says so.
Loading and error
The identity check spins for 1.4s, then fails. Retry and it passes.
Bars
One segment per step, every step clickable. The checkout look.
Dots
For onboarding carousels: the current dot widens on a spring.
Linked steps
Steps with href render as links through the app's router, with aria-current="step".
Sizes and tones
sm neutral, md brand, lg success with dashed connectors ahead.
Phone header
compact: "Step 2 of 4", the title, what comes next and a bar.
Files
- components/ui/steps.tsx
FAQ
Is the React Steps component free?
The preview, props and docs are free; copying the source needs a Pro plan. See plans.
How do I install Steps?
Run npx wingo-ui@latest add steps. It also adds the Wingo UI items it builds on (Spinner, useControllableState, Motion presets, Navigation, Tones and 1 more) and the npm package motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/steps.
See also
Used in
More React navigation components
Articles using this component
- React Multi Step Form with Zod, Saved Drafts and Motion
Component guides12 min read
- React Stepper Component: States, Variants and Phones
Component guides8 min read