{
  "name": "Checkbox",
  "source": "src/components/Checkbox.tsx",
  "propsType": "CheckboxProps",
  "description": "Checkbox wraps a native `<input type=\"checkbox\">` and hides it.\n\nThe native input is kept rather than replaced by a div with `role=checkbox`\nbecause it brings form association, the indeterminate property, label\nclicking, and correct announcement — none of which are free to reimplement,\nand all of which are easy to get subtly wrong.\n\n`indeterminate` is the reason for the effect below: HTML has no\n`indeterminate` attribute, only a DOM property, so React cannot set it\ndeclaratively and it must be written after every render.",
  "import": "import { Checkbox } from 'ionbase-ui';",
  "status": "stable",
  "summary": "A native checkbox with the system's styling, supporting an indeterminate state.",
  "useWhen": [
    "a single on/off choice inside a form that is submitted",
    "selecting rows in a Table"
  ],
  "useInstead": [
    {
      "when": "the change takes effect immediately rather than on submit",
      "use": "Toggle",
      "why": "a switch reads as a setting taking effect now; a checkbox reads as a value being collected"
    },
    {
      "when": "several options answer one question",
      "use": "CheckboxGroup",
      "why": "it announces the question with each option, carries the group's error, and can require at least one"
    },
    {
      "when": "the options are mutually exclusive",
      "use": "RadioGroup"
    },
    {
      "when": "there are many options and space is tight",
      "use": "Select"
    }
  ],
  "variants": {
    "size": {
      "sm": {
        "use": "dense forms and table rows"
      },
      "md": {
        "use": "the default"
      },
      "lg": {
        "use": "touch targets and prominent single choices"
      }
    },
    "intent": {
      "brand": {
        "use": "the default"
      },
      "neutral": {
        "use": "where the checked state is a fact rather than an approval — bulk-selection columns"
      },
      "danger": {
        "use": "consenting to something destructive or irreversible"
      }
    }
  },
  "slots": {
    "children": {
      "accepts": "text",
      "note": "the visible label; omit for a bare box and supply `aria-label` instead"
    }
  },
  "a11y": {
    "role": "checkbox",
    "guarantees": [
      "a real <input type=\"checkbox\">, so form association, label clicking, and correct announcement come from the platform",
      "`isIndeterminate` is written to the DOM property after every render — HTML has no such attribute, so React cannot set it declaratively"
    ],
    "requires": [
      "`children`, or `aria-label` when the box has no visible label — a row-selection checkbox always needs one"
    ]
  },
  "antiPatterns": [
    {
      "dont": "a bare checkbox with no `children` and no `aria-label`",
      "why": "every row announces an unnamed checkbox"
    },
    {
      "dont": "`isIndeterminate` on a leaf checkbox",
      "why": "indeterminate means \"some of my children are checked\"; on a leaf it is a state the user can never reach"
    },
    {
      "dont": "a div with `role=\"checkbox\"`",
      "why": "form association, the indeterminate property and label clicking are not free to reimplement"
    },
    {
      "dont": "<Checkbox isSelected={on} onChange={(isSelected) => setOn(isSelected)} />",
      "do": "<Checkbox isSelected={on} onSelectionChange={setOn} />",
      "why": "both selection shapes work, but they pair: `isSelected` goes with `onSelectionChange`, which receives the boolean, and `checked` goes with `onChange`, which receives the change event. Passing the Aria selection prop with the DOM handler name is the one combination that does not type — `onChange` is still the event handler. There is no `CheckboxChange` type; a generated eval invented one."
    }
  ],
  "deprecated": [
    {
      "prop": "disabled",
      "replacement": "isDisabled"
    }
  ],
  "stylesheet": "src/styles/checkbox.css",
  "tokens": [
    "--border-disabled",
    "--border-error-strong",
    "--border-focus",
    "--border-inverse",
    "--border-primary-strong",
    "--border-stronger",
    "--border-width-default",
    "--border-width-thick",
    "--font-family-sans",
    "--icon-disabled",
    "--icon-on-color",
    "--ion-checkbox-border",
    "--ion-checkbox-fill",
    "--ion-checkbox-font-size",
    "--ion-checkbox-gap",
    "--ion-checkbox-line-height",
    "--ion-checkbox-mark",
    "--ion-checkbox-radius",
    "--ion-checkbox-raised",
    "--ion-checkbox-size",
    "--ion-duration-base",
    "--ion-ease-out",
    "--ion-shadow-raised-flush-lg",
    "--ion-shadow-raised-flush-sm",
    "--ion-shadow-raised-flush-xs",
    "--radius-sm",
    "--radius-xs",
    "--spacing-12",
    "--spacing-16",
    "--spacing-20",
    "--spacing-24",
    "--spacing-4",
    "--spacing-8",
    "--surface-default",
    "--surface-disabled",
    "--surface-error",
    "--surface-inverse",
    "--surface-primary",
    "--text-disabled",
    "--text-secondary",
    "--type-body",
    "--type-body-line-height",
    "--type-body-sm",
    "--type-body-sm-line-height"
  ],
  "props": {
    "size": {
      "type": "CheckboxSize | undefined",
      "required": false,
      "origin": "own",
      "description": "Matches the Figma `Size` variant: Small, Medium, Large.",
      "values": [
        "sm",
        "md",
        "lg"
      ]
    },
    "intent": {
      "type": "CheckboxIntent | undefined",
      "required": false,
      "origin": "own",
      "description": "Matches the Figma `Color` variant: Brand, Neutral, Danger.",
      "values": [
        "neutral",
        "danger",
        "brand"
      ]
    },
    "isIndeterminate": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "Figma's `Indeterminate` state. Not an HTML attribute — `indeterminate` is a\nDOM property only, so it has to be assigned after render.",
      "default": false
    },
    "isDisabled": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "Whether the checkbox is disabled."
    },
    "disabled": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "tags": {
        "deprecated": "Use `isDisabled`. Accepted as an alias for one minor version."
      }
    },
    "children": {
      "type": "React.ReactNode",
      "required": false,
      "origin": "own",
      "description": "Figma's `Show Label` + `Label`. Omit for a bare box."
    },
    "isSelected": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "React Aria's name for `checked`. Wins when both are passed."
    },
    "onSelectionChange": {
      "type": "((isSelected: boolean) => void) | undefined",
      "required": false,
      "origin": "own",
      "description": "Receives the new selection state rather than the change event."
    }
  },
  "propCounts": {
    "own": 8,
    "aria": 0,
    "dom": 304,
    "other": 0
  }
}
