Marble UI
← Components

Toolbar

Preview: Plain

A row of controls with one tab stop; arrow keys move between them (React Aria Toolbar).

Import

import { Toolbar, ToolbarGroup, ToolbarSeparator } from '@marbleui/ui'

Props

<Toolbar>

PropTypeDefaultDescription
variant'floating' | 'plain''plain'

Also accepts React Aria props (80).

<ToolbarGroup>

No props of its own.

Also accepts React Aria props (16) and HTML element props (269).

<ToolbarSeparator>

No props of its own.

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria Group · React Aria Separator · React Aria Toolbar. Follow the primitive's docs for the full keyboard map.

Usage notes

A row of related controls with a single tab stop, such as text-formatting buttons. For bulk actions on a selection use ActionBar; for independent buttons that should each be tabbable use plain layout.

<Toolbar aria-label="Text formatting">
  <ToggleButton aria-label="Bold"><BoldIcon /></ToggleButton>
  <ToolbarSeparator />
  <ToolbarGroup aria-label="Insert">
    <ToggleButton aria-label="Link"><LinkIcon /></ToggleButton>
  </ToolbarGroup>
</Toolbar>
  • Always set aria-label on Toolbar. Arrow keys move between controls; Tab leaves the toolbar.
  • variant is plain (default) or floating; orientation="vertical" is supported.
  • Icon-only controls inside need their own aria-label.
  • ToolbarGroup groups related controls; ToolbarSeparator is a vertical divider.
Example source · show
import { Button } from '../button'
import { ToggleButton } from '../toggle-button'
import { ToggleButtonGroup } from '../toggle-button-group'
import { Toolbar, ToolbarGroup, ToolbarSeparator } from './toolbar'

const I = ({ d }: { d: string }) => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
    <path d={d} />
  </svg>
)
const icons = {
  bold: 'M6 12h9a4 4 0 0 1 0 8H6zM6 4h7a4 4 0 0 1 0 8H6z',
  italic: 'M19 4h-9M14 20H5M15 4 9 20',
  underline: 'M6 4v6a6 6 0 0 0 12 0V4M4 20h16',
  list: 'M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01',
  link: 'M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7',
}

const Editor = ({ variant }: { variant: 'plain' | 'floating' }) => (
  <Toolbar aria-label="Text formatting" variant={variant}>
    <ToggleButtonGroup aria-label="Style" selectionMode="multiple" variant="spaced">
      <ToggleButton id="bold" variant="soft" aria-label="Bold"><I d={icons.bold} /></ToggleButton>
      <ToggleButton id="italic" variant="soft" aria-label="Italic"><I d={icons.italic} /></ToggleButton>
      <ToggleButton id="underline" variant="soft" aria-label="Underline"><I d={icons.underline} /></ToggleButton>
    </ToggleButtonGroup>
    <ToolbarSeparator />
    <ToolbarGroup aria-label="Insert">
      <ToggleButton variant="soft" aria-label="Bulleted list"><I d={icons.list} /></ToggleButton>
      <ToggleButton variant="soft" aria-label="Link"><I d={icons.link} /></ToggleButton>
    </ToolbarGroup>
    <ToolbarSeparator />
    <Button size="sm" variant="ghost">Clear</Button>
  </Toolbar>
)

export const styles = { Plain: () => <Editor variant="plain" />, Floating: () => <Editor variant="floating" /> }

Source: packages/ui/src/toolbar/toolbar.tsx

Catalog

Category
navigation
Priority
Core
Primitive
react-aria
React Aria
Toolbar
Base UI
Toolbar