Morphos
Layout

Toolbar

A container for grouping action buttons with roving tabindex keyboard navigation.

Interactive example

Installation

npm install @morphos/layout
pnpm add @morphos/layout
yarn add @morphos/layout
bun add @morphos/layout

Import

import { Toolbar, ToolbarButton, ToolbarSeparator } from '@morphos/layout'

Usage

@Component()
class MyComponent extends StatefulComponent {
  @State() toolbar = new Toolbar({ orientation: 'horizontal', 'aria-label': 'Text formatting' })

  render() {
    return (
      <Toolbar toolbar={this.toolbar}>
        <ToolbarButton toolbar={this.toolbar} onClick={() => console.log('bold')}>
          Bold
        </ToolbarButton>
        <ToolbarButton toolbar={this.toolbar} onClick={() => console.log('italic')}>
          Italic
        </ToolbarButton>
        <ToolbarSeparator toolbar={this.toolbar} />
        <ToolbarButton toolbar={this.toolbar} onClick={() => console.log('link')}>
          Link
        </ToolbarButton>
        <ToolbarButton toolbar={this.toolbar} disabled>
          Comment
        </ToolbarButton>
      </Toolbar>
    )
  }
}

Compound components

ComponentDescription
ToolbarRoot container (role="toolbar") — manages roving tabindex state and arrow-key navigation
ToolbarButtonAn action button within the toolbar — registers itself with Toolbar on mount
ToolbarSeparatorA visual divider (role="separator") between button groups

Props — Toolbar

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Axis of the toolbar — determines which arrow keys move focus
aria-labelstringAccessible label for the toolbar
aria-labelledbystringID of element providing the label
classstringCSS class
idstringHTML id

Methods — Toolbar

MethodDescription
registerItem(el: HTMLElement)Internal — called by ToolbarButton on mount to join the roving-tabindex group
unregisterItem(el: HTMLElement)Internal — called by ToolbarButton on unmount
handleKeyDown(e: KeyboardEvent)Handles arrow-key navigation between registered buttons, wrapping at the ends

Props — ToolbarButton

PropTypeDefaultDescription
toolbarToolbarThe Toolbar state instance
disabledbooleanfalseDisables the button and excludes it from the roving-tabindex group
onClick() => voidClick handler
aria-labelstringAccessible label
childrenChildrenButton label
classstringCSS class
idstringHTML id

Props — ToolbarSeparator

PropTypeDefaultDescription
toolbarToolbarThe Toolbar state instance — used to compute the separator's perpendicular orientation
classstringCSS class
idstringHTML id

Keyboard navigation

KeyAction
ArrowRightMove focus to the next button (orientation="horizontal")
ArrowLeftMove focus to the previous button (orientation="horizontal")
ArrowDownMove focus to the next button (orientation="vertical")
ArrowUpMove focus to the previous button (orientation="vertical")

Only the currently-focused button is in the tab sequence (roving tabindex) — pressing Tab moves focus out of the toolbar entirely.

data-* attributes

AttributeElementWhen present
data-orientationToolbarAlways — reflects the orientation prop
data-disabledToolbarButtonThe button's disabled prop is set
data-orientationToolbarSeparatorAlways — the axis perpendicular to the toolbar's orientation

Always provide an aria-label or aria-labelledby on Toolbar so screen readers can identify its purpose.

Styling example

.morphos-toolbar[data-orientation="vertical"] {
  flex-direction: column;
  align-items: stretch;
}

.morphos-toolbar-button[data-disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

.morphos-toolbar-separator[data-orientation="vertical"] {
  width: 1px;
  align-self: stretch;
}

On this page