Back to Component Explorer

Password Strength Sign Up

signup

Sign up with live password strength bar and requirement checklist.

#signup#password#strength#validation
Live Interactive Preview

Secure sign up

Component Source Code

Select language in the dropdown
PasswordStrengthSignUp.tsx
1'use client';
2import React, { useState } from 'react';
3import { User, Mail, Lock, Eye, EyeOff, ArrowRight, Shield } from 'lucide-react';
4
5function strengthColor(s: number) {
6 if (s === 0) return 'bg-zinc-200 dark:bg-zinc-700';
7 if (s === 1) return 'bg-rose-500';
8 if (s === 2) return 'bg-amber-500';
9 if (s === 3) return 'bg-yellow-400';
10 return 'bg-emerald-500';
11}
12function strengthLabel(s: number) {
13 if (s === 0) return '';
14 if (s === 1) return 'Weak';
15 if (s === 2) return 'Fair';
16 if (s === 3) return 'Good';
17 return 'Strong';
18}
19
20export default function PasswordStrengthSignUp() {
21 const [showPass, setShowPass] = useState(false);
22 const [password, setPassword] = useState('');
23
24 const strength = [
25 password.length >= 8,
26 /[A-Z]/.test(password),
27 /[0-9]/.test(password),
28 /[^A-Za-z0-9]/.test(password),
29 ].filter(Boolean).length;
30
31 return (
32 <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">
33 <div className="mb-6 flex items-center gap-2">
34 <Shield className="h-6 w-6 text-blue-600 dark:text-blue-400" />
35 <h2 className="text-xl font-bold text-zinc-900 dark:text-zinc-100">Secure sign up</h2>
36 </div>
37 <form onSubmit={(e) => e.preventDefault()} className="space-y-4">
38 <div>
39 <label className="block text-xs font-semibold text-zinc-700 dark:text-zinc-300 mb-1.5">Full name</label>
40 <div className="relative">
41 <User className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-zinc-400" />
42 <input type="text" required placeholder="Your 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" />
43 </div>
44 </div>
45 <div>
46 <label className="block text-xs font-semibold text-zinc-700 dark:text-zinc-300 mb-1.5">Email</label>
47 <div className="relative">
48 <Mail className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-zinc-400" />
49 <input type="email" required 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" />
50 </div>
51 </div>
52 <div>
53 <label className="block text-xs font-semibold text-zinc-700 dark:text-zinc-300 mb-1.5">Password</label>
54 <div className="relative">
55 <Lock className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-zinc-400" />
56 <input type={showPass ? 'text' : 'password'} value={password} onChange={(e) => setPassword(e.target.value)} required placeholder="Create a password" 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" />
57 <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">
58 {showPass ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
59 </button>
60 </div>
61 {/* Strength meter */}
62 {password && (
63 <div className="mt-2">
64 <div className="flex gap-1 mb-1">
65 {[1, 2, 3, 4].map((s) => (
66 <div key={s} className={`h-1.5 flex-1 rounded-full transition-all duration-300 ${strength >= s ? strengthColor(strength) : 'bg-zinc-200 dark:bg-zinc-700'}`} />
67 ))}
68 </div>
69 <div className="flex items-center justify-between text-[10px]">
70 <span className="text-zinc-400">Password strength</span>
71 <span className={`font-semibold ${strength <= 1 ? 'text-rose-500' : strength === 2 ? 'text-amber-500' : strength === 3 ? 'text-yellow-500' : 'text-emerald-500'}`}>{strengthLabel(strength)}</span>
72 </div>
73 <div className="mt-2 space-y-1">
74 {[['8+ characters', password.length >= 8], ['Uppercase letter', /[A-Z]/.test(password)], ['Number', /[0-9]/.test(password)], ['Special character', /[^A-Za-z0-9]/.test(password)]].map(([label, met]) => (
75 <div key={String(label)} className={`text-[10px] flex items-center gap-1.5 ${met ? 'text-emerald-600 dark:text-emerald-400' : 'text-zinc-400'}`}>
76 <div className={`h-1.5 w-1.5 rounded-full ${met ? 'bg-emerald-500' : 'bg-zinc-300 dark:bg-zinc-700'}`} />
77 {String(label)}
78 </div>
79 ))}
80 </div>
81 </div>
82 )}
83 </div>
84 <button type="submit" 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">
85 Create Account <ArrowRight className="h-4 w-4" />
86 </button>
87 </form>
88 </div>
89 );
90}

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/PasswordStrengthSignUp.tsx and paste the copied code from the source viewer above.

Step 4: Usage Example

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