- Accordion
- Action Bar
- Action Toast
- Alert Banner
- Alert Dialog
- Alert
- Alphabet Index
- Amount Field
- Aspect Ratio
- Attachment
- Availability List
- Avatar
- Badge
- Bank Card
- Breadcrumb
- Bubble
- Button Group
- Button
- Calendar
- Camera Frame
- Card Design Picker
- Card Details
- Card Peek
- Card Stack
- Card
- Carousel
- Chart
- Chat Thread
- Checkbox
- Chip Group
- Choice Tile
- Code Block
- Code Dots
- Collapsible
- Combobox
- Command
- Context Menu
- Copy Field
- Countdown
- Country Select
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Direction
- Document Paper
- Drawer
- Dropdown Menu
- Empty
- Entity Avatar
- Field
- File Trigger
- File Upload Item
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Key Value
- Keypad
- Label
- Live Region
- Marker
- Message Scroller
- Message
- Money Amount
- Native Select
- Number Field
- Pagination
- Percent Split Editor
- Phone Field
- Popover
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Histogram
- Rating
- Resizable
- Scroll Area
- Search Field
- Select
- Separator
- Share Bar
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Sortable List
- Spinner
- Status Timeline
- Step Header
- Steps List
- Swipe Row
- Switch
- Table
- Tabs
- Text Field
- Textarea
- Tier Ladder
- Toggle Group
- Toggle
- Token Search Field
- Tooltip
- Trace
- Transaction Row
- Usage Meter
Where do you live?
We send the card to this address.
import {
StepHeader,
StepHeaderAction,The StepHeader component sits at the top of a multi-step flow such as ordering a card, verifying an identity, or sending a transfer. It shows where the user is, lets them go back or leave, and states what the current step asks for. Use StepHeaderCount with StepHeaderProgress for longer flows, and StepHeaderSteps when a short flow has three or four named steps.
Installation#
pnpm dlx shadcn@latest add @dots/step-header
Usage#
import {
StepHeader,
StepHeaderBack,
StepHeaderBar,
StepHeaderContent,
StepHeaderCount,
StepHeaderHeading,
StepHeaderProgress,
} from "@/components/ui/step-header"<StepHeader>
<StepHeaderBar>
<StepHeaderBack onPress={goBack} />
<StepHeaderCount step={2} total={5} />
</StepHeaderBar>
<StepHeaderProgress step={2} total={5} />
<StepHeaderContent>
<StepHeaderHeading>Where do you live?</StepHeaderHeading>
</StepHeaderContent>
</StepHeader>Composition#
Use the following composition to build a step header:
StepHeader
├── StepHeaderBar
│ ├── StepHeaderBack or StepHeaderClose
│ ├── StepHeaderCount or StepHeaderTitle
│ └── StepHeaderAction or StepHeaderClose side="end"
├── StepHeaderProgress or StepHeaderSteps
└── StepHeaderContent
├── StepHeaderHeading
└── StepHeaderDescriptionFeatures#
- A three-column bar that keeps the counter or title centered with or without a button on each side
- Segmented progress built on the React Aria
ProgressBar, read as "Step 2 of 5" - Partial fill of the current segment through
stepProgressfor a step with inner screens - Named steps for short flows, with a check on done steps and
aria-current="step"on the current one - Back and close buttons with default labels, and a text action slot for "Skip" or "Save and exit"
- A heading level you can set to fit the page outline
First step#
On the first step there is nothing to go back to, so put StepHeaderClose at the start of the bar instead of StepHeaderBack.
Choose a card
Virtual cards are ready in two minutes.
import {
StepHeader,
StepHeaderBar,Optional step#
Pass note to StepHeaderCount to mark a step as optional and add a StepHeaderAction to skip it. Set stepProgress to fill part of the current segment when a step has its own inner screens. When you replace the counter wording through children, pass the same text as valueLabel to StepHeaderProgress.
Add to your phone
Pay with your phone before the physical card arrives.
import {
StepHeader,
StepHeaderAction,Named steps#
For a short flow of up to four steps, show the step names with StepHeaderSteps and the flow name with StepHeaderTitle. Use side="end" to put the close button at the end of the bar.
- Done: Recipient
- Amount
- Review
import {
StepHeader,
StepHeaderBack,Changing steps#
Keep the button that moves forward, such as Continue, in the content below the header; StepHeaderAction is for a secondary action such as "Skip". When the step changes in place, the pressed Back or Continue button may unmount. Give StepHeaderHeading a ref and tabIndex={-1}, and focus it in an effect keyed on the step. Focus is not lost and the new step is read.
Your name
As it appears on your ID.
"use client"
import * as React from "react"const headingRef = React.useRef<HTMLHeadingElement>(null)
// Set on a step change, so the first render does not take focus.
const changed = React.useRef(false)
React.useEffect(() => {
if (changed.current) headingRef.current?.focus()
}, [step])
const go = (next: number) => {
changed.current = true
setStep(next)
}
<StepHeaderBack onPress={() => go(step - 1)} />
<StepHeaderHeading ref={headingRef} tabIndex={-1}>
{current.heading}
</StepHeaderHeading>Accessibility#
StepHeaderProgress renders a React Aria ProgressBar with role="progressbar", its value, and a value text of "Step 2 of 5". The segments are hidden from assistive tech. StepHeaderBack, StepHeaderClose, and StepHeaderAction render a Button, so they work with mouse, touch, and keyboard.
Labels#
StepHeaderBack and StepHeaderClose are icon-only and default to aria-label="Back" and aria-label="Close". Pass your own aria-label when the app is translated or the close button means something more specific, such as "Cancel transfer". StepHeaderProgress defaults to aria-label="Progress" and StepHeaderSteps to aria-label="Steps".
Named steps#
StepHeaderSteps renders an ordered list. Done steps get a visually hidden "Done:" prefix and the current step gets aria-current="step", so the state is not conveyed by the check or the color alone.
Focus on step change#
Move focus to StepHeaderHeading after each step change, as shown in Changing steps. Do not focus it on the first render.
API Reference#
StepHeader#
The root container. Make it sticky from the outside if the bar should stay visible while the content scrolls.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the root element. |
...props | React.ComponentProps<"div"> | - | Props spread to the <div>. |
StepHeaderBar#
The top row with three columns. The side columns never squeeze their buttons; the center truncates on narrow screens.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the bar. |
...props | React.ComponentProps<"div"> | - | Props spread to the <div>. |
StepHeaderBack#
Goes back one step. Renders an icon-only ghost Button.
| Prop | Type | Default | Description |
|---|---|---|---|
side | "start" | "end" | "start" | Which side of the bar the button sits on. |
aria-label | string | "Back" | The accessible name of the button. |
...props | Omit<React.ComponentProps<typeof Button>, "children" | "variant" | "size"> | - | Props spread to the underlying Button. |
StepHeaderClose#
Leaves the flow. Renders an icon-only ghost Button.
| Prop | Type | Default | Description |
|---|---|---|---|
side | "start" | "end" | "start" | Which side of the bar the button sits on. |
aria-label | string | "Close" | The accessible name of the button. |
...props | Omit<React.ComponentProps<typeof Button>, "children" | "variant" | "size"> | - | Props spread to the underlying Button. |
StepHeaderAction#
A text action at the end of the bar, such as "Skip" or "Save and exit". Renders a Button and accepts all of its props.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | React.ComponentProps<typeof Button>["variant"] | "ghost" | The button variant. |
size | React.ComponentProps<typeof Button>["size"] | "sm" | The button size. |
...props | React.ComponentProps<typeof Button> | - | Props spread to the underlying Button. |
StepHeaderCount#
The "Step 2 of 5" counter in the center of the bar.
| Prop | Type | Default | Description |
|---|---|---|---|
step | number | - | The current step, starting at 1. Required. |
total | number | - | The number of steps. Required. |
note | React.ReactNode | - | A short note after the counter, such as "Optional". |
children | React.ReactNode | - | Replaces the default "Step 2 of 5" wording, such as "2 of 5" or a translation. |
className | string | - | Additional classes to apply to the counter. |
...props | Omit<React.ComponentProps<"span">, "children"> | - | Props spread to the <span>. |
StepHeaderTitle#
The flow name in the center of the bar, used with named steps.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the title. |
...props | React.ComponentProps<"span"> | - | Props spread to the <span>. |
StepHeaderProgress#
Segmented progress built on the React Aria ProgressBar. Passed and current segments are filled, the rest show the track.
| Prop | Type | Default | Description |
|---|---|---|---|
step | number | - | The current step, starting at 1. Required. |
total | number | - | The number of steps. Required. |
stepProgress | number | - | How much of the current step is done, from 0 to 1. Without it the current segment is filled. |
valueLabel | React.ReactNode | "Step {step} of {total}" | The value text read by assistive tech. |
aria-label | string | "Progress" | The accessible name. Not applied by default when aria-labelledby is set. |
aria-labelledby | string | - | The id of an element that names the progress bar. |
className | string | - | Additional classes to apply to the progress bar. |
...props | Omit<ProgressBarProps, "children" | "className" | "style" | "value" | "minValue" | "maxValue"> | - | React Aria ProgressBar props, such as id. |
StepHeaderSteps#
Named steps for short flows, rendered as an ordered list.
| Prop | Type | Default | Description |
|---|---|---|---|
steps | React.ReactNode[] | - | The step names, up to four. Required. |
step | number | - | The current step, starting at 1. Required. |
aria-label | string | "Steps" | The accessible name of the list. |
className | string | - | Additional classes to apply to the list. |
...props | Omit<React.ComponentProps<"ol">, "children"> | - | Props spread to the <ol>. |
StepHeaderContent#
Wraps the step heading and description under the progress.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the content slot. |
...props | React.ComponentProps<"div"> | - | Props spread to the <div>. |
StepHeaderHeading#
The question or task of the step, such as "Where do you live?".
| Prop | Type | Default | Description |
|---|---|---|---|
level | 1 | 2 | 3 | 2 | The heading level in the page outline. |
className | string | - | Additional classes to apply to the heading. |
...props | React.ComponentProps<"h2"> | - | Props spread to the heading, including ref and tabIndex. |
StepHeaderDescription#
A short line under the heading that explains why the step is needed.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the description. |
...props | React.ComponentProps<"p"> | - | Props spread to the <p>. |
On This Page
InstallationUsageCompositionFeaturesFirst stepOptional stepNamed stepsChanging stepsAccessibilityLabelsNamed stepsFocus on step changeAPI ReferenceStepHeaderStepHeaderBarStepHeaderBackStepHeaderCloseStepHeaderActionStepHeaderCountStepHeaderTitleStepHeaderProgressStepHeaderStepsStepHeaderContentStepHeaderHeadingStepHeaderDescription