Skip to content
Home Theme Gallery

Toggle

The custom element is <hui-toggle>.

Overview

A pressed-state button. On its own it toggles a visual pressed state and carries no form value; given a name, it serialises its value while pressed, like a checkbox.

Example

Toggle
Source
<hui-toggle aria-label="Bold">Bold</hui-toggle>
<hui-toggle name="bold" value="1" pressed aria-label="Bold pressed">Bold</hui-toggle>

The Go template that renders it:

<hui-toggle name="bold" value="1" {{ if .Bold }}pressed{{ end }} aria-label="Bold">Bold</hui-toggle>

API

Attributes5
Attributes
NameTypeDefaultDescription
namestring''The form field name. Without a name the toggle never contributes a form value.
disabledbooleanfalseDisables the internal button and clears the form value.
pressedbooleanfalseThe pressed state. Reflected, so it can be styled and read from the attribute.
valuestring'on'The value submitted while pressed and named. Reflected.
variant"default" | "outline""default"The visual treatment. outline draws a hairline in --hui-border, nova’s bordered toggle; in a segmented hui-toggle-group the group’s own border stands in for it.
Properties5
Properties
NameTypeDefaultDescription
namestring''Reflects to the name attribute.
disabledbooleanfalseReflects to the disabled attribute.
pressedbooleanfalseReflects to the pressed attribute.
valuestring'on'Reflects to the value attribute.
variant"default" | "outline"'default'Reflects to the variant attribute.
Events3
Events
NameDescription
inputEmitted from the host when the toggle owns its own state and flips. Inside a hui-toggle-group the group owns the state and the item emits nothing. bubbles and composed; no detail.
changeEmitted from the host in the same turn as the standalone input. bubbles and composed; no detail.
clickThe native click bubbles and is composed, so a grouped item lets it reach hui-toggle-group, which owns the selection.
Slots1
Slots
NameDescription
(default)The visible label of the toggle.
CSS custom properties6
CSS custom properties
NameDefaultDescription
--hui-primaryoklch(0.496 0.265 301.924)Tint behind the pressed state.
--hui-backgroundoklch(1 0 0)Surface the pressed tint is mixed against.
--hui-primary-textoklch(0.496 0.265 301.924)Text colour while pressed.
--hui-mutedoklch(0.96 0.003 325.6)Hover fill when unpressed.
--hui-radius0.45remBase radius; the button uses --hui-radius-lg.
--hui-focus-ring-width3pxWidth of the keyboard focus ring.
::part() hooks1
::part() hooks
NameDescription
controlThe internal native <button> that carries aria-pressed.

States

Pressed with a value

A pressed toggle with the value it submits under its name. pressed is aria-pressed: a toggle is a button that stays down, not a checkbox.

Pressed with a value
Source
<hui-toggle name="bold" value="1" pressed aria-label="Bold pressed">Bold</hui-toggle>

Outline

The outline variant, up and down, for a toolbar that wants a visible edge around each control.

Outline
Source
<hui-toggle variant="outline" aria-label="Bold">Bold</hui-toggle>
<hui-toggle variant="outline" pressed aria-label="Italic">Italic</hui-toggle>

Disabled

Disabled: it keeps its pressed state and its name, and cannot be operated.

Disabled
Source
<hui-toggle disabled aria-label="Disabled toggle">Bold</hui-toggle>

Server-side mechanics

The server owns name, value, pressed and disabled. Without a name the toggle is purely visual and submits nothing; with one it submits its value under name while pressed, like a checkbox. A swap must re-send pressed to restore the pressed state, and a swap mid-interaction drops the uncommitted toggle. Inside a hui-toggle-group the group, not the item, owns the state and the form value.

Accessibility

  • The internal button exposes aria-pressed of true or false.
  • Without a name the toggle is purely visual and submits nothing; a control that must submit needs one.
  • Inside a group the group marks the item with data-grouped so it drops its own radius and joins the shared outline.
  • The accessible name comes from the slotted label or an aria-label.

Keyboard

Keyboard
KeysAction
TabMoves focus to and from the toggle; it is one tab stop.
Space, EnterToggles the pressed state, supplied by the internal native button.
Arrow keysMove focus only when the toggle sits inside a hui-toggle-group, which owns the roving tabindex.

Gotchas

  • restoreState sets pressed = true for any state string, so browser form-state restoration cannot represent an unpressed toggle.
  • Unlike hui-checkbox and hui-switch, its click is not stopped, so a grouped toggle's click reaches hui-toggle-group, which owns the selection.