Skip to content

Repository files navigation

@payloadcms/plugin-wizard-form

A multi-step wizard form plugin for Payload CMS that extends the official form builder with:

  • Multi-step wizard navigation - Break forms into logical steps with progress indicator
  • Conditional field display - Show/hide fields based on other field values
  • Calculated fields - Auto-compute values from formulas
  • Server-side validation - Formulas are re-computed on the server to prevent tampering
  • Tailwind CSS styling - Beautiful, customizable UI with CSS variables

Installation

npm install plugin-wizard-form
# or
pnpm add plugin-wizard-form
# or
yarn add plugin-wizard-form

Peer Dependencies

This plugin requires the following peer dependencies:

  • payload ^3.0.0
  • @payloadcms/plugin-form-builder ^3.0.0
  • react ^18.0.0 || ^19.0.0
  • react-dom ^18.0.0 || ^19.0.0

Quick Start

1. Add the Plugin to Payload Config

// payload.config.tsimport{buildConfig}from'payload'import{wizardFormPlugin}from'@payloadcms/plugin-wizard-form'exportdefaultbuildConfig({// ... your configplugins: [wizardFormPlugin({// Optional: pass form builder optionsformBuilderOptions: {redirectRelationships: ['pages'],},}),],})

2. Create a Wizard Form in Payload Admin

  1. Go to Forms collection in Payload admin
  2. Create a new form
  3. Check Enable Wizard Mode in the sidebar
  4. Add your form fields
  5. For each field, expand Wizard Settings to configure:
    • Step Number - Which wizard step this field belongs to (default: 1)
    • Step Label - Label shown in the step indicator (set on first field of each step)
    • Conditional Display - Show this field only when conditions are met
    • Calculated Field - Make this a read-only computed field

3. Render the Form in Next.js

// app/contact/page.tsximport{WizardForm}from'@payloadcms/plugin-wizard-form/client'import'@payloadcms/plugin-wizard-form/styles.css'exportdefaultfunctionContactPage(){return(<divclassName="max-w-2xl mx-auto py-12"><WizardFormform="your-form-id"onSuccess={()=>console.log('Form submitted!')}onError={(error)=>console.error(error)}/></div>)}

Or with a pre-fetched form:

import{getPayload}from'payload'import{WizardForm}from'@payloadcms/plugin-wizard-form/client'exportdefaultasyncfunctionContactPage(){constpayload=awaitgetPayload({ config })constform=awaitpayload.findByID({collection: 'forms',id: 'your-form-id',})return<WizardFormform={form}/>}

Configuration

Plugin Options

