Stepper
Show ordered steps and their progress.
- Your details (completed)Name and work email
- 2Company detailsCompany name and team size
- 3Invite your teamAdd colleagues by email
- 4Connect integrationsLink the tools your team already uses
Installation
pnpm dlx shadcn@4.18.0 add @siteplane/stepperComplete the one-time setup first. Registry JSON lists source files and dependencies.
For this page’s examples, also install:
pnpm dlx shadcn@4.18.0 add @siteplane/button @siteplane/inputUsage
import { Stepper, StepperItem } from "@/siteplane/components/stepper";
<Stepper>
<StepperItem index={1} title="Profile" />
</Stepper>;Composition
Stepper
├── StepperItem
└── StepperButtonItemInteractive steps
Use StepperButtonItem when people can go back to steps they have already reached. Two props describe a step and they are independent: status says where the step stands (done, current, open or blocked) and active says which step is open. Opening another step changes active only, so a completed step keeps its check and the step in progress keeps its marker wherever the person is. Your application decides each status and which steps are available: disable steps that haven’t been reached yet, and set disabled with status="blocked", which changes only the marker.
Steps with content
Pass children to a step to show content under its title, such as the form of the current step. The content opens when the children appear and closes when they go away, with the same expand and fade as every other change in the kit. Keep one item per step, each with a stable key, and pass children only to the step that is open: the markers, their colors, the descriptions and the connector then change in place instead of the steps being replaced.
In a StepperButtonItem the content sits under the button, never inside it, so it can hold fields and links. The title and the status of the button name it; the content is not part of its name.
A step moves between clickable and open without being replaced. Use StepperButtonItem for every step that people can open, and give it active while it is open.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
Item / Button | ReactNode | required | Step title. |
description | ReactNode | unset | Supporting text under the title. Text that changes cross-fades; give a description element a key to cross-fade between elements, or keep the same key to update it in place. |
children | ReactNode | unset | The content of the step, shown under its title. It expands when children appear and collapses when they go away; in a StepperButtonItem it sits outside the button. |
index | number | unset | Marker number for open/current states. |
status | open | current | done | blocked | open | Where the step stands: its marker and text. It does not depend on which step is open; see StepperButtonItem.active. |
status | string | done: "completed", blocked: "blocked" | Visually hidden status text after the title, read as "Title (completed)". Replace it to translate, or pass an empty string to omit it. |
Stepper | boolean | false | The step that is open: aria-current=step and the selection ring, independently of status. A done step keeps its check while it is open. current is a deprecated alias. |
Stepper | boolean | false | Prevents activation. |
Stepper | MouseEventHandler | unset | Navigate/change current step. |
Stepper accepts native ol props. StepperItemProps extends li props without native title; status=current sets aria-current=step. StepperButtonItemProps extends button props without native title and adds active; it uses a text Button. Both accept children for the content of the step and string className. The internal indicator/content helpers and status type are not exported. No automatic progression, validation or navigation is provided.
Every change animates through the shared motion tokens: the content expands and collapses, the marker changes its number, check or lock and its colors, a changed description cross-fades, and the connector follows the height of its step. All of it is instant when the system asks for reduced motion, when html carries data-motion-reduce="true", or inside SiteplaneMotionProvider preset="reduced".
Usage notes
The marker shows done and blocked steps only as an icon, so each title adds visually hidden status text for screen readers. Interactive steps use normal button keyboard behavior. Use Tabs if the interaction is a set of associated panels rather than a sequence.
The markers sit at the inline start of the steps and the connector runs down under them, so in a right-to-left page both are on the right.
Replacing one item component with another at the same position, for example StepperItem for the open step and StepperButtonItem for the others, remounts the step and loses the transition. Use StepperButtonItem for all of them.
Content that is closing is inert and hidden from assistive technology while it collapses, so focus inside it is lost when it closes. Move focus to the next control when a step closes.