Stepper
A standalone multi-step progress stepper indicator with checkmark drawing, connector fill, and an active pulse.
Shows the progress of a multi-step flow with dots and connectors: completed steps show a checkmark, connectors fill smoothly, and the active step carries a pulsing indicator. Both horizontal and vertical arrangements are supported.
Bring this into your project
Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.
npx webberui@latest add stepper.enStepper is a React stepper (step progress indicator) component built with Motion (motion/react) and Tailwind CSS, with horizontal and vertical layouts. Completed steps show a check mark, connectors fill as you progress, and the current step has a pulsing ring. It only displays progress; which step is current comes from the current value you pass.
Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<Stepper/>
The complete example includes the preview layout and data. Install the component first, then paste this file into your project.
When to use
- The top of a checkout page showing cart, details, payment and confirmation
- Order or shipment tracking pages, listing each stage vertically
- Account activation or KYC flows that take several days to complete
- Deployment or review pipeline progress in an admin dashboard
- Not a good fit: when step content needs to swap inside one container with back and next buttons, use Multi-step Form
Installation
npx webberui@latest add https://webberui.com/r/stepper.en.jsonOr, once registries are configured in components.json, install it as @webberui/stepper.
Usage
import { Stepper } from "@/components/ui/stepper";
const steps = [
{ title: "Account", description: "Create your sign-in details" },
{ title: "Profile", description: "Fill in your basic information" },
{ title: "Done", description: "Review and submit" },
];
<Stepper steps={steps} current={1} />;current is a 0-based index: steps below it count as completed, the one equal to it is active, and those above it are incomplete.
Examples
Vertical order progress
orientation="vertical" puts labels to the right of each dot, and description can hold a timestamp or a note.
import { Stepper } from "@/components/ui/stepper";
const orderSteps = [
{ title: "Order placed", description: "Oct 12, 2:32 PM" },
{ title: "Shipped", description: "Oct 13, 9:10 AM via UPS" },
{ title: "Out for delivery" },
{ title: "Delivered" },
];
<Stepper steps={orderSteps} current={2} orientation="vertical" size={28} />;Drive it with buttons
Stepper itself is not clickable; drive current with your own state.
"use client";
import * as React from "react";
import { Stepper } from "@/components/ui/stepper";
const steps = [
{ title: "Cart" },
{ title: "Details" },
{ title: "Payment" },
];
export function CheckoutProgress() {
const [current, setCurrent] = React.useState(0);
return (
<div className="space-y-6">
<Stepper steps={steps} current={current} />
<button
onClick={() => setCurrent((c) => Math.min(c + 1, steps.length))}
className="rounded-lg bg-neutral-900 px-4 py-2 text-sm text-white"
>
Next
</button>
</div>
);
}Everything complete
Setting current to steps.length marks every step complete, with no active step.
<Stepper steps={steps} current={steps.length} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
steps | StepperStep[] | — | The list of steps, each with a title and an optional description |
current | number | — | Current step index (0-based); steps below it are completed |
orientation | "horizontal" | "vertical" | "horizontal" | Arrangement direction |
size | number | 36 | Dot diameter (px); connectors align to its center |
className | string | — | Forwarded to the outermost container |
The StepperStep type is { title: string; description?: string }.
Accessibility
- The container carries
role="list"and anaria-label, and each step isrole="listitem" - The active step carries
aria-current="step" - When the user has "reduce motion" enabled at the system level, the pulse and the drawing animation are turned off and the final state is shown directly
FAQ
Does it work with the Next.js App Router?
Yes, the file already starts with "use client". The first render matches the server output, and it only switches to the static version for reduced motion after mounting.
Can users click a step to go back?
No, Stepper is display only. If you need click-to-go-back, use Multi-step Form, whose progress indicator lets users return to completed steps.
How do I change the size?
Set the dot diameter with size (default 36px); the number font size, check mark size and horizontal label width all scale from it.
Does it respect reduced motion?
Yes. With the OS "reduce motion" setting on, the pulse, scale and connector fill animations are turned off and the final state renders directly.
What are the dependencies?
motion, lucide-react, clsx and tailwind-merge. You can also copy the source from the Manual tab in the installation section.