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 notfalse
.
Known issues
- The first selected key is a key in a submenu,
autoFocus
being set to "first" or "last" won't work.
Menu
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.
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.
Render Item
s inside another Item
to create nested menu. The parent item's content is provided via title
prop, in
this case.
Dynamic API
While you can also dynamically map a list of objects to rendered Item
s, 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
.
MenuItemLayout
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.
Selection
Menu items can be marked as selected via selectedKeys
:
There is no onSelectedKeys
change callback. You should use onAction
and adjust selectedKeys
if needed.
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:
Full Example
MenuTrigger
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.
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.
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.
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.
Submenu Behaviour
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.