{
  "$schema": "https://blode.co/ui/schema/registry-item.json",
  "name": "checkbox",
  "title": "Checkbox",
  "author": "Matthew Blode",
  "description": "A control that allows the user to toggle between checked and unchecked states.",
  "dependencies": ["@base-ui/react"],
  "files": [
    {
      "path": "ui/checkbox.tsx",
      "content": "\"use client\";\n\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport \"./checkbox.css\";\n\ntype CheckedState = boolean | \"indeterminate\";\n\nexport interface CheckboxProps extends Omit<\n  React.ComponentProps<typeof CheckboxPrimitive.Root>,\n  \"checked\" | \"defaultChecked\" | \"indeterminate\" | \"onCheckedChange\"\n> {\n  checked?: CheckedState;\n  defaultChecked?: CheckedState;\n  hasError?: boolean;\n  indeterminate?: boolean;\n  onCheckedChange?: (checked: CheckedState) => void;\n}\n\nconst Checkbox = ({\n  checked,\n  className,\n  defaultChecked,\n  hasError,\n  indeterminate,\n  onCheckedChange,\n  ...props\n}: CheckboxProps) => {\n  const resolvedIndeterminate =\n    indeterminate ?? (checked === \"indeterminate\" || defaultChecked === \"indeterminate\");\n\n  return (\n    <CheckboxPrimitive.Root\n      aria-invalid={hasError || undefined}\n      checked={checked === \"indeterminate\" ? false : checked}\n      className={cn(\n        \"ft-checkbox peer relative inline-flex size-5 shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-[6px] bg-card align-middle shadow-input transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 data-disabled:cursor-not-allowed data-checked:text-primary-foreground data-indeterminate:text-primary-foreground data-disabled:opacity-50\",\n        className,\n      )}\n      data-slot=\"checkbox\"\n      defaultChecked={defaultChecked === \"indeterminate\" ? false : defaultChecked}\n      indeterminate={resolvedIndeterminate}\n      onCheckedChange={(nextChecked) => onCheckedChange?.(nextChecked)}\n      render={(renderProps, state) => {\n        let dataState: \"indeterminate\" | \"checked\" | \"unchecked\" = \"unchecked\";\n        if (state.indeterminate) {\n          dataState = \"indeterminate\";\n        } else if (state.checked) {\n          dataState = \"checked\";\n        }\n        return <span {...renderProps} data-state={dataState} />;\n      }}\n      {...props}\n    >\n      <CheckboxPrimitive.Indicator\n        className=\"pointer-events-none flex items-center justify-center text-current\"\n        data-slot=\"checkbox-indicator\"\n        keepMounted\n      >\n        <svg aria-hidden=\"true\" className=\"z-10 h-3 w-4\" role=\"presentation\" viewBox=\"0 0 17 18\">\n          <polyline\n            className=\"ft-checkbox-polyline\"\n            fill=\"none\"\n            points=\"1 9 7 14 15 4\"\n            stroke=\"currentColor\"\n            strokeDasharray={22}\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            strokeWidth={2}\n          />\n          <line\n            className=\"ft-checkbox-line\"\n            stroke=\"currentColor\"\n            strokeLinecap=\"round\"\n            strokeWidth={2}\n            x1=\"3\"\n            x2=\"13\"\n            y1=\"9\"\n            y2=\"9\"\n          />\n        </svg>\n      </CheckboxPrimitive.Indicator>\n    </CheckboxPrimitive.Root>\n  );\n};\n\nexport { Checkbox };\n",
      "type": "registry:ui",
      "target": ""
    },
    {
      "path": "ui/checkbox.css",
      "content": ".ft-checkbox[data-state=\"checked\"] .ft-checkbox-polyline {\n  stroke-dashoffset: 44;\n  transition: stroke-dashoffset 250ms linear 0.2s;\n}\n\n.ft-checkbox:not([data-state=\"checked\"]) .ft-checkbox-polyline {\n  stroke-dashoffset: 66;\n}\n\n.ft-checkbox .ft-checkbox-line {\n  opacity: 0;\n  transform: scaleX(0);\n  transform-origin: center;\n  transition:\n    opacity 250ms ease,\n    transform 250ms ease;\n}\n\n.ft-checkbox[data-state=\"indeterminate\"] .ft-checkbox-line {\n  opacity: 1;\n  transform: scaleX(1);\n  transition:\n    opacity 250ms ease 0.1s,\n    transform 250ms ease 0.1s;\n}\n\n.ft-checkbox[data-state=\"indeterminate\"] .ft-checkbox-polyline {\n  opacity: 0;\n}\n\n.ft-checkbox::after {\n  position: absolute;\n  inset: 0;\n  content: \"\";\n  background-color: var(--primary);\n  border-radius: 6px;\n  opacity: 0;\n  transform-origin: center;\n  scale: 0.5;\n  transition: all 200ms linear;\n}\n\n.ft-checkbox[data-state=\"checked\"]::after,\n.ft-checkbox[data-state=\"indeterminate\"]::after {\n  opacity: 1;\n  scale: 1;\n}\n\n.ft-checkbox[data-state=\"checked\"]::before,\n.ft-checkbox[data-state=\"indeterminate\"]::before {\n  border-color: var(--primary);\n}\n\n.ft-checkbox::before {\n  position: absolute;\n  inset: 0;\n  content: \"\";\n  border: 1px solid var(--input);\n  border-radius: 6px;\n  transform-origin: center;\n  transition: all;\n}\n\n.ft-checkbox:hover::before {\n  border-color: var(--input-hover, var(--input));\n}\n",
      "type": "registry:ui",
      "target": ""
    }
  ],
  "type": "registry:ui"
}
