{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "checkbox",
  "title": "Checkbox",
  "description": "A controlled or uncontrolled checkbox with indeterminate support.",
  "registryDependencies": [
    "@neumorphism-ui/utils"
  ],
  "files": [
    {
      "path": "src/components/ui/checkbox.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype CheckedState = boolean | \"indeterminate\";\n\ninterface CheckboxProps\n  extends Omit<\n    React.ComponentProps<\"input\">,\n    \"checked\" | \"defaultChecked\" | \"onChange\" | \"size\" | \"type\"\n  > {\n  checked?: CheckedState;\n  defaultChecked?: boolean;\n  onChange?: React.ChangeEventHandler<HTMLInputElement>;\n  onCheckedChange?: (checked: CheckedState) => void;\n}\n\nfunction Checkbox({\n  checked,\n  className,\n  defaultChecked,\n  disabled,\n  onChange,\n  onCheckedChange,\n  ref,\n  ...props\n}: CheckboxProps) {\n  const inputRef = React.useRef<HTMLInputElement>(null);\n  const isIndeterminate = checked === \"indeterminate\";\n\n  React.useLayoutEffect(() => {\n    if (inputRef.current) {\n      inputRef.current.indeterminate = isIndeterminate;\n    }\n  }, [isIndeterminate]);\n\n  const setRef = React.useCallback(\n    (node: HTMLInputElement | null) => {\n      inputRef.current = node;\n\n      if (typeof ref === \"function\") {\n        ref(node);\n      } else if (ref) {\n        ref.current = node;\n      }\n    },\n    [ref],\n  );\n\n  return (\n    <span\n      data-slot=\"checkbox-root\"\n      className={cn(\"relative inline-flex size-5 shrink-0 align-middle\", className)}\n    >\n      <input\n        ref={setRef}\n        type=\"checkbox\"\n        data-slot=\"checkbox\"\n        className=\"peer absolute inset-0 z-10 m-0 size-full cursor-pointer appearance-none rounded-[var(--neu-radius-small)] opacity-0 disabled:cursor-not-allowed\"\n        checked={checked === \"indeterminate\" ? false : checked}\n        defaultChecked={checked === undefined ? defaultChecked : undefined}\n        disabled={disabled}\n        aria-checked={isIndeterminate ? \"mixed\" : undefined}\n        onChange={(event) => {\n          onChange?.(event);\n          onCheckedChange?.(event.currentTarget.checked);\n\n          if (isIndeterminate) {\n            event.currentTarget.indeterminate = true;\n          }\n        }}\n        {...props}\n      />\n      <span\n        aria-hidden=\"true\"\n        className=\"relative flex size-5 items-center justify-center rounded-[var(--neu-radius-small)] border border-[color:var(--neu-edge)] bg-[var(--neu-surface)] text-[var(--neu-accent-ink)] [box-shadow:var(--neu-shadow-inset)] transition-[background-color,box-shadow] duration-[var(--neu-duration)] motion-reduce:transition-none peer-checked:bg-[var(--neu-surface)] peer-disabled:opacity-50 peer-disabled:shadow-none peer-disabled:border-[color:var(--muted-foreground)]/40 peer-focus-visible:ring-2 peer-focus-visible:ring-[var(--ring)] peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-[var(--background)] peer-indeterminate:bg-[var(--neu-surface)] peer-checked:[&_[data-check]]:opacity-100 peer-indeterminate:[&_[data-indeterminate]]:opacity-100\"\n      >\n        <svg data-check=\"\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"absolute size-3.5 opacity-0 transition-opacity\"><path d=\"m5 12 4 4L19 6\" /></svg>\n        <svg data-indeterminate=\"\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" className=\"absolute size-3.5 opacity-0 transition-opacity\"><path d=\"M5 12h14\" /></svg>\n      </span>\n    </span>\n  );\n}\n\nexport { Checkbox, type CheckedState };\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}