Stepper
Stepper shows which step of a multi-step process people are on; Wizard pairs it with each step's content and Back / Next buttons.
Step 1 of 4 · Account
Import
Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.
// npm install yugen-uiimport { Stepper, Step, Wizard, type WizardStep, type StepStatus } from "yugen-ui";Variants
Each tile is a standalone example: hover to copy, or press Code to see the source.
Step 2 of 4 · Shipping
Horizontal, controlled, non-linear
activeStep + onStepChange: click any step, or use the arrow keys and then Enter. Narrow the window to see the collapsed version.
- Step 1: Order placed, completed8:12 AM · Oct 21
- Step 2: Payment, completedBank transfer confirmed
- Step 3: Packing, errorOut of stock at the main warehouse
- Step 4: Delivery, not started
Vertical, error state, content inside a step
No onStepChange, so it is display only. In the vertical version, a Step's children appear in line with its text.
Step 2 of 4 · Income
Collapsed in a narrow container
The 288px container is narrower than 32rem, so it shows “Step 2 of 4 · Income” plus a ProgressBar. Turn this off with responsive={false}.
Usage
- Keep to 3–6 steps with short titles (nouns); merge steps if the process is longer.
- Check each step with validate and explain errors in text. Wizard shows the message and marks the step as failed.
- Use linear when each step depends on the previous one (checkout, opening an account).
- Don't use Stepper in place of Tabs for independent sections with no order.
- Don't signal errors with color alone. Use status="error", which adds an exclamation mark and the hidden text “error”.
- Don't clear entered data when people go back.
Props
| Prop · Type | Default | Description |
|---|---|---|
| activeStep / defaultActiveStepnumber / number | Default: — / 0 | Stepper: index of the current step, from 0 (controlled / uncontrolled). |
| onStepChange(index: number) => void | Default: — | When set, the steps are buttons (roving focus, arrow keys / Home / End). |
| orientation"horizontal" | "vertical" | Default: "horizontal" | Display direction. |
| linearboolean | Default: false (Wizard: true) | Only allows going back or to completed steps; other steps get aria-disabled. |
| responsiveboolean | Default: true | Horizontal + container < 32rem → “Step n of N · title” plus a ProgressBar. |
| Step | Default: — | Step title and short description. |
| Step | Default: — | Overrides the state derived from the step's position. |
| Step | Default: — | Shows “Optional” / prevents moving to the step. |
| Wizard | Default: — | { id?, title, description?, optional?, content, validate? }. |
| WizardStep | Default: — | false or a string blocks the step and shows an error; a Promise puts the Next button in loading (after 300ms). |
| Wizard | Default: — | Current step, controlled or uncontrolled. |
| Wizard | Default: — | Called when the last step passes validate; a Promise puts the Finish button in loading. |
| Wizard | Default: "Back" / "Next" / "Finish" | Wizard button labels. |
Messages
Text built into the component: labels, aria-labels, screen reader announcements.
English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.
messages.stepper
| Key · Type | Default (English) | messagesVi |
|---|---|---|
| labelstring aria-label mặc định của danh sách bước. | Default (English)"Steps" | messagesVi"Các bước" |
| step(index: number) => string Tiền tố ẩn (sr-only) trước tiêu đề bước, theo sau là ":"; | Default (English)(index) => `Step ${index}` | messagesVi(index) => `Bước ${index}` |
| completestring Trạng thái đọc sau tiêu đề bước (sr-only). | Default (English)"completed" | messagesVi"đã hoàn thành" |
| currentstring | Default (English)"current step" | messagesVi"bước hiện tại" |
| upcomingstring | Default (English)"not started" | messagesVi"chưa thực hiện" |
| errorstring | Default (English)"error" | messagesVi"có lỗi" |
| optionalstring Nhãn của bước | Default (English)"Optional" | messagesVi"Tuỳ chọn" |
| progress(current: number, total: number) => string Dòng tóm tắt khi Stepper ngang thu gọn ở màn hẹp; | Default (English)(current, total) => `Step ${current} of ${total}` | messagesVi(current, total) => `Bước ${current}/${total}` |
| progressLabel(current: number, total: number) => string aria-label thanh tiến độ khi thu gọn. | Default (English)(current, total) => `Step ${current} of ${total}` | messagesVi(current, total) => `Bước ${current} trên ${total}` |
messages.wizard
| Key · Type | Default (English) | messagesVi |
|---|---|---|
| backstring | Default (English)"Back" | messagesVi"Quay lại" |
| nextstring | Default (English)"Next" | messagesVi"Tiếp tục" |
| finishstring | Default (English)"Finish" | messagesVi"Hoàn tất" |
| invalidstring Lỗi khi | Default (English)"Check the information in this step." | messagesVi"Vui lòng kiểm tra lại thông tin ở bước này." |
| validateFailedstring Lỗi khi | Default (English)"Couldn't validate this step. Try again." | messagesVi"Không kiểm tra được bước này. Hãy thử lại." |
| panel(current: number, total: number) => string Tên ẩn của vùng nội dung bước, theo sau là ": " và tiêu đề bước; | Default (English)(current, total) => `Step ${current} of ${total}` | messagesVi(current, total) => `Bước ${current}/${total}` |