Menu

Menus display a list of up to 15 options when launched by an action or UI element like an icon or button.

GitHubStorybook
yarn add @workday/canvas-kit-preview-react
Sources
GitHubStorybook
Install
yarn add @workday/canvas-kit-preview-react

Anatomy

Image of a Popup Menu sample showing different possible states.

  1. Container: Rectangular container that houses the icon and text for menu list items.
  2. Text: Text for indicating where the link leads to when the menu is clicked on. Text can overflow to the next line but avoid going over more than two lines of text.
  3. Icons: Icons are optional and can be positioned before or after the text.

Usage Guidance

  • Popup Menus can appear next to, in front of, above, or below the element that launched them, such as Dropdown Buttons, Dropdown Icons, Icon Buttons or by right-clicking a contextual item.
  • Popup Menus should overlap and visually look like they are in front of other UI elements. They should always be positioned within the viewable areas of the screen and be 8px away from the element that launched them.
  • Popup Menus should always contain a list of menu selections, which are options users can choose from. The list should be scannable, kept as concise as possible, and written in title case instead of sentences.
  • Consider how important each option is. The list of options should be sorted in a logical order, such as alphabetical, chronological, order of importance, and so on.

When to Use

  • In most cases, as with Overflow Menus, where there aren't enough space on screen to show all the actions, there could be between 1-7 items to choose from. However, there shouldn't be more than 15 items listed at once on a single Popup Menu.
  • When users must make a single selection from the list of options.

When to Use Something Else

  • Consider using a Switch if the only options are yes or no.
  • For a list between 2 to 7 predefined options, consider using Radio Buttons to select one option or Checkboxes to select multiple options. Radio and Checkbox groups display all options upfront and do not require the user to interact with the input to view the list of options.
  • Use a Prompt when the number of list items is large or unknown. Prompts have search capabilities and folders which provide users with the means to browse options. Prompts can be configured to support single or multi-select.

Examples

Basic Example

Menu is typically triggered by an action such as pressing a button. Here's an example of how you might implement that behavior using a Popup.

Menu will automatically assign focus to itself when it appears provided you set the isOpen prop correctly, so you do not need to use the useInitialFocus Popup hook. You will, however, need to use useReturnFocus to return focus back to the triggering button after closing the Menu.

Menu follows the Actions Menu pattern using aria-activedescendant. Below is table of supported keyboard shortcuts and associated actions.

KeyAction
Enter or SpaceActivates the menu item and then closes the menu
EscapeCloses the menu
Up ArrowMoves focus to the previous menu item – if focus is on first menu item, it moves focus to the last menu item
Down ArrowMoves focus to the next menu item – if focus is on last menu item, it moves focus to the first menu item
HomeMoves focus to the first menu item
EndMoves focus to the last menu item
A-Z / a-zMoves focus to the next menu item with a label that starts with the typed character if such an menu item exists – otherwise, focus does not move

Note that although Menu includes support for keyboard shortcuts for the menu itself, you'll need to add your own keyboard handling and aria attributes to the triggering button.

Context Menu

Right click on this text (Context menu target)

Custom Menu Item

Menu renders a styled <ul> element with a role of menu, and MenuItems are <li> elements with the correct attributes to ensure they are accessible. If you choose to implement your own custom menu items, be sure to use semantic <li> elements with the following attributes:

  • role="menuitem"
  • tabindex={-1}

Below is an example:

Icons

Many Items

Component API

Usage

Menu renders a styled <ul role="menu"> element within a Card and follows the Active Menu pattern using aria-activedescendant.

Props

Undocumented props are spread to the underlying <ul> element.

NameTypeDefaultDescription
isOpenboolean | undefinedtrueIf true, set the Menu to the open state. Useful for showing and hiding the Menu from a parent component such as a menu button.
widthstring | number | undefinedThe width of the Menu. If no value is provided, the Menu will collapse around its content.
onSelect(() => void) | undefinedThe function called when a menu item is selected.
onClose(() => void) | undefinedThe function called when the Menu should close. This is called after a menu item is selected or if the escape shortcut key is used. This will not fire if the menu item sets `shouldClose` to false.
initialSelectedItemnumber | undefinedThe zero-based index of the menu item which should initially receive focus.
idstring | undefinedThe unique id of the Menu used for ARIA and HTML `id` attributes.
aria-labelledbystring | undefinedThe HTML `id` of the element that labels the Menu. Often used with menu buttons.
growboolean | undefinedTrue if the component should grow to its container's width. False otherwise.

Usage

MenuItem renders an <li> element with the correct attributes to ensure it is accessible. If you choose to implement your own custom menu items, be sure to use semantic <li> elements with the following attributes:

  • role="menuitem"
  • tabindex={-1}
  • ids following this pattern: ${MenuId}-${index}

Props

Undocumented props are spread to the underlying <li> element.

NameTypeDefaultDescription
onClick((event: MouseEvent<Element, MouseEvent>) => void) | undefinedThe function called when the MenuItem is clicked. If the item is a child of the Menu component, this callback will be decorated with the onSelect and onClose Menu callbacks. This callback will not fire if the item is disabled (see below).
idstring | undefinedThe unique id for the MenuItem used for ARIA attributes. If the item is a child of the `Menu` component, this property will be generated and overridden.
iconCanvasSystemIcon | undefinedThe icon of the MenuItem. This icon is displayed before what you supplied for the children.
secondaryIconCanvasSystemIcon | undefinedThe secondary icon of the MenuItem. This icon is displayed after what you supplied for the children.
hasDividerboolean | undefinedfalseIf true, render a top border on the MenuItem.
isDisabledboolean | undefinedfalseIf true, set the MenuItem to the disabled state so it is not clickable.
isFocusedboolean | undefinedfalseIf true, set the MenuItem to be the currently selected item. If the item is a child of the Menu component, this property will be generated and overridden.
rolestring | undefinedmenuitemThe role of the MenuItem. Use this to override the role of the item (e.g. you can use this element as an option in a Combobox).
shouldCloseboolean | undefinedIf true, allow the onClose Menu callback to be fired after the MenuItem has been clicked.

Specifications

GivenWhenThen
the Basic example is rendered
    • it should not have any axe errors
    the Basic example is rendered
    • the menu is opened
    • AND THEN the up arrow is pressed
    • it should scroll the menu to show the active menu item
    Source: MenuPreview.spec.ts

    Accessibility Guidelines

    • When the Menu is displayed, the focus should move onto the first option in the Menu.
    • The Menu as a whole should only receive one focus stop on each list item.
    • Up and down arrows must be used to navigate the Menu.

    Content Guidelines

    • When writing Menu list items, refer to the Menus section of the Content Style Guide.

    Can't Find What You Need?

    Check out our FAQ section which may help you find the information you're looking for.

    FAQ Section