Checkbox
A binary (or indeterminate) choice, typically submitted with a form.
@garn/ui/checkboxDefault
Default checkbox.
Sizing
Box size, mapped to the fixed --garn-box-* geometry (identity, not density).
smmdlgStates
Interactive states, toggled live.
<Checkbox />State
Labeled
Checkbox with a clickable label.
Indeterminate
The third state.
Installation
garn is copy-in — the garn CLI writes this component's source into your project, so you own and can edit it. It resolves any base files and installs the npm dependencies below for you.
npx garn-ui add checkbox- Registry
checkbox- Source
- checkbox.tsx
- Deps
@radix-ui/react-checkboxclass-variance-authoritylucide-react- Registry deps
utils
Import
import { Checkbox } from "@garn/ui/checkbox";Props
Generated from the component's TypeScript types.
size- Description
- No description.
- Type
"lg" | "md" | "sm"- Default
md
Plus 294 inherited native <button> attributes.
Styling
Target these data-slots and remap these tokens to restyle without forking the component.
[data-slot="checkbox"]| Property | Token | Tier |
|---|---|---|
size | --garn-box-md | semantic · identity |
fill | --garn-brand-solidbrandable | semantic |
ring | --garn-ringbrandable | semantic |
Overview
Checkbox toggles a single independent boolean ("Remember me", "I agree") or selects several items from a list where choices aren't mutually exclusive. It supports an indeterminate state for a parent that summarizes a partially-selected group. Reach for RadioGroup instead when exactly one of a few options must be chosen, or Switch when the change applies immediately with no Save step.
Guidelines
Pair every checkbox with a Label. The box alone is a tiny hit target with no accessible name; an associated Label both names it and extends the click area to the text. Keep the wording affirmative so checking it means "yes" — "Send me updates", not "Don't send updates".
Use indeterminate only for a summary parent. It's the visual for "some but not all children selected" in a select-all pattern — never a third user-settable value. Drive it from the children's state; clicking it should resolve to all-on or all-off.
Don't make a checkbox apply instantly. Checkboxes imply a pending choice confirmed on submit; if the toggle takes effect the moment it changes (a setting), that's a Switch. Group related checkboxes under a shared heading or fieldset so the relationship is announced.
Best practices
- Pair with a clickable label and keep the hit target generous.
- Use the
indeterminatestate for a parent that summarizes a partially-checked group.
- Don't use a checkbox for a setting that applies instantly — that's a switch.
- Don't group mutually exclusive options as checkboxes — use radio-group.
Content guidelines
- Phrase the label as the positive choice the user opts into (“Email me about updates”).
- Use sentence case, keep it to a short phrase, and make the whole label clickable.
- In a list, keep labels parallel and ordered so the set is easy to scan.
Accessibility
- Role
checkbox- ARIA APG
- checkbox
- Focus
- outline-hidden + 2px ring with a 2px offset.
Enforceable contracts
Give every checkbox an accessible label (a clickable <label htmlFor>, or aria-label).
when no associated <label> or aria-label/aria-labelledby
Keyboard
| Space | Toggle checked / unchecked. |
- • data-state reflects checked / unchecked / indeterminate (Radix maps it to aria-checked).
- Status
- Stable
- Version
v0.3.0- Introduced
v0.1.0
garn doesn't yet record a per-release version history. This reflects the component's current lifecycle state; full changelog entries will appear once the metadata pipeline emits a lifecycle.history field.