# Vertical Stepper With Descriptions

> Vertical stepper on a connecting rail where each step shows a title and description across completed, current, and upcoming states.

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

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

## Install

```bash
npx shadcn@latest add https://7ovr.com/r/steps-2.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/2/steps-block.tsx`

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

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

const steps: { title: string; description: string; status: Status }[] = [
  {
    title: "Create your account",
    description: "Sign up with your email and choose a password.",
    status: "done",
  },
  {
    title: "Verify your email",
    description: "Confirm your address from the link we sent you.",
    status: "done",
  },
  {
    title: "Set up your workspace",
    description: "Name your workspace and pick a starting template.",
    status: "current",
  },
  {
    title: "Invite your team",
    description: "Add teammates so you can start collaborating.",
    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-md">
        <ol className="flex flex-col">
          {steps.map((step, i) => {
            const last = i === steps.length - 1
            return (
              <li
                key={step.title}
                aria-current={step.status === "current" ? "step" : undefined}
                className="flex gap-4"
              >
                <div className="flex flex-col items-center">
                  <span
                    className={cn(
                      "flex size-8 shrink-0 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>
                  {!last && (
                    <span
                      aria-hidden="true"
                      className={cn(
                        "my-1 w-0.5 flex-1",
                        step.status === "done" ? "bg-primary" : "bg-border"
                      )}
                    />
                  )}
                </div>

                <div className={cn("pt-1", last ? "pb-0" : "pb-8")}>
                  <h3
                    className={cn(
                      "font-heading text-sm font-semibold",
                      step.status === "upcoming"
                        ? "text-muted-foreground"
                        : "text-foreground"
                    )}
                  >
                    {step.title}
                  </h3>
                  <p className="mt-1 text-sm/relaxed text-muted-foreground">
                    {step.description}
                  </p>
                </div>
              </li>
            )
          })}
        </ol>
      </div>
    </section>
  )
}
```
