Skip to content

HyToolbar ​

Usage examples on this page are written for Lit / plain HTML (<hy-toolbar>). The same component ships as HyToolbar in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A row (or column) of controls that is one tab stop: Tab enters the toolbar, the arrow keys move between its controls, Tab leaves — the WAI-ARIA APG toolbar pattern. It paints nothing but a gap; the controls keep their own size and look.

Items ​

  • Direct children that are hy-button, hy-icon-button, hy-toggle, hy-menu-button, hy-copy-button, hy-switch, a native button or an a[href].
  • The slot="trigger" control of a direct-child hy-tooltip or hy-popover — the way a hover hint is written.
  • The toggles of a direct-child hy-toggle-group: they join the toolbar's arrow order; the group keeps its selection, value and events.
  • Both segments of a direct-child hy-split-button, the same way.
  • hy-divider is laid out (at the opposite orientation, with room on each side: --hy-toolbar-divider-gap-layout-xs), never an item. Anything else — a text field, a select, a readout — is laid out and keeps its own tab stop, so its caret keys stay its own.
  • Disabled items are skipped.

Keyboard ​

  • Left / Right (Up / Down when vertical) move between items, swapped right to left; Home / End go to the ends; loop wraps at the ends.
  • The last focused item keeps the tab stop.
  • A menu button in a vertical toolbar opens on Enter / Space; Down moves on.

When to use

  • The controls that act on one area, in one row: an editor's formatting, a table's actions, a canvas's tools.

Do

  • Group related controls with a divider between groups.

When not to use

  • A row with a title, stats, badges or a close button: a bar such as hy-topbar, not a toolbar.
  • The actions of a dialog or a form, such as Cancel and Save: a plain row of hy-buttons.
  • One or two actions: plain buttons, each its own tab stop.
  • A row that is mostly fields: lay it out yourself. Fields keep their own tab stops.

Accessibility: your part ​

  • Give every control a name. A hover hint is an hy-tooltip wrapped around the button.
  • Put a search field or select at the start or the end of the row, never between the tools.

Examples ​

Text formatting ​

html
<hy-toolbar label="Text formatting">
  <hy-icon-button name="bold" label="Bold" pressed="false"></hy-icon-button>
  <hy-icon-button name="italic" label="Italic" pressed="false"></hy-icon-button>
  <hy-divider></hy-divider>
  <hy-toggle-group label="Alignment" value="left">
    <hy-toggle value="left">Left</hy-toggle>
    <hy-toggle value="center">Center</hy-toggle>
  </hy-toggle-group>
  <hy-divider></hy-divider>
  <hy-menu-button label="Insert">
    <hy-menu-item label="Image" value="image"></hy-menu-item>
  </hy-menu-button>
</hy-toolbar>

API ​

Properties ​

PropertyAttributeTypeDefaultDescription
labellabelstring''Accessible name of the toolbar ("Text formatting"). Required unless aria-labelledby names it.
orientationorientation'horizontal' | 'vertical''horizontal'Layout and arrow axis: Left / Right when horizontal, Up / Down when vertical.
looploopbooleantrueWrap at the ends.
wrapwrapbooleanfalseLet the items wrap onto more lines when the toolbar is narrower than they are (a horizontal toolbar in a resizable region). Off by default. The arrow order stays the DOM order.

Slots ​

SlotDescription
defaultThe controls, dividers and any other content of the toolbar

CSS Parts ​

PartDescription
baseThe layout wrapper around the items (the host carries role="toolbar")

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.

PropertyDefaultDescription
--hy-toolbar-gap-form-smvar(--hy-gap-form-sm)Gap between the toolbar's items
--hy-toolbar-divider-gap-layout-xsvar(--hy-gap-layout-xs)Room a divider adds on each side, on top of the gap

Methods ​

focus() ​

Focuses the item that holds the tab stop.

Built with Lit. Documented with VitePress.