Checkbox
An independent on/off choice that takes effect when a form is saved. A 16px square: input-tint outline at rest, ink with a check when on. Source: src/components/ui/checkbox.tsx.
With a label
Always pair it with a Label pointing at its id. Clicking the label toggles the box, which turns a 16px target into a full row.
States
Click the live ones. Hover lifts the outline; focus adds the brand ring; checked and indeterminate both fill ink.
Indeterminate renders the same check icon as checked; there is no dash glyph yet, so the parent's count or the visible children carry the “some” meaning.
With a description
Top-align the box with the label's first line (mt-0.5) and link the hint with aria-describedby.
Threads move to Archive 7 days after their last run.
Select all
A parent checkbox derives its state from its children: all, none or indeterminate. Toggle the children and watch the parent follow.
Required
No Field primitive: set aria-invalid after submit and render the message yourself. Submit unchecked to see it.
Disabled
Put the Label after the Checkbox and peer-disabled fades it with the box.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| checked | boolean | "indeterminate" | — | Controlled state. indeterminate draws the same ink box with a check (no dash glyph). |
| defaultChecked | boolean | "indeterminate" | — | Uncontrolled initial state. |
| onCheckedChange | (checked: boolean | "indeterminate") => void | — | Fires on click and Space. |
| disabled | boolean | false | 50% and not-allowed. A sibling Label after it fades too (peer-disabled). |
| required / name / value | Radix props | — | For native form posts; Radix renders a hidden input. |
| aria-invalid | boolean | "true" | "false" | — | Destructive outline. No ring: pair it with a visible message. |
| ...props | ComponentProps<typeof CheckboxPrimitive.Root> | — | No variants or sizes: every checkbox is 16px with 4px corners. className merges last. |
Best practices
When to use
- Choices that are saved with a form, or picking several items from a list.
- A setting that applies the moment it flips is a Switch.
- One choice out of several is a Select or Toggle group; there is no RadioGroup yet.
Behavior
- Space toggles a focused checkbox; clicking its Label does too.
- Don't auto-save on check in a form that has a Save button; it breaks the model.
Accessibility
- The box is only 16px: always give it a clickable Label so the hit area is the whole row.
- Group related checkboxes in a fieldset with a legend.
- Error state is a destructive outline only; pair aria-invalid with a message linked by aria-describedby.
Content
- Labels are positive statements: Send a weekly digest, not Don't send a weekly digest.