# Horizontal Numbered Stepper

> Horizontal progress stepper with numbered nodes, connectors, and labels across completed, current, and upcoming states for checkout or onboarding.

A shadcn/ui block from the [@7ovr](https://7ovr.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/7ovr/steps-1).

- Page, with a live preview: https://shadcn.exchange/r/7ovr/steps-1
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/7ovr/steps-1-light-7eea1c0f3a7c876a.png
- Registry item: https://7ovr.com/r/steps-1.json
- Categories: steps
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://7ovr.com/r/steps-1.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Files

### `registry/blocks/steps/1/steps-block.tsx`

```tsx
import { cn } from "@/lib/utils"
import { IconPlaceholder } from "@/components/icons/icon-placeholder"

type Status = "done" | "current" | "upcoming"

const steps: { label: string; status: Status }[] = [
  { label: "Cart", status: "done" },
  { label: "Details", status: "done" },
  { label: "Payment", status: "current" },
  { label: "Review", status: "upcoming" },
]

export default function StepsBlock() {
  return (
    <section className="flex w-full items-center justify-center bg-background px-6 py-16 text-foreground">
      <div className="w-full max-w-xl">
        <ol className="flex">
          {steps.map((step, i) => (
            <li
              key={step.label}
              aria-current={step.status === "current" ? "step" : undefined}
              className="relative flex flex-1 flex-col items-center"
            >
              {i < steps.length - 1 && (
                <span
                  aria-hidden="true"
                  className={cn(
                    "absolute top-4 left-1/2 h-0.5 w-full -translate-y-1/2",
                    step.status === "done" ? "bg-primary" : "bg-border"
                  )}
                />
              )}
              <span
                className={cn(
                  "relative z-10 flex size-8 items-center justify-center rounded-lg text-sm font-medium tabular-nums",
                  step.status === "done" &&
                    "bg-primary text-primary-foreground",
                  step.status === "current" &&
                    "border-2 border-primary bg-background text-primary",
                  step.status === "upcoming" &&
                    "border border-border bg-background text-muted-foreground"
                )}
              >
                {step.status === "done" ? (
                  <IconPlaceholder
                    lucide="Check"
                    tabler="IconCheck"
                    hugeicons="Tick02Icon"
                    phosphor="Check"
                    remixicon="RiCheckLine"
                    className="size-4"
                    aria-hidden="true"
                  />
                ) : (
                  i + 1
                )}
              </span>
              <span
                className={cn(
                  "mt-2 text-xs",
                  step.status === "upcoming"
                    ? "text-muted-foreground"
                    : "font-medium text-foreground"
                )}
              >
                {step.label}
              </span>
            </li>
          ))}
        </ol>
      </div>
    </section>
  )
}
```
