{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "auth5",
  "title": "Set New Password",
  "description": "Full-height reset-password screen with new and confirm password fields (each with a show/hide toggle) and a live requirements checklist that ticks off rules as the user types. Perfect for the final step of a password reset or invite flow.",
  "dependencies": [
    "clsx",
    "tailwind-merge",
    "lucide-react"
  ],
  "registryDependencies": [
    "button",
    "input",
    "field"
  ],
  "files": [
    {
      "path": "registry/auth5/auth5.tsx",
      "content": "\"use client\";\n\nimport { Check, Eye, EyeOff, Lock } from \"lucide-react\";\nimport { useId, useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Field, FieldGroup, FieldLabel } from \"@/components/ui/field\";\nimport { Input } from \"@/components/ui/input\";\nimport { cn } from \"@/lib/utils\";\n\ninterface PasswordRequirement {\n  label: string;\n  regex: string;\n}\n\ninterface Auth5Props {\n  icon?: React.ReactNode;\n  heading?: string;\n  description?: string;\n  requirements?: PasswordRequirement[];\n  labels?: {\n    newPassword?: string;\n    newPasswordPlaceholder?: string;\n    confirmPassword?: string;\n    confirmPasswordPlaceholder?: string;\n    submit?: string;\n    passwordToggle?: string;\n  };\n  className?: string;\n}\n\nexport const auth5Demo: Auth5Props = {\n  icon: <Lock className=\"size-6\" />,\n  heading: \"Set a new password\",\n  description:\n    \"Your new password must be different from previously used passwords.\",\n  requirements: [\n    { label: \"At least 8 characters\", regex: \".{8,}\" },\n    { label: \"One uppercase letter\", regex: \"[A-Z]\" },\n    { label: \"One number\", regex: \"[0-9]\" },\n    { label: \"One special character\", regex: \"[^A-Za-z0-9]\" },\n  ],\n  labels: {\n    newPassword: \"New password\",\n    newPasswordPlaceholder: \"Enter a new password\",\n    confirmPassword: \"Confirm password\",\n    confirmPasswordPlaceholder: \"Re-enter your password\",\n    submit: \"Reset password\",\n    passwordToggle: \"Toggle password visibility\",\n  },\n};\n\nexport function Auth5({\n  icon,\n  heading,\n  description,\n  requirements = [],\n  labels = {},\n  className,\n}: Auth5Props) {\n  const fieldId = useId();\n  const [password, setPassword] = useState(\"\");\n  const [confirmPassword, setConfirmPassword] = useState(\"\");\n  const [showPassword, setShowPassword] = useState(false);\n  const [showConfirm, setShowConfirm] = useState(false);\n\n  const {\n    newPassword: newPasswordLabel,\n    newPasswordPlaceholder,\n    confirmPassword: confirmPasswordLabel,\n    confirmPasswordPlaceholder,\n    submit: submitLabel,\n    passwordToggle: passwordToggleLabel,\n  } = labels;\n\n  return (\n    <section\n      className={cn(\n        \"flex min-h-screen items-center justify-center px-4 py-16 md:py-24 w-full\",\n        className\n      )}\n    >\n      <div className=\"w-full max-w-md\">\n        <div className=\"mb-8 flex flex-col items-center text-center\">\n          {icon && (\n            <div className=\"mb-6 flex size-14 items-center justify-center rounded-full bg-muted text-muted-foreground\">\n              {icon}\n            </div>\n          )}\n          {heading && (\n            <h1 className=\"text-2xl font-bold md:text-3xl\">{heading}</h1>\n          )}\n          {description && (\n            <p className=\"mt-2 text-base text-muted-foreground\">{description}</p>\n          )}\n        </div>\n\n        <div className=\"rounded-md border bg-card p-6 md:p-8\">\n          <form onSubmit={(e) => e.preventDefault()}>\n            <FieldGroup>\n              <Field>\n                {newPasswordLabel && (\n                  <FieldLabel htmlFor={`${fieldId}-new`}>\n                    {newPasswordLabel}\n                  </FieldLabel>\n                )}\n                <div className=\"relative\">\n                  <Input\n                    id={`${fieldId}-new`}\n                    type={showPassword ? \"text\" : \"password\"}\n                    placeholder={newPasswordPlaceholder}\n                    value={password}\n                    onChange={(e) => setPassword(e.target.value)}\n                    className=\"h-11 pr-11\"\n                  />\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    aria-label={passwordToggleLabel}\n                    onClick={() => setShowPassword((value) => !value)}\n                    className=\"absolute right-1 top-1/2 size-9 -translate-y-1/2 text-muted-foreground\"\n                  >\n                    {showPassword ? (\n                      <EyeOff className=\"size-4\" />\n                    ) : (\n                      <Eye className=\"size-4\" />\n                    )}\n                  </Button>\n                </div>\n              </Field>\n\n              <Field>\n                {confirmPasswordLabel && (\n                  <FieldLabel htmlFor={`${fieldId}-confirm`}>\n                    {confirmPasswordLabel}\n                  </FieldLabel>\n                )}\n                <div className=\"relative\">\n                  <Input\n                    id={`${fieldId}-confirm`}\n                    type={showConfirm ? \"text\" : \"password\"}\n                    placeholder={confirmPasswordPlaceholder}\n                    value={confirmPassword}\n                    onChange={(e) => setConfirmPassword(e.target.value)}\n                    className=\"h-11 pr-11\"\n                  />\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    aria-label={passwordToggleLabel}\n                    onClick={() => setShowConfirm((value) => !value)}\n                    className=\"absolute right-1 top-1/2 size-9 -translate-y-1/2 text-muted-foreground\"\n                  >\n                    {showConfirm ? (\n                      <EyeOff className=\"size-4\" />\n                    ) : (\n                      <Eye className=\"size-4\" />\n                    )}\n                  </Button>\n                </div>\n              </Field>\n\n              {requirements.length > 0 && (\n                <ul className=\"flex flex-col gap-2.5\">\n                  {requirements.map((requirement, index) => {\n                    const met =\n                      password.length > 0 &&\n                      new RegExp(requirement.regex).test(password);\n                    return (\n                      <li\n                        key={index}\n                        className=\"flex items-center gap-2.5 text-sm\"\n                      >\n                        <span\n                          className={cn(\n                            \"flex size-5 shrink-0 items-center justify-center rounded-full transition-colors\",\n                            met\n                              ? \"bg-emerald-500/15 text-emerald-500\"\n                              : \"bg-muted text-muted-foreground\"\n                          )}\n                        >\n                          <Check className=\"size-3.5\" />\n                        </span>\n                        <span\n                          className={cn(\n                            met ? \"text-foreground\" : \"text-muted-foreground\"\n                          )}\n                        >\n                          {requirement.label}\n                        </span>\n                      </li>\n                    );\n                  })}\n                </ul>\n              )}\n\n              {submitLabel && (\n                <Field>\n                  <Button type=\"submit\" size=\"lg\">\n                    {submitLabel}\n                  </Button>\n                </Field>\n              )}\n            </FieldGroup>\n          </form>\n        </div>\n      </div>\n    </section>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/beste/block/auth5.tsx"
    }
  ],
  "type": "registry:block"
}