Skip to content

Menu

Status: stableAccessibility reviewedtenet-ui@0.4.0
Import
import { Menu } from 'tenet-ui';

Source: src/components/Menu/Menu.tsx

When to use: a list of actions triggered from a button (a row’s ”⋯” overflow, a “New ▾” split of choices). For picking a value from a list use Select; for navigation use links.

  • Pass a focusable trigger (a Button) — it’s wired with aria-haspopup="menu", aria-expanded, and open/close handling. Each item runs its onSelect and the menu closes.
  • Give an aria-label describing the menu (e.g. “Repository actions”); otherwise it falls back to the trigger’s text.
  • Keyboard + ARIA are handled: arrows move, Enter/Space invoke, Escape closes and returns focus to the trigger, click-outside closes. Don’t rebuild this with a div of onClick rows.
  • Mark dangerous actions destructive (renders in the danger color); use a { type: 'separator' } to group. Keep menus short — long lists belong in a Select or a dedicated page.
  • <Menu aria-label="Row actions" trigger={<IconButton icon={<MoreHorizontalIcon />} aria-label="Row actions" />} items={[{label:'Edit',onSelect},{type:'separator'},{label:'Delete',onSelect,destructive:true}]} />
  • ❌ Using a Menu to choose a value that should persist in a field — that’s Select.
  • ❌ A non-focusable trigger (plain <div>).

See also: IconButton as the overflow trigger, Select for values, Popover for arbitrary content.

1 story for Menu — open in Storybook

The full matrix (all args, controls, accessibility panel) is in Storybook.

PropTypeDefaultDescription
trigger *ReactElementThe trigger element (e.g. a Button). It is wired with the menu's aria + click handling.
items *MenuItem[]The actions to show.
aria-labelstringtrigger labelAccessible name for the menu.
align'start' | 'end'startMenu alignment relative to the trigger.
classNamestring

* required

MenuAction

MemberTypeDefaultDescription
type'item'
label *ReactNodeVisible label.
onSelect *() => voidInvoked when the item is chosen (menu then closes).
iconReactNodeOptional leading icon.
disabledbooleanDisable this item.
destructivebooleanRender in the danger color for destructive actions.

MenuSeparator

MemberTypeDefaultDescription
type *'separator'