<!-- Protocore Design System — Menubar -->
# Menubar

- **Category:** Navigation (`navigation`)
- **Slug:** `navigation/menubar`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { Menubar } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/navigation/menubar

> Application menubar — a horizontal row of mono UPPERCASE menu triggers (File/Edit/View) opening raised panels of items, checkbox/radio items and submenus.

## When to use it

Use **Menubar** for the persistent, top-of-app command surface of a dense tool — an editor, a console, an admin workbench — where users expect a File/Edit/View row that groups many low-frequency actions.

- A single button that reveals a menu is a **DropdownMenu**, not a Menubar.
- A right-click surface on content is a **ContextMenu**.
- A row of *always-visible* controls (not menus) is a **Toolbar**.
- Primary section navigation belongs in a **Sidebar** or **TopBar**, not a menubar.

## Examples

### Basics

Compose `Menubar.Root` with a `Menubar.Menu` per top-level heading. Each menu pairs a `Menubar.Trigger` with a `Menubar.Content` panel of `Menubar.Item`s. Moving the pointer across triggers while one menu is open switches menus, just like a desktop app.

```tsx
import { Menubar } from "@protocore/pds";

export default function MenubarBasics() {
  return (
    <Menubar.Root>
      <Menubar.Menu>
        <Menubar.Trigger>File</Menubar.Trigger>
        <Menubar.Content>
          <Menubar.Item endHint="⌘N">New tenant</Menubar.Item>
          <Menubar.Item endHint="⌘D">Duplicate site</Menubar.Item>
          <Menubar.Separator />
          <Menubar.Item endHint="⌘S">Save draft</Menubar.Item>
          <Menubar.Item tone="danger">Delete tenant…</Menubar.Item>
        </Menubar.Content>
      </Menubar.Menu>

      <Menubar.Menu>
        <Menubar.Trigger>Edit</Menubar.Trigger>
        <Menubar.Content>
          <Menubar.Item endHint="⌘Z">Undo</Menubar.Item>
          <Menubar.Item endHint="⇧⌘Z">Redo</Menubar.Item>
          <Menubar.Separator />
          <Menubar.Item endHint="⌘F">Find in content…</Menubar.Item>
        </Menubar.Content>
      </Menubar.Menu>

      <Menubar.Menu>
        <Menubar.Trigger>Deploy</Menubar.Trigger>
        <Menubar.Content>
          <Menubar.Item>Build static export</Menubar.Item>
          <Menubar.Item>Invalidate CloudFront</Menubar.Item>
          <Menubar.Item>Publish to production</Menubar.Item>
        </Menubar.Content>
      </Menubar.Menu>
    </Menubar.Root>
  );
}
```

### Checkbox, radio & submenus

Menus reuse the DropdownMenu recipes: `Menubar.CheckboxItem`, a `Menubar.RadioGroup` of `Menubar.RadioItem`s, `Menubar.Label` section headings, `Menubar.Separator`s, and nested `Menubar.Sub` / `SubTrigger` / `SubContent`.

```tsx
import * as React from "react";
import { Menubar } from "@protocore/pds";

export default function MenubarRich() {
  const [showDrafts, setShowDrafts] = React.useState(true);
  const [showArchived, setShowArchived] = React.useState(false);
  const [env, setEnv] = React.useState("staging");

  return (
    <Menubar.Root>
      <Menubar.Menu>
        <Menubar.Trigger>View</Menubar.Trigger>
        <Menubar.Content>
          <Menubar.Label>Visible tenants</Menubar.Label>
          <Menubar.CheckboxItem checked={showDrafts} onCheckedChange={setShowDrafts}>
            Show drafts
          </Menubar.CheckboxItem>
          <Menubar.CheckboxItem checked={showArchived} onCheckedChange={setShowArchived}>
            Show archived
          </Menubar.CheckboxItem>
          <Menubar.Separator />
          <Menubar.Label>Target environment</Menubar.Label>
          <Menubar.RadioGroup value={env} onValueChange={setEnv}>
            <Menubar.RadioItem value="dev">dev</Menubar.RadioItem>
            <Menubar.RadioItem value="staging">staging</Menubar.RadioItem>
            <Menubar.RadioItem value="prod">prod</Menubar.RadioItem>
          </Menubar.RadioGroup>
        </Menubar.Content>
      </Menubar.Menu>

      <Menubar.Menu>
        <Menubar.Trigger>Tools</Menubar.Trigger>
        <Menubar.Content>
          <Menubar.Item>Run migration</Menubar.Item>
          <Menubar.Sub>
            <Menubar.SubTrigger>Export</Menubar.SubTrigger>
            <Menubar.SubContent>
              <Menubar.Item>CSV</Menubar.Item>
              <Menubar.Item>JSON</Menubar.Item>
              <Menubar.Item>Static bundle</Menubar.Item>
            </Menubar.SubContent>
          </Menubar.Sub>
          <Menubar.Separator />
          <Menubar.Item tone="danger">Purge media cache</Menubar.Item>
        </Menubar.Content>
      </Menubar.Menu>
    </Menubar.Root>
  );
}
```

## Do & don't

**Do**

- Group actions under conventional headings (File, Edit, View) users can predict.
- Use CheckboxItem / RadioItem for toggles and modes so state is visible in the menu.
- Reserve submenus for genuinely nested choices, not to hide overflow.
- Give destructive items `tone="danger"` and keep them separated by a rule.

**Don't**

- Don't use a Menubar for a single menu — a DropdownMenu is lighter.
- Don't nest submenus more than one level deep; it gets hard to steer.
- Don't put a primary, high-frequency action only in a menu — surface it in a Toolbar.
- Don't hand-draw the trigger case — the recipe sets mono UPPERCASE.

## Accessibility

**Keyboard**

| Keys | Action |
| --- | --- |
| `Arrow Left / Right` | Move between top-level menus. |
| `Arrow Down / Up` | Open the focused menu and move between its items. |
| `Enter / Space` | Activate the focused trigger or item. |
| `Type a letter` | Jump to the next item starting with that character. |
| `Esc` | Close the open menu and return focus to its trigger. |

**Notes**

- Built on Radix Menubar — the bar is a `role="menubar"`, triggers are `menuitem`s, and each panel is a portalled `role="menu"` with `menuitem` / `menuitemcheckbox` / `menuitemradio` children.
- Panels sit on the popover z-layer so a menubar hosted inside a Dialog or Sheet still paints above the modal overlay.
- Focus is managed by Radix: opening a menu moves focus in, Escape returns it to the trigger, and roving arrow navigation runs throughout.

## Related

`dropdown-menu`, `context-menu`, `toolbar`, `sidebar`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
