Version 0.11.2

Menu

A dropdown menu with actions, submenus, sections, and keyboard navigation.

Usage#

import { MenuTrigger, Menu, MenuItem } from '@backstage/ui';

<MenuTrigger>
  <Button>Menu</Button>
  <Menu>
    <MenuItem>Item 1</MenuItem>
    <MenuItem>Item 2</MenuItem>
  </Menu>
</MenuTrigger>

Triggers#

  • MenuTrigger combines a trigger element with a menu popover.
  • SubmenuTrigger combines a MenuItem with a nested submenu.

Containers#

  • Menu contains menu items or sections.
  • MenuListBox supports selection with checkmarks.
  • MenuAutocomplete adds a search input to filter items.
  • MenuAutocompleteListbox combines search with selection.

Items#

  • MenuItem is an interactive action in the menu.
  • MenuListBoxItem is a selectable item in a list box.

Grouping#

  • MenuSection groups items with a title.
  • MenuSeparator adds a horizontal divider.

API reference#

Accepts two children: the trigger element and a menu container.

PropTypeDefaultDescription
isOpen
boolean
-Controlled open state of the menu.
defaultOpen
boolean
-Whether the menu is open by default.
onOpenChange
(isOpen: boolean) => void
-Handler called when the open state changes.

Inherits all React Aria MenuTrigger props.

Accepts two children: a MenuItem and a menu container.

PropTypeDefaultDescription
delay
number
200Delay in milliseconds before the submenu opens on hover.

Inherits all React Aria SubmenuTrigger props.

PropTypeDefaultDescription
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-Position of the menu relative to the trigger.
onAction
(key: Key) => void
-Handler called when an item is activated. Receives the item key.
selectionMode
nonesinglemultiple
-How items can be selected.
selectedKeys
Iterable<Key>
-Controlled selected keys.
defaultSelectedKeys
Iterable<Key>
-Default selected keys for uncontrolled usage.
disabledKeys
Iterable<Key>
-Keys of items that are disabled.
virtualized
boolean
-Enable virtualization for large lists.
maxWidth
string
-Maximum width of the menu popover.
maxHeight
string
-Maximum height of the menu popover.
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria Menu props.

PropTypeDefaultDescription
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-Position of the list box relative to the trigger.
selectionMode
nonesinglemultiple
-How items can be selected.
selectedKeys
Iterable<Key>
-Controlled selected keys.
defaultSelectedKeys
Iterable<Key>
-Default selected keys for uncontrolled usage.
onSelectionChange
(keys: Selection) => void
-Handler called when selection changes.
disabledKeys
Iterable<Key>
-Keys of items that are disabled.
virtualized
boolean
-Enable virtualization for large lists.
maxWidth
string
-Maximum width of the list box popover.
maxHeight
string
-Maximum height of the list box popover.
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria ListBox props.

PropTypeDefaultDescription
placeholder
string
-Placeholder text for the search input.
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-Position of the menu relative to the trigger.
onAction
(key: Key) => void
-Handler called when an item is activated. Receives the item key.
selectionMode
nonesinglemultiple
-How items can be selected.
selectedKeys
Iterable<Key>
-Controlled selected keys.
defaultSelectedKeys
Iterable<Key>
-Default selected keys for uncontrolled usage.
disabledKeys
Iterable<Key>
-Keys of items that are disabled.
onSelectionChange
(keys: Selection) => void
-Handler called when selection changes.
virtualized
boolean
-Enable virtualization for large lists.
maxWidth
string
-Maximum width of the menu popover.
maxHeight
string
-Maximum height of the menu popover.
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria Menu props.

PropTypeDefaultDescription
placeholder
string
-Placeholder text for the search input.
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-Position of the list box relative to the trigger.
selectionMode
nonesinglemultiple
-How items can be selected.
selectedKeys
Iterable<Key>
-Controlled selected keys.
defaultSelectedKeys
Iterable<Key>
-Default selected keys for uncontrolled usage.
onSelectionChange
(keys: Selection) => void
-Handler called when selection changes.
virtualized
boolean
-Enable virtualization for large lists.
maxWidth
string
-Maximum width of the list box popover.
maxHeight
string
-Maximum height of the list box popover.
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria ListBox props.

PropTypeDefaultDescription
children
ReactNode
-Content displayed in the menu item.
id
Key
-Unique key for the item.
iconStart
ReactNode
-Icon displayed before the item content.
color
primarydanger
-Color variant. Use danger for destructive actions.
href
string
-URL to navigate to when the item is clicked.
isDisabled
boolean
-Whether the item is disabled.
textValue
string
-Text used for typeahead and accessibility.
onAction
() => void
-Handler called when the item is activated.
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria MenuItem props.

PropTypeDefaultDescription
children
ReactNode
-Content displayed in the list box item.
id
Key
-Unique key for the item.
textValue
string
-Text used for typeahead and accessibility.
isDisabled
boolean
-Whether the item is disabled.
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria ListBoxItem props.

