Stepper
ProThe steps of a process, with where the person is. A step is drawn as done only when the app says done; pressing a step opens it (through onStepSelect) and never completes it. The tick is drawn, and the rail after it filled, when done turns true while the stepper is on screen; steps that were already done when it appeared are still. Nothing is current until you set current.
Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
- 5.1.0
- 5.0.0
- 4.5.0
- 4.4.0
- 4.3.0
- 4.2.0
- 4.1.0
- 4.0.2
- 4.0.1
- 4.0.0
- 3.0.0
- 2.10.0
- 2.9.0
- 2.8.0
- 2.7.0
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.1
- 2.5.0
- 2.4.0
- 2.3.0
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0 and 2.2.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/stepper
Usage
"use client"
import * as React from "react"
import { Stepper, type StepperStep } from "@/components/candor/ui/stepper"
import { Button } from "@/components/candor/ui/button"
// What each step has really been through is the app's data: "done" is set by the save, not by pressing the step.
export default function Example() {
const [current, setCurrent] = React.useState("details")
const [saved, setSaved] = React.useState<string[]>([])
const steps: StepperStep[] = [
{ id: "details", title: "Details", description: "Name and region", done: saved.includes("details") },
{ id: "access", title: "Access", description: "Who can open it", done: saved.includes("access") },
{
id: "review",
title: "Review",
description: "Check before creating",
locked: saved.includes("details") && saved.includes("access") ? null : "Save Details and Access first.",
},
]
return (
<div className="flex max-w-xl flex-col gap-4">
<Stepper steps={steps} current={current} onStepSelect={setCurrent} label="New project" />
<div className="flex gap-2">
<Button
size="sm"
variant="outline"
onClick={() => setSaved((all) => (all.includes(current) ? all : [...all, current]))}
disabled={current === "review"}
>
Save this step
</Button>
</div>
</div>
)
}<Stepper>
| Prop | Type | Default | Description |
|---|---|---|---|
| stepsrequired | StepperStep[] | — | The steps in order. |
| current | string | undefined | — | The id of the step the person is on. Left out, no step is current and no count shows. |
| onStepSelect | ((id: string) => void) | undefined | — | Called with a step's id when a person presses it. Left out, the steps are plain text, not buttons. |
| orientation | "horizontal" | "vertical" | undefined | "horizontal" | Lay the steps out in a row or a column. |
| showCount | boolean | undefined | true | Prints "Step 2 of 5" above the steps when `current` is set. |
| label | string | undefined | — | The list's accessible name. Defaults to "Steps". |
| className | string | undefined | — | Extra classes for the outer element. |
Strings
The fixed words, in English by default. Change any of them under stepper in <LocaleProvider strings={{ … }}>; the table is exported as stepperStrings.
| Key | English |
|---|---|
| steps | Steps |
| count | Step {current} of {total} |
| done | Done |
| current | Current step |
| failed | Failed |
| upcoming | Not started |
Motion
| Moment | Family | What it does |
|---|---|---|
| done | mark, draw | The tick is drawn along its path when the app turns a step's `done` on while the stepper is on screen. A step that is already done when the stepper appears shows its tick at once, and pressing a step never completes it. |
| rail | fill | The line after a step fills towards the next step when that step turns done while the stepper is on screen, never ahead of it. Lines after steps that were done when the stepper appeared are already full. |
Set with --cd-motion-stepper-<moment>-* in your brand file; the families are in the design reference.
Types
- StepperStep
- One step. What it is and whether it is done come from the app; the stepper never decides either.
{ /** A stable id, passed to `onStepSelect` and matched against `current`. */ id: string; /** The step's name. */ title: React.ReactNode; /** A line under the title. */ description?: React.ReactNode | undefined; /** True only when the app knows the step is finished (saved, verified, accepted). Pressing a step never sets it. */ done?: boolean | undefined; /** True when the app knows the step failed. Drawn as a cross in the destructive colour. */ failed?: boolean | undefined; /** Why a person can't go to this step yet. The step stays focusable, says why, and doesn't open. Only used with `onStepSelect`. */ locked?: string | null | undefined; }