Menubar
Horizontal menu bar with dropdown menus
The Menubar component provides a horizontal menu bar similar to desktop applications.
Basic Usage
Application Menubar
Icons
An item's icon is a kebab-case Lucide icon name, resolved against lucide's
runtime icons record — the same surface ui:dropdown-menu, ui:context-menu
and the action:* family resolve against. It is read on every arm that draws
an item: a top-level item, a submenu trigger, and an item inside a submenu, at any
depth. A name that is not a live key of that record (an unknown or a retired
spelling such as edit) renders no glyph, never a fallback glyph and never
the literal name as text.
Dividers
An item is either a command or a divider between groups of commands — never
both, and a divider never carries a label (objectui#6523). Author a divider
as { "separator": true }; the retired { "type": "separator" } spelling is
refused at parse time rather than silently ignored.
Schema
interface MenubarCommandItem {
label: string;
icon?: string;
shortcut?: string; // e.g. "Ctrl+T" — a single string, not an array
disabled?: boolean;
// RUNTIME SLOT (objectui#6124): a React host supplies it; JSON refuses it
// by name. Author behaviour as a node type, e.g. an action:button node.
onClick?: () => void; // Click handler
children?: MenubarItem[]; // Submenu items — drawn as a nested submenu
}
interface MenubarDividerItem {
separator: true; // renders as a divider — no label
}
type MenubarItem = MenubarCommandItem | MenubarDividerItem;
interface MenubarMenu {
label: string;
items: MenubarItem[];
}
interface MenubarSchema {
type: 'menubar';
menus?: MenubarMenu[]; // Menu definitions
className?: string;
}The item's onClick is a runtime slot a React host supplies through the
TypeScript MenuItem interface; it has no JSON spelling, and the validator
refuses it by name on the item. The menu schema itself declares no authorable
event slot either, so there is no menu-level onSelect.