Step Forms
A flexible multi-step form component with stepper indicators, navigation, and customizable steps.
Installation
npx fivui add step-forms
This will add the step-forms component to your project along with all required dependencies.
Manual Installation
If you prefer to install manually, you'll need to install the required dependencies:
npm install lucide-react
Import
import { StepForms, type StepFormStep } from "@/components/ui/step-forms"
Examples
Dots Variant
Clean and minimal dots indicator for a modern look.
const [dotsFormData, setDotsFormData] = React.useState({ firstName: '', lastName: '', email: ''})
const validateDotsStep = (stepId: string, stepIndex: number) => { if (stepId === "personal") { const { firstName, lastName, email } = dotsFormData const isValid = firstName.trim() !== "" && lastName.trim() !== "" && email.trim() !== "" return { isValid, errors: isValid ? [] : ["Please fill in all required fields"] } } return { isValid: true }}
const steps = [ { id: "personal", title: "Personal Information", required: true, content: ( <div className="space-y-4"> <Input value={dotsFormData.firstName} onChange={(e) => setDotsFormData(prev => ({ ...prev, firstName: e.target.value }))} placeholder="First Name" required /> <Input value={dotsFormData.lastName} onChange={(e) => setDotsFormData(prev => ({ ...prev, lastName: e.target.value }))} placeholder="Last Name" required /> <Input value={dotsFormData.email} onChange={(e) => setDotsFormData(prev => ({ ...prev, email: e.target.value }))} placeholder="Email" type="email" required /> </div> ) }]
<StepForms steps={steps} variant="dots" onValidate={validateDotsStep} onComplete={() => console.log("Form completed!")}/>
Enhanced Stepper with Required Fields
Features connecting lines, required field indicators, smooth animations, and improved visual design.
Account Setup
Create your account credentials
Profile Details
Tell us about yourself
Verification
Verify your account
All Set!
Your account is ready
Must be at least 3 characters
At least 8 characters with mixed case
const validateStep = (stepId: string, stepIndex: number) => { // Handle server-side rendering if (typeof window === 'undefined') return { isValid: true } if (stepId === "account") { const username = (document.getElementById("username") as HTMLInputElement)?.value || "" const email = (document.getElementById("email-new") as HTMLInputElement)?.value || "" const password = (document.getElementById("password") as HTMLInputElement)?.value || "" const confirmPassword = (document.getElementById("confirm-password") as HTMLInputElement)?.value || "" const isValid = username.trim() !== "" && email.trim() !== "" && password.trim() !== "" && confirmPassword.trim() !== "" && password === confirmPassword return { isValid, errors: isValid ? [] : ["Please fill in all required fields and ensure passwords match"] } } if (stepId === "verification") { const verificationCode = (document.getElementById("verification-code") as HTMLInputElement)?.value || "" const isValid = verificationCode.trim().length === 6 return { isValid, errors: isValid ? [] : ["Please enter a valid 6-digit verification code"] } } return { isValid: true }}
const steps: StepFormStep[] = [ { id: "account", title: "Account Setup", description: "Create your account credentials", required: true, content: ( <div className="space-y-4"> <div className="space-y-2"> <Label htmlFor="username">Username *</Label> <Input id="username" placeholder="Enter username" required /> </div> <div className="space-y-2"> <Label htmlFor="email-new">Email Address *</Label> <Input id="email-new" type="email" placeholder="your@email.com" required /> </div> </div> ), }, { id: "verification", title: "Verification", description: "Verify your account", required: true, content: ( <div className="space-y-4"> <div className="space-y-2"> <Label htmlFor="verification-code">Verification Code *</Label> <Input id="verification-code" placeholder="Enter 6-digit code" maxLength={6} required value={enhancedFormData.verificationCode} onChange={(e) => setEnhancedFormData(prev => ({ ...prev, verificationCode: e.target.value }))} /> </div> </div> ), }, // ... more steps]
<StepForms steps={steps} onValidate={validateStep} onComplete={() => console.log("Form completed!")}/>
Progress Bar Variant
Shows completion percentage with a progress bar.
<StepForms steps={steps} variant="progress" onComplete={() => console.log("Form completed!")}/>
Controlled Component
Control the current step externally with your own state management.
Personal Information
Enter your basic details
Preferences
Choose your preferences
Review & Submit
Review your information before submitting
import { useState } from "react"
export default function ControlledForm() { const [currentStep, setCurrentStep] = useState(0) return ( <StepForms steps={steps} currentStep={currentStep} onStepChange={setCurrentStep} onComplete={() => console.log("Form completed!")} /> )}
Allow Step Skipping
Enable users to jump to any step by clicking on the step indicators.
Personal Information
Enter your basic details
Preferences
Choose your preferences
Review & Submit
Review your information before submitting
<StepForms steps={steps} allowStepSkipping={true} onComplete={() => console.log("Form completed!")}/>
Custom Button Text
Customize all button labels to match your application's terminology.
Personal Information
Enter your basic details
Preferences
Choose your preferences
<StepForms steps={steps} nextButtonText="Continue" previousButtonText="Go Back" completeButtonText="Finish" cancelButtonText="Exit" onComplete={() => console.log("Form completed!")} onCancel={() => console.log("Form cancelled!")}/>
API Reference
StepForms Props
Prop | Type | Default | Description |
---|---|---|---|
steps | StepFormStep[] | - | Array of step objects defining the form steps |
currentStep | number | - | Current step index (for controlled component) |
onStepChange | (step: number) => void | - | Callback fired when step changes |
onComplete | () => void | - | Callback fired when form is completed |
onCancel | () => void | - | Callback fired when form is cancelled |
variant | "default" | "dots" | "progress" | "default" | Visual variant of the stepper |
orientation | "horizontal" | "vertical" | "horizontal" | Layout orientation of the stepper |
showStepNumbers | boolean | true | Whether to show step numbers in indicators |
allowStepSkipping | boolean | false | Whether users can skip to any step |
nextButtonText | string | "Next" | Text for the next button |
previousButtonText | string | "Previous" | Text for the previous button |
completeButtonText | string | "Complete" | Text for the complete button |
cancelButtonText | string | "Cancel" | Text for the cancel button |
StepFormStep Interface
Property | Type | Description |
---|---|---|
id | string | Unique identifier for the step |
title | string | Title of the step |
description | string? | Optional description of the step |
content | React.ReactNode | Content to display for the step |
optional | boolean? | Whether the step is optional |
required | boolean? | Whether the step is required (shows required indicator) |