StepperCommandDialog
The StepperCommandDialog component provides a multi-step wizard dialog interface for executing commands, built on top of CommandStepper and the PrimeReact Stepper.
Purpose
Section titled “Purpose”StepperCommandDialog organizes a command form across multiple steps, guiding users through a wizard-like workflow. All steps gather into the same underlying command — the Submit button only appears when all fields across every step are valid and the user has reached the last step.
Key Features
Section titled “Key Features”- Multi-step wizard navigation with Previous and Next buttons
- All steps share a single command form — one command is submitted at the end
- Submit button only appears on the last step when all fields are valid
- Previous button hidden on the first step; Next button hidden on the last step
- Cancel via the X button in the upper-right corner — no footer Cancel button
- Step number circles change color to indicate validation state (red = errors, green = visited and valid)
- Non-active steps are visually dimmed to keep focus on the current step
- Busy state management during command execution
- All PrimeReact Stepper customization props available directly (orientation, headerPosition, pt, etc.)
- Supports any
CommandFormfield types inside eachStepperPanel - Full integration with Cratis Arc command system
Basic Usage
Section titled “Basic Usage”import { StepperCommandDialog } from '@cratis/components/CommandDialog';import { StepperPanel } from 'primereact/stepperpanel';import { InputTextField, TextAreaField, NumberField } from '@cratis/components/CommandForm/fields';import { CommandResult } from '@cratis/arc/commands';import { DialogResult, useDialog, useDialogContext } from '@cratis/arc.react/dialogs';
type CreateProjectResponse = { projectId: string;};
const CreateProjectDialog = () => { const { closeDialog } = useDialogContext<CommandResult<CreateProjectResponse>>();
return ( <StepperCommandDialog<CreateProject, CreateProjectResponse> command={CreateProject} title="Create New Project" okLabel="Create" onSuccess={(response) => { console.log('Project created:', response.projectId); closeDialog(DialogResult.Ok); }} onValidationFailure={(errors) => { console.error('Validation failed:', errors); }} onCancel={() => closeDialog(DialogResult.Cancelled)} > <StepperPanel header="Basic Info"> <InputTextField<CreateProject> value={c => c.name} title="Project Name" /> <InputTextField<CreateProject> value={c => c.email} title="Contact Email" type="email" /> </StepperPanel> <StepperPanel header="Details"> <TextAreaField<CreateProject> value={c => c.description} title="Description" rows={4} /> <NumberField<CreateProject> value={c => c.budget} title="Budget" /> </StepperPanel> </StepperCommandDialog> );};
function MyComponent() { const [CreateProjectDialogWrapper, showCreateProjectDialog] = useDialog(CreateProjectDialog);
return ( <> <button onClick={() => showCreateProjectDialog()}>Create Project</button> <CreateProjectDialogWrapper /> </> );}Required Props
Section titled “Required Props”command: Constructor for the command typetitle: Dialog title textchildren:StepperPanelelements defining each step
Dialog Props
Section titled “Dialog Props”visible: Boolean controlling dialog visibility (defaults totrue)initialValues: Initial values for the command formcurrentValues: Current values to populate the formonSuccess: Callback invoked on successful command execution with the typed responseonFailed: Callback invoked when command execution fails with the fullCommandResult<TResponse>onException: Callback invoked when the command throws an exception with error messages and stack traceonUnauthorized: Callback invoked when authorization failsonValidationFailure: Callback invoked on validation errors with the validation resultsonConfirm: Confirm callback — called only after successful command executiononCancel: Cancel callback — invoked when the X button is clickedonClose: Fallback close callbackokLabel: Label for the submit button shown on the last step when valid (default:'Submit')nextLabel: Label for the next step button (default:'Next')previousLabel: Label for the previous step button (default:'Previous')isValid: Additional validity gate combined with command form validitywidth: Dialog width (default:'600px')resizable: Whether the dialog can be resizedstyle: Custom CSS stylescontentStyle: Custom CSS styles for the dialog content areaonFieldValidate: Custom validation function for fieldsonFieldChange: Callback when field values changeonBeforeExecute: Transform command values before execution
Stepper Props
Section titled “Stepper Props”All PrimeReact Stepper customization props are available directly:
orientation:'horizontal'(default) or'vertical'headerPosition:'top','right','bottom', or'left'linear: Whether steps must be completed in order (default:true)onChangeStep: Callback when the active step changesstart: Custom content rendered before the stepper navigationend: Custom content rendered after the stepper navigationpt: PrimeReact PassThrough options for deep DOM customizationptOptions: PassThrough configuration optionsunstyled: Removes built-in component styles
Callback Behavior
Section titled “Callback Behavior”Result Callbacks
Section titled “Result Callbacks”StepperCommandDialog supports the following result callbacks that are invoked based on the command execution outcome:
onSuccess(response: TResponse): Invoked when the command executes successfully. Receives the typed response.onFailed(commandResult: CommandResult<TResponse>): Invoked when command execution fails for any reason.onException(messages: string[], stackTrace: string): Invoked when the command throws an exception.onUnauthorized(): Invoked when authorization fails.onValidationFailure(validationResults: ValidationResult[]): Invoked on validation errors.
Multiple callbacks may fire for the same execution. For example, both onFailed and onValidationFailure will be invoked for validation errors.
Dialog Callbacks
Section titled “Dialog Callbacks”onConfirmis executed only after command execution succeeds.- If
onConfirmreturnstrue, the dialog closes; otherwise it stays open. - If
onConfirmis not provided,onClose(DialogResult.Ok)is used. onCancelfollows the same behavior asDialog(truecloses).onClosecloses unless it returnsfalse.
Validation Indicators
Section titled “Validation Indicators”The step number circles in the wizard navigation bar reflect the validation state of each step:
| Circle color | Meaning |
|---|---|
| Red | The step contains at least one field with a validation error |
| Green | The step has been visited (navigated through) and all its fields are valid |
| Default (theme primary) | The step has not been visited yet |
Steps that are not currently active are dimmed to keep visual focus on the current step.
To show validation indicators immediately on open — before the user has touched any fields — pass the validateOnInit prop:
<StepperCommandDialog command={CreateProject} validateOnInit ...>This is useful when the dialog opens with pre-populated values that may already be partially invalid.
Navigation and Submit
Section titled “Navigation and Submit”| Step position | Footer content |
|---|---|
| First step | Next |
| Middle step | Previous, Next |
| Last step (invalid) | Previous |
| Last step (valid) | Previous, Submit |
Cancel is always available via the X button in the dialog header. The Submit button is hidden until the user reaches the last step and all command form fields across every step pass validation.
Busy State
Section titled “Busy State”StepperCommandDialog automatically manages a busy state during command execution:
- When Submit is clicked, the Submit button shows a loading spinner and all navigation buttons are disabled.
- Once execution completes (success or failure), the buttons return to their normal state.
Step Structure
Section titled “Step Structure”Each step is defined by a StepperPanel from primereact/stepperpanel. The header prop sets the step title shown in the stepper navigation:
<StepperPanel header="Contact Details"> <InputTextField<MyCommand> value={c => c.email} title="Email" /></StepperPanel>CommandForm fields placed inside a StepperPanel are automatically bound to the same command instance, regardless of which step they are on.
Integration
Section titled “Integration”StepperCommandDialog integrates with:
@cratis/arc/commandsfor command execution@cratis/arc.react/commandsfor form handling- PrimeReact Stepper and
StepperPanelcomponents for the wizard UI - PrimeReact
Dialogcomponent for the modal wrapper
See Also
Section titled “See Also”- Advanced Features - Field validation, transformation, and change tracking across steps
- CommandStepper - Standalone stepper foundation component