Pho Design System

Toolbar

A row of related controls that acts as a single tab stop, with arrow-key navigation between items — formatting bars, editor controls. Built on Base UI Toolbar.

Import

import { Toolbar } from "@photon-ai/pho-ui/components/toolbar";

Basic

Toolbar.Button, Link, and Input are the controls; Toolbar.Separator divides groups. Every icon-only control needs an aria-label.

<Toolbar.Root aria-label="Formatting">
  <Toolbar.Button aria-label="Bold">
    <TextB weight="bold" />
  </Toolbar.Button>
  <Toolbar.Button aria-label="Italic">
    <TextItalic />
  </Toolbar.Button>
  <Toolbar.Separator />
  <Toolbar.Button aria-label="Align left">
    <TextAlignLeft />
  </Toolbar.Button>
</Toolbar.Root>

Pressable toggles

A plain Toolbar.Button fires an action; for a formatting control that stays on until pressed again, render a Toggle through it with render. The button keeps its place in the roving focus order while Toggle tracks the pressed state (data-[pressed]). Group related toggles with Toolbar.Group.

import { Toggle } from "@photon-ai/pho-ui/components/toggle";

<Toolbar.Root aria-label="Formatting">
  <Toolbar.Group>
    <Toolbar.Button render={<Toggle aria-label="Bold" />}>
      <TextB weight="bold" />
    </Toolbar.Button>
    <Toolbar.Button render={<Toggle aria-label="Italic" defaultPressed />}>
      <TextItalic />
    </Toolbar.Button>
  </Toolbar.Group>
</Toolbar.Root>;

Toolbar.Input and Toolbar.Link join the same roving focus order as buttons, so a search field or a jump-out link stays reachable with the arrow keys.

<Toolbar.Root aria-label="Editor">
  <Toolbar.Button aria-label="Undo">
    <ArrowUUpLeft />
  </Toolbar.Button>
  <Toolbar.Separator />
  <Toolbar.Input placeholder="Search" aria-label="Search" />
  <Toolbar.Separator />
  <Toolbar.Link href="/docs">Docs</Toolbar.Link>
</Toolbar.Root>

Anatomy

Props

Toolbar.Root (renders a <div role="toolbar">)

Toolbar.Button (renders a <button>)

Toolbar.Separator (renders a <div role="separator">)

Accessibility

Toolbar.Root renders role="toolbar" and reflects aria-orientation. Give it an aria-label (or aria-labelledby) so its purpose is announced, and give every icon-only Toolbar.Button an aria-label that names the action.

Roving tabindex keeps only one item tabbable, so the whole toolbar is one stop in the page’s tab order. Focus wraps at the ends while loopFocus is true. Disabled buttons remain focusable by default (focusableWhenDisabled) so screen readers still announce them.

Best practices