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.
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.
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.
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.
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.
Guidelines
Q4 launch plan: ship the mobile app on Nov 18 and the price change on Dec 1.
Editors, spreadsheets and design tools have dozens of commands; File, Edit and Format give each one a place people already know.
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.
Separators split create, save and print, so people scan three short groups instead of one long list.
Print next to New, Delete next to Rename: people read every row, and a slip lands on the wrong one.
Props
Kbd. Display only: pair it with aria-keyshortcuts and wire the keys yourself."danger" colors a destructive item.<a> for a link.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
Tokens it reads
Color
Shape & size
Type & motion
This component only
Accessibility
- The bar is role=menubar and needs an aria-label. Its triggers are menuitem with aria-haspopup and aria-expanded; checkbox and radio items report aria-checked.
- Once a menu is open, hovering another trigger in the bar switches to it, as in a desktop app.
- Shortcuts in Kbd are only shown. Add aria-keyshortcuts so screen readers say them, and handle the keys in your app.
- After a command the menu is gone: announce the result with role="status" and leave focus on the trigger.