Back to Component Explorer

Multi-Step Sign Up

signup

Step-by-step sign up flow with visual progress steps and success screen.

#signup#multistep#wizard#progress
Live Interactive Preview
1
Account
2
Credentials
3
Done

Your name

How should we address you?

Component Source Code

Select language in the dropdown
MultiStepSignUp.tsx
1'use client';
2import React, { useState } from 'react';
3import { User, Mail, Lock, Eye, EyeOff, ArrowRight, Check } from 'lucide-react';
4
5export default function MultiStepSignUp() {
6 const [step, setStep] = useState(1);
7 const [name, setName] = useState('');
8 const [email, setEmail] = useState('');
9 const [password, setPassword] = useState('');
10 const [showPass, setShowPass] = useState(false);
11 const [done, setDone] = useState(false);
12
13 const steps = ['Account', 'Credentials', 'Done'];
14
15 if (done) {
16 return (
17 <div className="w-full max-w-sm rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 p-8 text-center">
18 <div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500 text-white">
19 <Check className="h-8 w-8" />
20 </div>
21 <h2 className="text-xl font-bold text-zinc-900 dark:text-zinc-100">Welcome, {name.split(' ')[0]}!</h2>
22 <p className="mt-2 text-sm text-zinc-500">Your account has been created successfully.</p>
23 <button onClick={() => { setDone(false); setStep(1); setName(''); setEmail(''); setPassword(''); }} className="mt-6 text-xs text-blue-600 dark:text-blue-400 hover:underline">Reset demo</button>
24 </div>
25 );
26 }
27
28 return (
29 <div className="w-full max-w-sm rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 p-8 shadow-lg">
30 {/* Progress */}
31 <div className="flex items-center justify-between mb-8">
32 {steps.map((s, i) => (
33 <React.Fragment key={s}>
34 <div className="flex flex-col items-center gap-1">
35 <div className={`flex h-8 w-8 items-center justify-center rounded-full text-xs font-bold transition ${i + 1 < step ? 'bg-emerald-500 text-white' : i + 1 === step ? 'bg-blue-600 text-white' : 'bg-zinc-100 dark:bg-zinc-800 text-zinc-400'}`}>
36 {i + 1 < step ? <Check className="h-4 w-4" /> : i + 1}
37 </div>
38 <span className="text-[10px] font-semibold text-zinc-500">{s}</span>
39 </div>
40 {i < steps.length - 1 && <div className={`flex-1 h-px mx-2 transition ${i + 1 < step ? 'bg-emerald-500' : 'bg-zinc-200 dark:bg-zinc-800'}`} />}
41 </React.Fragment>
42 ))}
43 </div>
44
45 {step === 1 && (
46 <div className="space-y-4">
47 <div>
48 <h3 className="text-lg font-bold text-zinc-900 dark:text-zinc-100 mb-1">Your name</h3>
49 <p className="text-xs text-zinc-500 mb-4">How should we address you?</p>
50 <div className="relative">
51 <User className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-zinc-400" />
52 <input value={name} onChange={(e) => setName(e.target.value)} type="text" placeholder="Full name" className="w-full rounded-lg border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800 py-2.5 pl-9 pr-3 text-sm text-zinc-900 dark:text-zinc-100 placeholder:text-zinc-400 outline-none focus:border-blue-500 transition" />
53 </div>
54 </div>
55 <button onClick={() => name && setStep(2)} className="flex w-full items-center justify-center gap-2 rounded-lg bg-blue-600 hover:bg-blue-700 py-2.5 text-sm font-semibold text-white transition disabled:opacity-50" disabled={!name}>
56 Continue <ArrowRight className="h-4 w-4" />
57 </button>
58 </div>
59 )}
60
61 {step === 2 && (
62 <div className="space-y-4">
63 <div>
64 <h3 className="text-lg font-bold text-zinc-900 dark:text-zinc-100 mb-1">Login credentials</h3>
65 <p className="text-xs text-zinc-500 mb-4">Set up your email and password</p>
66 </div>
67 <div>
68 <label className="block text-xs font-semibold text-zinc-700 dark:text-zinc-300 mb-1.5">Email</label>
69 <div className="relative">
70 <Mail className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-zinc-400" />
71 <input value={email} onChange={(e) => setEmail(e.target.value)} type="email" placeholder="you@example.com" className="w-full rounded-lg border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800 py-2.5 pl-9 pr-3 text-sm text-zinc-900 dark:text-zinc-100 placeholder:text-zinc-400 outline-none focus:border-blue-500 transition" />
72 </div>
73 </div>
74 <div>
75 <label className="block text-xs font-semibold text-zinc-700 dark:text-zinc-300 mb-1.5">Password</label>
76 <div className="relative">
77 <Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-zinc-400" />
78 <input value={password} onChange={(e) => setPassword(e.target.value)} type={showPass ? 'text' : 'password'} placeholder="Min 8 characters" className="w-full rounded-lg border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800 py-2.5 pl-9 pr-10 text-sm text-zinc-900 dark:text-zinc-100 placeholder:text-zinc-400 outline-none focus:border-blue-500 transition" />
79 <button type="button" onClick={() => setShowPass(!showPass)} className="absolute right-3 top-1/2 -translate-y-1/2 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200">
80 {showPass ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
81 </button>
82 </div>
83 </div>
84 <div className="flex gap-2">
85 <button onClick={() => setStep(1)} className="flex-1 rounded-lg border border-zinc-200 dark:border-zinc-800 py-2.5 text-sm font-semibold text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-800 transition">Back</button>
86 <button onClick={() => email && password.length >= 8 && setDone(true)} disabled={!email || password.length < 8} className="flex-1 flex items-center justify-center gap-2 rounded-lg bg-blue-600 hover:bg-blue-700 py-2.5 text-sm font-semibold text-white transition disabled:opacity-50">
87 Create <ArrowRight className="h-4 w-4" />
88 </button>
89 </div>
90 </div>
91 )}
92 </div>
93 );
94}

Installation & Integration Guide

Step 1: Tailwind CSS v4 Setup
Tailwind Docs

If you do not have Tailwind installed yet, run this installation command:

Terminal
npm install tailwindcss @tailwindcss/postcss postcss

Then add the Tailwind directive to your main stylesheet (globals.css):

@import "tailwindcss";

Step 2: Install Icon Dependencies

npm install lucide-react react-icons

Step 3: Add Component File

Create a new file in your project at src/components/signup/MultiStepSignUp.tsx and paste the copied code from the source viewer above.

Step 4: Usage Example

ExamplePage.tsx
1import MultiStepSignUp from '@/components/signup/MultiStepSignUp';
2
3export default function ExamplePage() {
4 return (
5 <main className="p-8 flex items-center justify-center min-h-screen">
6 <MultiStepSignUp />
7 </main>
8 );
9}