Checkbox enables users to select one or multiple options from a set. It supports individual checkboxes as well as grouped checkboxes with shared state management.
Installation
yarn add @twilio-paste/checkbox
Usage
import { Checkbox, CheckboxGroup } from '@twilio-paste/checkbox';
const MyComponent = () => {
const [checked, setChecked] = React.useState(false);
return (
<Checkbox
checked={checked}
onChange={(e) => setChecked(e.target.checked)}
>
Accept terms and conditions
</Checkbox>
);
};
Props
Checkbox Props
Label text for the checkbox.
Sets the id of the checkbox. Auto-generated if not provided.
Name attribute for form submission.
Controls the checked state (controlled component).
Default checked state for uncontrolled checkboxes.
Marks the checkbox as required, showing a RequiredDot.
Sets the checkbox to an error state.
Shows an indeterminate state (partial selection indicator).
Additional help text displayed below the checkbox label.
Styles the checkbox as a “select all” option with special styling.
Indicates this checkbox is a child of a select-all checkbox.
onChange
(event: React.ChangeEvent<HTMLInputElement>) => void
Callback fired when the checked state changes.
Value attribute for the checkbox.
element
string
default:"'CHECKBOX'"
Overrides the default element name for customization.
CheckboxGroup Props
Name for all checkboxes in the group.
legend
string | React.ReactNode
required
Label for the checkbox group displayed as a fieldset legend.
Collection of Checkbox components.
Disables all checkboxes in the group.
Error message displayed below the group.
Help text displayed below the group.
Marks the group as required.
orientation
'vertical' | 'horizontal'
default:"'vertical'"
Layout direction for the checkboxes.
Examples
Single Checkbox
import { Checkbox } from '@twilio-paste/checkbox';
const [agree, setAgree] = React.useState(false);
<Checkbox
checked={agree}
onChange={(e) => setAgree(e.target.checked)}
required
>
I agree to the terms of service
</Checkbox>
Checkbox Group
import { CheckboxGroup, Checkbox } from '@twilio-paste/checkbox';
<CheckboxGroup
name="notifications"
legend="Notification preferences"
helpText="Select which notifications you'd like to receive"
>
<Checkbox value="email">Email notifications</Checkbox>
<Checkbox value="sms">SMS notifications</Checkbox>
<Checkbox value="push">Push notifications</Checkbox>
</CheckboxGroup>
With Help Text
import { Checkbox } from '@twilio-paste/checkbox';
<Checkbox
helpText="This enables two-factor authentication for added security"
>
Enable 2FA
</Checkbox>
Indeterminate State
import { Checkbox } from '@twilio-paste/checkbox';
const [checkedItems, setCheckedItems] = React.useState([true, false]);
const allChecked = checkedItems.every(Boolean);
const isIndeterminate = checkedItems.some(Boolean) && !allChecked;
<>
<Checkbox
checked={allChecked}
indeterminate={isIndeterminate}
onChange={(e) => setCheckedItems([e.target.checked, e.target.checked])}
isSelectAll
>
Select all
</Checkbox>
<Checkbox
checked={checkedItems[0]}
onChange={(e) => setCheckedItems([e.target.checked, checkedItems[1]])}
isSelectAllChild
>
Option 1
</Checkbox>
<Checkbox
checked={checkedItems[1]}
onChange={(e) => setCheckedItems([checkedItems[0], e.target.checked])}
isSelectAllChild
>
Option 2
</Checkbox>
</>
Error State
import { CheckboxGroup, Checkbox } from '@twilio-paste/checkbox';
<CheckboxGroup
name="terms"
legend="Required agreements"
required
errorText="You must accept the terms to continue"
>
<Checkbox value="privacy" hasError>
I accept the privacy policy
</Checkbox>
<Checkbox value="terms" hasError>
I accept the terms of service
</Checkbox>
</CheckboxGroup>
Horizontal Layout
import { CheckboxGroup, Checkbox } from '@twilio-paste/checkbox';
<CheckboxGroup
name="features"
legend="Features"
orientation="horizontal"
>
<Checkbox value="feature1">Voice</Checkbox>
<Checkbox value="feature2">Video</Checkbox>
<Checkbox value="feature3">Messaging</Checkbox>
</CheckboxGroup>
Accessibility
- Each Checkbox includes a visible label via the children prop
- CheckboxGroup uses a fieldset with legend for grouping
- Supports keyboard navigation (Space to toggle)
- Required checkboxes show a RequiredDot with accessible label
- Help text is properly associated with aria-describedby
- Error state is announced to screen readers via aria-invalid
- Indeterminate state uses aria-checked=“mixed”
Best Practices
- Use for binary choices or when multiple selections are allowed
- For mutually exclusive options, use Radio Group instead
- Keep checkbox labels concise and clear
- Use CheckboxGroup to organize related checkboxes
- Always provide a legend for CheckboxGroup
- Use helpText for additional context, not instructions
- Show validation errors inline with clear messages
- Use isSelectAll pattern for hierarchical checkbox selections
- Consider horizontal orientation for short lists of simple options