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.
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.
Preview
Section titled “Preview”<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-menu-item value="close" destructive shortcut="⌘W">
Close
</nana-menu-item>
</nana-menubar-menu>
<nana-menubar-menu label="Edit">
<nana-menu-item value="undo" shortcut="⌘Z">Undo</nana-menu-item>
<nana-menu-item value="redo" shortcut="⇧⌘Z">Redo</nana-menu-item>
</nana-menubar-menu>
</nana-menubar> Installation
Section titled “Installation”npm install @nana-tec/ui-componentsImport
Section titled “Import”import "@nana-tec/ui-components/menubar-menu";Already registered if you imported @nana-tec/ui-components/menubar.
Basic usage
Section titled “Basic usage”<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.
Trigger
Section titled “Trigger”The default trigger is the label. Pass a custom one through the trigger
slot — for example to add an icon.
<nana-menubar bordered>
<nana-menubar-menu>
<button
slot="trigger"
style="
display: flex;
align-items: center;
gap: 0.375rem;
padding: 0.25rem 0.5rem;
border: 1px solid #d7e1df;
border-radius: 0.375rem;
background: #fff;
cursor: pointer;
"
>
<nana-icon name="account_circle"></nana-icon>
User
</button>
<nana-menu-item value="profile">Profile</nana-menu-item>
<nana-menu-item value="logout" destructive>Logout</nana-menu-item>
</nana-menubar-menu>
</nana-menubar> Open state
Section titled “Open state”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
Section titled “Disabled”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>Menu content
Section titled “Menu content”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.
<nana-menubar bordered>
<nana-menubar-menu label="File">
<nana-menu-item value="new" shortcut="⌘N">New file</nana-menu-item>
<nana-menu-item value="open" shortcut="⌘O">Open…</nana-menu-item>
<hr />
<nana-menu-label>Recent</nana-menu-label>
<nana-menu-item value="doc1">design-system.md</nana-menu-item>
<nana-menu-item value="doc2">tokens.json</nana-menu-item>
<hr />
<nana-menu-item value="delete" destructive>Delete</nana-menu-item>
</nana-menubar-menu>
</nana-menubar> Alignment & max height
Section titled “Alignment & max height”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.
Branding
Section titled “Branding”--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>Listening for a selection
Section titled “Listening for a selection”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.
Keyboard
Section titled “Keyboard”| Key | When closed | When 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
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
disabled | disabled | boolean | false | Disable the whole menu |
label | label | string | '' | Top-level label (default trigger only) |
open | open | boolean | false | Open state |
Events
| Event | Description |
|---|---|
nana-select | Bubbled from a chosen item (detail.value) |
nana-menubar-toggle | The trigger was activated; the parent menubar closes its siblings |
nana-menubar-peek | The trigger was hovered while another menu is open, so the bar should switch to this one |
nana-menubar-dismiss | An item was chosen, so the whole bar should close |
Slots
| Slot | Description |
|---|---|
trigger | Custom trigger content (falls back to the label text) |
(default) | nana-menu-item / nana-menu-label / <hr> children |
CSS parts
| Part | Description |
|---|---|
::part(trigger) | The top-level button |
::part(panel) | The floating panel |
CSS custom properties
| Property | Description |
|---|---|
--nana-menubar-accent | Brand accent for the trigger + dropdown rows |
--nana-menubar-accent-soft | Soft accent for trigger hover/focus |
--nana-menubar-on-accent | Text colour on the accent fill |
--nana-menubar-panel-min-width | Panel min width |
--nana-menubar-panel-bg | Panel background |
--nana-menubar-font-size | Trigger and item text size |
--nana-menubar-panel-blur | Backdrop blur behind the dropdown panel |
--nana-menubar-panel-max-height | Panel height before its items scroll |
--nana-menubar-panel-radius | Dropdown panel corner radius |
--nana-menubar-trigger-radius | Trigger corner radius |
--nana-menubar-z | Stacking order for the dropdown panel |
Accessibility
Section titled “Accessibility”- The trigger is a real
<button>witharia-haspopup="menu"and livearia-expanded. - The panel is
role="menu"witharia-labelset fromlabel(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.