Menu
A menu presents a list of menu items that a user can choose to perform an action with.
- Status
- alpha
- Version
- 7.0.0
- Import from
@twilio-paste/core/menu— or —@twilio-paste/menu
Using alpha components in your product
Alpha components are ready for you to use in production. Components such as Menu are likely to not see any API changes. This is only an alpha due to the lack of documentation and minimal design. Feel free to share your experience using this component at #help-design-system or start a discussion on GitHub.
Guidelines#
About Menu#
A menu presents a list of menu items that a user can choose to perform an action with. This component includes a menu trigger (a button in our case) and a menu comprising of menu items that are shown upon actioning the trigger. A menu item can be used to perform an action, a page navigation or show a sub menu.
Each menu item can only perform a single action.
Do not nest multiple actions within a menu item
Please do not add additional actionable elements inside a menu item. They will not be keyboard accessible.
Examples#
Basic menu#
Menu with groups#
Use MenuGroups to create hierarchy or logical groupings within longer menus. MenuGroups have a visible group label that should describe the grouping clearly. They can be given a prefix icon; please only use icons in a decorative manner and make the label descriptive standalone.
Add separators between MenuGroups and other menu items.
Menu with sub items#
Choosing a menu trigger#
The MenuButton is the standard Paste Button with some extra functionality. As a result it takes all the usual props the Paste Button takes, meaning you have full access to all the variants and styling options.
For example, you can create an icon button menu trigger like so:
Composition notes#
Performing actions#
A menu item can perform 2 basic tasks:
- trigger an action (switching a view between grid and list)
- trigger a page navigation (going to a new page)
To do so, either set href with a valid url to go to a new page, or set the onClick as an event handler on the MenuItem.
Composing menu items#
Note
Menu item content is composible however you want. We'll have more complete best practice guidelines soon, but in the meantime here are some example compositions using Paste components.
Anatomy#
MenuButton#
See the button component.
Menu#
| Property | Default token | Modifiable? |
|---|---|---|
| background-color | color-background-body | No |
| border-width | border-width-10 | No |
| border-color | color-border-light | No |
| border-radius | border-radius-20 | No |
| box-shadow | shadow | No |
| max-width | size-30 | No |
| min-width | size-20 | No |
| padding-top | space-30 | No |
| padding-bottom | space-30 | No |
| z-index | z-index-20 | No |
SubMenuButton and MenuItem#
Default#
| Property | Default token | Modifiable? |
|---|---|---|
| color | color-text (default) color-text-weaker (disabled) | No |
| padding-top | space-30 | No |
| padding-bottom | space-30 | No |
| padding-left | space-90 (in-group) or space-70 (regular) | No |
| padding-right | space-90 (in-group) or space-70 (regular) | No |
Hover & focused#
| Property | Default token | Modifiable? |
|---|---|---|
| color | color-text-link | No |
MenuGroup#
| Property | Default token | Modifiable? |
|---|---|---|
| padding-top | space-30 | No |
| padding-bottom | space-30 | No |
| padding-left | space-70 | No |
| padding-right | space-70 | No |
| color | color-text | No |
| font-weight | font-weight-bold | No |
MenuSeparator#
See the separator component.
| Property | Default token | Modifiable? |
|---|---|---|
| padding-top | space-40 | No |
| padding-bottom | space-40 | No |
Usage Guide#
API#
Installation#
yarn add @twilio-paste/menu - or - yarn add @twilio-paste/coreUsage#
import {Menu, MenuButton, MenuItem, MenuSeparator, useMenuState} from '@twilio-paste/menu';import {ChevronDownIcon} from '@twilio-paste/icons/esm/ChevronDownIcon';const PreferencesMenu = () => { const menu = useMenuState(); return ( <> <MenuButton {...menu} variant="primary"> Preferences <ChevronDownIcon decorative /> </MenuButton> <Menu {...menu} aria-label="Preferences"> <MenuItem {...menu}>Settings</MenuItem> <MenuItem {...menu} disabled> Extensions </MenuItem> <MenuSeparator {...menu} /> <MenuItem {...menu}>Keyboard shortcuts</MenuItem> </Menu> </> );};Props#
useMenuState#
Pass these as part of an object to the useMenuState hook.
| Prop | Type | Description | Default |
|---|---|---|---|
| baseId | string | ID that will serve as a base for all the items IDs. | |
| rtl | boolean | ||
| orientation | horizontal, vertical, undefined | ||
| currentId | string, null, undefined | The current focused item id. | |
| loop | boolean, horizontal, vertical | ||
| wrap | boolean, horizontal, vertical | ||
| visible | boolean | Whether it's visible or not. | |
| animated | number, boolean | ||
| placement | auto-start, auto, auto-end, top-start, top, top-end, right-start, right, right-end, bottom-end, bottom, bottom-start, left-end, left, left-start | ||
| gutter | number, undefined | Offset between the reference and the popover on the main axis. Should not be combined with unstable_offset. |
useMenuState returned props#
These props are returned by the state hook. You can spread them into this component ({...state}) or pass them separately. You can also provide these props from your own state logic.
| Prop | Type | Description | Default |
|---|---|---|---|
| baseId | string | ID that will serve as a base for all the items IDs. | |
| baseId | string | ID that will serve as a base for all the items IDs. | |
| visible | boolean | Whether it's visible or not. | |
| animated | number | boolean | ||
| modal | boolean | Toggles Dialog's modal state. | |
| animating | boolean | Whether it's animating or not. | |
| stopAnimation | () => void | Stops animation. It's called automatically if there's a CSS transition. | |
| hide | () => void | Changes the visible state to false | |
| placement | "auto-start" | "auto" | "auto-end" | "top-start... | Actual placement. | |
| orientation | "horizontal" | "vertical" | undefined | Defines the orientation of the composite widget. | |
| currentId | string | null | undefined | The current focused item id. | |
| wrap | boolean | "horizontal" | "vertical" | If enabled, moving to the next item from the last one in a row or column will focus the first item in the next row or column and vice-versa. | |
| groups | Group[] | Lists all the composite groups with their id and DOM ref. | |
| items | Item[] | Lists all the composite items with their id, DOM ref, disabled state and groupId if any. | |
| setCurrentId | (value: SetStateAction<string | null | undefine... | Sets currentId. | |
| first | () => void | Moves focus to the first item. | |
| last | () => void | Moves focus to the last item. | |
| move | (id: string | null) => void | Moves focus to a given item ID. | |
| next | (unstable_allTheWay?: boolean | undefined) => void | Moves focus to the next item. | |
| previous | (unstable_allTheWay?: boolean | undefined) => void | Moves focus to the previous item. |
Menu#
| Prop | Type | Description | Default |
|---|---|---|---|
| hideOnClickOutside | boolean, undefined | When enabled, user can hide the dialog by clicking outside it. | |
| disabled | boolean, undefined | Same as the HTML attribute. |
MenuArrow#
| Prop | Type | Description | Default |
|---|---|---|---|
| size | string, number, undefined |
MenuButton#
| Prop | Type | Description | Default |
|---|---|---|---|
| disabled | boolean, undefined | Same as the HTML attribute. |
MenuDisclosure#
| Prop | Type | Description | Default |
|---|---|---|---|
| disabled | boolean, undefined | Same as the HTML attribute. |
MenuGroup#
| Prop | Type | Description | Default |
|---|---|---|---|
| label | string | Names the grouping | |
| icon | React.ReactNode | One of our icon components. Must be decorative. |
MenuItem#
| Prop | Type | Description | Default |
|---|---|---|---|
| disabled | boolean, undefined | Same as the HTML attribute. | |
| id | string, undefined | Same as the HTML attribute. | |
| onClick | () => void | Same as the HTML attribute. | |
| href | string, undefined | Same as the HTML attribute. |
MenuItemCheckbox#
| Prop | Type | Description | Default |
|---|---|---|---|
| disabled | boolean, undefined | Same as the HTML attribute. | |
| value | string, number, undefined | Checkbox's value is going to be used when multiple checkboxes share the same state. Checking a checkbox with value will add it to the state array. | |
| checked | boolean, undefined | Checkbox's checked state. If present, it's used instead of state. | |
| id | string, undefined | Same as the HTML attribute. | |
| name | string | MenuItemCheckbox's name as in menu.values. |
MenuItemRadio#
| Prop | Type | Description | Default |
|---|---|---|---|
| disabled | boolean, undefined | Same as the HTML attribute. | |
| value | string, number, undefined | Checkbox's value is going to be used when multiple checkboxes share the same state. Checking a checkbox with value will add it to the state array. | |
| checked | boolean, undefined | Checkbox's checked state. If present, it's used instead of state. | |
| id | string, undefined | Same as the HTML attribute. | |
| name | string | MenuItemRadio's name as in menu.values. |