{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "InputOtp",
  "dependencies": [
    "cn",
    "input-otp",
    "lucide-react",
    "rescript-base-ui"
  ],
  "registryDependencies": [
    "@rescript-shadcn/Icons"
  ],
  "files": [
    {
      "path": "registry/base/ui/InputOtp.res",
      "content": "@@jsxConfig({version: 4, mode: \"automatic\", module_: \"BaseUi.BaseUiJsxDOM\"})\n\n@@directive(\"'use client'\")\n\n@module(\"cn\")\nexternal cn: (string, option<string>) => string = \"cn\"\n\nmodule InputOtpPrimitive = {\n  module Props = {\n    type t = {\n      size?: int,\n      children?: Jsx.element,\n      ...BaseUi.Types.BaseDomProps.t,\n      ...BaseUi.Types.ExtraDomProps.t,\n      containerClassName?: string,\n      onChange?: string => unit,\n      value?: string,\n      defaultValue?: string,\n    }\n  }\n  @module(\"input-otp\")\n  external make: React.component<Props.t> = \"OTPInput\"\n\n  type slot = {\n    isActive: bool,\n    char: nullable<string>,\n    hasFakeCaret: bool,\n  }\n\n  type renderProps = {\n    slots: array<slot>,\n    isFocused: bool,\n    isHovering: bool,\n  }\n\n  @module(\"input-otp\") @val\n  external context: React.Context.t<renderProps> = \"OTPInputContext\"\n}\n\n@react.componentWithProps(InputOtpPrimitive.Props.t)\nlet make = (props: InputOtpPrimitive.Props.t) => {\n  let containerClassName = props.containerClassName\n  <InputOtpPrimitive\n    {...props}\n    dataSlot={props.dataSlot->Option.getOr(\"input-otp\")}\n    containerClassName={cn(\"gap-2 flex items-center has-disabled:opacity-50\", containerClassName)}\n    spellCheck={props.spellCheck->Option.getOr(false)}\n    className={cn(\" disabled:cursor-not-allowed\", props.className)}\n  />\n}\n\nmodule Group = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <div\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"input-otp-group\")}\n      className={cn(\n        \"has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive rounded-lg has-aria-invalid:ring-3 flex items-center\",\n        props.className,\n      )}\n    />\n}\n\nmodule Slot = {\n  type props = {\n    ...BaseUi.Types.DomProps.t,\n    index: int,\n  }\n\n  let toBaseUiProps: props => BaseUi.Types.DomProps.t = %raw(`({index, ...props}) => props`)\n\n  @react.componentWithProps(props)\n  let make = (props: props) => {\n    let index = props.index\n    let children = props.children->Option.getOr(React.null)\n    let inputOtpContext = React.useContext(InputOtpPrimitive.context)\n    let (char, hasFakeCaret, isActive) = switch inputOtpContext.slots[index] {\n    | Some(slot) => (\n        slot.char->Nullable.map(React.string)->Nullable.getOr(React.null),\n        slot.hasFakeCaret,\n        slot.isActive,\n      )\n    | None => (React.null, false, false)\n    }\n    <div\n      {...props->toBaseUiProps}\n      dataSlot={props.dataSlot->Option.getOr(\"input-otp-slot\")}\n      dataActive={isActive}\n      className={cn(\n        \"dark:bg-input/30 border-input data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive size-8 border-y border-r text-sm transition-all outline-none first:rounded-l-lg first:border-l last:rounded-r-lg data-[active=true]:ring-3 relative flex items-center justify-center data-[active=true]:z-10\",\n        props.className,\n      )}\n    >\n      {char}\n      {hasFakeCaret\n        ? <div\n            {...props->toBaseUiProps}\n            className=\"pointer-events-none absolute inset-0 flex items-center justify-center\"\n          >\n            <div\n              {...props->toBaseUiProps}\n              className=\"animate-caret-blink bg-foreground h-4 w-px duration-1000\"\n            />\n          </div>\n        : React.null}\n      {children}\n    </div>\n  }\n}\n\nmodule Separator = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) => {\n    let role = props.role->Option.getOr(\"separator\")\n    let dataSlot = props.dataSlot->Option.getOr(\"input-otp-separator\")\n    <div\n      {...props}\n      role\n      dataSlot\n      className={props.className->Option.getOr(\n        \"[&_svg:not([class*='size-'])]:size-4 flex items-center\",\n      )}\n    >\n      <Icons.Minus />\n      {props.children->Option.getOr(React.null)}\n    </div>\n  }\n}\n\n@module(\"input-otp\") external regexpOnlyDigits: string = \"REGEXP_ONLY_DIGITS\"\n@module(\"input-otp\") external regexpOnlyDigitsAndChars: string = \"REGEXP_ONLY_DIGITS_AND_CHARS\"\n",
      "type": "registry:file",
      "target": "@ui/InputOtp.res"
    }
  ],
  "type": "registry:ui"
}