DhCheckbox
Native <input type="checkbox"> styled per the M3 spec — selected, unselected and indeterminate (via the DOM property), with error and disabled states.
Basic
<DhCheckbox bind:checked={newsletter} label="Monthly newsletter" />
<DhCheckbox bind:checked={releaseNotes} label="Release notes" />
<DhCheckbox bind:checked={terms} label="Accept terms"
helperText="Required before your first export." />Indeterminate
The parent reflects its children: fully checked, fully unchecked, or mixed. A click on a mixed checkbox clears the DOM property natively, so the parent re-asserts indeterminate from derived state. When passing checked without bind:, always handle onchange — otherwise a click strands the visual state.
<script>
let wifi = $state(true);
let bluetooth = $state(false);
let allSelected = $derived(wifi && bluetooth);
let someSelected = $derived((wifi || bluetooth) && !allSelected);
</script>
<DhCheckbox
label="Connectivity"
checked={allSelected}
indeterminate={someSelected}
onchange={(e) => { wifi = e.currentTarget.checked; bluetooth = e.currentTarget.checked; }}
/>
<DhCheckbox bind:checked={wifi} label="Wi-Fi" />
<DhCheckbox bind:checked={bluetooth} label="Bluetooth" />Label position
<DhCheckbox label="End (default)" />
<DhCheckbox label="Start" labelPosition="start" />States
<DhCheckbox label="Unselected (default)" />
<DhCheckbox label="Selected" checked />
<DhCheckbox label="Indeterminate" indeterminate />
<DhCheckbox label="Disabled" disabled />
<DhCheckbox label="Disabled selected" checked disabled />
<DhCheckbox label="Required" required />
<DhCheckbox label="Error" errorText="You must accept the terms." />
<DhCheckbox label="Error selected" checked errorText="This option conflicts with your plan." />In a form
<form>
<DhCheckbox label="Email me about new features" name="features" value="on" />
<DhCheckbox label="Email me a monthly digest" name="digest" value="on" />
<DhCheckbox label="Accept terms" name="terms" value="on" required />
<DhButton type="submit" variant="primary" text="Save preferences" />
</form>