MultiStepForm
Responsive multi-step form state, navigation, and indicators.
Quick Preview
Composition
Use this public composition when building MultiStepForm:
MultiStepForm
├── MultiStepFormIndicator
├── MultiStepFormContent
├── MultiStepFormPrevious
└── MultiStepFormNextUsage
<MultiStepForm steps={steps} defaultValue="account" onValidate={onValidate}>
<MultiStepFormIndicator type="stepper" />
<MultiStepFormContent value="account">Account fields</MultiStepFormContent>
<MultiStepFormContent value="profile">Profile fields</MultiStepFormContent>
<MultiStepFormPrevious>Previous</MultiStepFormPrevious>
<MultiStepFormNext>Next</MultiStepFormNext>
</MultiStepForm>Examples
Stepper Indicator
Use type="stepper" for a full desktop stepper with clickable step indicators. On mobile, the current-step card becomes a dropdown trigger for fast step navigation.
Progress Indicator
Use type="progress" when the form should emphasize completion percentage instead of every step label. The current-step title is a dropdown trigger, so jumping to another step still flows through onValidate.
Step 2 of 3
67%
Next: Review
React Hook Form Validation
Keep form state in the consuming app. MultiStepForm only coordinates navigation and calls onValidate before moving forward. Adjacent forward moves validate the current step; skipped forward jumps validate every previous step before the target.
Props
| Prop/API | Type | Default | Description |
|---|---|---|---|
steps | MultiStepFormStep[] | - | Ordered step definitions with value, title, optional rendered description, and optional fields. |
value | string | - | Controlled active step value. |
defaultValue | string | first step | Uncontrolled initial active step value. |
onValueChange | (value, step, meta) => void | - | Called after navigation succeeds. |
onValidate | (value, direction, targetValue) => boolean | Promise<boolean> | - | Guards navigation. Return false to keep the current step active. Forward jumps call this for each prerequisite step before the target. |
type on MultiStepFormIndicator | "stepper" | "progress" | "stepper" | Switches between the stepper and progress visual treatments. |
progressValue on MultiStepFormIndicator | number | derived | Overrides the computed percentage. |
showNextLabel on MultiStepFormIndicator | boolean | true | Shows the next-step caption for progress indicators. |
currentStepAction on MultiStepFormIndicator | ReactNode | - | Optional affordance rendered beside the current step title trigger. |
forceMount on MultiStepFormContent | boolean | false | Keeps inactive step content mounted and hidden. |
useMultiStepForm | hook | - | Exposes next, previous, goTo, current step data, and boundary state. |
| native/root props | React component props | - | Passed through to the underlying elements. |
Accessibility
- Keep
MultiStepFormIndicatorvisible so users can understand their current position in the flow. - Step clicks and dropdown changes use the same
goTopath, so keeponValidatedeterministic and side-effect-light apart from user feedback. - Use real form labels and field errors from the consuming form library.
- Keep navigation buttons as
type="button"unless the active control should submit the form. - Use
onValidatefor forward navigation so users do not advance past required fields without clear errors.