Stepper
The Stepper component provides a complete solution for multi-step forms and wizards. Features smooth Framer Motion animations, multiple indicator variants, and flexible navigation controls.
Installation
npm install @craftdotui/components
Import
import {
Stepper ,
StepperContent ,
Step ,
StepTitle ,
StepDescription ,
StepIndicator ,
StepperNavigation ,
} from "@craftdotui/components" ;
Usage
Basic Stepper
Progress Bar Indicator
Custom Styling
import {
Stepper ,
StepperContent ,
Step ,
StepTitle ,
StepDescription ,
StepIndicator ,
StepperNavigation ,
} from "@craftdotui/components" ;
export default function Example () {
return (
< Stepper totalSteps = { 3 } >
< StepIndicator variant = "dots" />
< StepperContent >
< Step step = { 1 } >
< StepTitle > Personal Information </ StepTitle >
< StepDescription > Enter your basic details </ StepDescription >
{ /* Form fields */ }
</ Step >
< Step step = { 2 } >
< StepTitle > Contact Details </ StepTitle >
< StepDescription > How can we reach you? </ StepDescription >
{ /* Form fields */ }
</ Step >
< Step step = { 3 } >
< StepTitle > Review </ StepTitle >
< StepDescription > Confirm your information </ StepDescription >
{ /* Summary */ }
</ Step >
</ StepperContent >
< StepperNavigation onFinish = { () => console . log ( "Completed!" ) } />
</ Stepper >
);
}
Components
Stepper (Root)
The stepper content including steps and navigation.
Total number of steps in the stepper.
Initial active step (0-indexed).
Callback fired when the step changes.
Step
StepIndicator
variant
'dots' | 'fraction' | 'progress' | 'numbers' | 'text'
default: "'dots'"
Visual style of the step indicator.
StepperNavigation
Callback fired when the last step’s “Finish” button is clicked.
Animation Details
Step Transition
initial = {{ opacity : 0 , y : 10 }}
animate = {{ opacity : 1 , y : 0 }}
exit = {{ opacity : 0 , y : - 10 }}
Progress Bar Animation
< motion.div
className = "bg-black dark:bg-zinc-700 h-2 rounded-full"
initial = { { width: 0 } }
animate = { { width: ` ${ progress } %` } }
/>
Indicator Dot Animation
initial = {{ scale : 1 }}
animate = {{ scale : index === currentStep ? 1.5 : 1 }}
All step transitions use AnimatePresence with mode="wait" for smooth enter/exit animations.
Hook: useStepper
Access stepper state and controls from any child component:
import { useStepper } from "@craftdotui/components" ;
function CustomStepContent () {
const { currentStep , totalSteps , goToNextStep , goToPreviousStep , isLastStep } = useStepper ();
return (
< div >
< p > Step { currentStep + 1 } of { totalSteps } </ p >
< button onClick = { goToNextStep } > Next </ button >
</ div >
);
}
Examples
Onboarding Flow
import { Stepper , Step , StepTitle , StepDescription , StepIndicator , StepperNavigation } from "@craftdotui/components" ;
import { User , Mail , Shield , Check } from "lucide-react" ;
export default function OnboardingFlow () {
const handleComplete = () => {
// Save user data and redirect
window . location . href = "/dashboard" ;
};
return (
< Stepper totalSteps = { 4 } className = "max-w-3xl mx-auto" >
< StepIndicator variant = "progress" className = "mb-12" />
< StepperContent >
< Step step = { 1 } >
< div className = "text-center" >
< User className = "w-16 h-16 mx-auto mb-4 text-blue-500" />
< StepTitle > Create Your Profile </ StepTitle >
< StepDescription > Tell us about yourself </ StepDescription >
< input className = "mt-4 w-full p-3 border rounded" placeholder = "Full Name" />
< input className = "mt-3 w-full p-3 border rounded" placeholder = "Username" />
</ div >
</ Step >
< Step step = { 2 } >
< div className = "text-center" >
< Mail className = "w-16 h-16 mx-auto mb-4 text-green-500" />
< StepTitle > Verify Email </ StepTitle >
< StepDescription > We've sent a code to your email </ StepDescription >
< input className = "mt-4 w-full p-3 border rounded text-center text-2xl tracking-widest" placeholder = "000000" maxLength = { 6 } />
</ div >
</ Step >
< Step step = { 3 } >
< div className = "text-center" >
< Shield className = "w-16 h-16 mx-auto mb-4 text-purple-500" />
< StepTitle > Set Preferences </ StepTitle >
< StepDescription > Customize your experience </ StepDescription >
{ /* Preference checkboxes */ }
</ div >
</ Step >
< Step step = { 4 } >
< div className = "text-center" >
< Check className = "w-16 h-16 mx-auto mb-4 text-green-500" />
< StepTitle > All Set! </ StepTitle >
< StepDescription > You're ready to get started </ StepDescription >
</ div >
</ Step >
</ StepperContent >
< StepperNavigation onFinish = { handleComplete } className = "mt-12" />
</ Stepper >
);
}
Multi-Step Form with Validation
import { useState } from "react" ;
import { Stepper , Step , StepIndicator , PrevStep , NextStep , useStepper } from "@craftdotui/components" ;
function StepOne () {
const { goToNextStep } = useStepper ();
const [ valid , setValid ] = useState ( false );
return (
< div >
< h3 > Personal Info </ h3 >
< input onChange = { ( e ) => setValid ( e . target . value . length > 0 ) } />
< button onClick = { goToNextStep } disabled = { ! valid } > Continue </ button >
</ div >
);
}
export default function MultiStepForm () {
return (
< Stepper totalSteps = { 3 } >
< StepIndicator variant = "numbers" />
< StepperContent >
< Step step = { 1 } >< StepOne /></ Step >
< Step step = { 2 } > { /* Step 2 content */ } </ Step >
< Step step = { 3 } > { /* Step 3 content */ } </ Step >
</ StepperContent >
</ Stepper >
);
}
E-commerce Checkout
import { Stepper , Step , StepTitle , StepIndicator , StepperNavigation } from "@craftdotui/components" ;
export default function CheckoutFlow () {
return (
< Stepper totalSteps = { 3 } >
< StepIndicator variant = "text" />
< StepperContent >
< Step step = { 1 } >
< StepTitle > Shipping Information </ StepTitle >
{ /* Address form */ }
</ Step >
< Step step = { 2 } >
< StepTitle > Payment Method </ StepTitle >
{ /* Payment form */ }
</ Step >
< Step step = { 3 } >
< StepTitle > Order Review </ StepTitle >
{ /* Order summary */ }
</ Step >
</ StepperContent >
< StepperNavigation
onFinish = { () => {
// Process order
submitOrder ();
} }
/>
</ Stepper >
);
}
Use the onStepChange callback to track analytics or save progress as users navigate through steps.
Indicator Variants
Dots (Default)
Simple, animated dots indicating progress.
Fraction
Displays “Step X of Y” text.
Progress
Linear progress bar filling from 0-100%.
Numbers
Clickable numbered buttons for each step.
Text
Text labels showing “Step 1”, “Step 2”, etc.
Best Practices
Keep steps between 3-7 for optimal user experience
Provide clear titles and descriptions for each step
Validate data before allowing navigation to next step
Show progress clearly with appropriate indicator variant
Allow users to go back to edit previous steps
Persist data across steps
Provide helpful error messages
Accessibility
Uses semantic <fieldset> and <legend> elements
Proper ARIA labels for navigation buttons
Keyboard navigation support
Screen reader announcements for step changes
Disabled state for navigation when appropriate