abaabil

Toggle

10th lightest of the thirty-two, by js weight

A button that stays pressed, and a group of them. The group is radio and checkbox inputs, which is the decision that makes it small enough to render with no JavaScript at all.

Example (a11y tier)

Text alignment
Text style

Import

import { Toggle, ToggleGroup } from 'abaabil/toggle'         // structure only
import { Toggle, ToggleGroup } from 'abaabil/toggle/styled'  // + CSS
import { Toggle, ToggleGroup } from 'abaabil/toggle/a11y'    // + aria-pressed, legend

The group is radios, not buttons

A single-select group of buttons needs roving tabindex, arrow-key handling, wrapping at the ends and selection that follows focus, all in JavaScript. That is most of what a toggle group costs in other libraries.

A set of radios sharing a name has every one of those behaviours already, from the browser, in the right order, in every locale, and it submits with a form. So single-select uses radios and multi-select uses checkboxes, both clipped to nothing and drawn as buttons by the stylesheet. Try the arrow keys on the first group above.

Clipped, not display: none. A hidden input is not focusable, and every behaviour this component depends on exists only while the input is real.

The standalone toggle is controlled

A lone toggle has no group to belong to, so it is a real <button> with a pressed prop you own. An uncontrolled version would need state, and state would mean a hook, and a hook would take the whole component out of the server tree for the sake of a boolean the consumer nearly always has anyway.

The a11y tier adds aria-pressed, which is the one thing separating a toggle from a button. Without it a screen reader announces “Bold, button” whether bold is on or off: the control looks obviously different and sounds identical.

Pressed is not colour alone

A pressed member is filled and inset. Someone who cannot separate the fill from the surface still sees it sitting lower than its siblings, which is WCAG 1.4.1. A ten-percent tint next to an unpressed neighbour would not survive that test, or a greyscale screenshot.

Props

PropTypeDefaultTierDescription
pressedbooleanfalseallToggle. Controlled; applied as data-pressed.
items{ value, label, disabled? }[]allToggleGroup.
namestringallToggleGroup. Required: it is what makes the set one group.
multiplebooleanfalseallCheckboxes instead of radios.
defaultValuestring | string[]allInitially pressed.
labelstringa11yHidden name on Toggle; a <legend> on ToggleGroup.
classNamestringallMerged with the base class.