{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "pass-strengthindicator",
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "./registry/components/form/password/pass-strength-indicator.tsx",
      "content": "'use client';\nimport { Check, Eye, EyeOff, X } from 'lucide-react';\nimport React, { useMemo, useState } from 'react';\n\n// Constants\nconst PASSWORD_REQUIREMENTS = [\n  { regex: /.{8,}/, text: 'At least 8 characters' },\n  { regex: /[0-9]/, text: 'At least 1 number' },\n  { regex: /[a-z]/, text: 'At least 1 lowercase letter' },\n  { regex: /[A-Z]/, text: 'At least 1 uppercase letter' },\n  { regex: /[!-/:-@[-`{-~]/, text: 'At least 1 special characters' },\n] as const;\n\ntype StrengthScore = 0 | 1 | 2 | 3 | 4 | 5;\n\nconst STRENGTH_CONFIG = {\n  colors: {\n    0: 'bg-border',\n    1: 'bg-red-500',\n    2: 'bg-orange-500',\n    3: 'bg-amber-500',\n    4: 'bg-amber-700',\n    5: 'bg-emerald-500',\n  } satisfies Record<StrengthScore, string>,\n  texts: {\n    0: 'Enter a password',\n    1: 'Weak password',\n    2: 'Medium password!',\n    3: 'Strong password!!',\n    4: 'Very Strong password!!!',\n  } satisfies Record<Exclude<StrengthScore, 5>, string>,\n} as const;\n\n// Types\ntype Requirement = {\n  met: boolean;\n  text: string;\n};\n\ntype PasswordStrength = {\n  score: StrengthScore;\n  requirements: Requirement[];\n};\n\nconst PasswordInput = () => {\n  const [password, setPassword] = useState('');\n  const [isVisible, setIsVisible] = useState(false);\n\n  const calculateStrength = useMemo((): PasswordStrength => {\n    const requirements = PASSWORD_REQUIREMENTS.map((req) => ({\n      met: req.regex.test(password),\n      text: req.text,\n    }));\n\n    return {\n      score: requirements.filter((req) => req.met).length as StrengthScore,\n      requirements,\n    };\n  }, [password]);\n\n  // console.log(calculateStrength);\n\n  return (\n    <div className='w-96 mx-auto py-14'>\n      <form className='space-y-2'>\n        <label htmlFor='password' className='block text-sm font-medium'>\n          Password\n        </label>\n        <div className='relative'>\n          <input\n            id='password'\n            type={isVisible ? 'text' : 'password'}\n            value={password}\n            onChange={(e) => setPassword(e.target.value)}\n            placeholder='Password'\n            aria-invalid={calculateStrength.score < 4}\n            aria-describedby='password-strength'\n            className='w-full p-2 border-2 rounded-md dark:bg-neutral-950 bg-neutral-50 outline-hidden focus-within:border-blue-700 transition'\n          />\n          <button\n            type='button'\n            onClick={() => setIsVisible((prev) => !prev)}\n            aria-label={isVisible ? 'Hide password' : 'Show password'}\n            className='absolute inset-y-0 right-0 flex items-center justify-center w-9 text-muted-foreground/80 '\n          >\n            {isVisible ? <EyeOff size={16} /> : <Eye size={16} />}\n          </button>\n        </div>\n      </form>\n\n      <div\n        className='mt-3 mb-2 h-1 rounded-full dark:bg-neutral-950 bg-neutral-50 overflow-hidden'\n        role='progressbar'\n        aria-valuenow={calculateStrength.score}\n        aria-valuemin={0}\n        aria-valuemax={4}\n      >\n        <div\n          className={`h-full ${\n            STRENGTH_CONFIG.colors[calculateStrength.score]\n          } transition-all duration-500`}\n          style={{ width: `${(calculateStrength.score / 5) * 100}%` }}\n        />\n      </div>\n\n      <p id='password-strength' className='mb-2 text-sm font-medium flex justify-between'>\n        <span>Must contain:</span>\n        <span>\n          {\n            STRENGTH_CONFIG.texts[\n              Math.min(calculateStrength.score, 4) as keyof typeof STRENGTH_CONFIG.texts\n            ]\n          }\n        </span>\n      </p>\n\n      <ul className='space-y-1.5' aria-label='Password requirements'>\n        {calculateStrength.requirements.map((req, index) => (\n          <li key={req.text} className='flex items-center space-x-2'>\n            {req.met ? (\n              <Check size={16} className='text-emerald-500' />\n            ) : (\n              <X size={16} className='text-muted-foreground/80' />\n            )}\n            <span className={`text-xs ${req.met ? 'text-emerald-600' : 'text-muted-foreground'}`}>\n              {req.text}\n              <span className='sr-only'>\n                {req.met ? ' - Requirement met' : ' - Requirement not met'}\n              </span>\n            </span>\n          </li>\n        ))}\n      </ul>\n    </div>\n  );\n};\n\nexport default PasswordInput;\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}