Checkbox
A styled native checkbox: checked, indeterminate, and disabled states.
Live demo
Checkbox stages a single boolean value: unlike a switch it doesn't apply on toggle, contributing its value to an enclosing form only on submit. It styles a native <input type="checkbox"> with appearance: none and overlays a custom indicator, so it keeps every native affordance (keyboard activation, form participation, label association) while looking the part.
Beyond the on/off pair it carries a third visual state, indeterminate, for the classic select-all / partial-selection pattern; the indicator switches from a check mark to a dash, and any user interaction clears it. Two sizes, sm and md, cover compact and default density.
When to use
How this component composes with the rest of the set.
Props
9 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Sizes
sm
Compact.
md
Default.
States
checked
Box filled with the chosen tone (accent by default), check mark shown.
indeterminate
Box filled, dash shown instead of the check mark.
focus-visible
Keyboard focus: a token-colored ring, plus a transparent outline that becomes real in forced-colors mode.
disabled
Non-interactive: muted fill, border, and ink.
Anatomy
The named parts that make up the component, with their selectors.
checkbox
The label root wrapping the control and text, so a click anywhere toggles the box.
control
The native checkbox input, stripped of its default look and redrawn as the box.
indicator
The overlaid check / dash glyph, drawn in the fill's foreground ink.
label
The text content wrapper beside the box.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xoji-default register
(derive(xojiDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent
--accent-2
--accent-2-fg
--accent-3
--accent-3-fg
--accent-4
--accent-4-fg
--accent-fg
--black
--black-fg
--blue
--blue-fg
--border-normal
--border-thin
--brown
--brown-fg
--cyan
--cyan-fg
--danger
--danger-fg
--duration-fast
--ease-standard
--fg-0
--fg-disabled
--field-bg
--field-border
--font-sans
--gray
--gray-fg
--green
--green-fg
--info
--info-fg
--leading-normal
--neutral
--neutral-fg
--orange
--orange-fg
--pink
--pink-fg
--purple
--purple-fg
--radius-sm
--red
--red-fg
--ring
--space-1
--space-2
--space-4
--space-5
--space-6
--state-disabled
--success
--success-fg
--text-body
--text-sm
--warn
--warn-fg
--weight-semibold
--white
--white-fg
--yellow
--yellow-fg
Slots
The visible label text beside the box.
Accessibility
Code
States
Unchecked, checked, indeterminate, and a disabled compact checkbox.
<xoji-checkbox name="terms" value="accepted">I accept the terms</xoji-checkbox>
<xoji-checkbox checked>Subscribe to the newsletter</xoji-checkbox>
<xoji-checkbox indeterminate>Select all</xoji-checkbox>
<xoji-checkbox size="sm" disabled>Unavailable option</xoji-checkbox>
<script lang="ts">
import { Checkbox } from "@xoji/svelte";
let accepted = $state(false);
let all = $state(false);
let partial = $state(true);
</script>
<Checkbox bind:checked={accepted} name="terms" value="accepted">I accept the terms</Checkbox>
<Checkbox bind:checked={all} bind:indeterminate={partial}>Select all</Checkbox>
<Checkbox size="sm" disabled>Unavailable option</Checkbox>
---
import { Checkbox } from "@xoji/astro";
---
<Checkbox name="terms" value="accepted">I accept the terms</Checkbox>
<Checkbox checked>Subscribe to the newsletter</Checkbox>
<Checkbox indeterminate>Select all</Checkbox>
<Checkbox size="sm" disabled>Unavailable option</Checkbox>
Group selection
A CheckboxGroup with a tri-state select-all heading that rolls up its items automatically.
<xoji-checkbox-group label="Notifications">
<xoji-checkbox checked>Mentions</xoji-checkbox>
<xoji-checkbox>Replies</xoji-checkbox>
<xoji-checkbox checked>Direct messages</xoji-checkbox>
</xoji-checkbox-group>
<script lang="ts">
import { CheckboxGroup, Checkbox } from "@xoji/svelte";
</script>
<CheckboxGroup label="Notifications">
<Checkbox checked>Mentions</Checkbox>
<Checkbox>Replies</Checkbox>
<Checkbox checked>Direct messages</Checkbox>
</CheckboxGroup>
---
import { CheckboxGroup, Checkbox } from "@xoji/astro";
---
<CheckboxGroup label="Notifications">
<Checkbox checked>Mentions</Checkbox>
<Checkbox>Replies</Checkbox>
<Checkbox checked>Direct messages</Checkbox>
</CheckboxGroup>