Menu

Menus display a list of choices on a temporary surface.

One family, one documentation

Menu, MenuItem, MenuSubmenu, MenuGroup, MenuHeadline and ContextMenu form a single family. This page is their shared documentation; each component keeps a dedicated API reference:

All adapters use the same core contract, the same styles and the same keyboard navigation engine.

Choosing the right semantics

Use purpose="actions" (the default) for commands. The container then exposes menu and its items expose menuitem, menuitemradio or menuitemcheckbox.

Use purpose="selection" for a list of options. The container becomes a listbox, the items become options and their state is announced with aria-selected.

accessibleLabel names the menu when no external label is linked to it.

Composition

  • MenuItem represents a command or a choice.
  • MenuSubmenu represents a command that opens another actions menu.
  • MenuGroup groups items and its label names the group.
  • MenuHeadline is a non-interactive visual marker. It does not replace the semantic label of a MenuGroup. In a menu made of groups, place it inside the relevant MenuGroup so it stays within its surface.
  • ContextMenu opens an actions menu at the pointer position or via Shift+F10.

Variants, icons and states

variant="standard" uses the neutral surface. variant="vibrant" applies the family color to the whole composition. Leading and trailing icons remain optional; a disabled item keeps its structure but receives no interaction or state layer. In an actions menu, a leading icon on any command aligns the labels of the other action rows to the same icon column. Selection toggles keep their own checkmark column. MenuItem.trailingIcon stays decorative; it can mark a link such as “Open API reference” with an open-in-new icon. Use MenuSubmenu when the row should open another menu.

When there is no MenuGroup, a MenuHeadline can be placed directly inside Menu.

Nested action menus

Use MenuSubmenu for a row that opens another actions menu. It inherits the parent variant, opens on pointer hover or click, and supports Arrow Right to open and focus the first child (Arrow Left in RTL). The opposite arrow or Escape closes it and returns focus to the trigger. A child command closes its submenu; a checkbox toggle keeps it open.

Controlled and uncontrolled selection

A selectable item declares selectionType="single" or selectionType="multiple".

  • In React, control it with selected and onSelectedChange.
  • In Angular, use selected and selectedChange, including with [(selected)].
  • In Svelte, use bind:selected or selected with onSelectedChange.
  • defaultSelected initializes an uncontrolled item.
  • An already selected single item does not deselect itself; the group’s owner picks the new value.

The former names activated and onToggle were removed: they mixed resolved state with the event, and did not distinguish single from multiple selection.

The following example brings both models together:

  • an actions menu with radio choices (single) and checkboxes (multiple);
  • a list of options with purpose="selection";
  • controlled states and one state initialized with defaultSelected.

With href, a MenuItem becomes a native link. A disabled link loses its destination and leaves the tab order. When the content exceeds the menu’s maximum height, the surface becomes scrollable without changing keyboard navigation.

TextField with type="select" opens a purpose="selection" surface, controls the selected value and closes the menu after the choice. Both adapters share this behavior; only the way options are declared differs:

  • in React, compose MenuItem children directly, or pass options;
  • in Angular, options is the only way to populate the menu: the adapter does not project custom MenuItems.
  • in Svelte, options is also the select-field model; custom MenuItem children are not projected by this mode.

Context menu

The context menu opens on secondary click or with Shift+F10. It moves focus to the first available item. Escape closes the popup and restores focus to the trigger; an outside click or a scroll also closes it.

Keyboard navigation

In an open menu:

  • Arrow down/up moves focus and wraps at both ends.
  • Arrow Right opens a focused submenu trigger and Arrow Left returns to its parent (the directions reverse in RTL).
  • Home/End goes to the first/last available item.
  • Typing a character searches for the next matching label.
  • Disabled items are skipped.