1 |
|
2 | title: "Menus"
|
3 | layout: detail
|
4 | section: components
|
5 | excerpt: "Non-cascading Material Design menus."
|
6 | iconId: menu
|
7 | path: /catalog/menus/
|
8 | -->
|
9 |
|
10 | # Menus
|
11 |
|
12 | A menu displays a list of choices on a temporary surface. They appear when users interact with a button, action,
|
13 | or other control.
|
14 |
|
15 | ## Important Changes
|
16 |
|
17 | Menu is currently being updated to use the new List implementation. For now,
|
18 | please continue to use the old implementation (`mdc-deprecated-list` and
|
19 | associated DOM/classes) instead of the new one (`mdc-list`).
|
20 |
|
21 | See the [List documentation](../mdc-list/README.md) for more information.
|
22 |
|
23 | ## Design & API Documentation
|
24 |
|
25 | <ul class="icon-list">
|
26 | <li class="icon-list-item icon-list-item--spec">
|
27 | <a href="https://material.io/go/design-menus">Material Design guidelines: Menus</a>
|
28 | </li>
|
29 | <li class="icon-list-item icon-list-item--link">
|
30 | <a href="https://material-components.github.io/material-components-web-catalog/#/component/menu">Demo</a>
|
31 | </li>
|
32 | </ul>
|
33 |
|
34 | ## Installation
|
35 |
|
36 | ```
|
37 | npm install @material/menu
|
38 | ```
|
39 |
|
40 | ## Basic Usage
|
41 |
|
42 | ### HTML Structure
|
43 |
|
44 | ```html
|
45 | <div class="mdc-menu mdc-menu-surface">
|
46 | <ul class="mdc-deprecated-list" role="menu" aria-hidden="true" aria-orientation="vertical" tabindex="-1">
|
47 | <li class="mdc-deprecated-list-item" role="menuitem">
|
48 | <span class="mdc-deprecated-list-item__ripple"></span>
|
49 | <span class="mdc-deprecated-list-item__text">A Menu Item</span>
|
50 | </li>
|
51 | <li class="mdc-deprecated-list-item" role="menuitem">
|
52 | <span class="mdc-deprecated-list-item__ripple"></span>
|
53 | <span class="mdc-deprecated-list-item__text">Another Menu Item</span>
|
54 | </li>
|
55 | </ul>
|
56 | </div>
|
57 | ```
|
58 |
|
59 | ### Styles
|
60 |
|
61 | ```scss
|
62 | @use "@material/list/mdc-list";
|
63 | @use "@material/menu-surface/mdc-menu-surface";
|
64 | @use "@material/menu/mdc-menu";
|
65 | ```
|
66 |
|
67 | ### JavaScript Instantiation
|
68 |
|
69 | ```js
|
70 | import {MDCMenu} from '@material/menu';
|
71 |
|
72 | const menu = new MDCMenu(document.querySelector('.mdc-menu'));
|
73 | menu.open = true;
|
74 | ```
|
75 |
|
76 | > See [Importing the JS component](../../docs/importing-js.md) for more information on how to import JavaScript.
|
77 |
|
78 | ## Variants
|
79 |
|
80 | ### Selection Group Menu
|
81 |
|
82 | Menus can contain a group of list items that can represent the selection state of elements within the group.
|
83 |
|
84 | ```html
|
85 | <div class="mdc-menu mdc-menu-surface" id="demo-menu">
|
86 | <ul class="mdc-deprecated-list" role="menu" aria-hidden="true" aria-orientation="vertical" tabindex="-1">
|
87 | <li>
|
88 | <ul class="mdc-menu__selection-group">
|
89 | <li class="mdc-deprecated-list-item" role="menuitem">
|
90 | <span class="mdc-deprecated-list-item__ripple"></span>
|
91 | <span class="mdc-deprecated-list-item__graphic mdc-menu__selection-group-icon">
|
92 | ...
|
93 | </span>
|
94 | <span class="mdc-deprecated-list-item__text">Single</span>
|
95 | </li>
|
96 | <li class="mdc-deprecated-list-item" role="menuitem">
|
97 | <span class="mdc-deprecated-list-item__ripple"></span>
|
98 | <span class="mdc-deprecated-list-item__graphic mdc-menu__selection-group-icon">
|
99 | ...
|
100 | </span>
|
101 | <span class="mdc-deprecated-list-item__text">1.15</span>
|
102 | </li>
|
103 | </ul>
|
104 | </li>
|
105 | <li class="mdc-deprecated-list-divider" role="separator"></li>
|
106 | <li class="mdc-deprecated-list-item" role="menuitem">
|
107 | <span class="mdc-deprecated-list-item__ripple"></span>
|
108 | <span class="mdc-deprecated-list-item__text">Add space before paragraph</span>
|
109 | </li>
|
110 | ...
|
111 | </ul>
|
112 | </div>
|
113 | ```
|
114 |
|
115 | ### Disabled Menu Items
|
116 |
|
117 | Menu items can be disabled by adding the `mdc-deprecated-list-item--disabled` modifier class (from [MDC List](../mdc-list)).
|
118 | Disabled menu items will be excluded from keyboard navigation.
|
119 |
|
120 | ### Anchors and Positioning
|
121 |
|
122 | #### Anchored To Parent
|
123 |
|
124 | The menu can be positioned to automatically anchor to a parent element when opened.
|
125 |
|
126 | ```html
|
127 | <div id="toolbar" class="toolbar mdc-menu-surface--anchor">
|
128 | <div class="mdc-menu mdc-menu-surface">
|
129 | ...
|
130 | </div>
|
131 | </div>
|
132 | ```
|
133 |
|
134 | #### Anchor To Element Within Wrapper
|
135 |
|
136 | The menu can be positioned to automatically anchor to another element, by wrapping the other element with the anchor class.
|
137 |
|
138 | ```html
|
139 | <div id="demo-menu" class="mdc-menu-surface--anchor">
|
140 | <button id="menu-button">Open Menu</button>
|
141 | <div class="mdc-menu mdc-menu-surface">
|
142 | ...
|
143 | </div>
|
144 | </div>
|
145 | ```
|
146 |
|
147 | #### Fixed Position
|
148 |
|
149 | The menu can use fixed positioning when being displayed.
|
150 |
|
151 | ```html
|
152 | <div class="mdc-menu mdc-menu-surface">
|
153 | ...
|
154 | </div>
|
155 | ```
|
156 |
|
157 | ```js
|
158 | // ...
|
159 | menu.setFixedPosition(true);
|
160 | ```
|
161 |
|
162 | #### Absolute Position
|
163 |
|
164 | The menu can use absolutely positioned when being displayed.
|
165 |
|
166 | ```html
|
167 | <div class="mdc-menu mdc-menu-surface">
|
168 | ...
|
169 | </div>
|
170 | ```
|
171 |
|
172 | ```js
|
173 | // ...
|
174 | menu.setAbsolutePosition(100, 100);
|
175 | ```
|
176 |
|
177 | ## Style Customization
|
178 |
|
179 | ### CSS Classes
|
180 |
|
181 | CSS Class | Description
|
182 | --- | ---
|
183 | `mdc-menu` | Required on the root element
|
184 | `mdc-menu-surface` | Required on the root element. See [`mdc-menu-surface` documentation](../mdc-menu-surface) for other `mdc-menu-surface` classes.
|
185 | `mdc-deprecated-list` | Required on the nested `ul` element. See [`mdc-list` documentation](../mdc-list) for other `mdc-deprecated-list` classes.
|
186 | `mdc-menu__selection-group` | Used to wrap a group of `mdc-deprecated-list-item` elements that will represent a selection group.
|
187 | `mdc-menu__selection-group-icon` | Required when using a selection group to indicate which item is selected. Should contain an icon or svg that indicates the selected state of the list item.
|
188 | `mdc-menu-item--selected` | Used to indicate which element in a selection group is selected.
|
189 |
|
190 | ### Sass Mixins
|
191 |
|
192 | Mixin | Description
|
193 | --- | ---
|
194 | `width($width)` | Used to set the `width` of the menu. When used without units (e.g. `4` or `5`) it computes the `width` by multiplying by the base width (`56px`). When used with units (e.g. `240px`, `15%`, or `calc(200px + 10px)` it sets the `width` to the exact value provided.
|
195 | `min-width($min-width)` | Sets the `min-width` of the menu. Use with units (e.g. `240px`, `15%`, or `calc(200px + 10px)` only.
|
196 |
|
197 | > See [Menu Surface](../mdc-menu-surface/README.md#sass-mixins) and [List](../mdc-list/README.md#sass-mixins) documentation for additional style customization options.
|
198 |
|
199 | ### Accessibility
|
200 |
|
201 | Please see [Menu Button](https://www.w3.org/TR/wai-aria-practices/#menubutton) WAI-ARIA practices article for details on recommended Roles, States, and Properties for menu button (button that opens a menu).
|
202 |
|
203 | With focus on the menu button:
|
204 |
|
205 | * <kbd>Enter</kbd>, <kbd>Space</kbd> & <kbd>Down Arrow</kbd> opens the menu and places focus on the first menu item.
|
206 | * <kbd>Up Arrow</kbd> opens the menu and moves focus to the last menu item.
|
207 | * The focus is set to list root element (where `role="menu"` is set) when clicked or touched. MDC List handles the keyboard navigation once it receives the focus.
|
208 |
|
209 | Use `setDefaultFocusState` method to set default focus state that will be focused every time when menu is opened.
|
210 |
|
211 | Focus state | Description
|
212 | --- | ---
|
213 | `DefaultFocusState.FIRST_ITEM` | Focuses the first menu item. Set this when menu button receives <kbd>Enter</kbd>, <kbd>Space</kbd>, <kbd>Down Arrow</kbd>.
|
214 | `DefaultFocusState.LAST_ITEM` | Focuses the last menu item. Set this when menu button receives <kbd>Up arrow</kbd>.
|
215 | `DefaultFocusState.LIST_ROOT` | Focuses the list root. Set this when menu button Clicked or Touched.
|
216 | `DefaultFocusState.NONE` | Does not change the focus. Set this if you do not want the menu to grab focus on open. (Autocomplete dropdown menu, for example).
|
217 |
|
218 | ## `MDCMenu` Properties and Methods
|
219 |
|
220 | See [Importing the JS component](../../docs/importing-js.md) for more information on how to import JavaScript.
|
221 |
|
222 | Property | Value Type | Description
|
223 | --- | --- | ---
|
224 | `open` | Boolean | Proxies to the menu surface's `open` property.
|
225 | `items` | `Array<Element>` | Proxies to the list to query for all `.mdc-deprecated-list-item` elements.
|
226 | `quickOpen` | Boolean | Proxies to the menu surface `quickOpen` property.
|
227 | `wrapFocus` | Boolean | Proxies to list's `wrapFocus` property.
|
228 | `hasTypeahead` | Boolean | Proxies to the list's `hasTypeahead` property.
|
229 |
|
230 | Method Signature | Description
|
231 | --- | ---
|
232 | `setAnchorCorner(Corner) => void` | Proxies to the menu surface's `setAnchorCorner(Corner)` method.
|
233 | `setAnchorMargin(Partial<MDCMenuDistance>) => void` | Proxies to the menu surface's `setAnchorMargin(Partial<MDCMenuDistance>)` method.
|
234 | `setAbsolutePosition(x: number, y: number) => void` | Proxies to the menu surface's `setAbsolutePosition(x: number, y: number)` method.
|
235 | `setFixedPosition(isFixed: boolean) => void` | Proxies to the menu surface's `setFixedPosition(isFixed: boolean)` method.
|
236 | `setSelectedIndex(index: number) => void` | Sets the list item to the selected state at the specified index.
|
237 | `setIsHoisted(isHoisted: boolean) => void` | Proxies to the menu surface's `setIsHoisted(isHoisted: boolean)` method.
|
238 | `setAnchorElement(element: Element) => void` | Proxies to the menu surface's `setAnchorElement(element)` method.
|
239 | `getOptionByIndex(index: number) => Element \| null` | Returns the list item at the `index` specified.
|
240 | `getPrimaryTextAtIndex(index: number) => string` | Returns the primary text at the `index` specified.
|
241 | `getDefaultFoundation() => MDCMenuFoundation` | Returns the foundation.
|
242 | `setDefaultFocusState(focusState: DefaultFocusState) => void` | Sets default focus state where the menu should focus every time when menu is opened. Focuses the list root (`DefaultFocusState.LIST_ROOT`) element by default.
|
243 | `setEnabled(index: number, isEnabled: boolean) => void` | Sets the enabled state to `isEnabled` for the menu item at given `index`.
|
244 | `layout() => void` | Proxies to the list's layout method.
|
245 | `typeaheadMatchItem(nextChar: string) => number` | Adds a character to the typeahead buffer and returns index of the next item in the list matching the buffer.
|
246 |
|
247 | > See [Menu Surface](../mdc-menu-surface/README.md) and [List](../mdc-list/README.md) documentation for more information on proxied methods and properties.
|
248 |
|
249 | ## Usage within Web Frameworks
|
250 |
|
251 | If you are using a JavaScript framework, such as React or Angular, you can create a Menu for your framework. Depending on your needs, you can use the _Simple Approach: Wrapping MDC Web Vanilla Components_, or the _Advanced Approach: Using Foundations and Adapters_. Please follow the instructions [here](../../docs/integrating-into-frameworks.md).
|
252 |
|
253 | ### `MDCMenuAdapter`
|
254 |
|
255 | Method Signature | Description
|
256 | --- | ---
|
257 | `addClassToElementAtIndex(index: number, className: string) => void` | Adds the `className` class to the element at the `index` specified.
|
258 | `removeClassFromElementAtIndex(index: number, className: string) => void` | Removes the `className` class from the element at the `index` specified.
|
259 | `addAttributeToElementAtIndex(index: number, attr: string, value: string) => void` | Adds the `attr` attribute with value `value` to the element at the `index` specified.
|
260 | `removeAttributeFromElementAtIndex(index: number, attr: string) => void` | Removes the `attr` attribute from the element at the `index` specified.
|
261 | `elementContainsClass(element: Element, className: string) => boolean` | Returns true if the `element` contains the `className` class.
|
262 | `closeSurface(skipRestoreFocus?: boolean) => void` | Closes the menu surface, skipping restoring focus to the previously focused element if `skipRestoreFocus` is true.
|
263 | `getElementIndex(element: Element) => number` | Returns the `index` value of the `element`.
|
264 | `notifySelected(index: number) => void` | Emits a `MDCMenu:selected` event for the element at the `index` specified.
|
265 | `getMenuItemCount() => number` | Returns the menu item count.
|
266 | `focusItemAtIndex(index: number)` | Focuses the menu item at given index.
|
267 | `focusListRoot() => void` | Focuses the list root element.
|
268 | `getSelectedSiblingOfItemAtIndex(index: number) => number` | Returns selected list item index within the same selection group which is a sibling of item at given `index`.
|
269 | `isSelectableItemAtIndex(index: number) => boolean` | Returns true if menu item at specified index is contained within an `.mdc-menu__selection-group` element.
|
270 |
|
271 | ### `MDCMenuFoundation`
|
272 |
|
273 | Method Signature | Description
|
274 | --- | ---
|
275 | `handleKeydown(evt: Event) => void` | Event handler for the `keydown` events within the menu.
|
276 | `handleItemAction(listItem: Element) => void` | Event handler for list's action event.
|
277 | `handleMenuSurfaceOpened() => void` | Event handler for menu surface's opened event.
|
278 | `setDefaultFocusState(focusState: DefaultFocusState) => void` | Sets default focus state where the menu should focus every time when menu is opened. Focuses the list root (`DefaultFocusState.LIST_ROOT`) element by default.
|
279 | `setSelectedIndex(index: number) => void` | Selects the list item at given `index`.
|
280 | `setEnabled(index: number, isEnabled: boolean) => void` | Sets the enabled state of the menu item at given `index`.
|
281 |
|
282 | ### Events
|
283 |
|
284 | Event Name | Data | Description
|
285 | --- | --- | ---
|
286 | `MDCMenu:selected` | `{detail: {item: Element, index: number}}` | Used to indicate when an element has been selected. This event also includes the item selected and the list index of that item.
|