Step Components
Beautiful step components built with TailwindCSS. Perfect for wizards, onboarding flows, and progress tracking.
1. Basic Step Indicator
A simple horizontal step indicator with numbered circles and connecting lines.
<!-- Basic Step Indicator -->
<div class="max-w-2xl mx-auto">
<div class="flex items-center justify-between">
<div class="flex flex-col items-center">
<div class="w-10 h-10 bg-purple-600 rounded-full flex items-center justify-center text-white font-bold">1</div>
<span class="text-sm mt-2">Step 1</span>
</div>
<div class="flex-1 h-1 bg-gray-300 mx-4"></div>
<div class="flex flex-col items-center">
<div class="w-10 h-10 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold">2</div>
<span class="text-sm mt-2">Step 2</span>
</div>
<div class="flex-1 h-1 bg-gray-300 mx-4"></div>
<div class="flex flex-col items-center">
<div class="w-10 h-10 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold">3</div>
<span class="text-sm mt-2">Step 3</span>
</div>
</div>
</div>
<template>
<!-- Basic Step Indicator -->
<div class="max-w-2xl mx-auto">
<div class="flex items-center justify-between">
<div class="flex flex-col items-center">
<div class="w-10 h-10 bg-purple-600 rounded-full flex items-center justify-center text-white font-bold">1</div>
<span class="text-sm mt-2">Step 1</span>
</div>
<div class="flex-1 h-1 bg-gray-300 mx-4"></div>
<div class="flex flex-col items-center">
<div class="w-10 h-10 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold">2</div>
<span class="text-sm mt-2">Step 2</span>
</div>
<div class="flex-1 h-1 bg-gray-300 mx-4"></div>
<div class="flex flex-col items-center">
<div class="w-10 h-10 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold">3</div>
<span class="text-sm mt-2">Step 3</span>
</div>
</div>
</div>
</template>
export default function BasicStepIndicator() {
return (
<div className="max-w-2xl mx-auto">
<div className="flex items-center justify-between">
<div className="flex flex-col items-center">
<div className="w-10 h-10 bg-purple-600 rounded-full flex items-center justify-center text-white font-bold">1</div>
<span className="text-sm mt-2">Step 1</span>
</div>
<div className="flex-1 h-1 bg-gray-300 mx-4"></div>
<div className="flex flex-col items-center">
<div className="w-10 h-10 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold">2</div>
<span className="text-sm mt-2">Step 2</span>
</div>
<div className="flex-1 h-1 bg-gray-300 mx-4"></div>
<div className="flex flex-col items-center">
<div className="w-10 h-10 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold">3</div>
<span className="text-sm mt-2">Step 3</span>
</div>
</div>
</div>
);
}
2. Vertical Step Indicator
A vertical step indicator with detailed descriptions and progress tracking.
Step 1: Setup
Configure your account settings
Step 2: Customize
Personalize your experience
Step 3: Complete
Finish and start using
<!-- Vertical Step Indicator -->
<div class="max-w-md mx-auto">
<div class="space-y-8">
<div class="flex items-start">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white font-bold text-sm">1</div>
<div class="w-1 h-16 bg-gray-300 mt-2"></div>
</div>
<div class="ml-4">
<h3 class="font-semibold">Step 1: Setup</h3>
<p class="text-sm text-gray-600">Configure your account settings</p>
</div>
</div>
<div class="flex items-start">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold text-sm">2</div>
<div class="w-1 h-16 bg-gray-300 mt-2"></div>
</div>
<div class="ml-4">
<h3 class="font-semibold">Step 2: Customize</h3>
<p class="text-sm text-gray-600">Personalize your experience</p>
</div>
</div>
<div class="flex items-start">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold text-sm">3</div>
</div>
<div class="ml-4">
<h3 class="font-semibold">Step 3: Complete</h3>
<p class="text-sm text-gray-600">Finish and start using</p>
</div>
</div>
</div>
</div>
<template>
<!-- Vertical Step Indicator -->
<div class="max-w-md mx-auto">
<div class="space-y-8">
<div class="flex items-start">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white font-bold text-sm">1</div>
<div class="w-1 h-16 bg-gray-300 mt-2"></div>
</div>
<div class="ml-4">
<h3 class="font-semibold">Step 1: Setup</h3>
<p class="text-sm text-gray-600">Configure your account settings</p>
</div>
</div>
<div class="flex items-start">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold text-sm">2</div>
<div class="w-1 h-16 bg-gray-300 mt-2"></div>
</div>
<div class="ml-4">
<h3 class="font-semibold">Step 2: Customize</h3>
<p class="text-sm text-gray-600">Personalize your experience</p>
</div>
</div>
<div class="flex items-start">
<div class="flex flex-col items-center">
<div class="w-8 h-8 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold text-sm">3</div>
</div>
<div class="ml-4">
<h3 class="font-semibold">Step 3: Complete</h3>
<p class="text-sm text-gray-600">Finish and start using</p>
</div>
</div>
</div>
</div>
</template>
export default function VerticalStepIndicator() {
return (
<div className="max-w-md mx-auto">
<div className="space-y-8">
<div className="flex items-start">
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white font-bold text-sm">1</div>
<div className="w-1 h-16 bg-gray-300 mt-2"></div>
</div>
<div className="ml-4">
<h3 className="font-semibold">Step 1: Setup</h3>
<p className="text-sm text-gray-600">Configure your account settings</p>
</div>
</div>
<div className="flex items-start">
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold text-sm">2</div>
<div className="w-1 h-16 bg-gray-300 mt-2"></div>
</div>
<div className="ml-4">
<h3 className="font-semibold">Step 2: Customize</h3>
<p className="text-sm text-gray-600">Personalize your experience</p>
</div>
</div>
<div className="flex items-start">
<div className="flex flex-col items-center">
<div className="w-8 h-8 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 font-bold text-sm">3</div>
</div>
<div className="ml-4">
<h3 className="font-semibold">Step 3: Complete</h3>
<p className="text-sm text-gray-600">Finish and start using</p>
</div>
</div>
</div>
</div>
);
}
3. Interactive Step Wizard
A fully interactive step wizard with navigation buttons, progress tracking, and smooth transitions.
Welcome to Setup
Let's get you started with a quick setup process. This will only take a few minutes.
Configure Settings
Customize your preferences and settings to match your workflow.
All Set!
You're all configured and ready to go. Enjoy your new setup!
<!-- Interactive Step Wizard -->
<div x-data="{ currentStep: 1, totalSteps: 3 }">
<!-- Step Indicator -->
<div class="flex items-center justify-between mb-8">
<div class="flex flex-col items-center">
<div :class="1 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">1</div>
<span class="text-sm mt-2" :class="1 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Step 1</span>
</div>
<div :class="1 < currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="2 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">2</div>
<span class="text-sm mt-2" :class="2 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Step 2</span>
</div>
<div :class="2 < currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="3 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">3</div>
<span class="text-sm mt-2" :class="3 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Step 3</span>
</div>
</div>
<!-- Step Content -->
<div class="bg-white rounded-lg shadow-lg p-8 mb-6">
<!-- Step 1 -->
<div x-show="currentStep === 1" x-transition class="text-center">
<div class="w-16 h-16 bg-gradient-to-r from-blue-500 to-purple-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Welcome to Setup</h3>
<p class="text-gray-600">Let's get you started with a quick setup process.</p>
</div>
<!-- Step 2 -->
<div x-show="currentStep === 2" x-transition class="text-center">
<div class="w-16 h-16 bg-gradient-to-r from-green-500 to-teal-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Configure Settings</h3>
<p class="text-gray-600">Customize your preferences and settings.</p>
</div>
<!-- Step 3 -->
<div x-show="currentStep === 3" x-transition class="text-center">
<div class="w-16 h-16 bg-gradient-to-r from-purple-500 to-pink-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">All Set!</h3>
<p class="text-gray-600">You're all configured and ready to go.</p>
</div>
</div>
<!-- Navigation Buttons -->
<div class="flex justify-between">
<button @click="currentStep = Math.max(1, currentStep - 1)" :disabled="currentStep === 1" :class="currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gradient-to-r from-gray-500 to-gray-600 hover:from-gray-600 hover:to-gray-700'" class="px-6 py-3 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button @click="currentStep = Math.min(totalSteps, currentStep + 1)" :class="currentStep === totalSteps ? 'bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700' : 'bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700'" class="px-6 py-3 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<span x-text="currentStep === totalSteps ? 'Finish' : 'Next'"></span>
<svg x-show="currentStep < totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
<svg x-show="currentStep === totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</button>
</div>
</div>
<template>
<!-- Interactive Step Wizard -->
<div>
<!-- Step Indicator -->
<div class="flex items-center justify-between mb-8">
<div class="flex flex-col items-center">
<div :class="1 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">1</div>
<span class="text-sm mt-2" :class="1 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Step 1</span>
</div>
<div :class="1 < currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="2 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">2</div>
<span class="text-sm mt-2" :class="2 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Step 2</span>
</div>
<div :class="2 < currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="3 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">3</div>
<span class="text-sm mt-2" :class="3 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Step 3</span>
</div>
</div>
<!-- Step Content -->
<div class="bg-white rounded-lg shadow-lg p-8 mb-6">
<!-- Step 1 -->
<div v-show="currentStep === 1" class="text-center">
<div class="w-16 h-16 bg-gradient-to-r from-blue-500 to-purple-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Welcome to Setup</h3>
<p class="text-gray-600">Let's get you started with a quick setup process.</p>
</div>
<!-- Step 2 -->
<div v-show="currentStep === 2" class="text-center">
<div class="w-16 h-16 bg-gradient-to-r from-green-500 to-teal-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Configure Settings</h3>
<p class="text-gray-600">Customize your preferences and settings.</p>
</div>
<!-- Step 3 -->
<div v-show="currentStep === 3" class="text-center">
<div class="w-16 h-16 bg-gradient-to-r from-purple-500 to-pink-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">All Set!</h3>
<p class="text-gray-600">You're all configured and ready to go.</p>
</div>
</div>
<!-- Navigation Buttons -->
<div class="flex justify-between">
<button @click="currentStep = Math.max(1, currentStep - 1)" :disabled="currentStep === 1" :class="currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gradient-to-r from-gray-500 to-gray-600 hover:from-gray-600 hover:to-gray-700'" class="px-6 py-3 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button @click="currentStep = Math.min(totalSteps, currentStep + 1)" :class="currentStep === totalSteps ? 'bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700' : 'bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700'" class="px-6 py-3 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
{{ currentStep === totalSteps ? 'Finish' : 'Next' }}
<svg v-if="currentStep < totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
<svg v-if="currentStep === totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const currentStep = ref(1)
const totalSteps = 3
</script>
import React, { useState } from 'react'
export default function InteractiveStepWizard() {
const [currentStep, setCurrentStep] = useState(1)
const totalSteps = 3
return (
<div className="max-w-2xl mx-auto">
<!-- Step Indicator -->
<div className="flex items-center justify-between mb-8">
<div className="flex flex-col items-center">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 ${1 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'}`}>1</div>
<span className={`text-sm mt-2 ${1 <= currentStep ? 'text-gray-900' : 'text-gray-500'}`}>Step 1</span>
</div>
<div className={`flex-1 h-1 mx-4 transition-all duration-300 ${1 < currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600' : 'bg-gray-300'}`}></div>
<div className="flex flex-col items-center">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 ${2 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'}`}>2</div>
<span className={`text-sm mt-2 ${2 <= currentStep ? 'text-gray-900' : 'text-gray-500'}`}>Step 2</span>
</div>
<div className={`flex-1 h-1 mx-4 transition-all duration-300 ${2 < currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600' : 'bg-gray-300'}`}></div>
<div className="flex flex-col items-center">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 ${3 <= currentStep ? 'bg-gradient-to-r from-blue-500 to-purple-600 text-white' : 'bg-gray-300 text-gray-600'}`}>3</div>
<span className={`text-sm mt-2 ${3 <= currentStep ? 'text-gray-900' : 'text-gray-500'}`}>Step 3</span>
</div>
</div>
<!-- Step Content -->
<div className="bg-white rounded-lg shadow-lg p-8 mb-6">
{currentStep === 1 && (
<div className="text-center">
<div className="w-16 h-16 bg-gradient-to-r from-blue-500 to-purple-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-2">Welcome to Setup</h3>
<p className="text-gray-600">Let's get you started with a quick setup process.</p>
</div>
)}
{currentStep === 2 && (
<div className="text-center">
<div className="w-16 h-16 bg-gradient-to-r from-green-500 to-teal-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-2">Configure Settings</h3>
<p className="text-gray-600">Customize your preferences and settings.</p>
</div>
)}
{currentStep === 3 && (
<div className="text-center">
<div className="w-16 h-16 bg-gradient-to-r from-purple-500 to-pink-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-2">All Set!</h3>
<p className="text-gray-600">You're all configured and ready to go.</p>
</div>
)}
</div>
<!-- Navigation Buttons -->
<div className="flex justify-between">
<button
onClick={() => setCurrentStep(Math.max(1, currentStep - 1))}
disabled={currentStep === 1}
className={`px-6 py-3 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2 ${currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gradient-to-r from-gray-500 to-gray-600 hover:from-gray-600 hover:to-gray-700'}`}
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button
onClick={() => setCurrentStep(Math.min(totalSteps, currentStep + 1))}
className={`px-6 py-3 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2 ${currentStep === totalSteps ? 'bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700' : 'bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700'}`}
>
{currentStep === totalSteps ? 'Finish' : 'Next'}
{currentStep < totalSteps ? (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7"/>
</svg>
) : (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
)}
</button>
</div>
</div>
);
}
4. Multi-Step Form
A clean multi-step form with validation and smooth transitions.
Personal Information
Account Details
Review Your Information
<!-- Multi-Step Form -->
<div x-data="{ currentStep: 1, totalSteps: 3, formData: { name: '', email: '', password: '', confirmPassword: '' } }">
<!-- Step Indicator -->
<div class="flex items-center justify-between mb-8">
<div class="flex flex-col items-center">
<div :class="1 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300">1</div>
<span class="text-sm mt-2" :class="1 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Personal</span>
</div>
<div :class="1 < currentStep ? 'bg-blue-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="2 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300">2</div>
<span class="text-sm mt-2" :class="2 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Account</span>
</div>
<div :class="2 < currentStep ? 'bg-blue-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="3 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300">3</div>
<span class="text-sm mt-2" :class="3 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Review</span>
</div>
</div>
<!-- Form Content -->
<div class="bg-white rounded-lg shadow-lg p-8 mb-6">
<!-- Step 1 -->
<div x-show="currentStep === 1" x-transition>
<h3 class="text-xl font-bold text-gray-900 mb-4">Personal Information</h3>
<div class="space-y-4">
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">Full Name</label>
<input x-model="formData.name" type="text" id="name" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email Address</label>
<input x-model="formData.email" type="email" id="email" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
</div>
</div>
<!-- Step 2 -->
<div x-show="currentStep === 2" x-transition>
<h3 class="text-xl font-bold text-gray-900 mb-4">Account Details</h3>
<div class="space-y-4">
<div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
<input x-model="formData.password" type="password" id="password" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
<div>
<label for="confirmPassword" class="block text-sm font-medium text-gray-700 mb-1">Confirm Password</label>
<input x-model="formData.confirmPassword" type="password" id="confirmPassword" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
</div>
</div>
<!-- Step 3 -->
<div x-show="currentStep === 3" x-transition>
<h3 class="text-xl font-bold text-gray-900 mb-4">Review Your Information</h3>
<div class="space-y-3">
<div class="flex justify-between">
<span class="text-gray-600">Name:</span>
<span class="font-medium" x-text="formData.name || 'Not provided'"></span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Email:</span>
<span class="font-medium" x-text="formData.email || 'Not provided'"></span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Password:</span>
<span class="font-medium" x-text="formData.password ? '••••••••' : 'Not set'"></span>
</div>
</div>
</div>
</div>
<!-- Navigation Buttons -->
<div class="flex justify-between">
<button @click="currentStep = Math.max(1, currentStep - 1)" :disabled="currentStep === 1" :class="currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-600 hover:bg-gray-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button @click="currentStep = Math.min(totalSteps, currentStep + 1)" :class="currentStep === totalSteps ? 'bg-green-600 hover:bg-green-700' : 'bg-blue-600 hover:bg-blue-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<span x-text="currentStep === totalSteps ? 'Submit' : 'Next'"></span>
<svg x-show="currentStep < totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
<svg x-show="currentStep === totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</button>
</div>
</div>
<template>
<!-- Multi-Step Form -->
<div>
<!-- Step Indicator -->
<div class="flex items-center justify-between mb-8">
<div class="flex flex-col items-center">
<div :class="1 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300">1</div>
<span class="text-sm mt-2" :class="1 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Personal</span>
</div>
<div :class="1 < currentStep ? 'bg-blue-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="2 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300">2</div>
<span class="text-sm mt-2" :class="2 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Account</span>
</div>
<div :class="2 < currentStep ? 'bg-blue-600' : 'bg-gray-300'" class="flex-1 h-1 mx-4 transition-all duration-300"></div>
<div class="flex flex-col items-center">
<div :class="3 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'" class="w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300">3</div>
<span class="text-sm mt-2" :class="3 <= currentStep ? 'text-gray-900' : 'text-gray-500'">Review</span>
</div>
</div>
<!-- Form Content -->
<div class="bg-white rounded-lg shadow-lg p-8 mb-6">
<!-- Step 1 -->
<div v-show="currentStep === 1">
<h3 class="text-xl font-bold text-gray-900 mb-4">Personal Information</h3>
<div class="space-y-4">
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">Full Name</label>
<input v-model="formData.name" type="text" id="name" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email Address</label>
<input v-model="formData.email" type="email" id="email" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
</div>
</div>
<!-- Step 2 -->
<div v-show="currentStep === 2">
<h3 class="text-xl font-bold text-gray-900 mb-4">Account Details</h3>
<div class="space-y-4">
<div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
<input v-model="formData.password" type="password" id="password" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
<div>
<label for="confirmPassword" class="block text-sm font-medium text-gray-700 mb-1">Confirm Password</label>
<input v-model="formData.confirmPassword" type="password" id="confirmPassword" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors">
</div>
</div>
</div>
<!-- Step 3 -->
<div v-show="currentStep === 3">
<h3 class="text-xl font-bold text-gray-900 mb-4">Review Your Information</h3>
<div class="space-y-3">
<div class="flex justify-between">
<span class="text-gray-600">Name:</span>
<span class="font-medium">{{ formData.name || 'Not provided' }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Email:</span>
<span class="font-medium">{{ formData.email || 'Not provided' }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Password:</span>
<span class="font-medium">{{ formData.password ? '••••••••' : 'Not set' }}</span>
</div>
</div>
</div>
</div>
<!-- Navigation Buttons -->
<div class="flex justify-between">
<button @click="currentStep = Math.max(1, currentStep - 1)" :disabled="currentStep === 1" :class="currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-600 hover:bg-gray-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button @click="currentStep = Math.min(totalSteps, currentStep + 1)" :class="currentStep === totalSteps ? 'bg-green-600 hover:bg-green-700' : 'bg-blue-600 hover:bg-blue-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
{{ currentStep === totalSteps ? 'Submit' : 'Next' }}
<svg v-if="currentStep < totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
<svg v-if="currentStep === totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const currentStep = ref(1)
const totalSteps = 3
const formData = ref({
name: '',
email: '',
password: '',
confirmPassword: ''
})
</script>
import React, { useState } from 'react'
export default function MultiStepForm() {
const [currentStep, setCurrentStep] = useState(1)
const totalSteps = 3
const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
confirmPassword: ''
})
const handleInputChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value
})
}
return (
<div className="max-w-2xl mx-auto">
<!-- Step Indicator -->
<div className="flex items-center justify-between mb-8">
<div className="flex flex-col items-center">
<div className={`w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300 ${1 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'}`}>1</div>
<span className={`text-sm mt-2 ${1 <= currentStep ? 'text-gray-900' : 'text-gray-500'}`}>Personal</span>
</div>
<div className={`flex-1 h-1 mx-4 transition-all duration-300 ${1 < currentStep ? 'bg-blue-600' : 'bg-gray-300'}`}></div>
<div className="flex flex-col items-center">
<div className={`w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300 ${2 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'}`}>2</div>
<span className={`text-sm mt-2 ${2 <= currentStep ? 'text-gray-900' : 'text-gray-500'}`}>Account</span>
</div>
<div className={`flex-1 h-1 mx-4 transition-all duration-300 ${2 < currentStep ? 'bg-blue-600' : 'bg-gray-300'}`}></div>
<div className="flex flex-col items-center">
<div className={`w-10 h-10 rounded-full flex items-center justify-center font-bold transition-all duration-300 ${3 <= currentStep ? 'bg-blue-600 text-white' : 'bg-gray-300 text-gray-600'}`}>3</div>
<span className={`text-sm mt-2 ${3 <= currentStep ? 'text-gray-900' : 'text-gray-500'}`}>Review</span>
</div>
</div>
<!-- Form Content -->
<div className="bg-white rounded-lg shadow-lg p-8 mb-6">
{currentStep === 1 && (
<div>
<h3 className="text-xl font-bold text-gray-900 mb-4">Personal Information</h3>
<div className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1">Full Name</label>
<input
name="name"
value={formData.name}
onChange={handleInputChange}
type="text"
id="name"
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">Email Address</label>
<input
name="email"
value={formData.email}
onChange={handleInputChange}
type="email"
id="email"
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
</div>
</div>
</div>
)}
{currentStep === 2 && (
<div>
<h3 className="text-xl font-bold text-gray-900 mb-4">Account Details</h3>
<div className="space-y-4">
<div>
<label htmlFor="password" className="block text-sm font-medium text-gray-700 mb-1">Password</label>
<input
name="password"
value={formData.password}
onChange={handleInputChange}
type="password"
id="password"
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
</div>
<div>
<label htmlFor="confirmPassword" className="block text-sm font-medium text-gray-700 mb-1">Confirm Password</label>
<input
name="confirmPassword"
value={formData.confirmPassword}
onChange={handleInputChange}
type="password"
id="confirmPassword"
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
</div>
</div>
</div>
)}
{currentStep === 3 && (
<div>
<h3 className="text-xl font-bold text-gray-900 mb-4">Review Your Information</h3>
<div className="space-y-3">
<div className="flex justify-between">
<span className="text-gray-600">Name:</span>
<span className="font-medium">{formData.name || 'Not provided'}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Email:</span>
<span className="font-medium">{formData.email || 'Not provided'}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Password:</span>
<span className="font-medium">{formData.password ? '••••••••' : 'Not set'}</span>
</div>
</div>
</div>
)}
</div>
<!-- Navigation Buttons -->
<div className="flex justify-between">
<button
onClick={() => setCurrentStep(Math.max(1, currentStep - 1))}
disabled={currentStep === 1}
className={`px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2 ${currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-600 hover:bg-gray-700'}`}
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button
onClick={() => setCurrentStep(Math.min(totalSteps, currentStep + 1))}
className={`px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2 ${currentStep === totalSteps ? 'bg-green-600 hover:bg-green-700' : 'bg-blue-600 hover:bg-blue-700'}`}
>
{currentStep === totalSteps ? 'Submit' : 'Next'}
{currentStep < totalSteps ? (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7"/>
</svg>
) : (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
)}
</button>
</div>
</div>
);
}
5. Circular Step Indicator
A modern circular step indicator with smooth animations, progress visualization, and highlighted labels.
Welcome to Setup
Let's get you started with a quick setup process. This will only take a few minutes.
Configure Settings
Customize your preferences and settings to match your workflow.
Review & Confirm
Please review your information before proceeding to the final step.
All Set!
You're all configured and ready to go. Enjoy your new setup!
<!-- Circular Step Indicator -->
<div x-data="{ currentStep: 1, totalSteps: 4 }">
<!-- Circular Step Indicator -->
<div class="relative flex items-center justify-center mb-12">
<svg class="w-64 h-64 transform -rotate-90" viewBox="0 0 256 256">
<circle cx="128" cy="128" r="120" stroke="#e5e7eb" stroke-width="8" fill="none"></circle>
<defs>
<linearGradient id="progressGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#1d4ed8;stop-opacity:1" />
</linearGradient>
</defs>
<circle cx="128" cy="128" r="120" stroke="url(#progressGradient)" stroke-width="8" fill="none" stroke-linecap="round" :stroke-dasharray="`${(currentStep / totalSteps) * 754} 754`" stroke-dashoffset="0" class="transition-all duration-500"></circle>
</svg>
<div class="absolute inset-0 flex items-center justify-center">
<div class="relative w-48 h-48">
<div class="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<div :class="1 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">1</div>
</div>
<div class="absolute top-1/2 right-0 transform translate-x-1/2 -translate-y-1/2">
<div :class="2 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">2</div>
</div>
<div class="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-1/2">
<div :class="3 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">3</div>
</div>
<div class="absolute top-1/2 left-0 transform -translate-x-1/2 -translate-y-1/2">
<div :class="4 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">4</div>
</div>
</div>
</div>
</div>
<!-- Step Labels -->
<div class="grid grid-cols-4 gap-4 mb-8">
<div class="text-center">
<span :class="1 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Setup</span>
</div>
<div class="text-center">
<span :class="2 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Configure</span>
</div>
<div class="text-center">
<span :class="3 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Review</span>
</div>
<div class="text-center">
<span :class="4 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Complete</span>
</div>
</div>
<!-- Step Content -->
<div class="bg-white rounded-lg shadow-lg p-8 mb-6">
<div x-show="currentStep === 1" x-transition class="text-center">
<div class="w-16 h-16 bg-blue-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Welcome to Setup</h3>
<p class="text-gray-600">Let's get you started with a quick setup process. This will only take a few minutes.</p>
</div>
<div x-show="currentStep === 2" x-transition class="text-center">
<div class="w-16 h-16 bg-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Configure Settings</h3>
<p class="text-gray-600">Customize your preferences and settings to match your workflow.</p>
</div>
<div x-show="currentStep === 3" x-transition class="text-center">
<div class="w-16 h-16 bg-purple-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Review & Confirm</h3>
<p class="text-gray-600">Please review your information before proceeding to the final step.</p>
</div>
<div x-show="currentStep === 4" x-transition class="text-center">
<div class="w-16 h-16 bg-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">All Set!</h3>
<p class="text-gray-600">You're all configured and ready to go. Enjoy your new setup!</p>
</div>
</div>
<!-- Navigation Buttons -->
<div class="flex justify-between">
<button @click="currentStep = Math.max(1, currentStep - 1)" :disabled="currentStep === 1" :class="currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-600 hover:bg-gray-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button @click="currentStep = Math.min(totalSteps, currentStep + 1)" :class="currentStep === totalSteps ? 'bg-green-600 hover:bg-green-700' : 'bg-blue-600 hover:bg-blue-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<span x-text="currentStep === totalSteps ? 'Finish' : 'Next'"></span>
<svg x-show="currentStep < totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
<svg x-show="currentStep === totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</button>
</div>
</div>
<template>
<!-- Circular Step Indicator -->
<div>
<!-- Circular Step Indicator -->
<div class="relative flex items-center justify-center mb-12">
<svg class="w-64 h-64 transform -rotate-90" viewBox="0 0 256 256">
<circle cx="128" cy="128" r="120" stroke="#e5e7eb" stroke-width="8" fill="none"></circle>
<defs>
<linearGradient id="progressGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#1d4ed8;stop-opacity:1" />
</linearGradient>
</defs>
<circle cx="128" cy="128" r="120" stroke="url(#progressGradient)" stroke-width="8" fill="none" stroke-linecap="round" :stroke-dasharray="`${(currentStep / totalSteps) * 754} 754`" stroke-dashoffset="0" class="transition-all duration-500"></circle>
</svg>
<div class="absolute inset-0 flex items-center justify-center">
<div class="relative w-48 h-48">
<div class="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<div :class="1 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">1</div>
</div>
<div class="absolute top-1/2 right-0 transform translate-x-1/2 -translate-y-1/2">
<div :class="2 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">2</div>
</div>
<div class="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-1/2">
<div :class="3 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">3</div>
</div>
<div class="absolute top-1/2 left-0 transform -translate-x-1/2 -translate-y-1/2">
<div :class="4 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'" class="w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300">4</div>
</div>
</div>
</div>
</div>
<!-- Step Labels -->
<div class="grid grid-cols-4 gap-4 mb-8">
<div class="text-center">
<span :class="1 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Setup</span>
</div>
<div class="text-center">
<span :class="2 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Configure</span>
</div>
<div class="text-center">
<span :class="3 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Review</span>
</div>
<div class="text-center">
<span :class="4 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'" class="text-sm transition-colors duration-300">Complete</span>
</div>
</div>
<!-- Step Content -->
<div class="bg-white rounded-lg shadow-lg p-8 mb-6">
<div v-show="currentStep === 1" class="text-center">
<div class="w-16 h-16 bg-blue-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Welcome to Setup</h3>
<p class="text-gray-600">Let's get you started with a quick setup process. This will only take a few minutes.</p>
</div>
<div v-show="currentStep === 2" class="text-center">
<div class="w-16 h-16 bg-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Configure Settings</h3>
<p class="text-gray-600">Customize your preferences and settings to match your workflow.</p>
</div>
<div v-show="currentStep === 3" class="text-center">
<div class="w-16 h-16 bg-purple-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">Review & Confirm</h3>
<p class="text-gray-600">Please review your information before proceeding to the final step.</p>
</div>
<div v-show="currentStep === 4" class="text-center">
<div class="w-16 h-16 bg-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
<h3 class="text-2xl font-bold text-gray-900 mb-2">All Set!</h3>
<p class="text-gray-600">You're all configured and ready to go. Enjoy your new setup!</p>
</div>
</div>
<!-- Navigation Buttons -->
<div class="flex justify-between">
<button @click="currentStep = Math.max(1, currentStep - 1)" :disabled="currentStep === 1" :class="currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-600 hover:bg-gray-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button @click="currentStep = Math.min(totalSteps, currentStep + 1)" :class="currentStep === totalSteps ? 'bg-green-600 hover:bg-green-700' : 'bg-blue-600 hover:bg-blue-700'" class="px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2">
{{ currentStep === totalSteps ? 'Finish' : 'Next' }}
<svg v-if="currentStep < totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
<svg v-if="currentStep === totalSteps" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const currentStep = ref(1)
const totalSteps = 4
</script>
import React, { useState } from 'react'
export default function CircularStepIndicator() {
const [currentStep, setCurrentStep] = useState(1)
const totalSteps = 4
return (
<div className="max-w-4xl mx-auto">
<!-- Circular Step Indicator -->
<div className="relative flex items-center justify-center mb-12">
<svg className="w-64 h-64 transform -rotate-90" viewBox="0 0 256 256">
<circle cx="128" cy="128" r="120" stroke="#e5e7eb" strokeWidth="8" fill="none" />
<defs>
<linearGradient id="progressGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#1d4ed8;stop-opacity:1" />
</linearGradient>
</defs>
<circle cx="128" cy="128" r="120" stroke={`url(#progressGradient)`} strokeWidth="8" fill="none" strokeLinecap="round" strokeDasharray={`${(currentStep / totalSteps) * 754} 754`} strokeDashoffset="0" className="transition-all duration-500" />
</svg>
<div className="absolute inset-0 flex items-center justify-center">
<div className="relative w-48 h-48">
<div className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 ${1 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'}`}>1</div>
</div>
<div className="absolute top-1/2 right-0 transform translate-x-1/2 -translate-y-1/2">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 ${2 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'}`}>2</div>
</div>
<div className="absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-1/2">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 ${3 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'}`}>3</div>
</div>
<div className="absolute top-1/2 left-0 transform -translate-x-1/2 -translate-y-1/2">
<div className={`w-12 h-12 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 ${4 <= currentStep ? 'bg-blue-600 text-white shadow-lg scale-110' : 'bg-gray-300 text-gray-600'}`}>4</div>
</div>
</div>
</div>
</div>
<!-- Step Labels -->
<div className="grid grid-cols-4 gap-4 mb-8">
<div className="text-center">
<span className={`text-sm transition-colors duration-300 ${1 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'}`}>Setup</span>
</div>
<div className="text-center">
<span className={`text-sm transition-colors duration-300 ${2 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'}`}>Configure</span>
</div>
<div className="text-center">
<span className={`text-sm transition-colors duration-300 ${3 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'}`}>Review</span>
</div>
<div className="text-center">
<span className={`text-sm transition-colors duration-300 ${4 <= currentStep ? 'text-blue-600 font-bold' : 'text-gray-500'}`}>Complete</span>
</div>
</div>
<!-- Step Content -->
<div className="bg-white rounded-lg shadow-lg p-8 mb-6">
{currentStep === 1 && (
<div className="text-center">
<div className="w-16 h-16 bg-blue-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-2">Welcome to Setup</h3>
<p className="text-gray-600">Let's get you started with a quick setup process. This will only take a few minutes.</p>
</div>
)}
{currentStep === 2 && (
<div className="text-center">
<div className="w-16 h-16 bg-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-2">Configure Settings</h3>
<p className="text-gray-600">Customize your preferences and settings to match your workflow.</p>
</div>
)}
{currentStep === 3 && (
<div className="text-center">
<div className="w-16 h-16 bg-purple-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-2">Review & Confirm</h3>
<p className="text-gray-600">Please review your information before proceeding to the final step.</p>
</div>
)}
{currentStep === 4 && (
<div className="text-center">
<div className="w-16 h-16 bg-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-2">All Set!</h3>
<p className="text-gray-600">You're all configured and ready to go. Enjoy your new setup!</p>
</div>
)}
</div>
<!-- Navigation Buttons -->
<div className="flex justify-between">
<button
onClick={() => setCurrentStep(Math.max(1, currentStep - 1))}
disabled={currentStep === 1}
className={`px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2 ${currentStep === 1 ? 'bg-gray-300 cursor-not-allowed' : 'bg-gray-600 hover:bg-gray-700'}`}
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 19l-7-7 7-7"/>
</svg>
Previous
</button>
<button
onClick={() => setCurrentStep(Math.min(totalSteps, currentStep + 1))}
className={`px-4 py-2 text-white font-medium rounded-lg transition-all duration-300 flex items-center gap-2 ${currentStep === totalSteps ? 'bg-green-600 hover:bg-green-700' : 'bg-blue-600 hover:bg-blue-700'}`}
>
{currentStep === totalSteps ? 'Finish' : 'Next'}
{currentStep < totalSteps ? (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7"/>
</svg>
) : (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
)}
</button>
</div>
</div>
);
}