import { useState } from "react"; import { Circle, CircleCheck } from "lucide-react"; import { Text } from "@/components/ui/text"; import { evaluatePasswordRules, type PasswordRuleResult } from "@/domain/auth/password-policy"; import { cn } from "@/lib/utils"; export type PasswordChecklistProps = { password: string; id?: string; className?: string; }; function describeChanges(previous: PasswordRuleResult[], next: PasswordRuleResult[]): string { return next .filter((rule, index) => rule.met !== previous[index]?.met) .map((rule) => `${rule.label}: ${rule.met ? "requirement met" : "requirement not met"}`) .join(". "); } /** * Live, per-rule feedback for the shared password policy. A polite status region * announces only the rules whose state changed, so screen-reader users hear * progress while typing without the whole list being re-read on each keystroke. */ export function PasswordChecklist({ password, id, className }: PasswordChecklistProps) { const results = evaluatePasswordRules(password); const signature = results.map((rule) => (rule.met ? "1" : "0")).join(""); const [previous, setPrevious] = useState({ signature, results }); const [announcement, setAnnouncement] = useState(""); if (previous.signature !== signature) { setPrevious({ signature, results }); setAnnouncement(describeChanges(previous.results, results)); } return ( <> {announcement} ); }