PropTypeDefaultDescription
title
string
-Heading displayed above the section.
children
ReactNode
-Menu items within the section.
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria MenuSection props.

PropTypeDefaultDescription
className
string
-Additional CSS class name for custom styling.

Inherits all React Aria Separator props.

Examples#

Nested navigation#

Submenus open to the right of their parent item.

<MenuTrigger>
  <Button variant="secondary">Menu</Button>
  <Menu>
    <MenuItem>New File</MenuItem>
    <SubmenuTrigger>
      <MenuItem>Open Recent</MenuItem>
      <Menu placement="right top">
        <MenuItem>File 1.txt</MenuItem>
        <MenuItem>File 2.txt</MenuItem>
      </Menu>
    </SubmenuTrigger>
    <MenuItem>Save</MenuItem>
  </Menu>
</MenuTrigger>

With icons#

<MenuTrigger>
  <Button variant="secondary">Menu</Button>
  <Menu>
    <MenuItem iconStart={<RiFileLine />}>New File</MenuItem>
    <MenuItem iconStart={<RiFolderLine />}>New Folder</MenuItem>
    <MenuItem iconStart={<RiImageLine />}>New Image</MenuItem>
  </Menu>
</MenuTrigger>

The href prop works with both internal and external links.

<MenuTrigger>
  <Button variant="secondary">Menu</Button>
  <Menu>
    <MenuItem href="/home">Home</MenuItem>
    <MenuItem href="/about">About</MenuItem>
    <MenuItem href="/contact">Contact</MenuItem>
  </Menu>
</MenuTrigger>

With sections#

<MenuTrigger>
  <Button variant="secondary">Menu</Button>
  <Menu>
    <MenuSection title="File">
      <MenuItem>New</MenuItem>
      <MenuItem>Open</MenuItem>
    </MenuSection>
    <MenuSection title="Edit">
      <MenuItem>Cut</MenuItem>
      <MenuItem>Copy</MenuItem>
      <MenuItem>Paste</MenuItem>
    </MenuSection>
  </Menu>
</MenuTrigger>

With separators#

<MenuTrigger>
  <Button variant="secondary">Menu</Button>
  <Menu>
    <MenuItem>New</MenuItem>
    <MenuItem>Open</MenuItem>
    <MenuSeparator />
    <MenuItem>Save</MenuItem>
    <MenuItem>Save As...</MenuItem>
  </Menu>
</MenuTrigger>

With autocomplete#

<MenuTrigger>
  <Button variant="secondary">Search</Button>
  <MenuAutocomplete placeholder="Type to search...">
    <MenuItem>Option 1</MenuItem>
    <MenuItem>Option 2</MenuItem>
    <MenuItem>Option 3</MenuItem>
  </MenuAutocomplete>
</MenuTrigger>

With list box#

<MenuTrigger>
  <Button variant="secondary">Select</Button>
  <MenuAutocompleteListbox placeholder="Type to filter...">
    <MenuListBoxItem>Option 1</MenuListBoxItem>
    <MenuListBoxItem>Option 2</MenuListBoxItem>
    <MenuListBoxItem>Option 3</MenuListBoxItem>
  </MenuAutocompleteListbox>
</MenuTrigger>

Multiple selection#

Set selectionMode="multiple" to allow multiple selections.

<MenuTrigger>
  <Button variant="secondary">Multi-select</Button>
  <MenuAutocompleteListbox
    placeholder="Type to filter..."
    selectionMode="multiple"
  >
    <MenuListBoxItem>Option 1</MenuListBoxItem>
    <MenuListBoxItem>Option 2</MenuListBoxItem>
    <MenuListBoxItem>Option 3</MenuListBoxItem>
  </MenuAutocompleteListbox>
</MenuTrigger>

Theming#

Our theming system is based on a mix between CSS classes, CSS variables and data attributes. If you want to customise this component, you can use one of these class names below.

  • bui-Menu
  • bui-MenuPopover
  • bui-MenuContent
  • bui-MenuSection
  • bui-MenuSectionHeader
  • bui-MenuItem
  • bui-MenuItemListBox
  • bui-MenuItemListBoxCheck
  • bui-MenuItemWrapper
  • bui-MenuItemContent
  • bui-MenuItemArrow
  • bui-MenuSeparator
  • bui-MenuSearchField
  • bui-MenuSearchFieldInput
  • bui-MenuSearchFieldClear
  • bui-MenuEmptyState

Changelog#

Version 0.11.0#

Changes

  • Fixed Menu component trigger button not toggling correctly. Removed custom click-outside handler that was interfering with React Aria's built-in state management, allowing the menu to properly open and close when clicking the trigger button. #32347

Version 0.9.0#

Breaking Changes

  • Breaking Changed className prop behavior to augment default styles instead of being ignored or overriding them.

    If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. #31496