{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "clerk-otp",
  "title": "clerk-otp",
  "description": "A clerk OTP component.",
  "dependencies": [
    "react",
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/eldoraui/clerk-otp.tsx",
      "content": "\"use client\"\n\nimport { useEffect, useState } from \"react\"\nimport { motion } from \"motion/react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst generateRandomDigits = () => {\n  return Array.from({ length: 6 }, () =>\n    Math.floor(Math.random() * 10).toString()\n  )\n}\n\ntype AnimatedOTPProps = {\n  delay?: number\n  cardTitle?: string\n  cardDescription?: string\n  whileHover?: boolean\n}\n\nconst AnimatedOTP = ({\n  delay = 3500,\n  cardTitle = \"Multifactor Authentication\",\n  cardDescription = \"Each user's self-serve multifactor settings are enforced automatically during sign-in.\",\n  whileHover = false,\n}: AnimatedOTPProps) => {\n  const [animationKey, setAnimationKey] = useState(0)\n  const delayTime = Math.max(delay, 3500)\n  useEffect(() => {\n    const interval = setInterval(() => {\n      setAnimationKey((prev) => prev + 1)\n    }, delayTime)\n\n    return () => clearInterval(interval)\n  }, [delayTime])\n\n  return (\n    <OTPinput\n      key={animationKey}\n      cardTitle={cardTitle}\n      cardDescription={cardDescription}\n      whileHover={whileHover}\n    />\n  )\n}\n\nexport default AnimatedOTP\n\nconst OTPinput = ({\n  cardTitle,\n  cardDescription,\n  whileHover,\n}: AnimatedOTPProps) => {\n  const [activeIndex, setActiveIndex] = useState(0)\n  const [fadeOut, setFadeOut] = useState(false)\n  const [digits] = useState(() => generateRandomDigits())\n  const [isCardHovered, setIsCardHovered] = useState(false)\n\n  useEffect(() => {\n    if (activeIndex > digits.length - 1) return\n\n    const shouldAnimate = !whileHover || (whileHover && isCardHovered)\n\n    if (!shouldAnimate) return\n\n    const interval = setInterval(() => {\n      setActiveIndex((prev) => prev + 1)\n    }, 400)\n\n    if (activeIndex === digits.length - 1) {\n      setTimeout(() => {\n        setFadeOut(true)\n      }, 450)\n    }\n\n    return () => clearInterval(interval)\n  }, [activeIndex, digits.length, whileHover, isCardHovered])\n\n  return (\n    <motion.div\n      initial={{ opacity: 1 }}\n      onHoverStart={() => setIsCardHovered(true)}\n      onHoverEnd={() => setIsCardHovered(false)}\n      className={cn(\n        \"relative\",\n        \"flex items-center justify-center\",\n        \"h-[14rem] w-full max-w-[350px]\",\n        \"rounded-md border bg-neutral-50 dark:bg-neutral-900\",\n        \"shadow-[0_3px_10px_rgb(0,0,0,0.2)]\"\n      )}\n    >\n      <div className=\"absolute top-[25%] left-1/2 -translate-x-1/2\">\n        <div className=\"flex w-full items-center justify-center gap-3\">\n          {digits.map((digit, idx) => (\n            <div\n              key={idx}\n              className={cn(\n                \"text-primary relative flex h-10 w-8 cursor-default items-center justify-center rounded-md bg-gradient-to-br from-neutral-100 to-neutral-50 dark:from-neutral-800 dark:to-neutral-800\",\n                \"shadow-[0_3px_10px_rgb(0,0,0,0.2)]\"\n              )}\n            >\n              {(!whileHover || (whileHover && isCardHovered)) && (\n                <motion.div\n                  className=\"absolute inset-0 rounded-md border border-cyan-400\"\n                  initial={{ opacity: 0 }}\n                  animate={{ opacity: [0, 1, 0] }}\n                  transition={{\n                    duration: 0.5,\n                    ease: \"easeInOut\",\n                    delay: 2.25,\n                  }}\n                  style={{\n                    boxShadow: \"inset 0 0 12px rgba(34, 211, 238, 0.5)\",\n                  }}\n                />\n              )}\n              {activeIndex === idx &&\n                (!whileHover || (whileHover && isCardHovered)) && (\n                  <motion.div\n                    key={idx}\n                    className=\"absolute inset-0 rounded-md border border-cyan-400\"\n                    initial={{ opacity: 0 }}\n                    animate={{ opacity: 1 }}\n                    transition={{\n                      duration: 0.3,\n                      ease: \"easeInOut\",\n                    }}\n                    style={{\n                      boxShadow: \"inset 0 0 12px rgba(34, 211, 238, 0.6)\",\n                    }}\n                  >\n                    <svg\n                      viewBox=\"0 0 20 20\"\n                      className=\"absolute inset-0 h-full w-full\"\n                      strokeWidth=\"0.4\"\n                    >\n                      <path\n                        d=\"M 3 19 h 14\"\n                        className=\"stroke-cyan-400 dark:stroke-cyan-500\"\n                      />\n                    </svg>\n                  </motion.div>\n                )}\n              <motion.span\n                initial={{ opacity: 0 }}\n                animate={{\n                  opacity: whileHover\n                    ? isCardHovered\n                      ? fadeOut\n                        ? 0\n                        : 1\n                      : 0\n                    : fadeOut\n                      ? 0\n                      : 1,\n                }}\n                transition={{\n                  duration: fadeOut ? 0.1 : 0.2,\n                  ease: \"easeInOut\",\n                  delay: fadeOut ? 0 : idx * 0.43,\n                }}\n                className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\"\n              >\n                {digit}\n              </motion.span>\n            </div>\n          ))}\n        </div>\n      </div>\n      <div className=\"absolute bottom-4 left-0 w-full px-3\">\n        <h3 className=\"text-primary text-sm font-semibold\">{cardTitle}</h3>\n        <p className=\"mt-2 text-xs text-neutral-600 dark:text-neutral-400\">\n          {cardDescription}\n        </p>\n      </div>\n    </motion.div>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}