nyuchimzizi
Mzizi — an open-architecture project of the Bundu Foundation, operated and developed by Nyuchi. Built on the Five African Minerals palette.
Built by Nyuchi Africav4.0.39
Visual password strength meter with requirement checklist.
No interactive demo is registered for this component yet — the source is shown directly.
"use client"
import * as React from "react"
import { Check, X } from "@/lib/icons"
import { cn } from "@/lib/utils"
interface PasswordStrengthProps extends React.ComponentProps<"div"> {
password: string
}
const CHECKS = [
{ label: "At least 8 characters", test: (p: string) => p.length >= 8 },
{ label: "Uppercase letter", test: (p: string) => /[A-Z]/.test(p) },
{ label: "Lowercase letter", test: (p: string) => /[a-z]/.test(p) },
{ label: "Number", test: (p: string) => /[0-9]/.test(p) },
{ label: "Special character", test: (p: string) => /[^A-Za-z0-9]/.test(p) },
] as const
function getStrength(password: string): { level: number; label: string } {
if (!password) return { level: 0, label: "" }
const passed = CHECKS.filter((c) => c.test(password)).length
if (passed <= 1) return { level: 1, label: "Weak" }
if (passed <= 2) return { level: 2, label: "Fair" }
if (passed <= 3) return { level: 3, label: "Good" }
return { level: 4, label: "Strong" }
}
const SEGMENT_COLORS: Record<number, string> = {
1: "bg-destructive",
2: "bg-mineral-gold",
3: "bg-mineral-cobalt",
4: "bg-mineral-malachite",
}
function PasswordStrength({ className, password, ...props }: PasswordStrengthProps) {
const { level, label } = getStrength(password)
return (
<div data-slot="password-strength" data-portal="https://design.nyuchi.com/components/password-strength" role="status" aria-live="polite" aria-label="Password strength indicator" className={cn("space-y-3 text-sm", className)} {...props}>
{/* Strength bar */}
<div className="space-y-1.5">
<div className="flex gap-1">
{[1, 2, 3, 4].map((seg) => (
<div
key={seg}
className={cn(
"h-1.5 flex-1 rounded-full transition-colors",
seg <= level ? SEGMENT_COLORS[level] : "bg-muted"
)}
/>
))}
</div>
{label && (
<p
className={cn(
"text-xs font-medium",
level === 1 && "text-destructive",
level === 2 && "text-mineral-gold",
level === 3 && "text-mineral-cobalt",
level === 4 && "text-mineral-malachite"
)}
>
{label}
</p>
)}
</div>
{/* Checklist */}
<ul className="space-y-1">
{CHECKS.map((check) => {
const passed = password ? check.test(password) : false
return (
<li key={check.label} className="flex items-center gap-2">
{passed ? (
<Check className="text-mineral-malachite size-3.5" />
) : (
<X className="size-3.5 text-muted-foreground" />
)}
<span className={cn(passed ? "text-foreground" : "text-muted-foreground")}>
{check.label}
</span>
</li>
)
})}
</ul>
</div>
)
}
export { PasswordStrength, type PasswordStrengthProps }
The variants, sizes, and props surfaced by the registry. Each is sourced from the Supabase component_docs table.
Hit the registry API live and see the JSON the shadcn CLI consumes when it installs this component.
/api/v1/ui/password-strengthnpx shadcn@latest add https://mzizi.dev/api/v1/ui/password-strengthcomponents/ui/password-strength.tsx