Stepper

Navigation

Multi-step progress indicator with navigation.

Preview

3
4

Usage

example.jsx
import { Stepper } from "@/components/ui/stepper";

export default function Example() {
  return <Stepper />;
}

Source Code

Copy this file into components/ui/stepper.jsx in your project.

stepper.jsx
"use client";

import { forwardRef } from "react";
import { cn } from "@/lib/utils";

const Stepper = forwardRef(({ className, steps = [], currentStep = 0, ...props }, ref) => (
  <div ref={ref} className={cn("flex items-center gap-2", className)} {...props}>
    {steps.map((step, i) => (
      <div key={i} className="flex items-center gap-2">
        <div className={cn("flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 text-sm font-semibold transition-colors",
          i < currentStep && "border-primary bg-primary text-primary-foreground",
          i === currentStep && "border-primary text-primary",
          i > currentStep && "border-muted-foreground/30 text-muted-foreground"
        )}>
          {i < currentStep ? (
            <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /></svg>
          ) : i + 1}
        </div>
        <div className="hidden sm:block">
          <div className={cn("text-sm font-medium", i <= currentStep ? "text-foreground" : "text-muted-foreground")}>{step.label || step}</div>
          {step.description && <div className="text-xs text-muted-foreground">{step.description}</div>}
        </div>
        {i < steps.length - 1 && <div className={cn("h-0.5 w-8 sm:w-16", i < currentStep ? "bg-primary" : "bg-muted-foreground/30")} />}
      </div>
    ))}
  </div>
));
Stepper.displayName = "Stepper";

export { Stepper };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge