Components · Forms

Multi-step form

A wizard that chunks a long form into ordered steps: a ProgressSteps header carries the done / current / upcoming state, the body renders only the current step's Fields (Label + Input/Select with hint & error wiring), and the footer pairs a Back (secondary) with a Continue (primary). Shown mid-flow — step 2 of 4 of a foster-volunteer application.

wizard shell · step 2 of 4 · stepper header + Field body + footer
  1. Your details
  2. Availability
  3. Skills & foster
  4. Review & submit

Step 2 of 4

Your availability

Tell us where and when you can help — you can change any of this later from your portal.

Queens, NY

A rough estimate is fine — most fosters give 4–8.

2026-07-03
We have a fenced yard and a calm senior lab — happy to take medical-hold or bottle-baby cases

Optional. Anything that helps us match the right dog to your home.

Step 2 of 4

Foster application — Marisol Vega. The header is a live ProgressSteps ordered list: step 1 completed (check + accent connector), step 2 aria-current="step" (number + ring halo), 3–4 pending. The body renders only the current step; the start-date field is in its error state (invalid ring + aria-describedby message).

marker states · vertical run · first & final-step footers
marker states — done / current / upcoming
Done
Current
Upcoming

Done + current share the accent fill (a completed step shows a check, current shows its number); the ring halo marks aria-current. Upcoming is a surface-3 muted circle.

orientation="vertical" — labels + descriptions
  1. Application received

    Submitted 12 min ago

  2. Home check scheduled

    Coordinator confirms your space

  3. Dog matched

    We pair you with an intake case

footer — first step (Back inert)
Step 1 of 4

On the first step there's nowhere to go back to — Back renders disabled (neutral inert face) while Continue stays primary.

footer — final step (primary submits)
Step 4 of 4

On the last step Continue becomes the terminal action — the primary carries the submit label; Back stays available.

steps / status
ProgressStep[] — each { label, status } where status is completed | current | pending. Completed + current fill accent (check vs number); pending is a muted surface-3 circle.
orientation
horizontal (default) lays circles + connectors in a row with labels beneath; vertical stacks them with labels — and optional descriptions — to the side.
connector semantics
The connector after a step turns accent only when that step is completed, so the accent run visually tracks progress up to the current step.
step body — Field
Each field is a Field: Label htmlFor + control + a hint or error. On error the message id is wired via aria-describedby and the control gets aria-invalid (the invalid ring).
footer pairing
Right-aligned Back (secondary) + Continue (primary) — the same primary + ghost/secondary rule as the Buttons page. First step disables Back; the final step's primary carries the submit label.
a11y
The header is an <ol> with a per-step aria-label (label + status suffix) and aria-current="step" on the active step; the ring halo is the visible echo of that state.

Source · ui/ProgressSteps.tsx (the stepper header) + ui/Field.tsx · Label.tsx · Input.tsx · Select.tsx (the step body) + ui/Button.tsx (the secondary + primary footer). The wizard shell composes these DS primitives on the Card/Surface primitive.