Skip to content

Checkbox

<Checkbox> is a Radix-backed checkbox. Use for “many of these” selections — a list of permissions, a multi-select filter, a “I agree” gate.

import from "@na/ui/components/checkbox" ▶ Open in Storybook packages/ui/src/components/checkbox.tsx

When to use

  • One independent binary choice (“I agree”, “Send me weekly digest”).
  • A bag of independent choices in a list (table row selection, permissions).

Don’t use Checkbox for: mutually-exclusive choices (RadioGroup), persistent settings that take effect immediately (Switch), or single-row multi-pick over many options (Combobox multi-mode — not yet shipped).

Default

<Label className="flex items-center gap-2">
<Checkbox defaultChecked />
Send me weekly digest
</Label>

Indeterminate

For a “select-all” parent that reflects partial child selection.

<Checkbox checked="indeterminate" onCheckedChange={} />

API

Prop Type Default Description
checked boolean | "indeterminate" Controlled state. Pair with onCheckedChange.
defaultChecked boolean Initial state for uncontrolled mode.
onCheckedChange (checked: boolean | "indeterminate") => void Fires on every change.
disabled boolean false Native disabled.
id string Pair with <Label htmlFor>.
name string Form-submission name.
value string "on" Form-submission value when checked.

Design guidelines

✓ Do

  • Pair with a Label. Click target should include the text — wrap with Label.
  • Use indeterminate for a parent "select all" only. Don't use for "partial" tri-state status.
  • Default unchecked unless the user has clearly opted in elsewhere.

✗ Don't

  • Use a Checkbox for an immediate setting toggle (background sync, theme). That's a Switch.
  • Render a Checkbox with no Label. Anonymous controls are unusable for screen readers.
  • Use Checkbox + Submit button for a single-choice setting. The Submit cycle adds latency for no reason.

Accessibility

  • Composes Radix Checkbox — role="checkbox", aria-checked (true / false / mixed for indeterminate), keyboard Space.
  • Pair with a <Label htmlFor> or wrap the checkbox in the label.
  • Disabled state sets aria-disabled automatically.
  • Switch — When the change takes effect immediately.
  • RadioGroup — Mutually-exclusive choices.
  • Form — react-hook-form integration.

▶ Open Checkbox stories in Storybook