Checkbox group
Asks one question with several answers that can all be true: “Notify me by” email, text and push. For one answer out of several, use a Radio button group; for a single yes or no, a Checkbox.
Live preview
Rendered by the component itself from the same generated tokens as the rest of the site.
const [value, setValue] = useState<string[]>(['email'])
<CheckboxGroup
label="Notify me by"
options={[
{ value: 'email', label: 'Email' },
{ value: 'sms', label: 'Text message' },
{ value: 'push', label: 'Push notification' },
]}
value={value}
onChange={setValue}
/>Installation
Install it with the shadcn CLI, along with everything it uses. New project? Set it up first, as Quick start shows.
npx shadcn@latest add https://www.graphite-ui.com/r/checkbox-group.jsonimport { CheckboxGroup } from '@/components/ui/checkbox-group'Anatomy
The group label, 8 above the options; one Checkbox per option in 22px rows; one message for the group under them. The label names the group for assistive tech, as a fieldset’s legend.
- Group labelRequiredThe fieldset's legend, Input Label in on-surface-variant, 8 above the options. It names the group.
- OptionsRequiredThe governed Checkbox, one per option, in 22px rows 8 apart (vertical) or 16 across (horizontal).
- Supporting textOptionalOne message for the group, 8 under the options; error and warning lead with the 16px status icon, 2 in, the text at 28.
Variants
Horizontal sets the options across, 16 apart, instead of down, 8 apart.
States
Invalid rings every box in danger and puts the error under the group. Warning keeps the boxes and adds the message. Read-only and Disabled reach every box.
API reference
Generated from the contract, versioned with it, and checked by drift-check. This table cannot describe props the component does not have.
| Prop | Type | Default | Notes |
|---|---|---|---|
| options | — | — | Each a value and a label, optionally disabled. |
| value / onChange | — | — | Controlled. The checked options' values. |
| orientation | 'vertical' | 'horizontal' | — | The kit's Horizontal. Vertical by default. |
| label | — | — | Required. |
| helpText / errorText / warningText | — | — | Through the shared field-message rule. An error rings every box in danger, as the kit's Invalid group does; a warning leaves the boxes as they are. |
| disabled | boolean | — | |
| readOnly | boolean | — | The kit's Read-only, passed to every box. |
Design tokens
Every swatch is live. Change the source color in the header and this table repaints, because it reads the same roles the component does.
on-surface-variantThe group label (Text/text-secondary) and help text.on-surfaceWarning text.dangerError text and the error status icon's triangle.warningThe warning status icon's triangle.on-warningThe "!" on the warning status icon.backgroundThe "!" on the error status icon.primaryThe disabled label, through primary-disabled-content.spacingThe 8 and 16 gaps and the message's 2 inset.
Usage
The contract's prohibitions, written as the choices you will actually face.
Do
- Label the question, not the answers: “Notify me by”.
- Say in the error what is needed, such as “Choose at least one”.
- Keep the options short enough to read down a column.
- Go across only for two or three short options.
Don’t
- Use it for a choice of one. That is a Radio button group.
- Put a single checkbox in a group.
- Give each box its own error. The group carries one message.
- Restyle the boxes. They are the governed Checkbox.
Accessibility
What the component does for you, and what it leaves to you.
- Roles
- A
fieldsetnamed by its legend, holding native checkboxes, each labelled by its option. - Keyboard
- Tab reaches each box in turn; Space toggles it. Read-only boxes stay reachable and do not change.
- Messages
- The group’s message describes the fieldset through
aria-describedby; an error is announced as it appears, and each box reportsaria-invalid. - Focus
- Each box takes Checkbox’s own 2px ring.
Figma parity
The kit draws Checkbox group as one set on the Checkbox page. The code is one component over the governed Checkbox.
| Kit axis | Values | Code | How it maps |
|---|---|---|---|
| State | Enabled · Invalid · Warning · Read-only | errorText, warningText, readOnly | Invalid rings every box; Warning leaves them. The kit has no Disabled; the code passes disabled to every box. |
| Horizontal | False · True | orientation | vertical and horizontal, 8 and 16 apart. |
| Helper / Error / Warning message | Boolean + text | helpText, errorText, warningText | One message for the group, through the shared field-message rule. |
| Group label | Inside the first Checkbox | label | The fieldset’s legend, so it names the group. The kit’s vertical Enabled variant reads “Group abel”. |
