{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "auth-11",
  "description": "Multi-input OTP/Magic Link verification form.",
  "registryDependencies": [
    "button",
    "input"
  ],
  "files": [
    {
      "path": "registry/blocks/auth/11/otp-form.tsx",
      "content": "\"use client\";\n\nimport { ArrowLeft, MailIcon } from \"lucide-react\";\nimport type React from \"react\";\nimport { useRef, useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\nconst DIGIT_REGEX = /^\\d*$/;\nconst OTP_FIELDS = [0, 1, 2, 3, 4, 5];\n\nexport function OtpForm() {\n  const [otp, setOtp] = useState([\"\", \"\", \"\", \"\", \"\", \"\"]);\n  const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n  const handleChange = (index: number, value: string) => {\n    let newValue = value;\n    if (newValue.length > 1) {\n      newValue = newValue.slice(-1);\n    }\n    if (!DIGIT_REGEX.test(newValue)) {\n      return;\n    }\n\n    const newOtp = [...otp];\n    newOtp[index] = newValue;\n    setOtp(newOtp);\n\n    // Move to next input if value is entered\n    if (newValue && index < 5) {\n      inputRefs.current[index + 1]?.focus();\n    }\n  };\n\n  const handleKeyDown = (\n    index: number,\n    e: React.KeyboardEvent<HTMLInputElement>\n  ) => {\n    if (e.key === \"Backspace\" && !otp[index] && index > 0) {\n      inputRefs.current[index - 1]?.focus();\n    }\n  };\n\n  return (\n    <div className=\"flex h-screen w-full items-center justify-center bg-background px-6 py-12\">\n      <div className=\"w-full max-w-[440px] space-y-12 text-center\">\n        <div className=\"flex flex-col items-center space-y-8\">\n          <div className=\"relative\">\n            <div className=\"flex size-20 items-center justify-center rounded-[2.5rem] bg-primary/5 text-primary shadow-sm ring-1 ring-primary/10 transition-transform duration-500 hover:scale-105\">\n              <MailIcon className=\"size-10\" />\n            </div>\n            <div className=\"-right-1 -top-1 absolute flex size-6 items-center justify-center rounded-full border-4 border-background bg-primary shadow-lg shadow-primary/20\">\n              <span className=\"size-1.5 animate-pulse rounded-full bg-white\" />\n            </div>\n          </div>\n\n          <div className=\"space-y-4\">\n            <h1 className=\"font-bold text-4xl tracking-tightest sm:text-5xl\">\n              Verify email\n            </h1>\n            <p className=\"mx-auto max-w-sm font-medium text-lg text-muted-foreground leading-relaxed\">\n              We've sent a 6-digit verification code to\n              <span className=\"mt-1 block font-bold text-foreground\">\n                v***k@example.com\n              </span>\n            </p>\n          </div>\n        </div>\n\n        <div className=\"space-y-10\">\n          <div className=\"flex justify-between gap-3 sm:gap-4\">\n            {OTP_FIELDS.map((index) => (\n              <Input\n                className=\"h-14 w-full rounded-2xl border-zinc-200 bg-zinc-50/50 text-center font-bold text-2xl outline-none transition-all focus:bg-background focus:ring-4 focus:ring-primary/5 dark:border-zinc-800 dark:bg-zinc-900/50\"\n                inputMode=\"numeric\"\n                key={`otp-digit-${index}`}\n                maxLength={1}\n                onChange={(e) => handleChange(index, e.target.value)}\n                onKeyDown={(e) => handleKeyDown(index, e)}\n                pattern=\"\\d*\"\n                ref={(el) => {\n                  inputRefs.current[index] = el;\n                }}\n                type=\"text\"\n                value={otp[index]}\n              />\n            ))}\n          </div>\n\n          <div className=\"space-y-4\">\n            <Button\n              className=\"h-14 w-full rounded-2xl font-bold text-base shadow-2xl shadow-primary/20 transition-all hover:scale-[1.01] active:scale-[0.99]\"\n              size=\"lg\"\n            >\n              Verify Account\n            </Button>\n\n            <p className=\"font-medium text-muted-foreground text-sm\">\n              Didn't receive the code?{\" \"}\n              <button\n                className=\"font-bold text-primary underline-offset-4 transition-all hover:underline\"\n                type=\"button\"\n              >\n                Resend code\n              </button>\n            </p>\n          </div>\n        </div>\n\n        <button\n          className=\"inline-flex items-center gap-2.5 font-bold text-muted-foreground/60 text-xs uppercase tracking-widest transition-all hover:text-foreground\"\n          type=\"button\"\n        >\n          <ArrowLeft className=\"size-4\" />\n          Back to sign in\n        </button>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "meta": {
    "height": "800px",
    "isPinned": true,
    "createdAt": "2024-03-26"
  },
  "categories": [
    "auth"
  ],
  "type": "registry:block"
}