{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"password-input","type":"registry:ui","title":"Password Input","description":"A password field with a button that shows or hides what you typed. The eye icon swaps with a quick pop.","dependencies":["@untitledui/icons@^0.0.23","motion@^14.0.0"],"files":[{"path":"components/ui/password-input.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { Eye, EyeOff } from \"@untitledui/icons\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as React from \"react\";\nimport { Input } from \"@/components/ui/input\";\nimport { cn } from \"@/lib/utils\";\n\nfunction PasswordInput({ className, ...props }: Omit<React.ComponentProps<typeof Input>, \"type\">) {\n  const [visible, setVisible] = React.useState(false);\n\n  return (\n    <div data-slot=\"password-input\" className=\"relative\">\n      <Input type={visible ? \"text\" : \"password\"} className={cn(\"pr-10\", className)} {...props} />\n      <button\n        type=\"button\"\n        aria-label={visible ? \"Hide password\" : \"Show password\"}\n        aria-pressed={visible}\n        onClick={() => setVisible((current) => !current)}\n        className=\"text-muted-foreground hover:text-foreground absolute top-1/2 right-1.5 flex size-7 -translate-y-1/2 items-center justify-center rounded-md transition-colors outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-foreground\"\n      >\n        <AnimatePresence mode=\"wait\" initial={false}>\n          <motion.span\n            key={visible ? \"hide\" : \"show\"}\n            initial={{ opacity: 0, scale: 0.6 }}\n            animate={{ opacity: 1, scale: 1 }}\n            exit={{ opacity: 0, scale: 0.6 }}\n            transition={{ duration: 0.15 }}\n            className=\"flex\"\n          >\n            {visible ? <EyeOff className=\"size-4\" /> : <Eye className=\"size-4\" />}\n          </motion.span>\n        </AnimatePresence>\n      </button>\n    </div>\n  );\n}\n\nexport { PasswordInput };\n"},{"path":"components/ui/input.tsx","type":"registry:ui","content":"import * as React from \"react\";\nimport { fieldSurface } from \"@/lib/field\";\nimport { cn } from \"@/lib/utils\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        fieldSurface,\n        \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 px-3 py-1 text-base file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium md:text-sm\",\n        \"focus:field-halo aria-invalid:focus:field-halo-invalid\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Input };\n"},{"path":"lib/field.ts","type":"registry:lib","content":"export const fieldSurface =\n  \"bg-background border-input dark:bg-input/30 rounded-lg border shadow-xs transition-[border-color,box-shadow] outline-none hover:border-foreground/25 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive\";\n\nexport function isFieldInvalid(meta: { isTouched: boolean; isValid: boolean }) {\n  return meta.isTouched && !meta.isValid;\n}\n"}],"css":{"@utility field-halo":{"border-color":"color-mix(in oklab, var(--foreground) 40%, transparent)","box-shadow":"0 0 0 3px color-mix(in oklab, var(--foreground) 9%, transparent)"},"@utility field-halo-invalid":{"box-shadow":"0 0 0 3px color-mix(in oklab, var(--destructive) 18%, transparent)"}}}