Overlays & Feedback

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.en

New project or installation trouble? Start here →

Stepper 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.

2
36
Active edited usageDefault props
<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.json

Or, 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

PropTypeDefaultDescription
stepsStepperStep[]—The list of steps, each with a title and an optional description
currentnumber—Current step index (0-based); steps below it are completed
orientation"horizontal" | "vertical""horizontal"Arrangement direction
sizenumber36Dot diameter (px); connectors align to its center
classNamestring—Forwarded to the outermost container

The StepperStep type is { title: string; description?: string }.

Accessibility

  • The container carries role="list" and an aria-label, and each step is role="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.