Checkbox

stable
Since 1.1
Independent on/off choice with indeterminate, invalid, and read-only states, plus a CheckboxGroup for related options.
Forms
primitive
Form Control
Needs State Matrix
import { Checkbox } from '@ivim/native/components';

When to use

Use when
A choice is independent of the others and any number can be selected.
A single opt-in must be explicitly agreed to, such as accepting terms.
A parent controls a set of children and needs a mixed state.
Don't use when
Exactly one option may be chosen — use RadioGroup.
The choice takes effect immediately with no submit step — use Toggle.

Playground

Adjust the controls to preview live prop combinations. The code snippet updates to match the current selection.
size
size
Indeterminate
isIndeterminate
Invalid
isInvalid
Disabled
isDisabled
Read only
isReadOnly
Label
label
<Checkbox label="Email me" />

Example

States
Unchecked
Checked
Indeterminate (announces as mixed)
With description
With a tooltip
Invalid
Read only (still announced as enabled)
Disabled
Small
CheckboxGroup
Group with label
Notifications
Horizontal
Channels
Required, with description
Notifications
*
Pick the channels you want to hear from.
With an error
Notifications
One option disabled
Notifications
Whole group disabled
Notifications

Anatomy

The parts that compose this component.
1
Control
The square box carrying border, fill, and the check or dash mark.
2
Mark
A check when selected, a dash when indeterminate; both animate in.
3
Label
The choice text, and the accessible name.
4
Description
Supporting text beneath the label; switches to the error color when invalid.

Guidelines

Do
Write labels as positive statements, so checked means yes and unchecked means no.
Do
Use CheckboxGroup for related options so the group name reaches assistive technology.
Do
Use isIndeterminate for a parent whose children are partly selected, not as a third user-selectable value.
Don't
Use a checkbox for a setting that applies instantly — a toggle communicates immediacy.
Don't
Phrase a label negatively ("Do not email me"), which makes checked mean no.

Props

Public props for this component. Required props are marked; defaults reflect the component implementation.
isSelected / defaultSelected
boolean
Controlled and uncontrolled checked state.
onChange
(isSelected: boolean) => void
Fires with the next checked value.
isIndeterminate
boolean
default: false
Mixed state for a partly-selected parent. Announces as mixed; pressing resolves to checked.
isInvalid
boolean
default: false
Applies the error treatment to the control and description.
isDisabled
boolean
default: false
Dims, blocks input, and announces disabled.
isReadOnly
boolean
default: false
Blocks input but still announces as an enabled control.
label / description
ReactNode
Choice text and supporting text.
tooltip
string
Contextual help behind a small info affordance beside the row. Supplementary only — anything required to act belongs in description.
name / value
string
Form field name and submitted value, for native web forms.
size
'sm' | 'md'
default: 'md'
Control and label scale.
aria-label
string
Accessible name when there is no visible label, or when the label is not plain text.
CheckboxGroup: options
CheckboxGroupOption[]
{ value, label, description?, isDisabled? }.
CheckboxGroup: value / defaultValue
string[]
Controlled and uncontrolled selection.
CheckboxGroup: errorMessage / isRequired / orientation
ReactNode / boolean / vertical | horizontal
Group error announced as an alert, required marker, and option stacking direction.

Deviations from Untitled UI

Where this component deliberately differs from Untitled UI's API, and why. These are kept choices, not gaps to close.
Untitled UI
`hint?: ReactNode` doubling as error text when invalid
Ours
`description` + `errorMessage`
UUI's `hint` is a UUI-ism layered over React Aria, which itself uses `description`/`errorMessage`. We follow the substrate; both slots can render simultaneously.

Accessibility

Roles and screen-reader behavior this component provides, plus keyboard interactions.
Announces accessibilityRole="checkbox" with checked state, and takes its name from a string label.
Indeterminate reports checked="mixed" — React Native models the third state natively — rather than reporting checked, which would claim every child is selected.
Pressing a mixed checkbox resolves it to checked, the platform convention.
Read-only rejects input but still announces as an enabled control, unlike disabled.
CheckboxGroup folds the group name into each option’s accessible name, since React Native has no aria-labelledby.
A group error message announces as an alert.
Tab
Moves focus to the checkbox.
Space
Toggles the focused checkbox.

Platform & RTL

Behavior that differs across the platforms this component runs on.
Web
Focusable with a visible inset focus ring; Space toggles.
iOS
VoiceOver announces the checkbox trait, its state, and mixed where applicable.
Android
TalkBack announces checked, unchecked, and mixed state.
RTL
The control and label swap sides with the writing direction.

State coverage

Interaction and visual states this component supports.
default
focus
error
disabled
selected

Token references

Semantic design tokens this component page exercises. Tap one to edit it live.