Stepper

A read-only display of progress through a multi-step flow.

StableSource
  1. Account, Completed
  2. Shipping, Current step
  3. Payment, Not started
  4. Review, Not started

Import

tsx
import { Stepper } from "@merid/react";

Anatomy

tsx
<Stepper.Root current={0}>
  <Stepper.Step title="…" description="…" />
</Stepper.Root>
  • Stepper.Root — an ordered list. current is the zero-based index of the active step; earlier steps are complete, later ones upcoming.
  • Stepper.Step — one step with a numbered marker (a check when complete), a title and an optional description.

Examples

Vertical with descriptions

  1. Create workspaceName and region, Completed
  2. Invite teamAdd up to 10 people, Completed
  3. Connect dataImport from CSV or an API, Current step
  4. Go live, Not started

Responsive behaviour

In horizontal orientation, titles and descriptions stay on one line and truncate with an ellipsis; string titles keep the full text in a title attribute. The stepper measures its own width (a CSS container query, not the viewport): below 560px it switches to a compact layout where only the current step shows its title and the others collapse to their numbered or checked markers. Collapsed titles stay in the accessibility tree, so screen readers hear every step either way, and narrow columns need no JavaScript or orientation switch.

API reference

Stepper.Root

Renders <ol> and accepts all its HTML attributes.

PropTypeDefaultDescription
currentRequirednumber–Zero-based index of the current step. Steps before it are complete.
orientation"horizontal" | "vertical""horizontal"Layout direction.
aria-labelstring"Progress"Accessible name for the step list.
refRef<HTMLOListElement>–Forwarded ref to the list.

Stepper.Step

Renders <li> and accepts its HTML attributes except title. Must be a direct child of Stepper.Root.

PropTypeDefaultDescription
titleRequiredReactNode–Step name.
descriptionReactNode–Optional supporting line.
statusLabelsPartial<Record<"complete" | "current" | "upcoming", string>>{ complete: "Completed", current: "Current step", upcoming: "Not started" }Screen-reader status words appended to each step.

Styling

  • .mrd-stepper[data-orientation] — root list, horizontal or vertical.
  • .mrd-stepper__step[data-state] — complete, current or upcoming.
  • .mrd-stepper__marker — 28px circle: --mrd-tray when upcoming, a 1.5px --mrd-accent ring when current, --mrd-accent-soft when complete.
  • .mrd-stepper__title / .mrd-stepper__description — text; the title turns --mrd-ink on the current step.
  • .mrd-stepper__step::after — the 1px --mrd-line connector between steps.

Accessibility

There is no APG pattern for steppers. It is a static ordered list — the same structure the APG landmark and list guidance recommends for structured content — and it is not interactive.

  • The list is named "Progress" by default; set aria-label to describe the flow.
  • The current step has aria-current="step".
  • Each step ends with a visually hidden status word ("Completed", "Current step", "Not started"), overridable with statusLabels for localisation.
  • Markers are aria-hidden; the number is conveyed by list position.

Steps are not focusable, so there are no keyboard interactions. If people can jump back to a step, put links or buttons inside the step content.

Guidelines

Do

Use short, noun-like step titles and keep the number of steps between three and six.

Avoid

Use a stepper as tabs or as the only way to navigate between steps.

Do

Localise statusLabels along with the titles.

Avoid

Mark a step complete before its data is actually saved.