Skip to content

Toolbar

hc-toolbar is a layout primitive for grouping related controls horizontally. It does not own styling of the children — buttons and inputs inside a toolbar keep their normal appearance.

  • Children — usually buttons, but any focusable controls work.
  • Separator<hr role="separator" aria-orientation="vertical"> draws a 1px vertical divider. It is purely visual; toolbars do not require separators.
  • Spacer<span data-hc-spacer="true"></span> expands to push trailing children to the end (e.g. a save button at the right).

The roving-tabindex keyboard behavior needs installToolbar()without it the arrow keys do nothing and the toolbar falls back to the native Tab order. Install it once at startup:

import { installToolbar } from '@hypermedia-components/core';
installToolbar(); // idempotent; returns an uninstaller

The zero-config @hypermedia-components/core/behaviors entry installs it automatically.

installToolbar() upgrades every .hc-toolbar[role="toolbar"] into the WAI-ARIA APG Toolbar pattern: the whole toolbar is a single Tab stop, and the arrow keys move focus between its controls. The plain .hc-toolbar layout class (without role="toolbar") keeps the native focus order and is left untouched.

KeyAction
Tab / Shift+TabMove into / out of the toolbar as one stop. Focus returns to the control you last used.
/ Previous / next control (horizontal toolbar). Wraps at the ends; mirrored in RTL.
/ Previous / next control when aria-orientation="vertical".
Home / EndFirst / last control.

Disabled controls (disabled or aria-disabled="true") are skipped. Navigation only moves focus — buttons keep their native Space / Enter activation.

<!-- Vertical toolbar: arrows become ↑ / ↓ -->
<div class="hc-toolbar" role="toolbar" aria-orientation="vertical"
aria-label="Drawing tools">
<button class="hc-button" data-variant="ghost">Pen</button>
<button class="hc-button" data-variant="ghost">Brush</button>
<button class="hc-button" data-variant="ghost">Eraser</button>
</div>

A text field inside a toolbar keeps the on-axis arrow for its own caret; use Home / End to jump past it to the toolbar ends.

  • Apply role="toolbar" on the wrapper and always include an aria-label describing what the toolbar controls ("Editor toolbar", "Filter actions").
  • With the behavior installed, the toolbar follows the APG roving tabindex pattern above. Without JavaScript the controls stay in the native left-to-right (or top-to-bottom) focus order — every control is still reachable, just as separate Tab stops.
  • Buttons inside a toolbar are still standard buttons. Use clear labels (and aria-pressed="true" for toggle buttons).
Token pathPurpose
toolbar.gapGap between children.
toolbar.padding-x / -yInner padding.
toolbar.bg / -border / -radiusSurface styling.
toolbar.separatorSeparator color.
Show the generated CSS variables
--hc-toolbar-gap
--hc-toolbar-padding-x | -padding-y
--hc-toolbar-bg | -border | -radius
--hc-toolbar-separator
  • Button — the usual toolbar child.
  • Pagination — a more specific page-link grouping.