Skip to content
Home Theme Gallery

Switch

The custom element is <hui-switch>.

Overview

A binary switch sharing the checkbox wire format, so an off switch submits nothing and an on switch submits its value. It reports role="switch" so assistive technology announces it as a switch rather than a checkbox.

Example

Switch
Source
<hui-switch name="notify" value="on" aria-label="Email notifications"></hui-switch>

The Go template that renders it:

<hui-switch name="notify" value="on" {{ if .Notify }}checked{{ end }} aria-label="Email notifications"></hui-switch>

API

Attributes6
Attributes
NameTypeDefaultDescription
namestring''The form field name. With no name the control contributes no entry to FormData.
disabledbooleanfalseDisables the internal button and clears the form value.
checkedbooleanfalseThe on state. Reflected.
indeterminatebooleanfalseInherited but ignored: a switch is binary, so no mixed style or state is drawn.
valuestring'on'The value submitted while on. Reflected.
requiredbooleanfalseReflected; marks the switch required for constraint validation.
Properties6
Properties
NameTypeDefaultDescription
namestring''Reflects to the name attribute.
disabledbooleanfalseReflects to the disabled attribute.
checkedbooleanfalseReflects to the checked attribute.
indeterminatebooleanfalseReflects but is ignored by the switch rendering.
valuestring'on'Reflects to the value attribute.
requiredbooleanfalseReflects to the required attribute.
Events3
Events
NameDescription
inputEmitted from the host after the checked flag flips. bubbles and composed; no detail.
changeEmitted from the host in the same turn as input. bubbles and composed; no detail.
clickThe internal button click is consumed with stopPropagation(), so a native click does not cross the shadow boundary. Bind to change instead.
CSS custom properties5
CSS custom properties
NameDefaultDescription
--hui-primaryoklch(0.496 0.265 301.924)Track fill while on.
--hui-inputoklch(0.62 0.019 323.02)Track fill while off.
--hui-backgroundoklch(1 0 0)Thumb fill.
--hui-shadow-sm0 1px 2px oklch(0 0 0 / 0.05)Thumb shadow.
--hui-focus-ring-width3pxWidth of the keyboard focus ring.
::part() hooks2
::part() hooks
NameDescription
controlThe internal native <button> that carries role="switch".
thumbThe sliding knob inside the track.

States

On

A switch carries a name and a value and submits like a checkbox when it is on.

On
Source
<hui-switch name="dark" value="1" checked aria-label="Dark mode"></hui-switch>

Disabled

Disabled off and on: the thumb stays where its state puts it, at half opacity.

Disabled
Source
<hui-switch name="off" disabled aria-label="Disabled"></hui-switch>
<hui-switch name="on" checked disabled aria-label="On and disabled"></hui-switch>

Server-side mechanics

The server owns name, value, checked, required and disabled. An on switch submits its value under name and an off switch submits nothing, the same wire format as a checkbox. A swap has to re-send checked to restore the on state, and a swap mid-toggle loses the flip. Server-rendered validation uses required plus aria-invalid="true" or a hui-field invalid wrapper.

Accessibility

  • The internal button exposes role="switch" with aria-checked of true or false.
  • The accessible name comes from an aria-label; a neighbouring label element does not name the shadow button.
  • indeterminate is deliberately ignored, because a switch has only two states.
  • When disabled the internal button carries the native disabled attribute and leaves the tab order.

Keyboard

Keyboard
KeysAction
TabMoves focus to and from the switch; it is a single tab stop.
Space, EnterToggles the switch. The internal native button supplies both keys.

Gotchas

  • The internal click is stopped at the shadow boundary, so a native click listener on the host never fires; bind to input or change instead.
  • indeterminate is inherited from the shared checkable base but ignored: a switch is binary, so no mixed state is drawn.