How to build an accessible Menu in React

The trigger exposes aria-haspopup="menu" and aria-expanded, the panel is role="menu" with role="menuitem" children, focus moves to the first enabled item on open, ArrowUp/ArrowDown rove focus between items, disabled items are aria-disabled and removed from the tab order, and separators use role="separator".

When to use a Menu

When not to use it

Keyboard interactions

Role menu, verified at WCAG 2.2-AA.

Common mistakes

Avoid: Using Menu items to pick a form value and showing the choice as selected

Prefer: Use Select for value selection; Menu items are one-shot actions

Menu items use role="menuitem" and close on activation — they are not selectable options and do not model a chosen value

Example

<Menu>
  <MenuTrigger>Options</MenuTrigger>
  <MenuItem onSelect={rename}>Rename</MenuItem>
  <MenuItem onSelect={duplicate}>Duplicate</MenuItem>
</Menu>

See the full Menu reference →