Switch
A switch is for a setting that applies as soon as it is flipped. A checkbox is for a choice you confirm later, with a submit button. If your control sits in a form with a Save at the bottom, it is a checkbox.
The component is called toggle() rather than switch() for a dull but unavoidable reason: switch is a reserved word, so it cannot be an import binding. Underneath it is a real <input type="checkbox"> carrying role="switch".
Basic switch
stack({ direction: 'row', gap: 'lg' },
toggle({ label: 'Public site', name: 'public' }),
toggle({ label: 'On', name: 'on', checked: true }),
)Colors
stack({ direction: 'row', gap: 'lg', wrap: true },
toggle({ label: 'Primary', checked: true, color: 'primary' }),
toggle({ label: 'Neutral', checked: true, color: 'neutral' }),
toggle({ label: 'Success', checked: true, color: 'success' }),
toggle({ label: 'Warning', checked: true, color: 'warning' }),
toggle({ label: 'Danger', checked: true, color: 'danger' }),
)Disabled
stack({ direction: 'row', gap: 'lg' },
toggle({ label: 'Off, and locked', disabled: true }),
toggle({ label: 'On, and locked', checked: true, disabled: true }),
)Without a label
A switch with no visible label still needs an accessible name. Pass aria-label — it falls through to the input.
toggle({ 'aria-label': 'Enable Pagefind search', checked: true })A settings list
The usual shape: the label on the left, the switch on the right, one row per setting.
- Pagefind searchIndexes every page at the end of the build.
- Image optimizationResizes and converts images at build time. Needs sharp.
- Server islandsRenders marked regions at request time.
return list(
[
['Pagefind search', 'Indexes every page at the end of the build.', true],
['Image optimization', 'Resizes and converts images at build time. Needs sharp.', true],
['Server islands', 'Renders marked regions at request time.', false],
].map(([name, description, on]) =>
listItem({
title: name,
description,
end: toggle({ 'aria-label': name, checked: on }),
}),
),
)Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | Child | — | Text beside the switch. Use aria-label when there is none. |
color | 'primary' | 'neutral' | 'success' | 'warning' | 'danger' | 'primary' | Track colour when on. |
checked | boolean | false | Whether it starts on. |
name | string | — | Form field name. |
disabled | boolean | false | Disables the input and dims the row. |
Everything else falls through to the <input>, which is where onchange and aria-* belong.