Menubar
Groups application menus in a compact 1px frame. Text-only triggers keep 44px targets and wrap to fit.
Preview
In action
When to use
Use it for
- Desktop-style application menus: File, Edit, View.
- Tools and editors with many commands grouped by verb.
Not for
- Site navigation; use NavigationMenu.
- One menu; use DropdownMenu.
Install
Three ways in. They share one source, so the pixels match whichever you pick.
1. Import the package
npm install @noorddev/vlak-react
// once, next to your app's root
import "@noorddev/vlak-react/css";
import { Menubar } from "@noorddev/vlak-react";Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/menubar.
2. Vendor the source
npx @noorddev/vlak-cli add menubar
The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.
3. Through shadcn
npx shadcn add https://vlak.dev/r/menubar.json
The same registry item, installed by shadcn's CLI.
CSS only
<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />
No React. Link vlak.css and use the markup and classes below.
React
import { Menubar } from "@noorddev/vlak-react";
<Menubar
aria-label="Application menus"
menus={[
{ label: "File", items: [{ label: "New", onSelect: create }, { label: "Open…", onSelect: open }] },
{ label: "Edit", items: [{ label: "Undo", onSelect: undo }, { label: "Redo", onSelect: redo }] },
]}
/>Props
Menubar
Dropdown menus in a hairline strip. The triggers are menuitems with one roving tab stop; ArrowLeft/ArrowRight move between them and an open menu follows.
| Prop | Type | Default | Description |
|---|---|---|---|
menusrequired | { label: ReactNode; items: DropdownMenuItem[]; }[] |
Also accepts HTMLAttributes<HTMLDivElement>.
Keyboard
| Keys | Does |
|---|---|
| Tab | Moves focus to the bar (one roving tab stop) |
| Arrow left, Arrow right | Moves between menus; an open menu follows |
| Home, End | First or last menu |
| Arrow down, Enter, Space | Opens the menu on the first item |
| Arrow up | Opens the menu on the last item |
| Escape | Closes the open menu and returns focus to its trigger |
Accessibility
- Renders role="menubar"; each trigger is a <button role="menuitem"> with aria-haspopup="menu", aria-expanded, and aria-controls.
- Open panels are role="menu" labelled by their trigger, with the same keyboard model as DropdownMenu.
- Text-only triggers have 44px minimum hit targets and wrap inside the bar. The open trigger uses a full-surface fill, never a leading stripe.
- The markup snippet shows the closed appearance only. Use the React component for opening, placement, roving focus, and keyboard interaction.
Markup
<div class="rs-menubar" role="menubar" aria-label="Application menus"><div class="rs-menubar-wrap"><button type="button" class="rs-menubar-trigger" role="menuitem" aria-haspopup="menu" aria-expanded="false" tabindex="0">File</button></div><div class="rs-menubar-wrap"><button type="button" class="rs-menubar-trigger" role="menuitem" aria-haspopup="menu" aria-expanded="false" tabindex="-1">Edit</button></div><div class="rs-menubar-wrap"><button type="button" class="rs-menubar-trigger" role="menuitem" aria-haspopup="menu" aria-expanded="false" tabindex="-1">View</button></div></div>