wizardFormPlugin({// Form builder options (passed through to @payloadcms/plugin-form-builder)formBuilderOptions: {redirectRelationships: ['pages'],// ... other form builder options},// Custom field blocks with wizard settingscustomBlocks: {// Your custom blocks will be extended with wizard settings},// Enable/disable server-side formula validation (default: true)enableServerValidation: true,// Additional form collection fieldsformOverrides: {fields: [// Additional fields for the Form collection],},// Additional form submission fieldsformSubmissionOverrides: {fields: [// Additional fields for the Form Submission collection],},})

WizardForm Component Props

PropTypeDefaultDescription
formstring | WizardFormTyperequiredForm ID or populated form object
hiddenFieldsstring[][]Field names to hide
fieldComponentsRecord<string, FieldComponent>-Custom field components (override defaults)
classNamesWizardClassNames-CSS class overrides for styling
nextLabelstring"Next"Next button label
prevLabelstring"Previous"Previous button label
submitLabelstring"Submit"Submit button label
submitEndpointstring"/api/form-submissions"API endpoint for submissions
onSuccess() => void-Callback after successful submission
onError(error: Error) => void-Callback on submission error
onStepChange(step: number) => void-Callback when step changes

Wizard Settings

Step Configuration

Each form field has a Wizard Settings section with:

SettingDescription
Step NumberWhich wizard step this field appears on (default: 1)
Step LabelLabel for the step indicator (set on first field of each step)

Conditional Display (showIf)

Show/hide fields based on other field values:

OptionDescription
FieldName of the field to check
Operatorequals, notEquals, in, notIn, exists, notExists
ValueValue to compare (comma-separated for in/notIn)

Example: Show "Company Name" only when "Account Type" equals "business":

  • Field: accountType
  • Operator: equals
  • Value: business

Calculated Fields

Create read-only computed fields:

OptionDescription
FormulaMathematical expression (e.g., quantity * price)
Output KeyKey name for the computed result

Supported operations:

  • Basic arithmetic: +, -, *, /
  • Parentheses for grouping: (a + b) * c
  • Field references by name: quantity, price
  • Numeric literals: 100, 0.5

Custom Field Components

Override default field components with your own:

import{WizardForm}from'@payloadcms/plugin-wizard-form/client'constCustomTextInput=({ name, label, value, onChange, error, required })=>(<div><label>{label}{required&&'*'}</label><inputname={name}value={value||''}onChange={(e)=>onChange(e.target.value)}/>{error&&<spanclassName="error">{error}</span>}</div>)exportdefaultfunctionMyForm(){return(<WizardFormform="my-form-id"fieldComponents={{text: CustomTextInput,// Override other field types...}}/>)}

Styling

Using Tailwind CSS

Add the package to your Tailwind content configuration:

// tailwind.config.jsmodule.exports={content: [// ... your content'./node_modules/@payloadcms/plugin-wizard-form/dist/**/*.{js,mjs}',],}

CSS Variables

Customize colors using CSS variables:

:root {
--wizard-primary:#3b82f6;
--wizard-primary-hover:#2563eb;
--wizard-secondary:#6b7280;
--wizard-success:#22c55e;
--wizard-error:#ef4444;
--wizard-border:#e5e7eb;
--wizard-background:#ffffff;
--wizard-foreground:#111827;
--wizard-muted:#f3f4f6;
--wizard-muted-foreground:#6b7280;
}
/* Dark theme */
[data-theme="dark"] {
--wizard-primary:#60a5fa;
--wizard-background:#1f2937;
/* ... */
}

Class Name Overrides

Use the classNames prop for fine-grained control:

<WizardFormform="my-form"classNames={{root: 'my-custom-form',content: 'px-6 py-4',stepIndicator: 'mb-8',field: 'mb-4',navigation: 'mt-8',}}/>

useWizardForm Hook

For custom implementations, use the useWizardForm hook:

import{useWizardForm}from'@payloadcms/plugin-wizard-form/client'functionCustomWizardForm({ fields }){const{
currentStep,
steps,
isFirstStep,
isLastStep,
formValues,
isCurrentStepValid,
setValue,
goToNext,
goToPrevious,}=useWizardForm({
fields,onStepChange: (step)=>console.log('Step:',step),})return(<div><h2>{currentStep?.label}</h2>{/* Render your custom form UI */}</div>)}

Server-Side Security

All calculated fields are re-computed on the server before saving to prevent client-side tampering. The computed values are stored in a computed JSON field on the form submission.

To disable server-side validation (not recommended):

wizardFormPlugin({enableServerValidation: false,})

Example: Multi-Step Registration Form

Step 1: Account Information

  • Email (required)
  • Account Type (select: personal/business)
  • Company Name (conditional: only when Account Type = business)

Step 2: Contact Details

  • Full Name (required)
  • Phone Number
  • Address

Step 3: Order Summary

  • Quantity (number)
  • Unit Price (number)
  • Total Price (calculated: quantity * unitPrice)

API Reference

Exports from @payloadcms/plugin-wizard-form

// Pluginexport{wizardFormPlugin}from'@payloadcms/plugin-wizard-form'// Configexport{wizardFieldsConfig,getWizardFieldsConfig}from'@payloadcms/plugin-wizard-form'// Server-side hookexport{recomputeFormulas}from'@payloadcms/plugin-wizard-form'// Utilitiesexport{computeFormula,validateFormula,evaluateShowIf,buildSteps,}from'@payloadcms/plugin-wizard-form'

Exports from @payloadcms/plugin-wizard-form/client

// Componentsexport{WizardForm,StepIndicator,StepNavigation}from'@payloadcms/plugin-wizard-form/client'// Field componentsexport{Text,Textarea,Email,Number,Date,Select,Radio,Checkbox,Message,CalculatedField,FieldWrapper,}from'@payloadcms/plugin-wizard-form/client'// UI primitivesexport{Button,Input,Label}from'@payloadcms/plugin-wizard-form/client'// Hooksexport{useWizardForm}from'@payloadcms/plugin-wizard-form/client'

License

MIT License - see LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages