Step Forms

A flexible multi-step form component with stepper indicators, navigation, and customizable steps.

Installation

bash
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:

bash
npm install lucide-react

Import

tsx
import { StepForms, type StepFormStep } from "@/components/ui/step-forms"

Examples

Dots Variant

Clean and minimal dots indicator for a modern look.

Personal InformationRequired
Enter your basic details
1 of 3
tsx
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

Required

Profile Details

Tell us about yourself

Verification

Verify your account

Required

All Set!

Your account is ready

Account SetupRequired
Create your account credentials
1 of 4

Must be at least 3 characters

At least 8 characters with mixed case

tsx
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.

Step 1 of 333% Complete
Personal InformationRequired
Enter your basic details
1 of 3
tsx
<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

Required

Preferences

Choose your preferences

Review & Submit

Review your information before submitting

Personal InformationRequired
Enter your basic details
1 of 3
tsx
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

Required

Preferences

Choose your preferences

Review & Submit

Review your information before submitting

Personal InformationRequired
Enter your basic details
1 of 3
tsx
<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

Required

Preferences

Choose your preferences

Personal InformationRequired
Enter your basic details
1 of 2
tsx
<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

PropTypeDefaultDescription
stepsStepFormStep[]-Array of step objects defining the form steps
currentStepnumber-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
showStepNumbersbooleantrueWhether to show step numbers in indicators
allowStepSkippingbooleanfalseWhether users can skip to any step
nextButtonTextstring"Next"Text for the next button
previousButtonTextstring"Previous"Text for the previous button
completeButtonTextstring"Complete"Text for the complete button
cancelButtonTextstring"Cancel"Text for the cancel button

StepFormStep Interface

PropertyTypeDescription
idstringUnique identifier for the step
titlestringTitle of the step
descriptionstring?Optional description of the step
contentReact.ReactNodeContent to display for the step
optionalboolean?Whether the step is optional
requiredboolean?Whether the step is required (shows required indicator)