Skip to content
Nana UI

Navigation

Menubar Menu

A single top-level menu within a nana-menubar — a labelled trigger that reveals a dropdown of nana-menu-item rows. The parent menubar coordinates opening, sibling switching and keyboard roving; on its own it still works as a self-contained click-to-open menu button.

View .md Download

A single top-level menu within a nana-menubar — a labelled trigger that reveals a dropdown of nana-menu-item rows. The parent menubar coordinates opening, sibling switching and keyboard roving; on its own it still works as a self-contained click-to-open menu button.

New Open Close Undo Redo
npm install @nana-tec/ui-components
import "@nana-tec/ui-components/menubar-menu";

Already registered if you imported @nana-tec/ui-components/menubar.

<nana-menubar bordered>
<nana-menubar-menu label="File">
<nana-menu-item value="new" shortcut="⌘N">New</nana-menu-item>
<nana-menu-item value="open" shortcut="⌘O">Open…</nana-menu-item>
</nana-menubar-menu>
</nana-menubar>

If you use it outside a menubar, give it an explicit label and it behaves as a click-to-toggle menu button — the menubar-specific events still fire but no parent coordinates them.

The default trigger is the label. Pass a custom one through the trigger slot — for example to add an icon.

Profile Logout

open reflects whether the dropdown is shown. The parent nana-menubar toggles this in response to clicks, hovers and keys. Setting it yourself opens or closes the panel (it still auto-dismisses on outside clicks and Escape when used within a menubar).

<nana-menubar-menu label="View" open>
<nana-menu-item value="list">List</nana-menu-item>
<nana-menu-item value="grid">Grid</nana-menu-item>
</nana-menubar-menu>

disabled greys the trigger, makes it non-interactive and removes it from the menubar’s roving tabindex.

<nana-menubar bordered>
<nana-menubar-menu label="File">
<nana-menu-item value="new">New</nana-menu-item>
</nana-menubar-menu>
<nana-menubar-menu label="Admin" disabled>
<nana-menu-item value="settings">Settings</nana-menu-item>
</nana-menubar-menu>
</nana-menubar>

The panel accepts nana-menu-item, nana-menu-label, and <hr> elements (via the default slot). A divider (<hr>) visually separates groups. Items can be destructive, carry a shortcut, be disabled, or link out with href.

New file Open…
Recent design-system.md tokens.json
Delete

The panel flips to data-align="end" when it would overflow the right edge of the viewport, so it never goes off-screen. --nana-menubar-panel-max-height controls when its items scroll internally — useful for long lists.

--nana-menubar-accent, --nana-menubar-accent-soft, and --nana-menubar-on-accent are resolved on the host and pushed down to slotted nana-menu-item rows. Set them on the menu (or an ancestor) to brand triggers and their dropdown items together.

<nana-menubar-menu label="Team" style="--nana-menubar-accent:#7c3aed">
<nana-menu-item value="invite">Invite</nana-menu-item>
</nana-menubar-menu>

nana-select bubbles when a child item is chosen — that is the event an application listens for:

document.querySelector("nana-menubar").addEventListener("nana-select", (e) => {
console.log(e.detail.value);
});

The other three events are internal coordination, used by the parent nana-menubar to close siblings, switch on hover, and dismiss the whole bar. They are all listed in the API table below.

KeyWhen closedWhen open
Enter Space ↓Open and focus the first enabled item; emit nana-menubar-toggle—
↑Open and focus the last enabled item; emit nana-menubar-toggle—
↓—Move focus to the next enabled item (wraps to first)
↑—Move focus to the previous enabled item (wraps to last)
Home End—Focus first / last enabled item
Escape—Close the menu and return focus to the trigger
Tab—Let the browser move focus (the menu may close depending on context)

Menu items handle typeahead within the panel themselves; the menu only moves by index in response to arrows/Home/End/Escape.

Properties

PropertyAttributeTypeDefaultDescription
disableddisabledbooleanfalseDisable the whole menu
labellabelstring''Top-level label (default trigger only)
openopenbooleanfalseOpen state

Events

EventDescription
nana-selectBubbled from a chosen item (detail.value)
nana-menubar-toggleThe trigger was activated; the parent menubar closes its siblings
nana-menubar-peekThe trigger was hovered while another menu is open, so the bar should switch to this one
nana-menubar-dismissAn item was chosen, so the whole bar should close

Slots

SlotDescription
triggerCustom trigger content (falls back to the label text)
(default)nana-menu-item / nana-menu-label / <hr> children

CSS parts

PartDescription
::part(trigger)The top-level button
::part(panel)The floating panel

CSS custom properties

PropertyDescription
--nana-menubar-accentBrand accent for the trigger + dropdown rows
--nana-menubar-accent-softSoft accent for trigger hover/focus
--nana-menubar-on-accentText colour on the accent fill
--nana-menubar-panel-min-widthPanel min width
--nana-menubar-panel-bgPanel background
--nana-menubar-font-sizeTrigger and item text size
--nana-menubar-panel-blurBackdrop blur behind the dropdown panel
--nana-menubar-panel-max-heightPanel height before its items scroll
--nana-menubar-panel-radiusDropdown panel corner radius
--nana-menubar-trigger-radiusTrigger corner radius
--nana-menubar-zStacking order for the dropdown panel
  • The trigger is a real <button> with aria-haspopup="menu" and live aria-expanded.
  • The panel is role="menu" with aria-label set from label (or “Menu”).
  • Focus is managed by roving tabindex across items when open; the trigger remains the only tabbable thing when closed.
  • Works with the nana-menubar’s WAI-ARIA menubar pattern for application menus.
Explore Menubar Menu interactively Every state, prop, and edge case — with live controls — in Storybook.
View in Storybook