// preview in
saved for every page

Menubar

A row of menus, like File, Edit and View in a desktop app. Use it only in app-like screens with many commands, such as an editor; on a regular web page, a toolbar or a few menu buttons are easier to find.

Built on Base UIPattern WAI-ARIA MenubarClient componentSource ↗

Installation

Set up Camaleo once (Installation), then import the parts you need. The menus render in a portal and keep the skin, mode and brand of the page around them.

import { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent, MenubarSeparator } from "@camaleo/react";

Anatomy

Menubar is the bar, one Tab stop. Each MenubarMenu pairs a MenubarTrigger in the bar with a MenubarContent popup, rendered in a portal. Items, checkbox items, radio items and submenus go inside.

Examples

Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above, and they all start closed.

minimal · light · #3fa34d

With shortcuts

Show each shortcut with Kbd so people learn it while they browse, and add aria-keyshortcuts so screen readers say it too. The menubar only displays it: wire the keys yourself.

Q4 launch plan: ship the mobile app on Nov 18 and the price change on Dec 1.

Checkbox items

Open View and turn the ruler off. MenubarCheckboxItem stays open after a click and reports aria-checked, so people can flip several settings in a row.

Q4 launch plan: ship the mobile app on Nov 18 and the price change on Dec 1.

Radio items

Pick a zoom level. A MenubarRadioGroup is for one value out of a few; each item is announced as "checked" or "not checked".

Submenu

Group variations of one command, like the export formats, under a MenubarSub. Keep it to one level: each level is one more hover and one more arrow key.

Disabled, with a reason

Keep an unavailable command in place so people learn where it lives, and say why in the item: disabled items stay focusable, so the reason is read with the name.

Destructive, with a confirm

Pick "Delete document". It comes last, after a separator, and opens an AlertDialog; finalFocus brings focus back to File when it closes.

Act, then announce

Pick a command. Focus goes back to the menu's trigger, and a role="status" line tells screen readers what happened, because the menu that showed it is gone.

In context

A menubar sits at the top of an app window, above the work. These are whole pieces of UI you can copy, in the skin you picked.

Budget 2027Saved
ItemQ1Q2
Office rent$18,000$18,000
Payroll$142,500$151,200
Ads$9,800$12,400
SpreadsheetMenubar · Badge · Kbd · Table
Photo editorMenubar · Toolbar
  • Julia MendesSigned contract for the Recife officeUnread
  • Rafael CostaRe: Q4 launch plan, comments on the timeline
  • Lucas TavaresInvoice INV-4031 is due on Nov 5
Mail clientMenubar · Avatar · Badge · Kbd

Guidelines

Q4 launch plan: ship the mobile app on Nov 18 and the price change on Dec 1.

DoA menubar for an app with many commands.

Editors, spreadsheets and design tools have dozens of commands; File, Edit and Format give each one a place people already know.

Don’tA menubar to move between pages.

Its items are not links: no middle-click, no "open in new tab", and arrow keys a website visitor doesn't expect. Use a NavigationMenu.

DoRelated commands together, with their shortcuts.

Separators split create, save and print, so people scan three short groups instead of one long list.

Don’tTen commands in no order.

Print next to New, Delete next to Rename: people read every row, and a slip lands on the wrong one.

Props

PropTypeDefaultDescription
iconReactNode—Icon before the label. It is hidden from screen readers.
shortcutReactNode—Shortcut shown at the end of the row, usually a Kbd. Display only: pair it with aria-keyshortcuts and wire the keys yourself.
tone"danger"—"danger" colors a destructive item.
renderReactElement | (props, state) => ReactElement—Renders another element, such as an <a> for a link.
onClickfunction—Runs when the item is chosen with a click, Enter or Space.
disabledbooleanfalseDisables the item. It stays focusable, so people can still read it.
labelstring—Text for typeahead when the item's content is not plain text.
closeOnClickbooleantrueWhether choosing the item closes the menu.

These are the props of MenubarItem. Menubar takes modal, disabled, loopFocus and orientation, and needs an aria-label. MenubarCheckboxItem takes checked, defaultChecked, onCheckedChange and shortcut; MenubarRadioGroup takes value, defaultValue and onValueChange. MenubarMenu takes Base UI's menu root props, such as open and onOpenChange.

Styling hooks

Restyle it without forking: target the attributes, or set the tokens on a parent, a skin or the bar itself.

Attributes

data-popup-openon the trigger whose menu is open
data-highlightedon the item under the keyboard or pointer
data-checked · data-uncheckedon checkbox and radio items
data-disabledon a disabled item
data-tonedanger
data-orientationhorizontal · vertical (on the bar)

Tokens it reads

Color

--cml-accent--cml-accent-fg--cml-border-control--cml-border-subtle--cml-brand--cml-danger--cml-fg--cml-fg-muted--cml-fg-secondary--cml-focus-offset--cml-focus-ring--cml-focus-width--cml-item-highlight-fg--cml-popover-bg--cml-popover-border--cml-shadow-popover--cml-surface-raised

Shape & size

--cml-border-width--cml-popover-border-width--cml-popover-padding--cml-radius-control--cml-radius-popover

Type & motion

--cml-font-body

This component only

--cml-disabled-opacity--cml-item-highlight--cml-item-hover--cml-menubar-active-bg--cml-menubar-active-fg--cml-menubar-bg--cml-menubar-height--cml-menubar-popup-radius--cml-menubar-popup-width--cml-menubar-radius--cml-menubar-shadow

Accessibility

TabMoves into the menubar, onto the last-used menu, and out again: the whole bar is one Tab stop.
→ / ←In the bar: moves to the next or previous menu, wrapping at the ends. In an open menu: → opens a submenu and ← closes it; on other items they open the next or previous menu.
↓ / Enter / SpaceOn a menu in the bar: opens it and focuses the first enabled item.
↓ / ↑Moves between items, wrapping at the ends. Disabled items are included.
Home / EndJumps to the first or last item.
A–ZJumps to the next item that starts with that letter.
Enter / SpaceRuns the item and closes the menu; on a checkbox or radio item, toggles it and keeps the menu open.
EscCloses the submenu, or the menu and returns focus to its trigger in the bar.
Was this page helpful? · Edit this page on GitHub