Checkbox
An accessible checkbox with checked, unchecked, and indeterminate states. Built on Radix UI.
Basic
With description
You can unsubscribe any time from the account settings.
Indeterminate (parent reflects partial selection)
Disabled
Installation
pnpm
pnpm dlx @hex-core/cli add checkboxControlled
Controlled checkbox
tsx
const [checked, setChecked] = useState(false);
<Checkbox checked={checked} onCheckedChange={setChecked} />Indeterminate (parent/children)
Parent renders a dash when some (but not all) children are selected
tsx
const [items, setItems] = useState({ email: true, push: false });
const count = Object.values(items).filter(Boolean).length;
const parent = count === 0 ? false : count === 2 ? true : "indeterminate";
<Checkbox
checked={parent}
onCheckedChange={(v) => setItems({ email: v === true, push: v === true })}
/>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | — | Controlled checked state |
defaultChecked | boolean | — | Default checked for uncontrolled |
onCheckedChange | function | — | Callback: (checked: boolean | 'indeterminate') => void |
disabled | boolean | false | Disable the checkbox |
required | boolean | false | Mark as required for form validation |
className | string | — | Additional CSS classes |
AI Guidance
When to use
Use for boolean toggles in forms (agree to terms, enable options), multi-select lists, or parent/children trees where the parent reflects partial selection via the `indeterminate` state.
When not to use
Don't use for mutually exclusive options (use RadioGroup). Don't use for instant toggles (use Switch).
Common mistakes
- Missing Label pairing
- Using onChange instead of onCheckedChange
- Forgetting that onCheckedChange can receive 'indeterminate' as well as boolean
Accessibility
Always pair with Label via htmlFor/id. Radix handles aria-checked automatically.
Token budget: 300