Checkbox
A checkbox. It takes part in forms as a native checkbox does and has an indeterminate state.
import '@usezeno/tokens/css';
import '@usezeno/core/web-components';
Examples
Basic
The text comes from label. indeterminate shows a dash for a group that is partly selected. It is cleared when the user makes a choice.
<zeno-checkbox label="Send me a weekly summary"></zeno-checkbox>
<zeno-checkbox label="Remember this device" checked></zeno-checkbox>
<zeno-checkbox label="Select all files" indeterminate></zeno-checkbox>
Sizes
<zeno-checkbox size="sm" label="Small"></zeno-checkbox>
<zeno-checkbox size="md" label="Medium"></zeno-checkbox>
<zeno-checkbox size="lg" label="Large"></zeno-checkbox>
Disabled, loading and error
loading shows a spinner in the box and stops changes. error marks the checkbox as invalid and shows the text under it.
<zeno-checkbox label="Disabled" disabled></zeno-checkbox>
<zeno-checkbox label="Disabled and checked" disabled checked></zeno-checkbox>
<zeno-checkbox label="Saving your choice" loading></zeno-checkbox>
<zeno-checkbox label="I accept the terms" error="Accept the terms to continue."></zeno-checkbox>
Events
A change by the user fires input and then change. Both carry checked, value and indeterminate in event.detail.
Not changed yet.
<zeno-checkbox label="Share usage data" value="usage"></zeno-checkbox>
<p data-result>Not changed yet.</p>
document.querySelector('zeno-checkbox').addEventListener('change', event => {
document.querySelector('[data-result]').textContent =
'checked: ' + event.detail.checked + ', value: ' + event.detail.value;
});
In a form
A checked box sends its name with its value, or with “on” when no value is set. An unchecked box sends nothing. A required box must be checked before the form submits.
<form>
<zeno-checkbox name="terms" label="I accept the terms" required></zeno-checkbox>
<zeno-checkbox name="updates" value="weekly" label="Send me a weekly summary" checked></zeno-checkbox>
<zeno-button type="submit">Create account</zeno-button>
<zeno-button type="reset" variant="ghost">Reset</zeno-button>
<p data-result>Nothing submitted yet.</p>
</form>
const form = document.querySelector('form');
form.addEventListener('submit', event => {
event.preventDefault();
const sent = [...new FormData(form)].map(([name, value]) => name + '=' + value);
document.querySelector('[data-result]').textContent = 'Submitted: ' + sent.join('&');
});
Attributes and properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
checked | checkedreflects | boolean | false | |
indeterminate | indeterminatereflects | boolean | false | |
size | sizereflects | 'sm' | 'md' | 'lg' | 'md' | |
loading | loadingreflects | boolean | false | |
defaultChecked | boolean | false | Whether it is checked when its form is reset. | |
value | value | FormValue | 'on' | From FormFieldMixin. |
name | namereflects | string | From FormFieldMixin. | |
required | requiredreflects | boolean | false | From FormFieldMixin. |
disabled | disabledreflects | boolean | false | From FormFieldMixin. |
readonly | readonlyreflects | boolean | false | From FormFieldMixin. |
error | error | string | An error to show, for example one a server returned. From FormFieldMixin. | |
label | label | string | A visible label. An outside <label for> works as well. From FormFieldMixin. | |
hideRequiredIndicator | hide-required-indicator | boolean | false | From FormFieldMixin. |
touched | boolean | false | True once the user has left the control or a submit was refused. From FormFieldMixin. | |
dirty | boolean | false | True once the user has changed the value. From FormFieldMixin. | |
defaultValue | FormValue | '' | The value the control goes back to when its form is reset. From FormFieldMixin. | |
formread only | HTMLFormElement | null | From FormFieldMixin. | ||
labelsread only | NodeList | From FormFieldMixin. | ||
validityread only | ValidityState | From FormFieldMixin. | ||
validationMessageread only | string | From FormFieldMixin. | ||
willValidateread only | boolean | From FormFieldMixin. | ||
isDisabledread only | boolean | True when the element or an ancestor fieldset disables it. From FormFieldMixin. | ||
invalidread only | boolean | True when the control should look invalid. From FormFieldMixin. | ||
testId | string | Test ID for automated testing From ZenoElement. |
Methods
| Method | Description |
|---|---|
focus(options?: FocusOptions): void | Focus the component or its first focusable element From ZenoElement. |
blur(): void | Blur the component or its focused element From ZenoElement. |
checkValidity(): boolean | Reports whether the value is valid without showing anything. Use reportValidity() or validate() to show the result as well. From FormFieldMixin. |
reportValidity(): boolean | From FormFieldMixin. |
setCustomValidity(message: string): void | From FormFieldMixin. |
validate(): boolean | Checks validity and shows the result on the control. From FormFieldMixin. |
Events
| Event | Detail | Description |
|---|---|---|
input | { checked: boolean; value: FormValue; indeterminate: boolean } | The user checked or unchecked the box. |
change | { checked: boolean; value: FormValue; indeterminate: boolean } | The user checked or unchecked the box. |
Slots
This element has no slots.
CSS parts
| Part |
|---|
base |
box |
error |
icon |
label |
loading |
required |
CSS custom properties
This element documents no custom properties of its own. Style it through its parts and through the tokens it reads.
The element's own source reads no tokens.
Types
type FormValue = string | number | boolean | Date | null | undefined;
Accessibility
Keyboard
| Key | What it does |
|---|---|
| Tab | Moves focus to the checkbox. |
| Space | Checks or unchecks it. |
Forms
- With a
name, the element adds its value to the data of the form it is in, and is left out while it is disabled. - It is labelled by its
labelattribute or by a<label for>that points at itsid. - It takes part in validation:
checkValidity(),reportValidity()andsetCustomValidity()work, and an invalid element blocks the submit and matches:invalid. - It follows a
<fieldset disabled>around it and goes back to its first value when the form is reset. - The messages it writes itself, such as “Please fill out this field.”, are in English only.
Notes
- Renders a native
<input type="checkbox">in its shadow root, hidden visually but still the control that takes focus and keys. The role, the checked state and the mixed state ofindeterminateare the browser’s own. - The native input sits inside a
<label>with thelabeltext, so the text names it and a click on the text toggles it. - A
<label for>outside the element also works: its text becomes thearia-labelof the input and a click on it toggles the checkbox. Anaria-labelon the element wins over it. - The input always has
aria-invalid,"true"or"false". While the error text shows,aria-describedbypoints at it. requiredis set on the native input. The asterisk after the label is hidden from assistive technology. When a required box is left unchecked, the error text is the browser’s own message for a checkbox, unlesserroris set.
Tests and known gaps
- Tested in a real browser by
checkbox.test.ts. - Checked with axe-core in the light and the dark theme.
- Has a Storybook story.
24 of the 39 properties, methods, events, slots and parts above have no description in the source
- the property
checked - the property
indeterminate - the property
size - the property
loading - the property
value - the property
name - the property
required - the property
disabled - the property
readonly - the property
hideRequiredIndicator - the property
form - the property
labels - the property
validity - the property
validationMessage - the property
willValidate - the method
reportValidity() - the method
setCustomValidity() - the part
base - the part
box - the part
error - the part
icon - the part
label - the part
loading - the part
required
Known gaps:
- The label is text only. There is no slot, so the label cannot hold a link, for example to the terms the user accepts.
readonlyis accepted but does nothing. The checkbox can still be changed.- A
loadingcheckbox is a disabled native input. It leaves the tab order, and assistive technology announces it as unavailable, the same asdisabled. - The error text is not a live region. A screen reader reads it when focus is on the checkbox, but does not announce it when it appears.