Review Step

Lists every answer of a multi-step form by step with Edit links before submit, flagging empty, missing and changed answers.

StopsWrong answer submitted in a wizard

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/review-step.json

The files land in your project. They're yours to edit.

Usage

review-step-usage.tsx
import { ReviewStep, type ReviewGroup } from "@/components/ui/review-step"

<ReviewStep
  steps={steps}
  previous={lastTime}
  onEdit={(step, field) => setEditing({ step, field })}
  onSubmit={() => new Promise((resolve) => setTimeout(resolve, 900))}
  submitLabel="Confirm and pay ₹4,990"
/>

What it catches

  • Missing required answers, blocking submit
  • Empty optional fields, shown as "Not provided"
  • Values changed since the previous submission
  • A click carried over from the previous step's button (guard window)
  • Repeat clicks while the submit is pending

Props

ReviewStep props
PropTypeDefault
steps* (required)

Every step of the form with its answers, in order.

ReviewGroup[]—
previous

Answers from the last submission, keyed by field id. Changed answers are highlighted.

Record<string, ReviewValue>—
onEdit* (required)

Jump back to a step, focusing that field when `fieldId` is given.

(stepId: string, fieldId?: string) => void—
onSubmit* (required)

Sends the form. Return a promise to show a pending state; a rejection re-enables submit.

() => void | Promise<void>—
guard

Clicks sooner than this (ms) after the review appears are ignored, so a double-click or held Enter on "Next" can't submit.

number700
heading

Heading above the review.

string"Check your answers"
submitLabel

Label of the submit button.

string"Submit"
pendingLabel

Submit label while onSubmit runs.

string"Submitting…"
doneLabel

Submit label after success.

string"Submitted"
editLabel

Label of each Edit button.

string"Edit"
addLabel

Label shown instead of Edit for an empty field.

string"Add"
emptyText

Shown for an empty optional answer.

string"Not provided"
missingText

Shown for a missing required answer.

string"Answer required"
changedText

Marks a value changed since last time.

string"Changed"
errorText

Shown when onSubmit rejects.

string"Couldn't submit. Nothing was sent, so you can try again."
missingHint

Under a blocked submit button. `{fields}` lists what is missing.

string"Answer {fields} to submit."

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Each step is a section labelled by its title
  • Edit/Add buttons have aria-labels naming the step or field
  • Submit is described by the missing-answers note; errors use role=alert
  • Changed values have a sr-only "Previously:" prefix

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Validate every answer again and make the final submit idempotent on the server.

  • Duplicate protection is client-side only
  • Display formatting is yours (pass format for money or masking)

What it stops

Wrong answer submitted in a wizard

Also known as

review page · summary step · confirm details · wizard · stepper · multi-step form · checkout review · application review

Dependencies

Pairs well with