Version 0.10.0

Menu

A list of actions in a dropdown, enhanced with 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 is a wrapper component that combines a button or other trigger element with a menu displayed in a popover.
  • SubmenuTrigger is a wrapper component that combines a MenuItem with a menu displayed in a popover.

Containers#

  • Menu is a container component that contains a list of menu items or sections.
  • MenuListBox is a container component that contains a list of menu items or sections.
  • MenuAutocomplete is a container component that contains a list of menu items or sections.
  • MenuAutocompleteListbox is a container component that contains a list of menu items or sections.

Items#

  • MenuItem is an individual interactive item in the menu.
  • MenuListBoxItem is an individual interactive item in the menu list box.

Separators#

  • MenuSeparator is a component that renders a horizontal line to separate menu items.
  • MenuSection is a component that renders a section in the menu.

API reference#

MenuTrigger accepts exactly two children: the first child should be the trigger element, and second child should be one of the menu containers containing the menu.

PropTypeDefaultResponsive
isOpen
boolean
-No
defaultOpen
boolean
-No
onOpenChange
(isOpen: boolean) => void
-No

The SubmenuTrigger accepts exactly two children: the first child should be the MenuItem which triggers opening of the submenu, and second child should be one of the menu containers containing the submenu.

PropTypeDefaultResponsive
delay
number
200No

Menu is a container component that contains a list of menu items or sections.

PropTypeDefaultResponsive
disabledKeys
Iterable<Key>
-No
selectionMode
nonesinglemultiple
-No
selectedKeys
allIterable<Key>
-No
defaultSelectedKeys
allIterable<Key>
-No
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-No
virtualized
boolean
falseNo
maxWidth
number
-No
maxHeight
number
-No
className
string
-No
style
CSSProperties
-No

MenuListBox is a container component that contains a list of menu items or sections.

PropTypeDefaultResponsive
disabledKeys
Iterable<Key>
-No
selectionMode
nonesinglemultiple
-No
selectedKeys
allIterable<Key>
-No
defaultSelectedKeys
allIterable<Key>
-No
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-No
virtualized
boolean
falseNo
maxWidth
number
-No
maxHeight
number
-No
className
string
-No
style
CSSProperties
-No

MenuAutocomplete is a container component that contains a list of menu items or sections.

PropTypeDefaultResponsive
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-No
virtualized
boolean
falseNo
maxWidth
number
-No
maxHeight
number
-No
className
string
-No
style
CSSProperties
-No

MenuAutocompleteListbox is a container component that contains a list of menu items or sections.

PropTypeDefaultResponsive
placement
topbottomleftrighttop starttop endbottom startbottom endleft startleft endright startright end
-No
virtualized
boolean
falseNo
maxWidth
number
-No
maxHeight
number
-No
className
string
-No
style
CSSProperties
-No

MenuItem is an individual interactive item in the menu.

PropTypeDefaultResponsive
id
Key
-No
value
string
-No
textValue
string
-No
isDisabled
boolean
-No
href
string
-No
onAction
(event) => void
-No
className
string
-No
style
CSSProperties
-No

MenuListBoxItem is an individual interactive item in the menu list box.

PropTypeDefaultResponsive
id
Key
-No
value
string
-No
textValue
string
-No
isDisabled
boolean
-No
className
string
-No
style
CSSProperties
-No

MenuSection is a component that renders a section in the menu.

PropTypeDefaultResponsive
title
string
-No
className
string
-No
style
CSSProperties
-No

MenuSeparator is a component that renders a horizontal line to separate menu items.

PropTypeDefaultResponsive
className
string
-No
style
CSSProperties
-No

Examples#

Nested navigation#

You can nest menus to create a more complex navigation structure. It is important to use the placement prop to ensure the submenu is displayed in the correct position. The best practice is to use the right top placement for the submenu.

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

With icons#

You can use the iconStart prop to add an icon to the menu item.

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

You can use the href prop to add a link to the menu item. This is using our router provider under the hood to work for 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#

You can use the MenuSection component to add a section to the menu.

<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#

You can use the MenuSeparator component to add a separator to the menu.

<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#

You can use the MenuAutocomplete component to add a autocomplete to the menu.

<MenuAutocomplete label="Search" placeholder="Type to search...">
  <MenuItem>Option 1</MenuItem>
  <MenuItem>Option 2</MenuItem>
  <MenuItem>Option 3</MenuItem>
</MenuAutocomplete>

With list box#

You can use the MenuListBox component to add a list box to the menu.

<MenuAutocomplete label="Select an option" placeholder="Type to filter...">
  <MenuListBoxItem>Option 1</MenuListBoxItem>
  <MenuListBoxItem>Option 2</MenuListBoxItem>
  <MenuListBoxItem>Option 3</MenuListBoxItem>
</MenuAutocomplete>

With list box with multiple selection#

You can use the MenuListBox component to add a list box to the menu. You can also use the selectionMode prop to allow multiple selection.

<MenuAutocomplete
  label="Select multiple options"
  placeholder="Type to filter..."
  selectionMode="multiple"
>
  <MenuListBoxItem>Option 1</MenuListBoxItem>
  <MenuListBoxItem>Option 2</MenuListBoxItem>
  <MenuListBoxItem>Option 3</MenuListBoxItem>
</MenuAutocomplete>

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#

  • 0.9.0 - BREAKING: Changed className prop behavior to augment default styles instead of being ignored or overriding them.

Affected components:

  • Menu, MenuListBox, MenuAutocomplete, MenuAutocompleteListbox, MenuItem, MenuListBoxItem, MenuSection, MenuSeparator
  • Switch
  • Skeleton
  • FieldLabel
  • Header, HeaderToolbar
  • HeaderPage
  • Tabs, TabList, Tab, TabPanel

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

  • 0.9.0 - Improved visual consistency of PasswordField, SearchField, and MenuAutocomplete components. #31679
  • 0.8.0 - Fix scroll jumping when opening menu in Backstage UI. #31394
  • 0.8.0 - Add new virtualized, maxWidth and maxHeight props to Menu, MenuListBox, MenuAutocomplete and MenuAutocompleteListBox to allow for virtalization of long lists inside menus. #31375
  • 0.8.0 - Using react router for internal links in the Menu component #31339
  • 0.7.2 - Using react router for internal links in the Menu component #31339
  • 0.7.0 - Breaking change We are updating the Menu component to use React Aria under the hood. The structure and all props are changing to follow React Aria's guidance. #30908
  • 0.7.0 - Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17. #30675
  • 0.7.0 - Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17. #30675
  • 0.4.0 - Add combobox option to Menu #29986
  • 0.4.0 - Improve Menu styles #29986
  • 0.3.0 - Update Menu styles #29351
  • 0.2.0 - New Menu component #29151