@workday/canvas-kit-docs
Version:
Documentation components of Canvas Kit components
113 lines (78 loc) • 5.3 kB
text/mdx
import {ExampleCodeBlock, SymbolDoc, Specifications} from '@workday/canvas-kit-docs';
import Basic from './examples/Basic';
import ContextMenu from './examples/ContextMenu';
import Icons from './examples/Icons';
import SelectableMenu from './examples/SelectableMenu';
import Grouping from './examples/Grouping';
import Nested from './examples/Nested';
import NestedDynamic from './examples/NestedDynamic';
# Canvas Kit Menu
`Menu` displays a list of options when triggered by an action or UI element like an icon or button.
[> Workday Design Reference](https://design.workday.com/components/popups/menus)
## Installation
```sh
yarn add @workday/canvas-kit-react
```
## Usage
### Basic Example
`Menu` is typically triggered by an action such as pressing a button. The `Menu` comes with a
`Target` subcomponent and a Popup.
<ExampleCodeBlock code={Basic} />
`Menu` will automatically focus on the cursor item (first item by default). The `Menu` uses a menu
model which composes a list model and a popup model and sets up accessibility features for you.
`Menu` follows the
[Actions Menu pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-actions/)
using roving tabindex. Below is table of supported keyboard shortcuts and associated actions.
| Key | Action |
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
| `Enter` or `Space` | Activates the menu item and then closes the menu |
| `Escape` | Closes the menu |
| `Up Arrow` | Moves focus to the previous menu item – if focus is on first menu item, it moves focus to the last menu item |
| `Down Arrow` | Moves focus to the next menu item – if focus is on last menu item, it moves focus to the first menu item |
| `Home` | Moves focus to the first menu item |
| `End` | Moves focus to the last menu item |
### Context Menu
<ExampleCodeBlock code={ContextMenu} />
### Icons
Menu supports more complex children, including icons, but the text of the item will no longer be
known. In this case, add a `data-text` attribute to inform the collection system what the text of
the item is. The text is used for components that filter based on text. For example, a Select
component will jump to an item based on the keys the user types. If the user types "C", the
component will jump to the first item that starts with a "C". This functionality requires knowledge
about the text of the item.
<ExampleCodeBlock code={Icons} />
### Selectable Menu
The `Menu.Item` renders a `role=menuitem` element which does not have `aria-selected` and thus no
selected state. If you wish your menu to have selectable menu items, use `Menu.Option` instead of
`Menu.Item`. The `Menu.Option` is meant to be used when the `Menu.Card` has a role of `listbox` and
is controlled via `aria-activedescendant`. This example uses `Menu.Option` to should what the
checkmark looks like, but the example is not keyboard or screen reader accessible. There are many
other behaviors that need to be composed into the `Menu.Target` and `Menu.List` components and the
behaviors depend on many other things. To see a full example of all these behaviors, look at the
`<Combobox>` and `<Select>` component source code as examples.
<ExampleCodeBlock code={SelectableMenu} />
### Grouping
Grouping adds hierarchy and categorization to menu items. Group headers do not represent menu items
and are not selectable with the keyboard or mouse.
> **Note**: Grouping is not supported in virtual rendering. Menus by default have `shouldVirtualize`
> set to `false`. Setting to `true` results in unspecified behavior. We use `react-virtual` which
> doesn't support nested virtualization.
<ExampleCodeBlock code={Grouping} />
### Nested
Menus support nesting. If you only have a few items and not very many nesting levels, the menu can
be defined statically using JSX. A submenu is defined using the `<Menu.Submenu>` component. The
`Submenu` is implemented as a special `Menu` subcomponent. The API of the submenu is the same as the
`Menu` except the submenu's target is also a menu item. The component is named `TargetItem` to
indicate this dual role.
<ExampleCodeBlock code={Nested} />
### Nested Dynamic Items
Menu nesting is simpler with the dynamic API. In this example, a `renderItem` function is defined to
allow recursive nesting of items using a data structure you define. A submenu will inherit the
`getId` and `getTextValue` functions of the parent menu. While you can pass a specialize `getId` or
`getTextValue` function to each submenu, it may be simpler to use the same one for the menu and
submenus.
<ExampleCodeBlock code={NestedDynamic} />
## Component API
<SymbolDoc name="Menu" fileName="/react/" />
## Specifications
<Specifications file="Menu.spec.ts" name="Menu" />