{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "confirm-pass-check",
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "./registry/components/form/password/confirm-pass-check.tsx",
      "content": "'use client';\n// shaadcn hover card\nimport { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/website/ui/hover-card';\nimport { Check, Eye, EyeOff, Info, 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: 'border-border',\n    1: 'border-red-500',\n    2: 'border-orange-500',\n    3: 'border-amber-500',\n    4: 'border-green-400',\n    5: 'border-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 [confirmPassword, setConfirmPassword] = 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  const isMatch = useMemo(() => {\n    if (confirmPassword === '') return null;\n    return password !== '' && confirmPassword === password;\n  }, [password, confirmPassword]);\n\n  return (\n    <div className='w-96 mx-auto py-12'>\n      <form className='space-y-4'>\n        <div className='flex justify-between'>\n          <label htmlFor='password' className='block text-sm font-medium'>\n            Password\n          </label>\n          <HoverCard openDelay={200}>\n            <HoverCardTrigger>\n              <Info\n                size={20}\n                className={`cursor-pointer  ${\n                  STRENGTH_CONFIG.colors[calculateStrength.score]\n                } transition-all `}\n              />\n            </HoverCardTrigger>\n            <HoverCardContent className='dark:bg-neutral-950 bg-neutral-50'>\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\n                      className={`text-xs ${\n                        req.met ? 'text-emerald-600' : 'text-muted-foreground'\n                      }`}\n                    >\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            </HoverCardContent>\n          </HoverCard>\n        </div>\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={`cursor-pointer  ${\n              STRENGTH_CONFIG.colors[calculateStrength.score]\n            } transition-all w-full p-2 border-2 rounded-md dark:bg-neutral-950 bg-neutral-50 outline-hidden`}\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 outline-hidden flex items-center justify-center w-9 text-muted-foreground/80 hover:text-foreground'\n          >\n            {isVisible ? <EyeOff size={16} /> : <Eye size={16} />}\n          </button>\n        </div>\n\n        <div>\n          <label htmlFor='confirm-password' className='block text-sm font-medium'>\n            Confirm Password\n          </label>\n          <input\n            id='confirm-password'\n            type={isVisible ? 'text' : 'password'}\n            value={confirmPassword}\n            onChange={(e) => setConfirmPassword(e.target.value)}\n            placeholder='Confirm Password'\n            aria-invalid={confirmPassword !== '' ? isMatch === false : undefined}\n            className={`cursor-pointer w-full p-2 border-2 rounded-md dark:bg-neutral-950 bg-neutral-50 outline-hidden transition-all ${\n              confirmPassword === '' ? '' : isMatch ? 'border-green-400' : 'border-red-500'\n            }`}\n          />\n          {confirmPassword !== '' && isMatch === false && (\n            <p className='text-red-500 text-sm mt-1'>Passwords do not match</p>\n          )}\n        </div>\n      </form>\n    </div>\n  );\n};\n\nexport default PasswordInput;\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}