Checkbox
checkbox() renders a <label> wrapping a real <input type="checkbox"> and the box you see. The input is visually hidden but still there, so it is focusable, it submits, and the whole label is a hit target — the tick mark is drawn from the input’s own :checked state, with no script involved.
Basic checkbox
stack({ direction: 'row', gap: 'lg' },
checkbox({ label: 'Email me updates', name: 'updates' }),
checkbox({ label: 'Checked', name: 'checked', checked: true }),
)Colors
stack({ direction: 'row', gap: 'lg', wrap: true },
checkbox({ label: 'Primary', checked: true, color: 'primary' }),
checkbox({ label: 'Neutral', checked: true, color: 'neutral' }),
checkbox({ label: 'Success', checked: true, color: 'success' }),
checkbox({ label: 'Warning', checked: true, color: 'warning' }),
checkbox({ label: 'Danger', checked: true, color: 'danger' }),
)Disabled
stack({ direction: 'row', gap: 'lg' },
checkbox({ label: 'Unavailable', disabled: true }),
checkbox({ label: 'On, and locked', checked: true, disabled: true }),
)Long labels
The box stays aligned with the first line rather than centring itself against a paragraph.
checkbox({
label: 'Run a Lighthouse audit after every build, and fail the build when a score drops below its threshold.',
name: 'lighthouse',
checked: true,
})Groups
choiceGroup() builds a set of checkboxes from data, with a shared legend and name. Pass an array as value to tick several.
choiceGroup({
legend: 'Generate',
name: 'generate',
type: 'checkbox',
value: ['sitemap', 'rss'],
options: [
{ value: 'sitemap', label: 'sitemap.xml' },
{ value: 'rss', label: 'rss.xml' },
{ value: 'pagefind', label: 'Pagefind index' },
],
help: 'Each one is written into dist/ at the end of the build.',
})In a row
choiceGroup({
legend: 'Categories',
name: 'categories',
type: 'checkbox',
direction: 'row',
value: ['performance'],
options: ['performance', 'accessibility', 'seo'],
})With a field
A single checkbox rarely needs a label above it as well. When a group does, field() gives it the same label, help and error treatment as a text field.
field({ label: 'Terms', error: 'You need to accept the terms to continue.' },
checkbox({ label: 'I accept the terms', name: 'terms', color: 'danger' }),
)Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | Child | — | Text beside the box. Omit it for a bare control. |
color | 'primary' | 'neutral' | 'success' | 'warning' | 'danger' | 'primary' | Colour when checked. |
checked | boolean | false | Whether it starts ticked. |
name | string | — | Form field name. |
value | string | number | — | Value submitted when checked. |
disabled | boolean | false | Disables the input and dims the label. |
Anything else lands on the <input>, not the label — so required, onchange and data-* go where you would expect. Use class to style the label itself.
For a set built from data, see choiceGroup() on the Radio group page — it takes the same options either way, switched by type: 'checkbox'.