Mischief

91 / Controls

Stepper

Where someone is in something with a beginning and an end, said in words as well as drawn.

Installation

Copy the source into your project, or keep it behind a package.

npx shadcn@latest add Tinkerers-Labs/mischief-ui/stepper
import { Stepper } from "mischief-ui/stepper"
Also installs
  • lucide-react

Or paste it in yourself. The source imports the shared cn helper from @/lib/utils, so point that at your own copy.

registry/default/stepper/stepper.tsx
"use client" import * as React from "react"import { Check } from "lucide-react"import { cn } from "@/lib/utils" export type Step = {  id: string  label: string  description?: string} export type StepperProps = Omit<  React.HTMLAttributes<HTMLElement>,

Usage

export function Setup({ step }) {
  return (
    <Stepper
      current={step}
      steps={[
        { id: "account", label: "Account", description: "Name and email" },
        { id: "workspace", label: "Workspace" },
        { id: "done", label: "Done" },
      ]}
    />
  )
}

Progress that does not live in a colour

A filled circle means finished and an outlined one means not started, and neither of those is available to a reader who cannot see them. So each step also carries its state as text: finished, in progress, or not started, read after its name.

The current step is marked as the current step in the page, which is how assistive technology finds it without being told where to look.

Going back only when there is somewhere to go

Pass onSelect and finished steps become buttons that return to them. Leave it out and nothing in the stepper is interactive, which is the right default: most steppers report progress rather than offering navigation, and a control that looks pressable and is not is worse than no control.

Steps ahead of the current one are never reachable, whether or not onSelect is passed.

API

stepsStep[]The steps, in order.
currentnumberIndex of the step being worked on.
orientation"horizontal" | "vertical"Which way it runs. Defaults to "horizontal".
onSelect(index, step) => voidMakes finished steps revisitable. Without it they are not.
labelstringNames the navigation. Defaults to "Progress".

Step

idstringIdentifies the step.
labelstringWhat it is called.
descriptionstringAn optional line underneath.

Accessibility

A navigation landmark holding an ordered list. Each step's state is written out after its name, the current step is marked as current, and the connecting lines are hidden. Revisitable steps are real buttons, named with where they go, and steps ahead are never among them.