Skip to content
Components, switch product

Checkbox

<gui-checkbox> is a checkbox for a yes or no choice. It renders a native <input type="checkbox"> inside its label, so clicking the text checks it too.

Code of the example above
CheckboxBasic.tsx
import { GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function CheckboxBasic() {
return <GuiCheckbox label="Send me the monthly newsletter" />;
}

The element’s entry point is @golemui/gui-components/checkbox, which registers <gui-checkbox> and nothing else. To install the package and load the stylesheet, see Installation.

The @golemui/gui-components/react components have typed props and an on* prop for each event. React 18 or later.

NewsletterField.tsx
import { useState } from 'react';
import { GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function NewsletterField() {
const [newsletter, setNewsletter] = useState(false);
return (
<GuiCheckbox
label="Send me the monthly newsletter"
name="newsletter"
value={newsletter}
onGuiChange={(event) => setNewsletter(event.detail.value ?? false)}
/>
);
}

Properties

Property Type Default Description
localeId attribute locale-id string 'en' BCP 47 locale for formatting and parsing, such as en-US or es.
value boolean – Whether it is checked. As an attribute, value checks it and value="false" does not.
checkboxPosition attribute checkbox-position 'left' | 'right' 'left' Side of the label the checkbox is on.
uid string – The id of the element's control. The ids of its label, hint and errors derive from it. Optional: when it is not set, the element generates one from its tag name and a page-wide counter, e.g. gui-textinput-3. Generated ids depend on creation order, so a server-rendered element must set uid or its ids will not match after hydration.

Form control properties

Every field has these, from the base class of the form controls.

Property Type Default Description
name string – The name the value is submitted under. Without it the element stays out of its form. Reflected, like a native control's: the form reads a single value's name from the attribute.
label string – The visible label, which also names the control for assistive technology. Without one the control has no accessible name; the date, time, range, tags and file fields warn about it in development builds.
hint string – Help text shown under the label and announced as the control's description.
errors string[] [] Error messages to show, typically from your own validation. They show as soon as they are set, unless touched is false.
touched boolean – Whether the user has interacted with the control. Leave it unset unless you validate on interaction: false holds errors back until it becomes true.
required boolean false The control needs a value: it is marked as required and, with a name, blocks submission.
readOnly attribute readonly boolean – The value can be read and focused but not changed.
disabled boolean – Disabled by its own attribute or by a disabled <fieldset> around it. Setting the property sets the attribute, like a native control's.
form read-only, no attribute HTMLFormElement | null – The <form> the element belongs to, if any.
validity read-only, no attribute ValidityState – The element's validity, like a native control's.
validationMessage read-only, no attribute string – The message the browser shows for an invalid value.

Methods

Method Description
checkValidity(): boolean –
reportValidity(): boolean –

Events

Every event bubbles and is composed, so you can listen on any ancestor.

Event Description
gui-input The user changed the value. detail.value is the new value.
gui-change The user committed the value. detail.value is the committed value.
gui-blur Focus left the control.

The value is true or false. As an attribute, value checks the box and value="false" leaves it unchecked. From JavaScript, set the value property to true or false.

Code of the example above
CheckboxChecked.tsx
import { GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function CheckboxChecked() {
return <GuiCheckbox label="Remember me on this device" value />;
}

hint shows under the label. Screen readers read it as the checkbox’s description.

Code of the example above
CheckboxHint.tsx
import { GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function CheckboxHint() {
return (
<GuiCheckbox
label="Share anonymous usage data"
hint="It helps us fix crashes. We never collect your files."
/>
);
}

The checkbox sits before the label. checkbox-position="right" puts it after the label.

Code of the example above
CheckboxPosition.tsx
import { GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function CheckboxPosition() {
return (
<GuiCheckbox
label="Email me when someone replies"
checkboxPosition="right"
/>
);
}

A disabled checkbox can’t be focused or changed, and a form doesn’t submit it. A readonly checkbox can be focused but clicks and Space don’t change it, and a form submits its value.

Code of the example above
CheckboxDisabledReadonly.tsx
import { GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function CheckboxDisabledReadonly() {
return (
<div className="gui-grid gui-grid--row">
<div className="gui-grid__cell">
<GuiCheckbox label="Two-factor sign-in" value disabled />
</div>
<div className="gui-grid__cell">
<GuiCheckbox label="Admin access" value readOnly />
</div>
</div>
);
}

errors takes a list of messages from your own validation, and shows them under the checkbox. Set the errors property from a gui-change listener to validate as the user works. Check the box, then uncheck it.

Code of the example above
CheckboxValidation.tsx
import { useState } from 'react';
import { GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function CheckboxValidation() {
const [errors, setErrors] = useState<string[]>([]);
return (
<GuiCheckbox
id="terms-check"
label="I accept the terms of service"
errors={errors}
onGuiChange={(event) =>
setErrors(
event.detail.value
? []
: ['Accept the terms to create your account.'],
)
}
/>
);
}

With a name, a checked <gui-checkbox> submits on under that name, like a native checkbox, and an unchecked one submits nothing. required blocks the submit until the box is checked. Submit the form below, then check the first box and submit again.

Code of the example above
CheckboxNativeForm.tsx
import { useState, type SubmitEvent } from 'react';
import { GuiButton, GuiCheckbox } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function CheckboxNativeForm() {
const [result, setResult] = useState('');
const onSubmit = (event: SubmitEvent<HTMLFormElement>) => {
event.preventDefault();
const data = Object.fromEntries(new FormData(event.currentTarget));
setResult(`Submitted ${JSON.stringify(data)}`);
};
return (
<form id="signup" onSubmit={onSubmit}>
<div className="gui-grid">
<div className="gui-grid__cell">
<GuiCheckbox
label="I accept the terms of service"
name="terms"
required
/>
</div>
<div className="gui-grid__cell">
<GuiCheckbox label="Send me product news" name="news" />
</div>
<div className="gui-grid__cell">
<GuiButton type="submit" label="Create account" />
</div>
</div>
<p id="signup-result" role="status">
{result}
</p>
</form>
);
}

How the elements submit, validate and reset is in Native forms.

<gui-checkbox> renders into the light DOM, so you can style every part with plain CSS. The label wraps the checkbox and its text, and the hint and the errors follow it:

gui-checkbox
<gui-checkbox class="gui-field">
<label class="gui-label" for="terms" id="terms_label">
<div class="gui-widget gui-widget--horizontal">
<input
type="checkbox"
id="terms"
aria-describedby="terms_hint"
aria-invalid="true"
aria-errormessage="terms_errors"
aria-required="true"
/>
</div>
<span class="gui-label__container">
<span class="gui-label__text">
I accept the terms<span aria-hidden="true"> *</span>
</span>
</span>
</label>
<div class="gui-widget-hint">
<span id="terms_hint">You can read them first.</span>
<div class="gui-validator" id="terms_errors" role="alert">
<div class="gui-validator__error">Accept the terms to continue.</div>
</div>
</div>
</gui-checkbox>
ClassPart
gui-fieldThe element itself. Lines its parts up with the fields next to it in a gui-grid row.
gui-checkbox--rightOn the element with checkbox-position="right".
gui-labelThe label, with the checkbox and the text.
gui-widgetThe box around the checkbox.
gui-widget--horizontalOn the box: lays it out in a row.
gui-label__containerThe wrapper of the label text.
gui-label__textThe label text and the required marker.
gui-widget-hintThe hint, and the errors after it. It is always there; the hint text has the hint’s id.
gui-validatorThe errors container. It is always there, so the alert role announces new errors.
gui-validator__errorOne error message.

The ids derive from uid, or from a generated id such as gui-checkbox-3 when you don’t set one. Select by class or by tag, not by id.

The checkbox reads these design tokens. Set them on :root to change every checkbox, or on any element to change the checkboxes inside it:

TokenWhat it styles
--gui-bg-surfaceThe box’s background.
--gui-border-defaultThe box’s border.
--gui-radius-smThe box’s corner radius.
--gui-intent-primaryThe tick.
--gui-text-defaultThe label text.
--gui-font-familyThe font.
--gui-font-smThe text size of the label.
--gui-font-xsThe text size of the hint and the errors.
--gui-text-secondaryThe hint.
--gui-border-focusThe box’s border while focused.
--gui-shadow-focusThe focus ring.
--gui-intent-errorThe box’s border and the messages when there are errors.
--gui-shadow-focus-errorThe focus ring when there are errors.
--gui-space-1The space above the errors.
styles.css
/* A green tick and rounder boxes. */
:root {
--gui-intent-primary: #2f7d4f;
--gui-radius-sm: 4px;
}

To restyle beyond the tokens, see Overriding styles; for dark mode and the Clay theme, see Themes and dark mode.

  • Name. The label names the checkbox. The native <label> wraps it, so a click on the text checks it too. Without a label the checkbox has no accessible name.
  • Description. The hint is the checkbox’s description, through aria-describedby.
  • Errors. While errors show, the checkbox has aria-invalid="true" and points at them with aria-errormessage, and screen readers announce new errors as they appear.
  • Required. required sets aria-required; the visual marker is hidden from screen readers.
  • Read-only. readonly sets aria-readonly. The checkbox stays in the tab order.
KeyAction
TabMoves focus to the checkbox, and away from it.
SpaceChecks or unchecks it, and fires gui-change.

What every element shares, such as translating the browser messages, is in Accessibility.