Stepper

Guides a user through a sequence of steps and indicates progress.

Choose the project type and confirm who the workflow belongs to.
Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/stepper.json
Usage
Drive `value` with state. Each `StepperItem.step` matches a `StepperContent.value` to render the right panel.
TSImport
import { Stepper } from "@/components/ui/stepper";
TSExample
"use client";

import * as React from "react";
import { Stepper } from "@/components/ui/stepper";

export function Example() {
  const [step, setStep] = React.useState(1);
  return (
    <Stepper
      value={step}
      onValueChange={setStep}
      steps={[
        { step: 1, content: "Step 1 content" },
        { step: 2, content: "Step 2 content" },
        { step: 3, content: "Step 3 content" },
      ]}
    />
  );
}
Composition
Anatomy of the Stepper primitive.
Stepper                           (single component — pass steps as data)
├── steps={[
│     { step?, title?, content?, indicator?, tooltip?, completed?, disabled?, loading? },
│     …
│   ]}
├── numbered                       (render the step number inside the dot)
├── orientation="horizontal" | "vertical"
├── indicators={{ active?, completed?, inactive?, loading? }}
└── ...rest                       (value / defaultValue / onValueChange / className)

Auto-emits StepperNav + StepperItem(+ Trigger + Indicator + Separator) per
step; StepperPanel + StepperContent for any step that has `content`.

Need a fully custom nav (e.g. multi-step form with header + side panel)?
The slot exports — StepperNav, StepperItem, StepperTrigger,
StepperIndicator, StepperSeparator, StepperTitle, StepperDescription,
StepperPanel, StepperContent — remain available as the escape hatch.
Default
Controlled horizontal stepper with previous and next actions.
Choose the project type and confirm who the workflow belongs to.
States
Per-step props let you preview completed, active, disabled, and loading states.
Inline title
Pass `numbered` and a `title` per step for compact horizontal flows.
Collapsed
Set `siblingCount` to collapse middle steps into a popover ellipsis — matches Pagination's UX for long sequences. `siblingCount={0}` keeps the rail at a max of 5 items (first, ellipsis, active, ellipsis, last).
Stacked (horizontal)
Pass `layout="stacked"` plus a `description` per step to stack the title + description under the indicator. Good for wizards that want labels visible at all times.
Stacked (vertical)
Pair `layout="stacked"` with `orientation="vertical"` for a side-by-side indicator + title/description list — onboarding sidebars and signup checklists.
Minimal
Pass `layout="minimal"` for a segmented progress bar — no dots or numbers, just brand-colored segments with a gradient on the active one and the current step listed to the side. Still fully clickable and `value`-driven like every other layout.
Step 3 of 6
Minimal (card edge)
Hide the label with `minimalShowLabel={false}` and absolutely position the stepper flush along the card's bottom edge. Build the card from `card-surface`, then drop its bottom border (`border-b-transparent`) and outer ring (`ring-0`) so the gaps between segments don't reveal an outline underneath — the segmented bar becomes the bottom edge. Give any step a `tooltip` to label its segment on hover (or set `minimalTooltipTrigger="click"` to open it on click).

Build your organization

Complete the actions to unlock new features along the way.

3 steps to complete
Chips
Pass `layout="chips"` for a compact, breadcrumb-style row of outlined chips joined by carets. Steps before `value` (or marked `completed`) show a filled brand check, the active chip gets a brand ring, upcoming ones a hollow circle. Untitled steps read "Step N"; `indicator`, `loading`, `disabled` and `content` work as on every layout.
Read-only with tooltips
`readOnly` turns off clicking on every layout — the stepper just reports progress from `value`. Give any step a `tooltip` to show it on hover; that works on every layout, clickable or not.
Read-only chips (vertical)
Add `orientation="vertical"` to the chips layout to stack the chips in a column. A short rail joins each chip to the next and turns brand once that step is reached — a progress track for a narrow side column.
Card
Pass `layout="card"` plus a `title` per step to render equal-width bordered cards with a "STEP N" eyebrow — the active card fills with the brand color. Matches the project-creation stepper on the dynamic form. Add `content` per step to render a panel below the cards (style it via `panelClassName`); mark a step `disabled` to gate it.
Give your project a title and tell us when you need it.
API Reference
Props exposed by the Stepper component.

Stepper

PropTypeDefaultDescription
stepsStepperStep[]—Step specs. Without this prop, Stepper stays compound (drop in StepperNav + StepperItem children manually).
numberedbooleanfalseRender the step number inside each indicator (otherwise the inactive dot is empty).
layout"inline" | "stacked" | "minimal" | "card" | "chips""inline"Layout style. "minimal" renders a segmented brand-colored progress bar (no dots/numbers) with the current step listed to one side. "card" renders equal-width bordered cards with a "STEP N" eyebrow above each `title`; the active card fills with the brand color. "chips" renders compact outlined chips joined by carets — a filled check on completed steps, a brand ring on the active one.
minimalShowLabelbooleantrueMinimal layout only — show or hide the step label next to the bar.
minimalSegmentClassNamestring—Minimal layout only — extra classes on every segment. Pair `rounded-none` with `navClassName="gap-0"` to fuse the segments into one continuous bar (e.g. running flush along a card edge as its bottom border).
minimalLabelSide"left" | "right""right"Minimal layout only — which side the step label sits on.
minimalLabel(activeStep, total) => ReactNode—Minimal layout only — custom label renderer. Defaults to the active step's title, or "Step N of M".
minimalTooltipTrigger"hover" | "click""hover"Minimal layout only — how a step's `tooltip` opens. `hover` shows a Tooltip; `click` opens a small Popover (the click still selects the step). Steps without a `tooltip` render plain segments.
readOnlybooleanfalseShow progress only: steps can't be clicked or tabbed to, on every layout (the collapsed ellipsis stays shut). Drive the active step with `value`. Hover tooltips still work.
siblingCountnumber—Show this many step indicators on each side of the active step; remaining steps collapse into a popover ellipsis (like Pagination). `0` keeps the rail at its tightest — first, ellipsis, active, ellipsis, last (max 5 items). Omit to render every step inline.
valuenumber—Controlled active step (1-indexed).
defaultValuenumber—Uncontrolled initial active step.
onValueChange(step: number) => void—Fires when the active step changes.
orientation"horizontal" | "vertical""horizontal"Layout direction of nav and separators.
indicators{ active?, completed?, inactive?, loading? }—Override the rendered indicator content per state.
navClassNamestring—Class names applied to the auto-emitted StepperNav.
panelClassNamestring—Class names applied to the auto-emitted StepperPanel.

StepperStep

PropTypeDefaultDescription
stepnumber—1-indexed step number. Defaults to the array index + 1.
titleReactNode—Inline label rendered next to the indicator (auto-emits a StepperTitle).
contentReactNode—Panel content shown when this step is active.
indicatorReactNode—Override the indicator content. When `numbered` is set on the parent, the step number is the default.
tooltipReactNode—Shown on hover over this step, on every layout. The minimal layout can open it on click instead (`minimalTooltipTrigger`). Disabled steps don't show it.
completedboolean—Force the completed (checkmark) state.
disabledboolean—Disable the trigger and dim the indicator.
loadingboolean—Show a spinner in the indicator.