Wizards & Multi-Step Forms
Interactive multi-step forms and wizards with Alpine.js for guiding users through complex processes.
Numbered Step Wizard
A classic wizard with numbered steps, connecting lines, and step-by-step navigation.
Account Information
Personal Details
Preferences
Review & Submit
- Account Status
- Ready to create
- Profile Completeness
- 100%
- Next Steps
- Click submit to create your account
<div x-data="{ step: 1 }">
<div class="wizard-steps">
<div class="wizard-step" :class="{ 'active': step === 1, 'completed': step > 1 }">
<div class="wizard-step-circle">
<span x-show="step <= 1">1</span>
<i class="bi bi-check" x-show="step > 1"></i>
</div>
<div class="wizard-step-label">Account Info</div>
</div>
<!-- More steps... -->
</div>
<div class="wizard-content" x-show="step === 1">
<!-- Step 1 content -->
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-outline-secondary" @click="step--" :disabled="step === 1">
Previous
</button>
<button class="btn btn-primary" @click="step++" x-show="step < 4">
Next
</button>
</div>
</div>
Icon Step Wizard
Use icons instead of numbers to represent each step in the wizard process.
Profile Information
Payment Details
Billing Address
Confirmation
Please review your details and click submit to complete the process.
<div x-data="{ step: 1 }">
<div class="wizard-steps">
<div class="wizard-step" :class="{ 'active': step === 1, 'completed': step > 1 }">
<div class="wizard-step-circle">
<i class="bi bi-person" x-show="step === 1"></i>
<i class="bi bi-check" x-show="step > 1"></i>
</div>
<div class="wizard-step-label">Profile</div>
</div>
<!-- More steps with different icons... -->
</div>
<div class="wizard-content" x-show="step === 1">
<h4><i class="bi bi-person me-2"></i>Profile Information</h4>
<!-- Step content -->
</div>
</div>
Progress Bar Wizard
A clean wizard design with a horizontal progress bar showing completion percentage with smooth transitions.
Step 1 of 4: Basic Information
Let's start with some basic details about you.
Step 2 of 4: Contact Information
How can we reach you?
Step 3 of 4: Security Settings
Secure your account with a strong password.
Step 4 of 4: All Done!
Setup Complete!
Your account is ready to use. Click submit to get started.
<div x-data="{ step: 1, totalSteps: 4 }">
<div class="wizard-progress-bar">
<div class="wizard-progress-percentage"
x-text="Math.round((step / totalSteps) * 100) + '%'"></div>
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated"
:style="`width: ${(step / totalSteps) * 100}%`">
</div>
</div>
<div class="wizard-step-labels">
<div class="step-label" :class="{ 'active': step === 1 }">Step 1</div>
<div class="step-label" :class="{ 'active': step === 2 }">Step 2</div>
</div>
</div>
<div class="wizard-content" x-show="step === 1">
<!-- Step content -->
</div>
</div>
Vertical Timeline Wizard
A vertical layout with timeline-style steps on the left and content on the right.
Project Details
Tell us about your project.
Team Members
Add people to your project team.
Project Settings
Configure your project preferences.
Ready to Launch
Project Summary
- Project name and description set
- Team members invited
- Settings configured
<div x-data="{ step: 1 }">
<div class="vertical-wizard">
<div class="vertical-wizard-steps">
<div class="vertical-wizard-step"
:class="{ 'active': step === 1, 'completed': step > 1 }"
@click="step = 1">
<div class="vertical-wizard-circle">
<span x-show="step <= 1">1</span>
<i class="bi bi-check" x-show="step > 1"></i>
</div>
<div class="vertical-wizard-label">Step 1</div>
</div>
<!-- More steps... -->
</div>
<div class="vertical-wizard-content">
<div class="wizard-content" x-show="step === 1">
<!-- Step content -->
</div>
</div>
</div>
</div>
Card-Based Wizard
An accordion-style wizard where each step is a card that expands when active.
Summary
- Company information completed
- Contact person details added
- Business address provided
<div x-data="{ step: 1 }">
<div class="wizard-card-step" :class="{ 'active': step === 1, 'completed': step > 1 }">
<div class="wizard-card-header" @click="step = 1">
<div class="wizard-card-number">
<span x-show="step <= 1">1</span>
<i class="bi bi-check" x-show="step > 1"></i>
</div>
<div class="flex-grow-1">
<strong>Step Title</strong>
<div class="small" x-show="step > 1">Completed</div>
</div>
<div>
<i class="bi bi-chevron-down" x-show="step !== 1"></i>
<i class="bi bi-chevron-up" x-show="step === 1"></i>
</div>
</div>
<div class="wizard-card-body" x-show="step === 1">
<!-- Step content -->
<button class="btn btn-primary" @click="step = 2">Continue</button>
</div>
</div>
<!-- More card steps... -->
</div>
Tab-Style Wizard
Bootstrap nav-tabs style wizard with active highlighting and checkmarks on completed steps.
Account Setup
Create your account credentials.
Profile Information
Tell us more about yourself.
Preferences & Settings
Customize your experience.
All Set!
Welcome Aboard!
Your account has been successfully created.
<div x-data="{ step: 1 }">
<div class="wizard-tabs">
<div class="wizard-tab" :class="{ 'active': step === 1, 'completed': step > 1 }" @click="step = 1">
<div class="wizard-tab-icon">
<span x-show="step <= 1">1</span>
<i class="bi bi-check" x-show="step > 1"></i>
</div>
<span>Account</span>
</div>
<!-- More tabs... -->
</div>
<div class="wizard-content" x-show="step === 1">
<!-- Step 1 content -->
</div>
</div>
Pills Progress Wizard
Modern pill-shaped indicators with connecting lines showing progress through each step.
Order Details
Provide information about your order.
Payment Information
Enter your payment details securely.
Order Confirmation
Order Summary
- Product:
- Professional Plan
- Quantity:
- 1
- Total:
- $29.99
<div x-data="{ step: 1 }">
<div class="wizard-pills">
<div class="wizard-pill" :class="{ 'active': step === 1, 'completed': step > 1 }">
<div class="wizard-pill-number">
<span x-show="step <= 1">1</span>
<i class="bi bi-check" x-show="step > 1"></i>
</div>
<span>Details</span>
</div>
<div class="wizard-pill-connector" :class="{ 'completed': step > 1 }"></div>
<!-- More pills... -->
</div>
<div class="wizard-content" x-show="step === 1">
<!-- Step content -->
</div>
</div>
Split-Screen Wizard
Modern SaaS-style onboarding with a dark sidebar navigation and white content area.
Personal Information
Company Information
Your Preferences
You're All Set!
Your account has been configured successfully.
What's Next?
- Explore your dashboard
- Invite team members
- Start your first project
- Customize your workspace
<div x-data="{ step: 1 }">
<div class="split-wizard">
<div class="split-wizard-sidebar">
<h3>Getting Started</h3>
<p>Complete these steps to set up your account</p>
<div class="split-wizard-step-list">
<div class="split-wizard-step-item"
:class="{ 'active': step === 1, 'completed': step > 1 }"
@click="step = 1">
<div class="split-wizard-step-number">1</div>
<div class="split-wizard-step-info">
<div class="split-wizard-step-title">Personal Info</div>
<div class="split-wizard-step-desc">Your basic details</div>
</div>
</div>
<!-- More steps... -->
</div>
</div>
<div class="split-wizard-content">
<div x-show="step === 1">
<!-- Step 1 content -->
</div>
</div>
</div>
</div>
Stepper with Validation
Form wizard with required field validation, error states, and success indicators. Cannot proceed to next step until all required fields are valid.
Personal Information
Contact Information
Address Information
All Done!
Your information has been validated successfully.
<div x-data="{
step: 1,
formData: { name: '', email: '', phone: '' },
touched: { name: false, email: false, phone: false },
isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
},
isStep1Valid() {
return this.formData.name.trim().length > 0 &&
this.formData.email.trim().length > 0 &&
this.isValidEmail(this.formData.email);
},
getFieldClass(field) {
if (!this.touched[field]) return '';
if (field === 'email') {
return this.formData[field].length > 0 &&
this.isValidEmail(this.formData[field]) ? 'is-valid' : 'is-invalid';
}
return this.formData[field].trim().length > 0 ? 'is-valid' : 'is-invalid';
}
}">
<div class="validation-wizard-steps">
<div class="validation-step" :class="{ 'active': step === 1, 'completed': step > 1 }">
<div class="validation-step-circle">
<span x-show="step <= 1">1</span>
<i class="bi bi-check" x-show="step > 1"></i>
</div>
<div class="validation-step-label">Personal Info</div>
</div>
</div>
<div class="wizard-content">
<div x-show="step === 1">
<div class="mb-3">
<label class="form-label">
Full Name <span class="required-indicator">*</span>
</label>
<input
type="text"
class="form-control"
:class="getFieldClass('name')"
x-model="formData.name"
@blur="touched.name = true">
</div>
</div>
</div>
<button
class="btn btn-primary"
@click="step++"
:disabled="!isStep1Valid()">
Next
</button>
</div>
Circular Progress Wizard
Modern dashboard-style wizard with a large circular progress indicator showing percentage completion.
Step 1: Choose Your Plan
Select the plan that works best for you
Step 2: Account Setup
Create your account credentials
Step 3: Customize
Personalize your experience
Step 4: Review & Confirm
Everything looks good!
<div x-data="{
step: 1,
totalSteps: 4,
get percentage() {
return Math.round((this.step / this.totalSteps) * 100);
},
get circumference() {
return 2 * Math.PI * 65;
},
get dashOffset() {
return this.circumference - (this.percentage / 100) * this.circumference;
}
}">
<div class="circular-progress-container">
<div class="circular-progress">
<svg viewBox="0 0 150 150">
<circle
class="circular-progress-bg"
cx="75" cy="75" r="65">
</circle>
<circle
class="circular-progress-fill"
cx="75" cy="75" r="65"
:stroke-dasharray="circumference"
:stroke-dashoffset="dashOffset">
</circle>
</svg>
<div class="circular-progress-text" x-text="percentage + '%'"></div>
</div>
<div class="circular-wizard-content">
<div x-show="step === 1">
<h4>Step 1: Choose Your Plan</h4>
<!-- Step content -->
</div>
</div>
<div class="d-flex gap-2">
<button class="btn btn-outline-secondary" @click="step--" x-show="step > 1">
Back
</button>
<button class="btn btn-primary" @click="step++" x-show="step < totalSteps">
Next
</button>
</div>
</div>
</div>