Checkbox
Checkbox with checked, unchecked and indeterminate states.
Installation
npx axiom add checkboxpnpm dlx axiom add checkboxyarn dlx axiom add checkboxbun x axiom add checkboxRequires the check and minus icons in your icon registry.
Usage
import { Checkbox } from '@/components/ui/checkbox';
<Checkbox checked={accepted} onCheckedChange={setAccepted} label="I accept the terms" />
<Checkbox checked="indeterminate" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | 'indeterminate' | — | Current state. 'indeterminate' draws a dash, for a parent whose children are partly checked. |
defaultChecked | boolean | false | Initial state when the checkbox manages its own state. |
onCheckedChange | (checked: boolean) => void | — | Called with the new state. Pressing an indeterminate checkbox calls it with true. |
label | ReactNode | — | Text next to the box. The whole row becomes pressable, not only the 22pt box. |
description | ReactNode | — | Secondary text under the label. |
disabled | boolean | false | Blocks changes and uses the disabled tokens. |
error | boolean | false | Red border, for a required checkbox left unchecked on submit. |
accessibilityLabel | string | label text | Required when there is no label. |
style | StyleProp<ViewStyle> | — | Extra styles for the pressable row. |
Box and check colors come from checkbox.default.{default,checked,invalid,disabled} in the component tokens.
Use cases
Consent before submitting
A required checkbox with its explanation as the label. error shows when the user submits without checking it.
<Checkbox
checked={accepted}
onCheckedChange={setAccepted}
error={submitted && !accepted}
label={
<Text>
I agree to the <Link href="/terms">Terms</Link>
</Text>
}
description={
submitted && !accepted ? "Required to create an account." : undefined
}
/>Select all in a list
The header checkbox is true, false or 'indeterminate' depending on how many rows are checked.
const all = selected.size === files.length;
const some = selected.size > 0 && !all;
<Checkbox
label="Select all"
checked={all ? true : some ? "indeterminate" : false}
onCheckedChange={(v) =>
setSelected(v ? new Set(files.map((f) => f.id)) : new Set())
}
/>;Filters with several choices
Checkboxes when any number of options can be on at once. For exactly one, use Radio.
{
cuisines.map((c) => (
<Checkbox
key={c.id}
label={c.name}
checked={filters.has(c.id)}
onCheckedChange={(v) => toggleFilter(c.id, v)}
/>
));
}