Menubar
Group app commands in familiar menus such as File, Edit and View.
import { Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger } from '@youj/react'
Installation & usage
npm i @youj/reactFor an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.
Use a menubar for the command surface of a document-style app: an editor, a design tool, an IDE in the browser, where people expect menus they can scrub across. For one menu behind a button, use a Dropdown Menu. For site navigation between pages, use a Navigation Menu.
import {
Menubar,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarSeparator,
MenubarShortcut,
MenubarTrigger,
} from '@youj/react'
export function EditorMenubar() {
return (
<Menubar>
<MenubarMenu>
<MenubarTrigger>File</MenubarTrigger>
<MenubarContent>
<MenubarItem>
New document <MenubarShortcut>⌘N</MenubarShortcut>
</MenubarItem>
<MenubarSeparator />
<MenubarItem>Print…</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu>
<MenubarTrigger>Edit</MenubarTrigger>
<MenubarContent>
<MenubarItem>Undo</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar>
)
}Each MenubarMenu is a menu whose trigger sits in the bar. Its content takes everything a Dropdown Menu does, under Menubar names: MenubarItem (with variant="danger" and inset), MenubarCheckboxItem, MenubarRadioGroup and MenubarRadioItem, MenubarLabel, MenubarGroup, MenubarSeparator, MenubarShortcut, and submenus with MenubarSub, MenubarSubTrigger and MenubarSubContent. The API matches shadcn/ui's Menubar, so its examples paste in.
Description
A document menu bar with File, Edit and View menus, including a submenu, checkbox items and a radio group.
Once a menu is open, the bar behaves like a desktop menu bar: hovering another trigger, or pressing ← or →, closes the open menu and opens its neighbor without another click. The open trigger is marked by one Sliding Indicator, so the mark glides along the bar as you scrub, and retargets if you change direction mid-glide. With no menu open, triggers light up on hover on their own.
Code
menubar-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propscontainer, presentation (2)
Props
Menubar
Menubar adds no props of its own. They pass through to MenubarPrimitive.Props.
Base UI's Menubar takes orientation ('horizontal' by default, which sets the arrow keys), loopFocus (default true), modal and disabled.
MenubarContent
| Prop | Type | |
|---|---|---|
container | HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null>Where the portal renders. Default: document.body. | – |
presentation | OverlayPresentation'auto''sheet''popover'
| – |
It defaults to align="start" with the first row under the trigger's label, sideOffset={6}, and takes Dropdown Menu's side, align, alignOffset, collisionPadding and container.
MotionOpen-menu mark, mark appears and leaves, menu opens… · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| Open-menu markglides to the trigger whose menu opened | spring.smooth0.36s, bounce 0 | 0.36s, bounce 0 | |
| Mark appears and leaveswhen the first menu opens and the last one closes | duration.fastease.standard140ms · cubic-bezier(0.2, 0, 0, 1) | 140mscubic-bezier(0.2, 0, 0, 1) | |
| Menu opensyj-pop from the trigger, as Dropdown Menu | duration.fastease.enter140ms · cubic-bezier(0.16, 1, 0.3, 1) | 140mscubic-bezier(0.16, 1, 0.3, 1) | |
| Row highlightone highlight glides between rows, as Dropdown Menu | spring.smooth0.36s, bounce 0 | 0.36s, bounce 0 |
Reduced motion
The mark jumps to the open trigger, menus appear without the pop, and the row highlight jumps.
Reduced motion
The mark moves straight to the open trigger, menus open in place and rows highlight without gliding. Which menu is open reads exactly the same.
AccessibilityKeyboard, ARIA, focus
Accessibility
- The bar is a
menubarand each trigger amenuitemwitharia-haspopupandaria-expanded. It's a single tab stop;←and→move between triggers and wrap, mirrored in right-to-left layouts. ↓,EnterorSpaceopens a menu and focuses its first row; inside, the arrow keys, typeahead,HomeandEndwork as in any menu.Escapecloses it and returns focus to its trigger.- The gliding mark is decorative (
aria-hidden). In forced-colors mode the open trigger gets an outline instead.