{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "p-input-group-26",
  "description": "Password input with strength indicator",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "@coss/button",
    "@coss/input-group",
    "@coss/label"
  ],
  "files": [
    {
      "path": "registry/default/particles/p-input-group-26.tsx",
      "content": "\"use client\";\n\nimport { CheckIcon, EyeIcon, EyeOffIcon, XIcon } from \"lucide-react\";\nimport { useId, useMemo, useState } from \"react\";\nimport { Button } from \"@/registry/default/ui/button\";\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupInput,\n} from \"@/registry/default/ui/input-group\";\nimport { Label } from \"@/registry/default/ui/label\";\n\nconst 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];\n\nexport default function Particle() {\n  const id = useId();\n  const [password, setPassword] = useState(\"\");\n  const [isVisible, setIsVisible] = useState(false);\n\n  const strength = requirements.map((req) => ({\n    met: req.regex.test(password),\n    text: req.text,\n  }));\n\n  const strengthScore = useMemo(() => {\n    return strength.filter((req) => req.met).length;\n  }, [strength]);\n\n  const getStrengthColor = (score: number) => {\n    if (score === 0) return \"bg-border\";\n    if (score <= 1) return \"bg-red-500\";\n    if (score <= 2) return \"bg-orange-500\";\n    if (score === 3) return \"bg-amber-500\";\n    return \"bg-emerald-500\";\n  };\n\n  const getStrengthText = (score: number) => {\n    if (score === 0) return \"Enter a password\";\n    if (score <= 2) return \"Weak password\";\n    if (score === 3) return \"Medium password\";\n    return \"Strong password\";\n  };\n\n  return (\n    <div className=\"flex flex-col gap-3\">\n      <div className=\"flex flex-col gap-2\">\n        <Label htmlFor={id}>Password</Label>\n        <InputGroup>\n          <InputGroupInput\n            aria-describedby={`${id}-description`}\n            id={id}\n            onChange={(e) => setPassword(e.target.value)}\n            placeholder=\"Password\"\n            type={isVisible ? \"text\" : \"password\"}\n            value={password}\n          />\n          <InputGroupAddon align=\"inline-end\">\n            <Button\n              aria-label={isVisible ? \"Hide password\" : \"Show password\"}\n              onClick={() => setIsVisible(!isVisible)}\n              size=\"icon-xs\"\n              variant=\"ghost\"\n            >\n              {isVisible ? (\n                <EyeOffIcon aria-hidden=\"true\" />\n              ) : (\n                <EyeIcon aria-hidden=\"true\" />\n              )}\n            </Button>\n          </InputGroupAddon>\n        </InputGroup>\n      </div>\n\n      <div\n        aria-label=\"Password strength\"\n        aria-valuemax={4}\n        aria-valuemin={0}\n        aria-valuenow={strengthScore}\n        className=\"h-1 w-full overflow-hidden rounded-full bg-border\"\n        role=\"progressbar\"\n        tabIndex={-1}\n      >\n        <div\n          className={`h-full ${getStrengthColor(strengthScore)} transition-all duration-500 ease-out`}\n          style={{ width: `${(strengthScore / 4) * 100}%` }}\n        />\n      </div>\n\n      <p\n        className=\"font-medium text-foreground text-sm\"\n        id={`${id}-description`}\n      >\n        {getStrengthText(strengthScore)}. Must contain:\n      </p>\n\n      <ul aria-label=\"Password requirements\" className=\"flex flex-col gap-1.5\">\n        {strength.map((req) => (\n          <li className=\"flex items-center gap-2\" key={req.text}>\n            {req.met ? (\n              <CheckIcon\n                aria-hidden=\"true\"\n                className=\"size-4 text-emerald-500\"\n              />\n            ) : (\n              <XIcon\n                aria-hidden=\"true\"\n                className=\"size-4 text-muted-foreground/80\"\n              />\n            )}\n            <span\n              className={`text-xs ${req.met ? \"text-emerald-600\" : \"text-muted-foreground\"}`}\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    </div>\n  );\n}\n",
      "type": "registry:block"
    }
  ],
  "meta": {
    "className": "**:data-[slot=preview]:w-full **:data-[slot=preview]:max-w-64"
  },
  "categories": [
    "button",
    "input",
    "input group",
    "label"
  ],
  "type": "registry:block"
}