What is @material/menu?
@material/menu is a Material Design menu component for the web. It provides a simple way to create menus that follow the Material Design guidelines, including support for nested menus, keyboard navigation, and accessibility features.
What are @material/menu's main functionalities?
Basic Menu
This code demonstrates how to create a basic menu using the @material/menu package. It initializes a menu component and opens it.
import {MDCMenu} from '@material/menu';
const menu = new MDCMenu(document.querySelector('.mdc-menu'));
menu.open = true;
Menu with Items
This code shows how to create a menu with items and add an event listener to handle item clicks.
import {MDCMenu} from '@material/menu';
const menu = new MDCMenu(document.querySelector('.mdc-menu'));
menu.open = true;
const listItem = document.querySelector('.mdc-list-item');
listItem.addEventListener('click', () => {
console.log('Item clicked');
});
Nested Menus
This code demonstrates how to create nested menus using the @material/menu package. It initializes a parent menu and a child menu, and opens the child menu when an item in the parent menu is clicked.
import {MDCMenu} from '@material/menu';
const parentMenu = new MDCMenu(document.querySelector('.mdc-menu-parent'));
const childMenu = new MDCMenu(document.querySelector('.mdc-menu-child'));
parentMenu.open = true;
const parentItem = document.querySelector('.mdc-list-item-parent');
parentItem.addEventListener('click', () => {
childMenu.open = true;
});
Other packages similar to @material/menu
react-select
react-select is a flexible and customizable menu component for React applications. It provides a wide range of features including multi-select, async options, and customizable styles. Compared to @material/menu, react-select is more focused on providing a rich set of features for select inputs rather than general-purpose menus.
rc-menu
rc-menu is a React component for creating menus. It supports nested menus, keyboard navigation, and customizable styles. While it offers similar functionality to @material/menu, rc-menu is specifically designed for React applications and provides more flexibility in terms of customization.
semantic-ui-react
semantic-ui-react is the official React integration for Semantic UI. It includes a Menu component that provides a wide range of features including vertical and horizontal menus, submenus, and item grouping. Compared to @material/menu, semantic-ui-react offers a more comprehensive set of UI components and is designed to work seamlessly with the Semantic UI framework.
A menu displays a list of choices on a temporary surface. They appear when users interact with a button, action,
or other control.
Design & API Documentation
Installation
npm install @material/menu
Basic Usage
HTML Structure
<div class="mdc-menu" tabindex="-1">
<ul class="mdc-menu__items mdc-list" role="menu" aria-hidden="true">
<li class="mdc-list-item" role="menuitem" tabindex="0">
A Menu Item
</li>
<li class="mdc-list-item" role="menuitem" tabindex="0">
Another Menu Item
</li>
</ul>
</div>
Styles
@import "@material/menu/mdc-list";
@import "@material/menu/mdc-menu-surface";
@import "@material/menu/mdc-menu";
JavaScript Instantiation
import {MDCMenu} from '@material/menu';
const menu = new MDCMenu(document.querySelector('.mdc-menu'));
menu.show();
See Importing the JS component for more information on how to import JavaScript.
Variants
Menus can contain a group of list items that can represent the selection state of elements within the group.
<div class="mdc-menu mdc-menu-surface" tabindex="-1" id="demo-menu">
<ul class="mdc-list" role="menu" aria-hidden="true" aria-orientation="vertical">
<li>
<ul class="mdc-menu__selection-group">
<li class="mdc-list-item" role="menuitem">
<span class="mdc-menu__selection-group-icon">
...
</span>
Single
</li>
<li class="mdc-list-item" role="menuitem">
<span class="mdc-menu__selection-group-icon">
...
</span>
1.15
</li>
</ul>
</li>
<li class="mdc-list-divider" role="separator"></li>
<li class="mdc-list-item" role="menuitem">Add space before paragraph</li>
...
</ul>
</div>
Anchors and Positioning
Anchored To Parent
The menu can be positioned to automatically anchor to a parent element when opened.
<div id="toolbar" class="toolbar mdc-menu-surface--anchor">
<div class="mdc-menu mdc-menu-surface">
...
</div>
</div>
Anchor To Element Within Wrapper
The menu can be positioned to automatically anchor to another element, by wrapping the other element with the anchor class.
<div id="demo-menu" class="mdc-menu-surface--anchor">
<button id="menu-button">Open Menu</button>
<div class="mdc-menu mdc-menu-surface">
...
</div>
</div>
Fixed Position
The menu can use fixed positioning when being displayed.
<div class="mdc-menu mdc-menu-surface">
...
</div>
menu.setFixedPosition(true);
Absolute Position
The menu can use absolutely positioned when being displayed.
<div class="mdc-menu mdc-menu-surface">
...
</div>
menu.hoistMenuToBody();
menu.setAbsolutePosition(100, 100);
Style Customization
CSS Classes
CSS Class | Description |
---|
mdc-menu | Required on the root element |
mdc-menu-surface | Required on the root element. See mdc-menu-surface documentation for other mdc-menu-surface classes. |
mdc-list | Required on the nested ul element. See mdc-list documentation for other mdc-list classes. |
mdc-menu__selection-group | Used to wrap a group of mdc-list-item elements that will represent a selection group. |
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. |
mdc-menu-item--selected | Used to indicate which element in a selection group is selected. |
Sass Mixins
Mixin | Description |
---|
mdc-menu-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. |
MDCMenu
Properties and Methods
See Importing the JS component for more information on how to import JavaScript.
Property | Value Type | Description |
---|
open | Boolean | Proxies to the menu surface's open property. |
items | Array | Proxies to the list to query for all .mdc-list-item elements. |
quickOpen | Boolean | Proxies to the menu surface quickOpen property. |
Method Signature | Description |
---|
setAnchorCorner(Corner) => void | Proxies to the menu surface's setAnchorCorner(Corner) method. |
setAnchorMargin(AnchorMargin) => void | Proxies to the menu surface's setAnchorMargin(AnchorMargin) method. |
setAbsolutePosition(x: number, y: number) => void | Proxies to the menu surface's setAbsolutePosition(x: number, y: number) method. |
setFixedPosition(isFixed: boolean) => void | Proxies to the menu surface's setFixedPosition(isFixed: boolean) method. |
hoistMenuToBody() => void | Proxies to the menu surface's hoistMenuToBody() method. |
setIsHoisted(isHoisted: boolean) => void | Proxies to the menu surface's setIsHoisted(isHoisted: boolean) method. |
setAnchorElement(element: HTMLElement) => void | Proxies to the menu surface's setAnchorElement(element) method. |
getOptionByIndex(index: number) => ?HTMLElement | Returns the list item at the index specified. |
getDefaultFoundation() => MDCMenuFoundation | Returns the foundation. |
See Menu Surface and List documentation for more information on proxied methods and properties.
Usage within Web Frameworks
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.
Method Signature | Description |
---|
addClassToElementAtIndex(index: number, className: string) => void | Adds the className class to the element at the index specified. |
removeClassFromElementAtIndex(index: number, className: string) => void | Removes the className class from the element at the index specified. |
addAttributeToElementAtIndex(index: number, attr: string, value: string) => void | Adds the attr attribute with value value to the element at the index specified. |
removeAttributeFromElementAtIndex(index: number, attr: string) => void | Removes the attr attribute from the element at the index specified. |
elementContainsClass(element: HTMLElement, className: string) => boolean | Returns true if the element contains the className class. |
closeSurface() => void | Closes the menu surface. |
getElementIndex(element: HTMLElement) => number | Returns the index value of the element . |
getParentElement(element: HTMLElement) => ?HTMLElement | Returns the .parentElement element of the element provided. |
getSelectedElementIndex(element: HTMLElement) => number | Returns the index value of the element within the selection group provided, element that contains the mdc-menu-item--selected class. |
notifySelected(index: number) => void | Emits a MDCMenu:selected event for the element at the index specified. |
getCheckboxAtIndex(index: number) => ?HTMLElement | Returns the checkbox element contained within the element at the index specified. |
toggleCheckbox(checkbox: HTMLElement) => void | Toggles the checkbox element provided and triggers a change event for the element. |
Method Signature | Description |
---|
handleKeydown(evt: Event) => void | Event handler for the keydown events within the menu. |
handleClick(evt: Event) => void | Event handler for the click events within the menu. |
Events
Event Name | Data | Description |
---|
MDCMenu:selected | {detail: {item: HTMLElement, 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. |