Search for a command to run...
A standard binary control. Use for opting in/out of options where multiple selections are valid; for mutually exclusive choices, use `RadioGroup`. Supports an `indeterminate` third state for "select all" patterns.
Forwards every Radix Checkbox.Root prop. The most relevant:
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | "indeterminate" | — | Controlled state. Pass "indeterminate" for the "some-but-not-all-children-selected" case in a select-all checkbox. |
defaultChecked | boolean | "indeterminate" | false | Uncontrolled initial state. |
onCheckedChange | (checked: boolean | "indeterminate") => void | — | Fires on toggle. For the "select all" pattern, the parent flips between true/false; children compute the boolean. |
disabled | boolean | false | Standard HTML disabled. Removes pointer events and dims the control. |
aria-invalid | boolean | false | Renders the destructive ring + border for validation feedback. |
aria-label | string | — | Required when the checkbox sits alone with no adjacent text label. |
Pair every checkbox with a label and (when useful) a description. Compose with Field +
FieldContent + FieldTitle + FieldDescription for the canonical settings-row layout.
Use indeterminate for "some children are selected" — the canonical select-all pattern in
tables. Set checked= {selectedCount === total ? true : selectedCount > 0 ? "indeterminate" : false}.
Include aria-label when the checkbox sits alone with no adjacent text — e.g. in a table row's
select cell.
Apply changes on onCheckedChange immediately. For staged changes (toggle now, save later),
Checkbox is correct — but make the "save" step obvious.
Use a checkbox for instant on/off changes (notifications, dark mode). That's Switch — the
visual language signals "this applies right now".
Use a checkbox for mutually exclusive choices. RadioGroup or ToggleGroup are correct.
Hide the checkbox in a wall of unlabeled icon-only ones. The label is what makes the option
meaningful — even aria-label is just a fallback.
Set disabled without an explanation. Pair with a tooltip or inline reason so the user knows
why they can't toggle.