HyToggle
Usage examples on this page are written for Lit / plain HTML (
<hy-toggle>). The same component ships asHyTogglein@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
A toggle button — an option of an hy-toggle-group, or a standalone pressable button. Represents a single option that can be pressed (selected) or unpressed.
Glyph-only toggles
A toggle with a glyph (the prefix or suffix slot) and nothing in its default slot is glyph-only: the empty label makes no box and the button is square — width equals height at every size and density. It has no text to be named by, so it takes its name from aria-label / aria-labelledby on the host (any toggle may; the name goes on its button), and a glyph-only toggle without one warns in development.
Who owns pressed
- Inside an
hy-toggle-groupthe group owns the state: a click selects through the group (which fires its ownchange), and the toggle neither flips itself nor firespress-change. - Standalone the toggle flips itself on click (uncontrolled) and fires
press-changewith the new state — the same contract as ReactHyToggle(defaultPressed/onPressChange; React also takes a controlledpressed). Setpressedto change it from code; that fires no event.
Key Features
- Pressed/unpressed visual state
- Prefix and suffix slots for icons
- Size and variant inherited from parent group
- Full keyboard and accessibility support
Accessibility: built in
- Role switches between
radio(single mode) andbutton(multiple mode) aria-checkedoraria-pressedbased on selection mode- Focus delegation via
delegatesFocus— parent group manages host tabindex - High contrast mode support
- Reduced motion support
Accessibility: your part
- On a glyph-only toggle, set
aria-labeland add anhy-tooltipwith the same words.
When to use
- One option of a toggle group: a view, a filter or a format among a few.
- A single tool in a toolbar that stays on until it is turned off: bold, a grid overlay.
Do
- Label each option with the value it sets.
- Keep the options of a group parallel: all words or all icons, the same kind of thing.
When not to use
- One on / off setting that applies at once:
hy-switch. One collected for a form:hy-checkbox. - A control that runs an action and holds no state:
hy-button.
Examples
Basic usage within a toggle group
<hy-toggle-group value="center">
<hy-toggle value="left">Left</hy-toggle>
<hy-toggle value="center">Center</hy-toggle>
<hy-toggle value="right">Right</hy-toggle>
</hy-toggle-group>With icon
<hy-toggle value="bold">
<hy-icon slot="prefix" name="bold"></hy-icon>
Bold
</hy-toggle>A glyph-only toggle — square, named on the host
<hy-toggle-group aria-label="Text style">
<hy-toggle value="bold" aria-label="Bold"
><hy-icon slot="prefix" name="bold"></hy-icon
></hy-toggle>
<hy-toggle value="italic" aria-label="Italic"
><hy-icon slot="prefix" name="italic"></hy-icon
></hy-toggle>
</hy-toggle-group>API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
value | value | string | '' | Unique value for this toggle item. Used by the parent group to track selection. |
pressed | pressed | boolean | false | Whether this toggle is currently pressed/selected. Managed by the parent group inside an hy-toggle-group; a standalone toggle flips it on click (and fires press-change). |
disabled | disabled | boolean | false | Whether this toggle is disabled. |
size | size | 'small' | 'medium' | 'large' | 'medium' | Size of the toggle button. Typically inherited from the parent group. |
variant | variant | 'neutral' | 'brand' | 'neutral' | Visual variant (role). Typically inherited from the parent group. |
emphasis | emphasis | 'soft' | 'outlined' | 'soft' | Visual chrome weight on top of the role. Typically inherited from the parent toggle group. |
selectionMode | selection-mode | 'single' | 'multiple' | 'single' | Selection mode. Inherited from the parent toggle group. |
autofocus | autofocus | boolean | false | Marks this toggle as the auto-focus target. Read by hy-dialog (and other overlay containers) on show to choose initial focus. Also focuses on first connect when used outside an overlay, mirroring native HTML autofocus but routed through JS so SSR'd HTML doesn't pull focus during hydration. |
Events
| Event | Detail | Description |
|---|---|---|
press-change | — | A standalone toggle was clicked and flipped. Detail: { pressed: boolean } (the new state). Not fired inside an hy-toggle-group (the group fires change) or when pressed is set from code. |
Slots
| Slot | Description |
|---|---|
default | Button content (text, icons, or both) |
prefix | Content before the default slot (e.g. icon) |
suffix | Content after the default slot |
CSS Parts
| Part | Description |
|---|---|
base | The button element |
prefix | Prefix slot wrapper |
suffix | Suffix slot wrapper |
CSS Custom Properties
The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.
| Property | Default | Description |
|---|---|---|
--hy-toggle-background-brand-soft-rest | var(--hy-background-brand-soft-rest) | One of the generated color hooks (paint/toggle.mjs): --hy-toggle[-<part>]-<family>-<variant>-<emphasis-or-on>-<state> (family: background, foreground or border), one per cell and state, each falling back to the job token of the same name (the default cell is neutral soft). Components ▸ Add an override lists them all. |
--hy-toggle-radius-action-md-top-start | var(--hy-radius-action-md-top-start) | Top-start corner radius override; set per first/last-child by hy-toggle-group to compose connected button-group corners. |
--hy-toggle-radius-action-md-top-end | var(--hy-radius-action-md-top-end) | Top-end corner radius override. See top-start. |
--hy-toggle-radius-action-md-bottom-start | var(--hy-radius-action-md-bottom-start) | Bottom-start corner radius override. See top-start. |
--hy-toggle-radius-action-md-bottom-end | var(--hy-radius-action-md-bottom-end) | Bottom-end corner radius override. See top-start. |
--hy-toggle-text-transform | none | Text transform for toggle label |
--hy-toggle-control-label-md-font-family | var(--hy-control-label-md-font-family) | Font family override for toggle label |
--hy-toggle-control-label-sm-font-family | var(--hy-control-label-sm-font-family) | Font family override for toggle label |
--hy-toggle-control-label-lg-font-family | var(--hy-control-label-lg-font-family) | Font family override for toggle label |
--hy-toggle-control-height-sm | var(--hy-control-height-sm) | Outer height for small size variant. Per-component override in the form-control height contract. |
--hy-toggle-control-height-md | var(--hy-control-height-md) | Outer height for medium size variant. |
--hy-toggle-control-height-lg | var(--hy-control-height-lg) | Outer height for large size variant. |
--hy-toggle-motion-transition-hover-duration | var(--hy-motion-transition-hover-duration) | Transition duration for hover and focus state feedback |
--hy-toggle-motion-transition-hover-easing | var(--hy-motion-transition-hover-easing) | Transition easing for hover and focus state feedback |
--hy-toggle-justify | center | justify-content of the label and its prefix / suffix inside the toggle (center unless set) |
--hy-toggle-focus-ring-offset | var(--hy-focus-ring-offset) | Focus ring offset. A connected hy-toggle-group sets it negative so the ring is drawn inside the segment |
Methods
focus()
Sets focus on the underlying button element.
blur()
Removes focus from the underlying button element.