Steps

Shows the steps of a flow.

Orientation

    1. , doneBuild1m 12s
    2. , doneEvaluate200 tickets
    3. 3, currentReviewWaiting on you
    4. 4ShipTo production

    horizontaldefault

    1. , doneBuild1m 12s
    2. , doneEvaluate200 tickets
    3. 3, currentReviewWaiting on you
    4. 4ShipTo production

    vertical

Sizes

    1. , doneBuild1m 12s
    2. , doneEvaluate200 tickets
    3. 3, currentReviewWaiting on you
    4. 4ShipTo production

    sm

    1. , doneBuild1m 12s
    2. , doneEvaluate200 tickets
    3. 3, currentReviewWaiting on you
    4. 4ShipTo production

    defaultdefault

States

    1. , doneBuild

    done

    1. 2, currentEvaluate

    current

    1. 2Review

    upcoming

    1. , runningEvaluate

    pending

    1. MigrateFailed

    error

Usage

When to use it
Use
A flow has two to six steps in a fixed order and the person needs to see where they are: a setup, an import.
Use
Work runs through stages and each stage has a state: a deploy, an agent's plan.
Not for
The panels can be read in any order. Use Tabs.
Not for
Only the share done matters, with no named steps. Use Progress.
Not for
The events have times and a log of what happened. Use Item.

Rules

8 rules
Must
Give Steps an aria-label naming the flow: "Deploy", "Connect a data source". Because the list is read as "list, 4 items" with no name, so a screen reader cannot tell a deploy's stages from a setup.
Must
Number each Step from 1 in the order it renders, and pass the current one as value. Because done, current, upcoming and how far the track fills are all worked out from step against value, so a gap or a repeat marks the wrong steps done.
Must
Set state="pending" on a step while it runs and state="error" when it failed; never colour a title or a marker by hand. Because the state draws the arc or the coral cross and says "running" or "Failed", so a hand-set colour is a status nobody hears and a dot nobody can name.
Should
Put a StepSeparator in every Step, after its StepTrigger; the last step draws none. Because the track is what joins the markers into one flow, and its gradient fill up to the current step is the progress at a glance.
Never
Restyle a marker with glass, a hue or a status dot, or set the done gradient on any other state. Because the small glaze means done and nothing else on the row, so a glazed current marker reads as finished, and a green or dotted one as a status badge.
Should
Pass onValueChange only when the person can go back to a step, and leave linear on unless the steps are independent. Because a step that looks like a button but does nothing is a dead control, and a later step picked out of order skips the ones it needs.
Should
Title each step with a verb or a noun of one or two words, and keep the detail to one line of StepDescription. Because horizontal steps share the width and both lines truncate, so a long title loses its end.
Should
Use size="sm" inside a card, a panel header or a dialog, and the default on a page of its own. Because the 16px marker and 12px label sit with the 26px small controls around them; the default 20px marker beside them looks loud.

State order

5 states, highest first
1
error
2
pending
3
done
4
current
5
upcoming

Accessibility

7 checks
Steps is an ordered list, so a screen reader reads the order and the count; name it with aria-label.
The current step carries aria-current="step".
Each marker says its state as hidden text (done, current, running); error says "Failed" as visible text beside the label, so no state is told by shape or colour alone.
With onValueChange each step is a button with its label as its name; steps past the current one are disabled when linear.
The white check on the small glaze is about 6:1 at the glyph's top and 9.5:1 at its middle (4.8:1 only at the marker's top edge, where no glyph sits); in dark the ink check on the light glaze is 9:1 or better.
The current numeral is text-1 on paper (11.9:1). The upcoming numeral is text-3 (3.3:1), a mark and not the step's name: the label beside it is text-2 at 5.5:1. The error word is the failure text at 5.9:1.
The track is decoration (aria-hidden); the fill slides on --dur-overlay and jumps under reduced motion.

Keyboard

2 keys
Tab
With onValueChange, moves through the steps that can be picked.
Enter, Space
Goes back to the focused step.

Edge cases

8 edge cases
Narrow container
Horizontal labels and descriptions truncate; under 480px use orientation="vertical".
More than six steps
Group them into stages; a row of seven markers is too dense to read.
A step fails
state="error" on it, and the steps after it stay upcoming until the person retries; its track stays empty.
A step is running
state="pending" turns the arc in its marker; under reduced motion the arc stands still.
Value jumps several steps
Every track between fills at once over --dur-overlay.
Every step done
Pass value one past the last step, so every marker is a check, every track full and none current.
Right to left
The steps run right to left and the fill grows from the right.
Dark theme
The small glaze turns light with an ink check, and the track fill follows it.

API

9 props
Steps value
number default required
Steps onValueChange
(step: number) => void
Steps orientation
'horizontal' | 'vertical' default 'horizontal'
Steps size
'sm' | 'default' default 'default'
Steps linear
boolean default true
Step step, state, disabled
number, 'done' | 'current' | 'upcoming' | 'pending' | 'error', boolean default state from value
StepIndicator children
ReactNode default by state
StepTitle errorText
ReactNode default 'Failed'
StepTrigger, StepText, StepDescription, StepSeparator
parts

Tokens

22 tokens
--glaze-sm-top
#6b6b6b
--glaze-sm-mid
#3d3d3d
--glaze-sm-bottom
#232323
--glaze-sm-text
rgb(255 255 255 / 0.92)
--paper
#ffffff
--field
#efefef
--ink
#050505
--line
rgb(5 5 5 / 0.10)
--text-1
rgb(5 5 5 / 0.80)
--text-2
rgb(5 5 5 / 0.60)
--text-3
rgb(5 5 5 / 0.45)
--fail
#e35e49
--fail-tint
#fbe9e5
--fail-text
#b23c29
--radius-pill
999px
--type-label
500 13px/1.35 var(--font-sans)
--type-label-sm
500 12px/1.35 var(--font-sans)
--type-caption
400 12px/1.35 var(--font-sans)
--dur-overlay
200ms
--dur-state
160ms
--ease-out
cubic-bezier(0.2, 0.8, 0.2, 1)
--dur-spin
800ms

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.