Checkbox
A custom box with checked, indeterminate, and disabled states, Space/Enter keyboard toggling, and an inlined Lucide check icon. Form-associated; emits a composed change event.
Preview
<esa-checkbox label="Subscribe to updates" checked></esa-checkbox> States
<esa-checkbox label="Unchecked"></esa-checkbox>
<esa-checkbox label="Checked" checked></esa-checkbox>
<esa-checkbox label="Indeterminate" indeterminate></esa-checkbox>
<esa-checkbox label="Disabled" disabled></esa-checkbox>
<esa-checkbox label="Disabled + checked" disabled checked></esa-checkbox> Sizes
<esa-checkbox label="Extra small" size="xs" checked></esa-checkbox>
<esa-checkbox label="Small" size="sm" checked></esa-checkbox>
<esa-checkbox label="Medium" size="md" checked></esa-checkbox>
<esa-checkbox label="Large" size="lg" checked></esa-checkbox> No label
Omit label for a bare box — supply an aria-label for an accessible name.
<esa-checkbox checked aria-label="Select row"></esa-checkbox> Form participation
Checked boxes submit on under their name; unchecked boxes submit nothing.
<form>
<esa-checkbox label="Subscribe" name="subscribe" checked></esa-checkbox>
<button type="submit">Submit</button>
</form> API
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | '' | Text rendered beside the box. |
checked | boolean | false | Whether the box is checked. |
indeterminate | boolean | false | Renders the mixed/partial state with a dash. |
size | 'xs' | 'sm' | 'md' | 'lg' | 'md' | Box and label size. |
disabled | boolean | false | Disables interaction. |
Events
| Event | Type | Default | Description |
|---|---|---|---|
change | CustomEvent<{ checked: boolean }> | — | Fired when toggled. Composed and bubbling; detail.checked is the new state. |
Accessibility
- The box has
role="checkbox"witharia-checkedreflecting checked ormixed(indeterminate). - Focusable via
tabindexand toggles on Space or Enter. aria-disabledand a-1tabindex are applied when disabled.- Without a
label, provide anaria-labelfor an accessible name.
Theming surface
Every public token this component reads, extracted from its source at build time.
The Resolves to column walks each token's real lineage —
component → semantic → primitive → raw value — so you
can see exactly where re-pointing it lands. A spoke re-skins by overriding these in
its theme-<slug>.css; component internals are never edited. No
hook for what you need? File it with /request-lego.
| Token | Tier | Resolves to |
|---|---|---|
--focus-ring-color | component | #65ba74 via --color-border-focus → --color-grass-8 |
--focus-ring-width | component | 2px |
--form-bg | component | #fcfcfc via --color-surface → --color-gray-1 |
--form-border-color | component | #cecece via --color-border → --color-gray-7 |
--form-border-color-focus | component | #65ba74 via --color-border-focus → --color-grass-8 |
--form-border-width | component | 1px |
--form-font-size-lg | component | clamp(0.875rem, 0.77rem + 0.52vw, 1.125rem) via --type-size-300 |
--form-font-size-md | component | clamp(0.75rem, 0.66rem + 0.44vw, 0.9375rem) via --type-size-200 |
--form-font-size-sm | component | clamp(0.625rem, 0.56rem + 0.32vw, 0.75rem) via --type-size-100 |
--form-font-size-xs | component | clamp(0.5rem, 0.44rem + 0.3vw, 0.625rem) via --type-size-050 |
--form-radius-lg | component | 0.5rem via --radius-200 |
--form-radius-md | component | 0.5rem via --radius-200 |
--form-radius-sm | component | 0.25rem via --radius-100 |
--form-radius-xs | component | 0.25rem via --radius-100 |
--color-primary | semantic | #46a758 via --color-grass-9 |
--color-text-inverse | semantic | #fcfcfc via --color-gray-1 |
--color-text-primary | semantic | #202020 via --color-gray-12 |
--font-sans | semantic | 'DM Sans', sans-serif |
--transition-fast | semantic | 150ms ease |
--spacing-200 | primitive | 0.5rem |