Checkbox

A checkbox turns one option on or off, and a group of them lets people pick any number of options at once. For a single choice out of several use a radio, and for a setting that applies at once a switch.

Usage

<script lang="ts">
	import { Checkbox } from 'noph-ui'
</script>

<Checkbox aria-label="Unchecked" />
<Checkbox aria-label="Checked" checked />
<Checkbox aria-label="Indeterminate" indeterminate />

Disabled

<script lang="ts">
	import { Checkbox } from 'noph-ui'
</script>

<Checkbox aria-label="Unchecked" disabled />
<Checkbox aria-label="Checked" disabled checked />
<Checkbox aria-label="Indeterminate" disabled indeterminate />

Error

<script lang="ts">
	import { Checkbox } from 'noph-ui'
</script>

<Checkbox aria-label="Unchecked" issues={[{ message: 'Required' }]} />
<Checkbox aria-label="Checked" checked issues={[{ message: 'Required' }]} />
<Checkbox aria-label="Indeterminate" indeterminate issues={[{ message: 'Required' }]} />

issues is shaped like a SvelteKit remote form's field issues, so passing a field's issues() straight through is enough to drive the error state.

Label

<script lang="ts">
	import { Checkbox } from 'noph-ui'
</script>

<label style="display: flex; align-items: center"><Checkbox />Checkbox one</label>
<label style="display: flex; align-items: center"><Checkbox />Checkbox two</label>

Theming

TokenDefault value
--np-checkbox-container-shape2px
--np-checkbox-outline-color--np-color-on-surface-variant
--np-checkbox-selected-container-color--np-color-primary
--np-checkbox-selected-icon-color--np-color-on-primary
--np-checkbox-marginmax(0px, (48px - 18px) / 2)

--np-checkbox-margin is the space that grows the 18dp box into a 48dp touch target. Only shrink it where the checkbox already sits inside a large enough target of its own, such as a list item.

Example

<script lang="ts">
	import { Checkbox } from 'noph-ui'
</script>

<Checkbox
	checked
	aria-label="Themed checkbox"
	--np-checkbox-container-shape="10px"
	--np-checkbox-outline-color="var(--np-color-tertiary)"
	--np-checkbox-selected-container-color="var(--np-color-error)"
	--np-checkbox-selected-icon-color="var(--np-color-on-error)"
/>

Accessibility

The component renders a native <input type="checkbox"> with the Material 3 drawing on top, so checked, focus, the space key and form submission are the browser's work, not ours.

It brings no label of its own. Wrap it in a <label>, as the Label example does, or pass aria-label. The indeterminate state reports aria-checked="mixed", and issues sets aria-invalid so the error reaches assistive technology and not only the eye.

API

AttributeTypeDefaultDescription
issues{ message: string }[]undefinedDraws the checkbox in the error color and sets aria-invalid on the input when non-empty. Shaped like a SvelteKit remote form's field issues, so it wires straight in. A disabled checkbox keeps its disabled styling instead.
...attributesOmit<HTMLInputAttributes, 'type'>

Bindables

AttributeTypeDescription
indeterminateboolean | null | undefinedInput property
checkedboolean | null | undefinedInput property
group(string | number)[] | nullInput property
elementHTMLElementA reference to the root DOM element of the component. This variable is bound using bind:this, allowing direct access to the underlying HTML element for manipulation or querying within the component's logic.