Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 73x 73x 38x 38x 38x 73x 73x 73x 73x | import { PASSWORD_RULES } from "../../lib/validation";
import { Check, X } from "lucide-react";
interface PasswordStrengthProps {
password: string;
}
export function PasswordStrength({ password }: PasswordStrengthProps) {
if (!password) return null;
const passed = PASSWORD_RULES.filter((r) => r.test(password)).length;
const total = PASSWORD_RULES.length;
const strength = passed / total;
const barColor =
strength <= 0.4
? "bg-destructive"
: strength <= 0.8
? "bg-yellow-500"
: "bg-green-500";
return (
<div className="space-y-2 mt-2">
<div className="flex gap-1">
{Array.from({ length: total }).map((_, i) => (
<div
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-length strength segments
key={i}
className={`h-1 flex-1 rounded-full transition-colors ${
i < passed ? barColor : "bg-muted"
}`}
/>
))}
</div>
<ul className="space-y-0.5">
{PASSWORD_RULES.map((rule) => {
const ok = rule.test(password);
return (
<li
key={rule.label}
className={`flex items-center gap-1.5 text-xs ${
ok ? "text-green-600" : "text-muted-foreground"
}`}
>
{ok ? (
<Check className="h-3 w-3 shrink-0" />
) : (
<X className="h-3 w-3 shrink-0" />
)}
{rule.label}
</li>
);
})}
</ul>
</div>
);
}
|