1
ComponentsNavigation

Toolbar

A compact roving-focus group for equal-priority buttons, toggles, links and lightweight controls.

Purpose

Use Toolbar to group equal-priority actions and controls in one compact roving-focus region.

Command toolbar

import { Button } from "@/components/ui/button";
import { Toolbar, ToolbarButton, ToolbarGroup, ToolbarInput, ToolbarSeparator } from "@/components/ui/toolbar";

export function Example() {
  return (
    <Toolbar>
      <ToolbarGroup><ToolbarButton aria-label="Copy" render={<Button size="icon-sm" variant="ghost" />}>Copy</ToolbarButton></ToolbarGroup>
      <ToolbarSeparator />
    </Toolbar>
  );
}

Installation

With the Siteplane registry alias configured, add the component and import the installed source from your app.

CLI

pnpm dlx shadcn@4.16.1 add @siteplane/toolbar

Import

import { Toolbar } from "@/components/ui/toolbar";
import { ToolbarButton, ToolbarGroup, ToolbarInput, ToolbarLink, ToolbarSeparator } from "@/components/ui/toolbar";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { Select, SelectItem, SelectPopup, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tooltip, TooltipPopup, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";

Need the machine-readable source metadata? View registry JSON.

Usage

Use Toolbar to group compact commands for an editor, filter surface or utility row.

import { Button } from "@/components/ui/button";
import { Toolbar, ToolbarButton, ToolbarGroup, ToolbarInput, ToolbarSeparator } from "@/components/ui/toolbar";

export function Example() {
  return (
    <Toolbar>
      <ToolbarGroup><ToolbarButton aria-label="Copy" render={<Button size="icon-sm" variant="ghost" />}>Copy</ToolbarButton></ToolbarGroup>
      <ToolbarSeparator />
    </Toolbar>
  );
}

Examples

Toolbar slots stay unstyled pass-throughs: compose them with Button, Toggle and Select via render while Base UI handles roving focus.

Grouped actions

<Toolbar aria-label="Text style toolbar">
  <ToolbarGroup aria-label="Text style">
    <ToolbarButton aria-label="Bold" render={<Button size="icon" variant="ghost" />}>
      <BoldIcon />
    </ToolbarButton>
    <ToolbarButton aria-label="Italic" render={<Button size="icon" variant="ghost" />}>
      <ItalicIcon />
    </ToolbarButton>
    <ToolbarButton aria-label="Underline" render={<Button size="icon" variant="ghost" />}>
      <UnderlineIcon />
    </ToolbarButton>
  </ToolbarGroup>
  <ToolbarSeparator />
  <ToolbarButton render={<Button variant="ghost" />}>Save</ToolbarButton>
</Toolbar>

Disabled

disabled on the root and its buttons; focusableWhenDisabled stays part of the Base UI contract.

<Toolbar aria-label="Disabled toolbar" disabled>
  <ToolbarGroup aria-label="Text style">
    <ToolbarButton
      aria-label="Bold"
      disabled
      render={<Button disabled size="icon" variant="ghost" />}
    >
      <BoldIcon />
    </ToolbarButton>
  </ToolbarGroup>
  <ToolbarSeparator />
  <ToolbarButton disabled render={<Button disabled variant="ghost" />}>
    Save
  </ToolbarButton>
</Toolbar>

Vertical

<Toolbar
  aria-label="Vertical toolbar"
  className="w-fit flex-col items-stretch"
  orientation="vertical"
>
  <ToolbarButton aria-label="Bold" render={<Button size="icon" variant="ghost" />}>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton aria-label="Italic" render={<Button size="icon" variant="ghost" />}>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton aria-label="Underline" render={<Button size="icon" variant="ghost" />}>
    <UnderlineIcon />
  </ToolbarButton>
</Toolbar>

With toggles

<Toolbar aria-label="Formatting toggles">
  <ToolbarGroup aria-label="Text formatting">
    <ToolbarButton aria-label="Bold" render={<Toggle />}>
      <BoldIcon />
      Bold
    </ToolbarButton>
    <ToolbarButton aria-label="Underline" render={<Toggle />}>
      <UnderlineIcon />
      Underline
    </ToolbarButton>
  </ToolbarGroup>
  <ToolbarSeparator />
  <ToolbarButton render={<Button />}>Save</ToolbarButton>
</Toolbar>

Formatting toolbar

ToggleGroup, Select and Tooltip composed into one roving-focus toolbar.

<TooltipProvider>
  <Toolbar aria-label="Formatting toolbar">
    <ToggleGroup className="border-none p-0" defaultValue={["left"]}>
      <Tooltip>
        <TooltipTrigger
          render={
            <ToolbarButton aria-label="Align left" render={<ToggleGroupItem value="left" />}>
              <AlignLeftIcon />
            </ToolbarButton>
          }
        />
        <TooltipPopup sideOffset={8}>Align left</TooltipPopup>
      </Tooltip>
      {/* Align center / right follow the same pattern */}
    </ToggleGroup>
    <ToolbarSeparator />
    <ToolbarGroup aria-label="Numerical format">
      <ToolbarButton aria-label="Format as currency" render={<Button size="icon" variant="ghost" />}>
        <DollarSignIcon />
      </ToolbarButton>
      <ToolbarButton aria-label="Format as percent" render={<Button size="icon" variant="ghost" />}>
        <PercentIcon />
      </ToolbarButton>
    </ToolbarGroup>
    <ToolbarSeparator />
    <ToolbarGroup aria-label="Font family">
      <Select defaultValue="helvetica" items={fontItems}>
        <ToolbarButton
          render={
            <SelectTrigger aria-label="Font family">
              <SelectValue />
            </SelectTrigger>
          }
        />
        <SelectPopup>
          {fontItems.map(({ label, value }) => (
            <SelectItem key={value} value={value}>{label}</SelectItem>
          ))}
        </SelectPopup>
      </Select>
    </ToolbarGroup>
    <ToolbarSeparator />
    <ToolbarGroup aria-label="Save actions">
      <ToolbarButton render={<Button />}>Save</ToolbarButton>
    </ToolbarGroup>
  </Toolbar>
</TooltipProvider>

With input

<Toolbar aria-label="Search toolbar example" className="w-full max-w-72">
  <SearchIcon className="ml-2 size-4 shrink-0 text-muted-foreground" />
  <ToolbarInput
    aria-label="Search toolbar"
    className="h-8 min-w-0 flex-1 bg-transparent px-1 text-sm outline-none placeholder:text-muted-foreground"
    placeholder="Search toolbar"
  />
</Toolbar>

API Reference

The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.

  • Compose Toolbar, ToolbarGroup, ToolbarButton, ToolbarLink, ToolbarInput and ToolbarSeparator.
  • Toolbar accepts Base UI toolbar props including orientation, loopFocus and focusableWhenDisabled.
  • Compose ToolbarButton through render with an existing Button, Toggle, Select or popup trigger instead of nesting interactive elements.
  • In a vertical Toolbar, the separator becomes horizontal through the native orientation contract; include it when groups need a real boundary.

Motion

Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.

  • Toolbar itself is static. Nested Button, Toggle, Select and Tooltip primitives retain their own native motion.
  • No additional toolbar-level reduced-motion handling is required.

Accessibility

  • Preserve Base UI roving focus and arrow-key navigation.
  • Give icon-only actions an accessible name; a Tooltip supplements but does not replace the trigger name.
  • Use inputs sparingly because arrow keys also have text-cursor meaning inside an input.

Implementation Guidance

  • Use render to compose existing controls into toolbar items.
  • Match separator direction to the toolbar orientation and keep related actions in ToolbarGroup.
  • Do not invent a parallel toolbar button visual contract.

On This Page