{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input-otp",
  "title": "Input OTP",
  "description": "One-time-code input with slots that spring as digits land.",
  "dependencies": [
    "input-otp"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json",
    "https://ui.cuelark.com/r/motion.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/input-otp.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { OTPInput, OTPInputContext } from \"input-otp\";\n\nimport { gsap, motionScale } from \"@/lib/motion\";\nimport { cn } from \"@/lib/utils\";\n\nfunction InputOTP({ className, containerClassName, ...props }: React.ComponentProps<typeof OTPInput> & { containerClassName?: string }) {\n  return (\n    <OTPInput\n      data-slot=\"input-otp\"\n      containerClassName={cn(\"flex items-center gap-2 has-disabled:opacity-50\", containerClassName)}\n      className={cn(\"disabled:cursor-not-allowed\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"input-otp-group\" className={cn(\"flex items-center gap-1.5\", className)} {...props} />;\n}\n\n/** Each digit drops into its slot with a small spring (GSAP) as it is typed or pasted. */\nfunction InputOTPSlot({ index, className, ...props }: React.ComponentProps<\"div\"> & { index: number }) {\n  const context = React.useContext(OTPInputContext);\n  const { char, hasFakeCaret, isActive } = context?.slots[index] ?? {};\n  const charRef = React.useRef<HTMLSpanElement>(null);\n\n  React.useEffect(() => {\n    const el = charRef.current;\n    if (!char || !el) return;\n    const scale = motionScale(el);\n    if (scale) gsap.fromTo(el, { y: -6 * scale, scale: 1 + 0.25 * scale, opacity: 0 }, { y: 0, scale: 1, opacity: 1, duration: 0.35, ease: \"cue-snap\", overwrite: true });\n  }, [char]);\n\n  return (\n    <div\n      data-slot=\"input-otp-slot\"\n      data-active={isActive}\n      className={cn(\n        \"relative flex h-ctl-lg w-10 items-center justify-center rounded-md border border-input bg-card font-mono text-lg font-medium shadow-well transition-[border-color,box-shadow] duration-150 ease-cue aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/20\",\n        className,\n      )}\n      {...props}\n    >\n      <span ref={charRef}>{char}</span>\n      {hasFakeCaret && (\n        <span className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n          <span className=\"h-5 w-px animate-pulse bg-foreground duration-1000\" />\n        </span>\n      )}\n    </div>\n  );\n}\n\nfunction InputOTPSeparator(props: React.ComponentProps<\"div\">) {\n  return (\n    <div data-slot=\"input-otp-separator\" role=\"separator\" aria-hidden=\"true\" className=\"w-3 text-center font-mono text-muted-foreground\" {...props}>\n      –\n    </div>\n  );\n}\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/input-otp",
  "categories": [
    "forms"
  ],
  "type": "registry:ui"
}