---
title: Toolbar
description: A container for grouping a set of controls, such as buttons, toggle groups, or links, built on the Base UI Toolbar primitive.
---

```tsx
import {
  AlignLeftIcon,
  AlignRightIcon,
  BoldIcon,
  ItalicIcon,
  UnderlineIcon,
} from "lucide-react";

import { Toggle } from "@/registry/base/ui/toggle";
import { ToggleGroup } from "@/registry/base/ui/toggle-group";
import {
  Toolbar,
  ToolbarButton,
  ToolbarLink,
  ToolbarSeparator,
} from "@/registry/base/ui/toolbar";

export default function ToolbarDemo() {
  return (
    <Toolbar>
      <ToggleGroup
        multiple
        defaultValue={["bold"]}
        aria-label="Text formatting"
      >
        <ToolbarButton
          render={<Toggle />}
          aria-label="Toggle bold"
          value="bold"
        >
          <BoldIcon />
        </ToolbarButton>
        <ToolbarButton
          render={<Toggle />}
          aria-label="Toggle italic"
          value="italic"
        >
          <ItalicIcon />
        </ToolbarButton>
        <ToolbarButton
          render={<Toggle />}
          aria-label="Toggle underline"
          value="underline"
        >
          <UnderlineIcon />
        </ToolbarButton>
      </ToggleGroup>
      <ToolbarSeparator />
      <ToggleGroup defaultValue={["align-left"]} aria-label="Alignment">
        <ToolbarButton
          render={<Toggle />}
          aria-label="Align left"
          value="align-left"
        >
          <AlignLeftIcon />
        </ToolbarButton>
        <ToolbarButton
          render={<Toggle />}
          aria-label="Align right"
          value="align-right"
        >
          <AlignRightIcon />
        </ToolbarButton>
      </ToggleGroup>
      <ToolbarSeparator />
      <ToolbarLink href="#">Edited 2 hours ago</ToolbarLink>
    </Toolbar>
  );
}
```

## Installation

<InstallCommand item="toolbar" />

## Usage

```tsx
"use client";

import { Toggle } from "@/components/ui/toggle";
import { ToggleGroup } from "@/components/ui/toggle-group";
import {
  Toolbar,
  ToolbarButton,
  ToolbarLink,
  ToolbarSeparator,
} from "@/components/ui/toolbar";

export default function ToolbarDemo() {
  return (
    <Toolbar>
      <ToggleGroup multiple defaultValue={["bold"]} aria-label="Text formatting">
        <ToolbarButton render={<Toggle />} aria-label="Toggle bold" value="bold">
          B
        </ToolbarButton>
      </ToggleGroup>
      <ToolbarSeparator />
      <ToolbarLink href="#">Edited 2 hours ago</ToolbarLink>
    </Toolbar>
  );
}
```

## API reference

Toolbar is a Base UI bonus primitive absent from shadcn/ui, like Meter
and Number Field.

### Toolbar

Extends the
[Base UI Toolbar](https://base-ui.com/react/components/toolbar) Root —
renders `<div role="toolbar">`. Arrow keys move roving focus across
button, link, and input items (skipping disabled ones); `Home`/`End`
jump to the first/last item.

| Prop          | Type                            | Default        |
| ------------- | ------------------------------- | -------------- |
| `orientation` | `"horizontal" \| "vertical"` — arrow-key axis | `"horizontal"` |
| `loopFocus`   | `boolean` — wrap focus at the ends            | `true`         |
| `disabled`    | `boolean` — disables every item               | `false`        |

### ToolbarButton

Renders a native `<button>`, but — like `Tabs.Tab` and
`Accordion.Trigger` — it passes `focusableWhenDisabled: true`
internally: a disabled button stays focusable and receives
`aria-disabled="true"` instead of the native `disabled` attribute, so it
remains keyboard-reachable and tooltips still open on it. Style the
disabled state with `data-disabled:`, not the `disabled:` Tailwind
variant.

### ToolbarLink and ToolbarInput

Render a native `<a>` and `<input>`. Use at most **one** input, placed
last in the toolbar — arrow keys move focus between items, which
conflicts with cursor movement inside a text field.

### ToolbarGroup and ToolbarSeparator

`ToolbarGroup` groups related items — give it an `aria-label`.
`ToolbarSeparator`'s `orientation` defaults to the **opposite** of the
toolbar's (a horizontal toolbar renders a vertical separator line); its
`data-orientation` reflects the separator's own orientation.

### Composition

Popup triggers (AlertDialog, Dialog, Menu, Popover, Select) render
**inside** `ToolbarButton` — `<ToolbarButton render={<MenuTrigger />} />`.
Tooltip is **inverted** — `<TooltipTrigger render={<ToolbarButton />} />`.
Toggle buttons render as `<ToolbarButton render={<Toggle />} value="…" />`
inside a [Toggle Group](/docs/components/toggle-group), which owns the
pressed state: give each button a `value`, set the initially pressed
ones with `defaultValue={[...]}`, and add `multiple` for a multi-select
group.
