New

Password Strength

Password input with strength meter and requirement checklist.

Forms & Inputpasswordstrengthvalidationsecurityinput

Dependencies

Other dependencies:

@/components/ui/input@/components/ui/card@/components/ui/label@/components/ui/progress

How to use this component

Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.

Code

1"use client";
2
3import { useState } from 'react';
4import { Input } from '@/components/ui/input';
5import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
6import { Label } from '@/components/ui/label';
7import { Progress } from '@/components/ui/progress';
8import { Eye, EyeOff, Check, X } from 'lucide-react';
9
10export default function PasswordStrength() {
11 const [password, setPassword] = useState('');
12 const [showPassword, setShowPassword] = useState(false);
13
14 const requirements = [
15 { id: 'length', label: 'At least 8 characters', check: (p: string) => p.length >= 8 },
16 { id: 'uppercase', label: 'One uppercase letter', check: (p: string) => /[A-Z]/.test(p) },
17 { id: 'lowercase', label: 'One lowercase letter', check: (p: string) => /[a-z]/.test(p) },
18 { id: 'number', label: 'One number', check: (p: string) => /[0-9]/.test(p) },
19 { id: 'special', label: 'One special character', check: (p: string) => /[^A-Za-z0-9]/.test(p) }
20 ];
21
22 const metRequirements = requirements.filter(req => req.check(password)).length;
23 const strength = (metRequirements / requirements.length) * 100;
24
25 const getStrengthColor = () => {
26 if (strength <= 25) return 'bg-red-500';
27 if (strength <= 50) return 'bg-orange-500';
28 if (strength <= 75) return 'bg-yellow-500';
29 return 'bg-green-500';
30 };
31
32 const getStrengthLabel = () => {
33 if (strength <= 25) return 'Weak';
34 if (strength <= 50) return 'Fair';
35 if (strength <= 75) return 'Good';
36 return 'Strong';
37 };
38
39 return (
40 <Card className="w-full max-w-md mx-auto">
41 <CardHeader>
42 <CardTitle>Create Password</CardTitle>
43 </CardHeader>
44 <CardContent className="space-y-4">
45 <div className="space-y-2">
46 <Label htmlFor="password">Password</Label>
47 <div className="relative">
48 <Input
49 id="password"
50 type={showPassword ? 'text' : 'password'}
51 value={password}
52 onChange={e => setPassword(e.target.value)}
53 placeholder="Enter your password"
54 className="pr-10"
55 />
56 <button
57 type="button"
58 onClick={() => setShowPassword(!showPassword)}
59 className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
60 >
61 {showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
62 </button>
63 </div>
64 </div>
65
66 <div className="space-y-2">
67 <div className="flex items-center justify-between text-sm">
68 <span className="text-muted-foreground">Strength</span>
69 <span className={`font-medium \` +
70 `${strength <= 25 ? 'text-red-500' : ''}\` +
71 `${strength > 25 && strength <= 50 ? 'text-orange-500' : ''}\` +
72 `${strength > 50 && strength <= 75 ? 'text-yellow-500' : ''}\` +
73 `${strength > 75 ? 'text-green-500' : ''}`}>
74 {getStrengthLabel()}
75 </span>
76 </div>
77 <Progress value={strength} className="h-2">
78 <div className={`h-full transition-all ${getStrengthColor()}`} style={{ width: `${strength}%` }} />
79 </Progress>
80 </div>
81
82 <div className="space-y-2">
83 {requirements.map(req => {
84 const met = req.check(password);
85 return (
86 <div key={req.id} className={`flex items-center gap-2 text-sm \` +
87 `${met ? 'text-green-600' : 'text-muted-foreground'}`}>
88 {met ? (
89 <Check className="w-4 h-4" />
90 ) : (
91 <X className="w-4 h-4" />
92 )}
93 <span>{req.label}</span>
94 </div>
95 );
96 })}
97 </div>
98 </CardContent>
99 </Card>
100 );
101}

Related Forms & Input Components

Command Palette

Search for a command to run...