Stepper
Shows progress through a sequence of steps. Step state is derived from activeStep — everything before it is complete, everything after is upcoming — across four layouts, four connector styles, three marker sizes and three label placements. There is deliberately no per-item state prop: one number driving every step is the whole reason four of them stay consistent.
import { Stepper, StepperItem, StepperCounter } from "@pestoui/core"Horizontal
The default. Complete markers and the connectors behind them take --selected, the visible brand green the system uses for anything checked, active or progressing — never --info, which is reserved for informational UI. The current step keeps its number instead of a check.
- ConnectPick a data source
- ConfigureSet the agent's goal
- ReviewCheck the first run
- PublishShip to the workspace
Vertical
For setup checklists and side panels, where each step carries a longer description.
- Workspace createdteam.example.com
- Members invited4 invites sent
- Connect appsChat, docs and code
- Launch first agentRuns on your schedule
Dots
A compact indicator for wizards and carousels. Titles are still required — they stay in the accessibility tree even though only the dot is drawn.
- Connect
- Configure
- Review
- Publish
Bar
Rails instead of markers, for a long-running job where the question is how far, not which step. Each step owns its own rail and the gap between them is the seam — contiguous segments would read as one bar with stripes painted on. progress fills the current step's rail partially; every other step is full or empty, so a partial value anywhere else is ignored rather than quietly believed.
- Upload4 files
- ExtractPage 12 of 26
- EmbedWaiting
- IndexWaiting
Connectors
line, dashed, progress and none, top to bottom. dashed is drawn as a border rather than a background, which is what keeps it honouring --border instead of needing an arbitrary gradient. progress looks identical at rest and grows its fill on the layout spring when a step completes, so it reads as travel rather than as a colour swap — see it move in the last demo on this page. none keeps its slot, so step widths stay equal whether or not anything is drawn between them.
- Draft
- Review
- Approve
- Publish
- Draft
- Review
- Approve
- Publish
- Draft
- Review
- Approve
- Publish
- Draft
- Review
- Approve
- Publish
Marker sizes
sm, default and lg — 24, 32 and 40px markers, each pinning its own type size so the number stays optically centred. The label offset moves with the diameter too, which is why a vertical stack stays level at every size. Ignored by dots, whose pip is fixed, and by bar, which has no marker at all.
- Connect
- Configure
- Review
- Connect
- Configure
- Review
- Connect
- Configure
- Review
Icons & the error status
icon replaces the number inside the marker and is hidden from assistive tech — title is what names the step, so the glyph is free to be decorative. status="error" decorates the derived state rather than replacing it: the failed step is still the step you are on, so it keeps the ringed treatment and only changes tone. Colour alone cannot report a failure, so the accessible name is prefixed with “Error:” and the marker shakes once on arrival.
- ConnectSource linked
- ConfigureGoal set
- Error: VerifyToken rejected
- PublishNot started
Label placement & the counter
labels defaults to below for horizontal and bar, end for vertical, none for dots — and the nonsensical pairings are clamped rather than rendered, since a vertical stack has no room under a marker. With labels="end" every step is forced onto the same basis so titles wrap instead of shoving their neighbours along the row. StepperCounter reads the count off the same context the list does, so “Step 2 of 3” cannot drift from the number of children; place it inside Stepper and it is lifted out of the list and rendered after it. It stays silent for screen readers while labels are on screen, because aria-current has already said which step is current, and only speaks when it is the sole indication.
- ConnectPick a source
- ConfigureSet the goal
- PublishShip it
- Connect
- Configure
- Publish
Step 2 of 3
Clickable steps
onSelect turns the marker into a real button with a hit area enlarged past its own box, and hands back the index it was given. The li then drops its own aria-current so the step is not announced as current twice. Click along the row to watch the progress connector travel rather than snap.
- ConnectPick a data source
- ConfigureSet the agent's goal
- ReviewCheck the first run
- PublishShip to the workspace
Props
Pesto UI · 117 documented components