Skip to main content

Menu

Features

  • Nested menu items
  • Check-able menu items
  • Default menu layout with icon, text and keyboard shortcut
  • Full keyboard support
  • Viewport-aware positioning with respect to a trigger.
  • Toggle submenus by press, instead of hover. (example: Git Branches popup menu)
  • Ability to define action for menu items with submenu (Run Configurations dropdown menu)

Remaining

  • Advanced hover behaviour, which detects attempt to go to submenu and doesn't close the menu on mouse out.

Known differences

  • In the reference impl, hovering over disabled items removes previously highlighted menu item. Here it preserves it.
  • In the reference impl, there is a delay in opening submenu
  • Moving mouse out of the menu de-highlights currently highlighted menu, if it's not a menu item with a nested menu. Here menu items are not de-highlighted when mouse goes away from the menu.
  • If selectedKeys is passed and non-empty, it will be autofocused, irrespective of autoFocus value being true, "first" or "last", as long as autofocus is not false.

Known issues

  • The first selected key is a key in a submenu, autoFocus being set to "first" or "last" won't work.

Menu component implements the UI of the menu itself. While MenuTrigger implements how the menu is opened via a trigger and positioned with respect to it.

Similar to all collection components, there are two ways for defining menu items: as jsx, in children (static), and via items prop (dynamic).

Static API

Item component can be rendered in the children of Menu to define the menu items. It's best suited for the use cases where the menu items are static. Use key to give each item a unique identifier, which is used in props on onAction, or disabledKeys. If key is not provided, an index-based auto-generated key will be assigned to each item.

tip

If the content of an Item is not plain text, use textValue to specify the plain text value for the item. It's needed for making the menu item accessible via type-to-select.

tip

Render Items inside another Item to create nested menu. The parent item's content is provided via title prop, in this case.

Result
Loading...
Live Editor

Dynamic API

While you can also dynamically map a list of objects to rendered Items, items prop is designed for dynamically rendering menu items based on an array of objects. Then you use a render function in children, to specify how each item should be mapped to an Item or Section.

Result
Loading...
Live Editor

MenuItemLayout can be rendered inside Item, when plain text is not enough for a menu item. MenuItemLayout has three parts:

  • An icon rendered before the menu item text
  • The text content of the menu item
  • Shortcut rendered on the right side.
Result
Loading...
Live Editor

Selection

Menu items can be marked as selected via selectedKeys:

Result
Loading...
Live Editor

There is no onSelectedKeys change callback. You should use onAction and adjust selectedKeys if needed.

note

If a selected menu item renders MenuItemLayout with an icon, the checkmark icon will replace the menu item icon.

Disabled items

Menu items can be disabled through disabledKeys prop on the Menu:

Result
Loading...
Live Editor

Full Example

Result
Loading...
Live Editor

MenuTrigger links a menu to a trigger for the menu. It handles the opening/closing logic and renders the menu as an overlay, positioned with respect to the trigger element. children of MenuTrigger must be a render function which renders the trigger. It's invoked with props and ref to be passed down to the trigger element.

info

Currently, menu is closed when a menu action is triggered. For some actions (e.g. toggleable view options), that's not the best UX. In future releases, there will be a way to control if the menu should be kept open after the triggered action.

Result
Loading...
Live Editor

Positioning options

TODO

Controlled and uncontrolled

TODO

Focus restoration

Use restoreFocus to have focus restored to the trigger, after the menu is closed. While it's an accessibility best practice to restore the focus, restoreFocus is false by default. That is based on the observed majority of the use cases in Intellij Platform applications.

ContextMenu

ContextMenuContainer provides a generic container component that is capable of opening a context menu. You can use it as a wrapper for List, Tree, or anything else, to let them have a context menu.

Result
Loading...
Live Editor
info

In future versions, there might be an integrated support for context menu in List, Tree, etc. But for now it's done just by composition of those components and ContextMenuContainer. A caveat to have in mind is the extra wrapper element that will be added if you want context menu, which may need some styling to have no effect on the layout.

By default, menu items with submenu open the submenu on hover. Pressing such items also opens the submenu, if not already opened (e.g. when keyboard is used for navigation). Using submenuBehavior prop, this default behavior can be fine-tuned for specific use cases:

  • toggleOnPress:
  • actionOnPress:

SpeedSearchMenu

A drop-in replacement for Menu, which lets user filter items.

Result
Loading...
Live Editor