Toggle
<gui-toggle> is an on and off switch, for a setting that takes effect at once. It renders a
native checkbox with the switch role, styled as a track and a knob.
import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function ToggleBasic() { return <GuiToggle label="Dark mode" />;}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/toggle';
@Component({ selector: 'app-toggle-basic', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: `<gui-toggle label="Dark mode"></gui-toggle>`,})export class ToggleBasicComponent {}<script setup lang="ts">import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';</script>
<template> <gui-toggle label="Dark mode"></gui-toggle></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('toggle-basic')export class ToggleBasic extends LitElement { protected override createRenderRoot() { return this; }
override render() { return html` <gui-toggle label="Dark mode"></gui-toggle> `; }}<gui-toggle label="Dark mode"></gui-toggle>The element’s entry point is @golemui/gui-components/toggle, which registers <gui-toggle>
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.
import { useState } from 'react';import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function DarkModeField() { const [darkMode, setDarkMode] = useState(false);
return ( <GuiToggle label="Dark mode" name="darkMode" value={darkMode} onGuiChange={(event) => setDarkMode(event.detail.value ?? false)} /> );}Add CUSTOM_ELEMENTS_SCHEMA to the component that uses the tags, and the stylesheet to styles in angular.json.
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import type { GuiEventMap, GuiToggleEvents } from '@golemui/gui-components';import '@golemui/gui-components/toggle';
type ChangeEvent = GuiEventMap<typeof GuiToggleEvents>['gui-change'];
@Component({ selector: 'app-dark-mode-field', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-toggle label="Dark mode" name="darkMode" [value]="darkMode" (gui-change)="onChange($event)" ></gui-toggle> `,})export class DarkModeFieldComponent { darkMode = false;
onChange(event: Event) { this.darkMode = (event as ChangeEvent).detail.value ?? false; }}"styles": ["node_modules/@golemui/gui-components/lib/styles/index.css"]Tell Vue's compiler that gui-* tags are custom elements, and add the typings once for typed props and @gui-* handlers.
<script setup lang="ts">import { ref } from 'vue';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
const darkMode = ref(false);</script>
<template> <gui-toggle label="Dark mode" name="darkMode" :value="darkMode" @gui-change="darkMode = $event.detail.value ?? false" /></template>vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('gui-') } },});import type {} from '@golemui/gui-components/vue';The page's stylesheet styles the gui-* elements, so it only reaches them outside a shadow root. Render the host component into the light DOM too, as below, or load the stylesheet into its shadow root.
import { LitElement, html } from 'lit';import { customElement, state } from 'lit/decorators.js';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('dark-mode-field')export class DarkModeField extends LitElement { @state() private darkMode = false;
protected override createRenderRoot() { return this; }
override render() { return html` <gui-toggle label="Dark mode" name="darkMode" .value=${this.darkMode} @gui-change=${(event: CustomEvent) => (this.darkMode = event.detail.value)} ></gui-toggle> `; }}With any bundler, such as Vite. Import the element once, anywhere, and use the tag in your markup.
<gui-toggle label="Dark mode" name="darkMode"></gui-toggle>
<script type="module" src="./main.js"></script>import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
const element = document.querySelector('gui-toggle');
element.addEventListener('gui-change', (event) => { console.log(event.detail.value);});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 on. As an attribute, value turns it on and value="false" does not. |
togglePosition
attribute toggle-position | 'left' | 'right' | 'left' | Side of the label the switch 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. |
CSS custom properties
| Property | Default | Description |
|---|---|---|
--gui-toggle-width | – | Width of the switch. |
--gui-toggle-height | – | Height of the switch. |
--gui-toggle-slider-width | – | Width of the knob. |
--gui-toggle-slider-height | – | Height of the knob. |
--gui-toggle-slider-transform | – | Distance the knob moves when on. |
Examples
Section titled “Examples”The value is true or false. As an attribute, value turns the switch on and value="false"
leaves it off. From JavaScript, set the value property to true or false.
import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function ToggleOn() { return <GuiToggle label="Automatic updates" value />;}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/toggle';
@Component({ selector: 'app-toggle-on', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: `<gui-toggle label="Automatic updates" value></gui-toggle>`,})export class ToggleOnComponent {}<script setup lang="ts">import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';</script>
<template> <gui-toggle label="Automatic updates" :value="true"></gui-toggle></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('toggle-on')export class ToggleOn extends LitElement { protected override createRenderRoot() { return this; }
override render() { return html` <gui-toggle label="Automatic updates" value></gui-toggle> `; }}<gui-toggle label="Automatic updates" value></gui-toggle>hint shows under the label. Screen readers read it as the switch’s description.
import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function ToggleHint() { return ( <GuiToggle label="Vacation reply" hint="Replies to every email with your away message." /> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/toggle';
@Component({ selector: 'app-toggle-hint', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-toggle label="Vacation reply" hint="Replies to every email with your away message." ></gui-toggle> `,})export class ToggleHintComponent {}<script setup lang="ts">import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';</script>
<template> <gui-toggle label="Vacation reply" hint="Replies to every email with your away message." ></gui-toggle></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('toggle-hint')export class ToggleHint extends LitElement { protected override createRenderRoot() { return this; }
override render() { return html` <gui-toggle label="Vacation reply" hint="Replies to every email with your away message." ></gui-toggle> `; }}<gui-toggle label="Vacation reply" hint="Replies to every email with your away message."></gui-toggle>Toggle position
Section titled “Toggle position”The switch sits before the label. toggle-position="right" puts it after the label.
import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function TogglePosition() { return ( <GuiToggle label="Show weekends in the calendar" togglePosition="right" /> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/toggle';
@Component({ selector: 'app-toggle-position', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-toggle label="Show weekends in the calendar" toggle-position="right" ></gui-toggle> `,})export class TogglePositionComponent {}<script setup lang="ts">import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';</script>
<template> <gui-toggle label="Show weekends in the calendar" toggle-position="right" ></gui-toggle></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('toggle-position')export class TogglePosition extends LitElement { protected override createRenderRoot() { return this; }
override render() { return html` <gui-toggle label="Show weekends in the calendar" toggle-position="right" ></gui-toggle> `; }}<gui-toggle label="Show weekends in the calendar" toggle-position="right"></gui-toggle>Disabled and read-only
Section titled “Disabled and read-only”A disabled switch can’t be focused or changed, and a form doesn’t submit it. A readonly
switch can be focused but clicks and Space don’t change it, and a form submits its
value.
import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function ToggleDisabledReadonly() { return ( <div className="gui-grid gui-grid--row"> <div className="gui-grid__cell"> <GuiToggle label="Backups" value disabled /> </div> <div className="gui-grid__cell"> <GuiToggle label="Single sign-on" value readOnly /> </div> </div> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/toggle';
@Component({ selector: 'app-toggle-disabled-readonly', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <div class="gui-grid gui-grid--row"> <div class="gui-grid__cell"> <gui-toggle label="Backups" value disabled></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Single sign-on" value readonly></gui-toggle> </div> </div> `,})export class ToggleDisabledReadonlyComponent {}<script setup lang="ts">import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';</script>
<template> <div class="gui-grid gui-grid--row"> <div class="gui-grid__cell"> <gui-toggle label="Backups" :value="true" :disabled="true"></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Single sign-on" :value="true" :readOnly="true" ></gui-toggle> </div> </div></template>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('toggle-disabled-readonly')export class ToggleDisabledReadonly extends LitElement { protected override createRenderRoot() { return this; }
override render() { return html` <div class="gui-grid gui-grid--row"> <div class="gui-grid__cell"> <gui-toggle label="Backups" value disabled></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Single sign-on" value readonly></gui-toggle> </div> </div> `; }}<div class="gui-grid gui-grid--row"> <div class="gui-grid__cell"> <gui-toggle label="Backups" value disabled></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Single sign-on" value readonly></gui-toggle> </div></div>Reacting to changes
Section titled “Reacting to changes”A switch usually applies its setting right away. Listen to gui-change: event.detail.value is
the new state.
Notifications are off.
import { useState } from 'react';import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function ToggleEvents() { const [on, setOn] = useState(false);
return ( <> <GuiToggle id="alerts-toggle" label="Push notifications" onGuiChange={(event) => setOn(!!event.detail.value)} /> <p id="alerts-status" role="status"> Notifications are {on ? 'on' : 'off'}. </p> </> );}import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';import type { GuiEventMap, GuiToggleEvents } from '@golemui/gui-components';import '@golemui/gui-components/toggle';
type ToggleEvent<K extends keyof typeof GuiToggleEvents> = GuiEventMap< typeof GuiToggleEvents>[K];
@Component({ selector: 'app-toggle-events', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-toggle id="alerts-toggle" label="Push notifications" (gui-change)="onChange($event)" ></gui-toggle> <p id="alerts-status" role="status"> Notifications are {{ on() ? 'on' : 'off' }}. </p> `,})export class ToggleEventsComponent { on = signal(false);
onChange(event: Event) { this.on.set(!!(event as ToggleEvent<'gui-change'>).detail.value); }}<script setup lang="ts">import { ref } from 'vue';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
const on = ref(false);</script>
<template> <gui-toggle id="alerts-toggle" label="Push notifications" @gui-change="on = !!$event.detail.value" ></gui-toggle> <p id="alerts-status" role="status"> Notifications are {{ on ? 'on' : 'off' }}. </p></template>import { LitElement, html } from 'lit';import { customElement, state } from 'lit/decorators.js';import type { GuiEventMap, GuiToggleEvents } from '@golemui/gui-components';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
type ToggleEvent<K extends keyof typeof GuiToggleEvents> = GuiEventMap< typeof GuiToggleEvents>[K];
@customElement('toggle-events')export class ToggleEvents extends LitElement { @state() private on = false;
protected override createRenderRoot() { return this; }
private onChange(event: ToggleEvent<'gui-change'>) { this.on = !!event.detail.value; }
override render() { return html` <gui-toggle id="alerts-toggle" label="Push notifications" @gui-change=${this.onChange} ></gui-toggle> <p id="alerts-status" role="status"> Notifications are ${this.on ? 'on' : 'off'}. </p> `; }}<gui-toggle id="alerts-toggle" label="Push notifications"></gui-toggle><p id="alerts-status" role="status">Notifications are off.</p>
<script type="module"> const alerts = document.querySelector('#alerts-toggle');
alerts.addEventListener('gui-change', (event) => { const state = event.detail.value ? 'on' : 'off'; document.querySelector('#alerts-status').textContent = `Notifications are ${state}.`; });</script>Five tokens size the switch: the track’s width and height, the knob’s width and height, and how far the knob travels when the switch turns on. Set them together on the switch, or on any element around it.
import { GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
const sizeStyles = ` .large-toggle { --gui-toggle-width: 52px; --gui-toggle-height: 28px; --gui-toggle-slider-width: 24px; --gui-toggle-slider-height: 24px; --gui-toggle-slider-transform: 24px; }`;
export function ToggleSize() { return ( <> <GuiToggle className="large-toggle" label="Focus mode" value /> <style>{sizeStyles}</style> </> );}import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import '@golemui/gui-components/toggle';
@Component({ selector: 'app-toggle-size', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <gui-toggle class="large-toggle" label="Focus mode" value></gui-toggle> `, styles: ` .large-toggle { --gui-toggle-width: 52px; --gui-toggle-height: 28px; --gui-toggle-slider-width: 24px; --gui-toggle-slider-height: 24px; --gui-toggle-slider-transform: 24px; } `,})export class ToggleSizeComponent {}<script setup lang="ts">import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';</script>
<template> <gui-toggle class="large-toggle" label="Focus mode" :value="true" ></gui-toggle></template>
<style>.large-toggle { --gui-toggle-width: 52px; --gui-toggle-height: 28px; --gui-toggle-slider-width: 24px; --gui-toggle-slider-height: 24px; --gui-toggle-slider-transform: 24px;}</style>import { LitElement, html } from 'lit';import { customElement } from 'lit/decorators.js';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('toggle-size')export class ToggleSize extends LitElement { protected override createRenderRoot() { return this; }
override render() { return html` <gui-toggle class="large-toggle" label="Focus mode" value></gui-toggle>
<style> .large-toggle { --gui-toggle-width: 52px; --gui-toggle-height: 28px; --gui-toggle-slider-width: 24px; --gui-toggle-slider-height: 24px; --gui-toggle-slider-transform: 24px; } </style> `; }}<gui-toggle class="large-toggle" label="Focus mode" value></gui-toggle>
<style> .large-toggle { --gui-toggle-width: 52px; --gui-toggle-height: 28px; --gui-toggle-slider-width: 24px; --gui-toggle-slider-height: 24px; --gui-toggle-slider-transform: 24px; }</style>In a form
Section titled “In a form”With a name, a <gui-toggle> that is on submits on under that name, like a native checkbox,
and one that is off submits nothing. required blocks the submit while the switch is off. Submit
the form below, then change the switches and submit again.
import { useState, type SubmitEvent } from 'react';import { GuiButton, GuiToggle } from '@golemui/gui-components/react';import '@golemui/gui-components/index.css';
export function ToggleNativeForm() { const [publicProfile, setPublicProfile] = useState<boolean | undefined>(true); 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="privacy" onSubmit={onSubmit}> <div className="gui-grid"> <div className="gui-grid__cell"> <GuiToggle label="Public profile" name="publicProfile" value={publicProfile} onGuiChange={(event) => setPublicProfile(event.detail.value)} /> </div> <div className="gui-grid__cell"> <GuiToggle label="Show my email" name="showEmail" /> </div> <div className="gui-grid__cell"> <GuiButton type="submit" label="Save settings" /> </div> </div> <p id="privacy-result" role="status"> {result} </p> </form> );}import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';import '@golemui/gui-components/button';import '@golemui/gui-components/toggle';
@Component({ selector: 'app-toggle-native-form', schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <form id="privacy" #form (submit)="onSubmit($event, form)"> <div class="gui-grid"> <div class="gui-grid__cell"> <gui-toggle label="Public profile" name="publicProfile" value ></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Show my email" name="showEmail"></gui-toggle> </div> <div class="gui-grid__cell"> <gui-button type="submit" label="Save settings"></gui-button> </div> </div> <p id="privacy-result" role="status">{{ result() }}</p> </form> `,})export class ToggleNativeFormComponent { result = signal('');
onSubmit(event: SubmitEvent, form: HTMLFormElement) { event.preventDefault(); const data = Object.fromEntries(new FormData(form)); this.result.set(`Submitted ${JSON.stringify(data)}`); }}<script setup lang="ts">import { ref } from 'vue';import '@golemui/gui-components/button';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
const result = ref('');
function onSubmit(event: SubmitEvent) { if (!(event.currentTarget instanceof HTMLFormElement)) return; const data = Object.fromEntries(new FormData(event.currentTarget)); result.value = `Submitted ${JSON.stringify(data)}`;}</script>
<template> <form id="privacy" @submit.prevent="onSubmit"> <div class="gui-grid"> <div class="gui-grid__cell"> <gui-toggle label="Public profile" name="publicProfile" :value="true" ></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Show my email" name="showEmail"></gui-toggle> </div> <div class="gui-grid__cell"> <gui-button type="submit" label="Save settings"></gui-button> </div> </div> <p id="privacy-result" role="status">{{ result }}</p> </form></template>import { LitElement, html } from 'lit';import { customElement, query, state } from 'lit/decorators.js';import '@golemui/gui-components/button';import '@golemui/gui-components/toggle';import '@golemui/gui-components/index.css';
@customElement('toggle-native-form')export class ToggleNativeForm extends LitElement { @query('#privacy') private form!: HTMLFormElement; @state() private result = '';
protected override createRenderRoot() { return this; }
private onSubmit(event: SubmitEvent) { event.preventDefault(); const data = Object.fromEntries(new FormData(this.form)); this.result = `Submitted ${JSON.stringify(data)}`; }
override render() { return html` <form id="privacy" @submit=${this.onSubmit}> <div class="gui-grid"> <div class="gui-grid__cell"> <gui-toggle label="Public profile" name="publicProfile" value ></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Show my email" name="showEmail"></gui-toggle> </div> <div class="gui-grid__cell"> <gui-button type="submit" label="Save settings"></gui-button> </div> </div> <p id="privacy-result" role="status">${this.result}</p> </form> `; }}<form id="privacy"> <div class="gui-grid"> <div class="gui-grid__cell"> <gui-toggle label="Public profile" name="publicProfile" value></gui-toggle> </div> <div class="gui-grid__cell"> <gui-toggle label="Show my email" name="showEmail"></gui-toggle> </div> <div class="gui-grid__cell"> <gui-button type="submit" label="Save settings"></gui-button> </div> </div> <p id="privacy-result" role="status"></p></form>
<script type="module"> const form = document.querySelector('#privacy');
form.addEventListener('submit', (event) => { event.preventDefault(); const data = Object.fromEntries(new FormData(form)); document.querySelector('#privacy-result').textContent = `Submitted ${JSON.stringify(data)}`; });</script>How the elements submit, validate and reset is in Native forms.
Styling
Section titled “Styling”Anatomy
Section titled “Anatomy”<gui-toggle> renders into the light DOM, so you can style every part with plain CSS. The label
wraps the switch and its text, and the hint and the errors follow it:
<gui-toggle class="gui-field"> <label class="gui-label" for="vacation" id="vacation_label"> <div class="gui-widget gui-widget--horizontal gui-toggle--switch"> <input type="checkbox" role="switch" id="vacation" aria-describedby="vacation_hint" aria-invalid="true" aria-errormessage="vacation_errors" aria-required="true" /> <span class="gui-toggle--slider" role="presentation"></span> </div> <span class="gui-label__container"> <span class="gui-label__text"> Vacation reply<span aria-hidden="true"> *</span> </span> </span> </label> <div class="gui-widget-hint"> <span id="vacation_hint">Replies with your away message.</span> <div class="gui-validator" id="vacation_errors" role="alert"> <div class="gui-validator__error">Set an away message first.</div> </div> </div></gui-toggle>| Class | Part |
|---|---|
gui-field | The element itself. Lines its parts up with the fields next to it in a gui-grid row. |
gui-toggle--right | On the element with toggle-position="right". |
gui-label | The label, with the switch and the text. |
gui-widget | The box around the switch. |
gui-widget--horizontal | On the box: lays it out in a row. |
gui-toggle--switch | On the box: the switch, sized by the toggle tokens. The checkbox in it is transparent. |
gui-toggle--slider | The track, with the knob drawn as its ::before. |
gui-label__container | The wrapper of the label text. |
gui-label__text | The label text and the required marker. |
gui-widget-hint | The hint, and the errors after it. It is always there; the hint text has the hint’s id. |
gui-validator | The errors container. It is always there, so the alert role announces new errors. |
gui-validator__error | One error message. |
The ids derive from uid, or from a generated id such as gui-toggle-3 when you don’t set one.
Select by class or by tag, not by id.
Tokens
Section titled “Tokens”The switch reads these design tokens. Set them on :root to change every switch, or on any
element to change the switches inside it:
| Token | What it styles |
|---|---|
--gui-toggle-width | The track’s width. |
--gui-toggle-height | The track’s height. |
--gui-toggle-slider-width | The knob’s width. |
--gui-toggle-slider-height | The knob’s height. |
--gui-toggle-slider-transform | How far the knob moves when the switch turns on. |
--gui-bg-default | The track while off, and the knob while on. |
--gui-border-default | The track’s border, and the knob while off. |
--gui-intent-primary | The track and its border while on. |
--gui-bg-disabled | The track when disabled. |
--gui-text-default | The label text. |
--gui-font-family | The font. |
--gui-font-sm | The text size of the label. |
--gui-font-xs | The text size of the hint and the errors. |
--gui-text-secondary | The hint. |
--gui-border-focus | The track’s border while focused. |
--gui-shadow-focus | The focus ring. |
--gui-intent-error | The track’s border and the messages when there are errors. |
--gui-shadow-focus-error | The focus ring when there are errors. |
--gui-space-1 | The space above the errors. |
/* A brand color for every switch that is on. */:root { --gui-intent-primary: #2f7d4f;}--gui-intent-primary also colors buttons, ticks and selections. To recolor only the switches,
override the rule instead:
gui-toggle input:checked + .gui-toggle--slider { background-color: #2f7d4f; border-color: #2f7d4f;}To restyle beyond the tokens, see Overriding styles; for dark mode and the Clay theme, see Themes and dark mode.
Accessibility
Section titled “Accessibility”- Role. The switch is a native checkbox with
role="switch", so screen readers announce it as a switch that is on or off. - Name. The
labelnames the switch. The native<label>wraps it, so a click on the text flips it too. Without a label the switch has no accessible name. - Description. The
hintis the switch’s description, througharia-describedby. - Errors. While errors show, the switch has
aria-invalid="true"and points at them witharia-errormessage, and screen readers announce new errors as they appear. - Required and read-only.
requiredsetsaria-requiredandreadonlysetsaria-readonly. A read-only switch stays in the tab order.
| Key | Action |
|---|---|
| Tab | Moves focus to the switch, and away from it. |
| Space | Turns it on or off, and fires gui-change. |
What every element shares, such as translating the browser messages, is in Accessibility.