Prototype Library

Button toggle

A segmented single-select — one-of-N choices rendered as a row of connected buttons. Form-associated, holds the selected value, and follows the WAI-ARIA radiogroup pattern with arrow-key navigation.

Inherited wc import '@esa/ecology/esa-button-toggle';

Preview

<esa-button-toggle label="View" id="bt-preview"></esa-button-toggle>

<script>
  el.options = [
    { value: 'list', label: 'List' },
    { value: 'grid', label: 'Grid' },
    { value: 'map', label: 'Map' },
  ];
  el.value = 'grid';
</script>

Sizes

Four sizes share the form scale. Default is md.

<esa-button-toggle size="xs"></esa-button-toggle>
<esa-button-toggle size="sm"></esa-button-toggle>
<esa-button-toggle size="md"></esa-button-toggle>
<esa-button-toggle size="lg"></esa-button-toggle>

States

<esa-button-toggle label="Default"></esa-button-toggle>
<esa-button-toggle label="With hint" hint="Pick a layout"></esa-button-toggle>
<esa-button-toggle label="Disabled" disabled></esa-button-toggle>

Form participation

The control submits its selected value under its name. Submitting logs the view entry.

<form>
  <esa-button-toggle name="view" label="View"></esa-button-toggle>
  <button type="submit">Submit</button>
</form>

API

PropTypeDefaultDescription
options { value: string, label: string }[] [] The segments. Set as a property (it is an array, not an attribute).
value string '' Selected option's value. Single-select; bound to the form value.
label string '' Optional visible label above the group; becomes the radiogroup name.
hint string '' Optional helper text below the group.
size 'xs' | 'sm' | 'md' | 'lg' 'md' Control size (shared form scale).
required boolean false Marks the field required (adds an asterisk and aria-required).
disabled boolean false Disables every segment.

Events

EventTypeDefaultDescription
change CustomEvent<{ value: string }> Fired when the selection changes. Composed and bubbling; detail.value is the newly selected value.

Accessibility

  • Renders role="radiogroup" wrapping role="radio" buttons with aria-checked reflecting selection.
  • Roving tabindex: only the selected (or first) segment is tab-reachable; Arrow keys move selection through the group, wrapping at the ends.
  • Home and End jump to the first and last segments; Enter and Space select the focused segment.
  • The label becomes the group's accessible name via aria-labelledby; hint is wired with aria-describedby.
  • Visible focus ring on the active segment via --focus-ring-* tokens; the focused segment is raised so its ring sits above neighbors.
  • Best for small fixed option sets — past about six options, prefer a select.

Tokens

Override the form and semantic token layers to re-skin without touching the component:

  • --color-primary · --color-text-inverse — selected segment fill and text
  • --form-{height,padding-x,font-size,radius}-{xs,sm,md,lg} — size scale
  • --form-bg · --form-border-color · --form-text-color — unselected segments
  • --color-surface-sunken — hover tint · --color-disabled-text — disabled state
  • --focus-ring-width / --focus-ring-color — focus ring
  • --form-label-color · --form-help-color — label and hint