{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "checkbox",
  "title": "Checkbox",
  "description": "A checkbox component.",
  "files": [
    {
      "path": "registry/default/checkbox/checkbox.tsx",
      "content": "\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { Checkbox as BaseCheckbox } from \"@base-ui/react/checkbox\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\n\r\n// strokeDasharray 22 matches this path's computed length (~20px, rounded up for a clean draw-on).\r\nfunction CheckmarkIcon({ className }: { className?: string }) {\r\n  return (\r\n    <svg\r\n      viewBox=\"0 0 24 24\"\r\n      fill=\"none\"\r\n      stroke=\"currentColor\"\r\n      strokeWidth={2.5}\r\n      strokeLinecap=\"round\"\r\n      strokeLinejoin=\"round\"\r\n      className={cn(\r\n        // Crossfade: visible when checked (not indeterminate), hidden when indeterminate\r\n        \"not-in-data-indeterminate:scale-100 not-in-data-indeterminate:opacity-100\",\r\n        \"scale-90 opacity-0\",\r\n        \"ease-out-expo transition-[opacity,filter,transform,scale] duration-200 motion-reduce:transition-none\",\r\n        // Start hidden on mount for enter animation\r\n        \"in-data-starting-style:scale-90 in-data-starting-style:opacity-0\",\r\n        // Subtle blur during indeterminate crossfade\r\n        \"in-data-indeterminate:blur-[2px]\",\r\n        className,\r\n      )}\r\n    >\r\n      <path\r\n        d=\"M5 14L8.5 17.5L19 6.5\"\r\n        style={{\r\n          strokeDasharray: 22,\r\n        }}\r\n        className=\"ease-out-expo transition-[stroke-dashoffset] duration-200 not-in-data-indeterminate:delay-15 not-in-data-indeterminate:[stroke-dashoffset:0] in-data-indeterminate:[stroke-dashoffset:22] in-data-starting-style:[stroke-dashoffset:22] motion-reduce:transition-none\"\r\n      />\r\n    </svg>\r\n  );\r\n}\r\n\r\n// strokeDasharray 16 = exact length of the M20,12 L4,12 segment.\r\nfunction MinusIcon({ className }: { className?: string }) {\r\n  return (\r\n    <svg\r\n      viewBox=\"0 0 24 24\"\r\n      fill=\"none\"\r\n      stroke=\"currentColor\"\r\n      strokeWidth={2.5}\r\n      strokeLinecap=\"round\"\r\n      strokeLinejoin=\"round\"\r\n      className={cn(\r\n        // Crossfade: visible when indeterminate, hidden when checked\r\n        \"in-data-indeterminate:scale-100 in-data-indeterminate:opacity-100\",\r\n        \"scale-90 opacity-0\",\r\n        \"ease-out-expo transition-[opacity,filter,transform,scale] duration-200 motion-reduce:transition-none\",\r\n        // Start hidden on mount for enter animation\r\n        \"in-data-starting-style:scale-90 in-data-starting-style:opacity-0\",\r\n        // Subtle blur when transitioning away from indeterminate\r\n        \"not-in-data-indeterminate:blur-[2px]\",\r\n        className,\r\n      )}\r\n    >\r\n      <path\r\n        d=\"M20 12L4 12\"\r\n        style={{\r\n          strokeDasharray: 16,\r\n        }}\r\n        className=\"ease-out-expo transition-[stroke-dashoffset] duration-200 not-in-data-indeterminate:[stroke-dashoffset:16] in-data-indeterminate:delay-15 in-data-indeterminate:[stroke-dashoffset:0] in-data-starting-style:[stroke-dashoffset:16] motion-reduce:transition-none\"\r\n      />\r\n    </svg>\r\n  );\r\n}\r\n\r\nfunction Checkbox({\r\n  className,\r\n  variant = \"default\",\r\n  ...props\r\n}: React.ComponentProps<typeof BaseCheckbox.Root> & {\r\n  variant?: \"default\" | \"elevated\";\r\n}) {\r\n  return (\r\n    <BaseCheckbox.Root\r\n      data-slot=\"checkbox\"\r\n      className={cn(\r\n        \"peer text-primary-foreground aria-invalid:outline-destructive/50 aria-invalid:text-destructive focus-visible:outline-ring/50 ease-out-expo relative flex aspect-square size-4.5 shrink-0 items-center justify-center rounded-xs outline-0 outline-offset-0 outline-transparent transition-[outline-width,outline-offset,outline-color] duration-200 outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 aria-invalid:outline-2 aria-invalid:outline-offset-2 aria-invalid:outline-solid data-disabled:cursor-not-allowed data-disabled:opacity-60 motion-reduce:transition-none sm:size-4\",\r\n        // Edge: real border + bg-clip-padding so the border draws on the\r\n        // substrate (matches Input). The ::before fill uses -inset-px to\r\n        // extend over the border area when checked, hiding it completely.\r\n        \"border bg-clip-padding\",\r\n        variant === \"default\" ? \"bg-input\" : \"bg-input-elevated\",\r\n        // Background scale animation using ::before pseudo-element\r\n        \"before:bg-primary before:absolute before:-inset-px before:rounded-xs before:content-['']\",\r\n        \"before:ease-out-expo before:origin-center before:scale-80 before:transform-gpu before:opacity-0 before:transition-[transform,opacity,scale] before:duration-200 before:will-change-transform motion-reduce:before:transition-none\",\r\n        \"data-checked:before:scale-100 data-checked:before:opacity-100\",\r\n        \"data-indeterminate:before:scale-100 data-indeterminate:before:opacity-100\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <BaseCheckbox.Indicator\r\n        data-slot=\"checkbox-indicator\"\r\n        className=\"ease-out-expo grid place-items-center transition-opacity duration-200 *:col-start-1 *:row-start-1 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none\"\r\n      >\r\n        <CheckmarkIcon className=\"size-3.5 sm:size-3\" />\r\n        <MinusIcon className=\"size-3.5 sm:size-3\" />\r\n      </BaseCheckbox.Indicator>\r\n    </BaseCheckbox.Root>\r\n  );\r\n}\r\n\r\nexport { Checkbox };\r\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/checkbox.tsx"
    }
  ],
  "type": "registry:ui"
}