Skip to content
EspañolEnglish
All components (204)

Menubar

Navigation · Menubar · .amset-menubar

What it is and when to use it

A menu bar like the ones in a desktop application: File, Edit, View, each with its list of actions.

When to use it

  • In a tool with many actions grouped by topic: an editor, an admin panel, a viewer.
  • When whoever uses it expects to move from one menu to another with the mouse or the arrows without closing them.

When not to

  • For the actions of a row or of a specific object: that is an ActionMenu.
  • For a site's navigation, which is links: that is a NavigationMenu.
  • With fewer than three menus: buttons or an ActionMenu are enough.

Keyboard: the bar is a single tab stop and the left and right arrows move from one menu to its neighbour, wrapping around (the other way round in a right-to-left language). Down or Enter open and enter by the first action, up enters by the last; with a menu open, the side arrows open the neighbour. Typing jumps to the action that starts that way. Escape closes returning focus, and Tab closes and carries on outwards.

Accessibility: it is a named role="menubar"; each menu is a menuitem with aria-haspopup and aria-expanded. A switched-off menu carries aria-disabled and cannot be reached with the keyboard. The actions, submenus and sections are those of ActionMenu.

With the mouse: with a menu open, hovering another opens it; with all closed it opens nothing. That is why it is a non-modal layer, unlike ActionMenu, which makes the rest of the page inert.

Fine-tuning: CSS variable --amset-menubar-height (height of each button in the bar).

What it looks like

Open a menu and move to the next one with the arrow keys.

<Menubar
  label="Application menu"
  menus={[
    { key: "archivo", label: "File", actions: [{ key: "nuevo", label: "New order", detail: "Ctrl+N" }] },
    { key: "editar", label: "Edit", actions: [{ key: "deshacer", label: "Undo", detail: "Ctrl+Z" }] },
  ]}
  onSelect={(accion, menu) => ejecutar(menu, accion)}
/>

Props

Import it with import { Menubar } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
labelrequiredstringWhat the bar is, for the screen reader: "Application menu".
menusrequiredreadonly MenubarMenu[]—
onSelectrequired(key: string, menu: string) => voidCalled with the chosen action and the menu it belongs to, and the menu closes.
classNamestringMerged with the library classes; it does not replace them.
minWidthstring—
offsetnumberSeparation in pixels between the bar and the panel.
size"sm" | "md" | "lg"—

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

CSS variables

These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.

VariableDefault
--amset-menubar-heightvar(--amset-height-control)

How to change it

.amset-menubar {
  --amset-menubar-height: ...;
}

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: