A menu of actions that opens from a trigger button, with icons, shortcut hints, dividers ({ key, divider: true }) and tone="danger" items. Arrow keys move, Home / End jump, Enter or Space chooses, and Escape closes the menu and returns focus to the trigger. Outside clicks close it. Items take the same fields as ActionMenu: description, badge, href (a real link, with linkComponent / linkProp for router links), tone="warning" and hasDialog. For a plain, flat list of page actions, ActionMenu is lighter.

Last action: nothing yet

Nested menus: give an item children to make it open a submenu, to any depth. Hovering the item or pressing Right opens it, Left or Escape closes just that level, and a click anywhere in an open submenu counts as inside the menu.

Last action: nothing yet. Try the arrow keys: Right opens a submenu, Left closes it.

Leave out trigger and pass anchorRef with open / onOpenChange to anchor the menu to your own element and control it yourself.

Controlled with open and anchorRef. Last action: nothing yet

Same look as ActionMenu: look="actions" gives the menu ActionMenu's appearance (uppercase labels, ruled rows, a fixed width), also in submenus. Use it when the app shows both menus, or when an action menu needs a submenu.

Headings: an item with a heading is a group label, not an item. The items after it, up to the next heading or divider, are grouped under it for screen readers (role="group"), and arrow keys skip it. It works in both looks. Or nest them: an item with items is a group, its label is the heading, and the items go inside it (dividers and submenus work there too).

Props

  • itemsMenuItem[]

    The entries. children makes a submenu; { key, divider: true } is a separator. See the MenuItem table below.

  • triggerReactNode

    Content of the trigger button; leave it out to use anchorRef.

  • labelstring

    Accessible name of the trigger and the menu.

  • variant'default' | 'secondary' | 'flat' | 'success' | 'danger' | 'warning'
    Default: 'secondary'

    Style of the trigger button.

  • placement'bottom-start' | 'bottom-end' | 'top-start' | ...
    Default: 'bottom-start'

    Where the menu opens; it flips when there is no room.

  • look'default' | 'actions'
    Default: 'default'

    The look of the menu: "actions" matches ActionMenu (uppercase labels, ruled rows, a fixed width); the default is the compact one.

  • linkComponentElementType
    Default: 'a'

    Component used for items with a site path as href (not absolute URLs), e.g. a router Link.

  • linkPropstring
    Default: 'href'

    Prop that receives the href on linkComponent, e.g. "to".

  • openboolean

    Open state (controlled).

  • defaultOpenboolean
    Default: false

    Initial open state when uncontrolled.

  • onOpenChange(open: boolean) => void

    Called when it opens or closes.

  • anchorRefRefObject<HTMLElement>

    Element the menu is placed next to when there is no trigger.

  • classNamestring
    Default: ''

    Extra classes for the root element.

  • keystring

    Unique key of the item.

  • labelReactNode

    Text of the item (not needed for a divider or heading).

  • headingReactNode

    A group label instead of an item; the items after it, up to the next heading or divider, are grouped under it.

  • itemsMenuItem[]

    Makes the item a group: its label is the heading and these are the items under it (dividers and submenus work inside).

  • iconReactNode

    Shown before the label, hidden from screen readers.

  • descriptionReactNode

    A smaller grey line under the label.

  • badgeReactNode

    Short value at the end of the row, e.g. a count.

  • shortcutstring

    A keyboard shortcut hint at the end, e.g. "Ctrl+C" (display only).

  • disabledboolean
    Default: false

    Dim the item and ignore it.

  • tone'default' | 'warning' | 'danger'
    Default: 'default'

    Color of the item; "danger" is red, for destructive actions.

  • hasDialogboolean
    Default: false

    Marks an item that opens a dialog (aria-haspopup="dialog").

  • hrefstring

    Makes the item a real link instead of a button; onClick is then optional.

  • targetstring

    For link items: where to open it. "_blank" opens a new tab and adds rel="noopener noreferrer".

  • externalboolean

    Show the external-link arrow. By default a link is external when it has target="_blank" or an absolute http(s) address.

  • onClick() => void

    Called when the item is chosen.

  • childrenMenuItem[]

    Makes the item open a submenu with these items.

  • dividerboolean
    Default: false

    A separator line instead of an item (only key is needed).