{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "checkbox",
  "title": "Checkbox",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-react/components/checkbox/checkbox.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport * as CheckboxPrimitive from '@radix-ui/react-checkbox'\nimport { Check, Minus, Loader2 } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface CheckboxProps\n  extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, 'checked' | 'defaultChecked'> {\n  /** The controlled checked state of the checkbox. */\n  checked?: boolean | 'indeterminate'\n  /** The default checked state when uncontrolled. */\n  defaultChecked?: boolean | 'indeterminate'\n  /** The value given as data when submitted with a name. */\n  value?: string\n  /** Id of the element */\n  id?: string\n  /** Size of the checkbox */\n  size?: 'sm' | 'md' | 'lg'\n  /** Custom color for the checked state - matches Vuetify color system */\n  color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | string\n  /** Label text displayed next to the checkbox */\n  label?: string\n  /** Hint text shown below the checkbox */\n  hint?: string\n  /** Error message to display */\n  errorMessages?: string | string[]\n  /** Whether to show error state */\n  error?: boolean\n  /** When `true`, prevents the user from interacting with the checkbox */\n  disabled?: boolean\n  /** When `true`, shows an indeterminate state */\n  indeterminate?: boolean\n  /** Density of the checkbox - affects spacing */\n  density?: 'compact' | 'default' | 'comfortable'\n  /** When `true`, the icon is hidden */\n  hideIcon?: boolean\n  /** Loading state - shows a spinner */\n  loading?: boolean\n  /** Label position - before or after the checkbox */\n  labelPosition?: 'before' | 'after'\n  /** Whether the checkbox appears flat (no elevation) */\n  flat?: boolean\n  /** Inline text style */\n  inline?: boolean\n  /** Name attribute for form submission */\n  name?: string\n}\n\n// Size classes\nconst sizeClasses = {\n  sm: 'size-3.5',\n  md: 'size-4',\n  lg: 'size-5',\n}\n\nconst iconSizes = {\n  sm: 'size-2.5',\n  md: 'size-3.5',\n  lg: 'size-4',\n}\n\n// Color classes for checked state\nconst colorClasses: Record<string, string> = {\n  primary:\n    'data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary',\n  secondary:\n    'data-[state=checked]:bg-secondary data-[state=checked]:border-secondary data-[state=indeterminate]:bg-secondary data-[state=indeterminate]:border-secondary',\n  success:\n    'data-[state=checked]:bg-[var(--success)] data-[state=checked]:border-[var(--success)] data-[state=indeterminate]:bg-[var(--success)] data-[state=indeterminate]:border-[var(--success)]',\n  warning:\n    'data-[state=checked]:bg-[var(--warning)] data-[state=checked]:border-[var(--warning)] data-[state=indeterminate]:bg-[var(--warning)] data-[state=indeterminate]:border-[var(--warning)]',\n  error:\n    'data-[state=checked]:bg-destructive data-[state=checked]:border-destructive data-[state=indeterminate]:bg-destructive data-[state=indeterminate]:border-destructive',\n  info: 'data-[state=checked]:bg-[var(--info)] data-[state=checked]:border-[var(--info)] data-[state=indeterminate]:bg-[var(--info)] data-[state=indeterminate]:border-[var(--info)]',\n}\n\n// Density classes\nconst densityClasses = {\n  compact: 'gap-1',\n  default: 'gap-2',\n  comfortable: 'gap-3',\n}\n\nconst Checkbox = React.forwardRef<React.ElementRef<typeof CheckboxPrimitive.Root>, CheckboxProps>(\n  (\n    {\n      className,\n      checked,\n      defaultChecked,\n      value,\n      id,\n      size = 'md',\n      color = 'primary',\n      label,\n      hint,\n      errorMessages,\n      error,\n      disabled,\n      indeterminate,\n      density = 'default',\n      hideIcon = false,\n      loading,\n      labelPosition = 'after',\n      flat = false,\n      inline = false,\n      name,\n      children,\n      ...props\n    },\n    ref,\n  ) => {\n    const hasError =\n      Boolean(error) ||\n      Boolean(errorMessages && (typeof errorMessages === 'string' ? errorMessages : errorMessages.length > 0))\n\n    // Determine if the checkbox is in an indeterminate state\n    const isIndeterminate = Boolean(indeterminate) || checked === 'indeterminate'\n\n    const resolvedChecked: boolean | 'indeterminate' | undefined = isIndeterminate ? 'indeterminate' : checked\n\n    const checkboxClasses = cn(\n      'peer border-input data-[state=checked]:text-primary-foreground data-[state=indeterminate]:text-primary-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive shrink-0 rounded-[4px] border shadow-xs transition-colors duration-200 outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',\n      sizeClasses[size],\n      colorClasses[color] || colorClasses.primary,\n      hasError &&\n        'border-destructive data-[state=checked]:!bg-destructive data-[state=checked]:!border-destructive data-[state=indeterminate]:!bg-destructive data-[state=indeterminate]:!border-destructive',\n      flat && 'shadow-none',\n      className,\n    )\n\n    const labelClasses = cn(\n      'cursor-pointer text-sm leading-none font-medium select-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',\n      hasError ? 'text-destructive' : '',\n      disabled && 'cursor-not-allowed opacity-50',\n    )\n\n    return (\n      <div className={cn('flex items-start', densityClasses[density], inline ? 'inline-flex' : 'flex-col')}>\n        {label && labelPosition === 'before' && (\n          <label htmlFor={id} className={cn('mr-2', labelClasses)}>\n            {label}\n          </label>\n        )}\n\n        <div className=\"flex items-center\">\n          <CheckboxPrimitive.Root\n            ref={ref}\n            data-slot=\"checkbox\"\n            id={id}\n            value={value}\n            name={name}\n            disabled={disabled}\n            checked={resolvedChecked}\n            defaultChecked={defaultChecked}\n            className={checkboxClasses}\n            {...props}\n          >\n            <CheckboxPrimitive.Indicator\n              data-uipkge=\"\"\n              data-slot=\"checkbox-indicator\"\n              forceMount={isIndeterminate || hideIcon ? true : undefined}\n              className=\"grid place-content-center text-current transition-none\"\n            >\n              {children ?? (\n                <>\n                  {loading ? (\n                    <Loader2 className={cn(iconSizes[size], 'animate-spin')} />\n                  ) : isIndeterminate ? (\n                    <Minus className={iconSizes[size]} />\n                  ) : !hideIcon ? (\n                    <Check className={iconSizes[size]} />\n                  ) : null}\n                </>\n              )}\n            </CheckboxPrimitive.Indicator>\n          </CheckboxPrimitive.Root>\n\n          {label && labelPosition === 'after' && (\n            <label htmlFor={id} className={cn('ml-2', labelClasses)}>\n              {label}\n            </label>\n          )}\n        </div>\n\n        {hint && !hasError && <p className=\"text-muted-foreground mt-1 text-xs\">{hint}</p>}\n\n        {hasError && (\n          <div className=\"mt-1 flex flex-col gap-0.5\">\n            {typeof errorMessages === 'string' ? (\n              <p className=\"text-destructive text-xs\">{errorMessages}</p>\n            ) : (\n              errorMessages?.map((msg, i) => (\n                <p key={i} className=\"text-destructive text-xs\">\n                  {msg}\n                </p>\n              ))\n            )}\n          </div>\n        )}\n      </div>\n    )\n  },\n)\nCheckbox.displayName = 'Checkbox'\n\nexport interface CheckboxOption {\n  label: string\n  value: string\n  disabled?: boolean\n}\n\nexport interface CheckboxGroupProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'defaultValue'> {\n  /** The value of the checkbox items that should be checked when initially rendered. */\n  defaultValue?: string[]\n  /** The controlled value of checked items. */\n  value?: string[]\n  /** Called when the checked items change. */\n  onValueChange?: (value: string[]) => void\n  /** When `true`, prevents the user from interacting with the checkboxes. */\n  disabled?: boolean\n  /** Specifies whether the checkbox group is in an error state */\n  error?: boolean\n  /** Error messages to display */\n  errorMessages?: string | string[]\n  /** Label for the group */\n  label?: string\n  /** Hint text for the group */\n  hint?: string\n  /** The orientation of the checkboxes */\n  orientation?: 'horizontal' | 'vertical'\n  /** Whether to show a border around the group */\n  bordered?: boolean\n  /** Density of the checkboxes */\n  density?: 'compact' | 'default' | 'comfortable'\n  /** Options to render as checkboxes automatically */\n  options?: (string | CheckboxOption)[]\n  /** Name attribute for all checkboxes in the group */\n  name?: string\n  /** Inline layout (alias for horizontal) */\n  inline?: boolean\n}\n\nconst CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps>(\n  (\n    {\n      className,\n      defaultValue,\n      value,\n      onValueChange,\n      disabled,\n      error,\n      errorMessages,\n      label,\n      hint,\n      orientation = 'vertical',\n      bordered = false,\n      density = 'default',\n      options,\n      name,\n      inline,\n      children,\n      ...props\n    },\n    ref,\n  ) => {\n    const [internalValue, setInternalValue] = React.useState<string[]>(defaultValue ?? [])\n    const isControlled = value !== undefined\n    const selected = isControlled ? value : internalValue\n\n    const setSelected = React.useCallback(\n      (next: string[]) => {\n        if (!isControlled) setInternalValue(next)\n        onValueChange?.(next)\n      },\n      [isControlled, onValueChange],\n    )\n\n    const toggle = React.useCallback(\n      (optionValue: string, checked: boolean | 'indeterminate') => {\n        const isChecked = checked === true\n        const next = isChecked ? [...selected, optionValue] : selected.filter((v) => v !== optionValue)\n        setSelected(next)\n      },\n      [selected, setSelected],\n    )\n\n    const actualOrientation = inline ? 'horizontal' : orientation\n\n    return (\n      <div\n        ref={ref}\n        data-slot=\"checkbox-group\"\n        role=\"group\"\n        data-orientation={actualOrientation}\n        className={cn(\n          'flex flex-col gap-2',\n          actualOrientation === 'horizontal' ? 'flex-row items-center' : 'flex-col',\n          bordered && 'rounded-lg border p-4',\n          className,\n        )}\n        {...props}\n      >\n        {label && <label className=\"text-sm font-medium\">{label}</label>}\n\n        {hint && !error && <p className=\"text-muted-foreground text-xs\">{hint}</p>}\n\n        <div\n          className={cn(\n            'flex gap-4',\n            actualOrientation === 'horizontal' ? 'flex-row flex-wrap items-center' : 'flex-col',\n          )}\n        >\n          {options && options.length > 0\n            ? options.map((option, i) => {\n                const optValue = typeof option === 'string' ? option : option.value\n                const optLabel = typeof option === 'string' ? option : option.label\n                const optDisabled = typeof option === 'string' ? undefined : option.disabled\n                return (\n                  <Checkbox\n                    key={i}\n                    value={optValue}\n                    label={optLabel}\n                    disabled={disabled || optDisabled}\n                    name={name}\n                    density={density}\n                    checked={selected.includes(optValue)}\n                    onCheckedChange={(checked) => toggle(optValue, checked)}\n                  />\n                )\n              })\n            : children}\n        </div>\n\n        {(error || errorMessages) && (\n          <div className=\"flex flex-col gap-0.5\">\n            {typeof errorMessages === 'string' ? (\n              <p className=\"text-destructive text-xs\">{errorMessages}</p>\n            ) : (\n              errorMessages?.map((msg, i) => (\n                <p key={i} className=\"text-destructive text-xs\">\n                  {msg}\n                </p>\n              ))\n            )}\n          </div>\n        )}\n      </div>\n    )\n  },\n)\nCheckboxGroup.displayName = 'CheckboxGroup'\n\nexport { Checkbox, CheckboxGroup }\n",
      "type": "registry:ui",
      "target": "~/components/ui/checkbox/checkbox.tsx"
    },
    {
      "path": "packages/registry-react/components/checkbox/index.ts",
      "content": "export {\n  Checkbox,\n  CheckboxGroup,\n  type CheckboxProps,\n  type CheckboxGroupProps,\n  type CheckboxOption,\n} from './checkbox'\n",
      "type": "registry:ui",
      "target": "~/components/ui/checkbox/index.ts"
    }
  ],
  "dependencies": [
    "@radix-ui/react-checkbox",
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Standalone or in-form binary toggle, built on Radix UI. Supports indeterminate state for tri-state lists, sizes, and proper keyboard / screen-reader behavior. Pair with Label for clickable text.",
  "categories": [
    "form"
  ]
}