# Menus
# Menus & Menu Items
Menus appear by clicking an "anchor" element and may include submenus and checkboxes for multiple selection. Also see Dropdown Menus, which use the Menu component internally to allow for a single selection.
By setting the Menu's anchorEl prop to a clickable element, the menu will open whenever that element is clicked. By default, the menu will open below the element, aligned to the left edge. The default placement can be changed via the placement prop. If the default placement does not have available space for the menu, then the placement will be changed automatically.
To add a divider between items, use a traditional hr element.
<mx-icon-button ref="actionButton" el-aria-label="Open action menu" chevron-down />
<mx-menu ref="actionMenu">
<mx-menu-item icon="ph ph-file" @click="clickHandler">New…</mx-menu-item>
<mx-menu-item icon="ph ph-folder-open" @click="clickHandler">Open…</mx-menu-item>
<hr>
<mx-menu-item icon="ph ph-floppy-disk" @click="clickHandler">Save</mx-menu-item>
<mx-menu-item @click="clickHandler">Save As…</mx-menu-item>
<hr>
<mx-menu-item @click="clickHandler">Close</mx-menu-item>
</mx-menu> 2
3
4
5
6
7
8
9
this.$refs.actionMenu.anchorEl = this.$refs.actionButton The preferred way to nest menu items is to place an mx-menu-accordion inside a menu item's "accordion" slot. To create cascading menus, add slot="submenu" to a child mx-menu.
<mx-button ref="editButton" btn-type="simple" dropdown>Edit</mx-button>
<mx-menu ref="editMenu">
<mx-menu-item @click="clickHandler">Undo</mx-menu-item>
<mx-menu-item @click="clickHandler" disabled>Redo</mx-menu-item>
<mx-menu-item @click="clickHandler">
Cut
<i slot="right" class="text-1 ph ph-scissors"></i>
</mx-menu-item>
<mx-menu-item @click="clickHandler">
Copy
<i slot="right" class="text-1 ph ph-copy"></i>
</mx-menu-item>
<mx-menu-item>
AutoFill
<mx-menu-accordion slot="accordion">
<mx-menu-item @click="clickHandler">
Contact…
</mx-menu-item>
<mx-menu-item @click="clickHandler">
Passwords…
</mx-menu-item>
</mx-menu-accordion>
</mx-menu-item>
<hr>
<mx-menu-item>
Find & Sort
<mx-menu slot="submenu">
<mx-menu-item @click="clickHandler">Find…</mx-menu-item>
<mx-menu-item @click="clickHandler">Find Next</mx-menu-item>
<mx-menu-item @click="clickHandler">Find Previous</mx-menu-item>
<mx-menu-item>
Sort By
<mx-menu slot="submenu">
<mx-menu-item @click="clickHandler">Name</mx-menu-item>
<mx-menu-item checked @click="clickHandler">Date Modified</mx-menu-item>
<mx-menu-item @click="clickHandler">Size</mx-menu-item>
</mx-menu>
</mx-menu-item>
</mx-menu>
</mx-menu-item>
</mx-menu> 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// For JSX-based frameworks, you may be able to set the anchorEl within the template.
// Otherwise, assign the anchorEl property in your script.
this.$refs.editMenu.anchorEl = this.$refs.editButton 2
3
# Headings, labels, subtitles & checkboxes
Place a paragraph element with a role of "heading" inside a menu to add a section label. Use the Menu Item's label prop to add a label to an individual item. Use the subtitle prop to add a subtitle below the menu item text.
To add checkboxes to Menu Items, add the multi-select property, and set the checked accordingly. The checked property can also be used without multi-select to simply add a checkmark icon to the item.
Appearance
<div>
<mx-icon-button ref="dotsButton" el-aria-label="Open menu" icon="ph ph-dots-three-outline" />
<mx-menu ref="dotsMenu">
<p role="heading" aria-level="1">Appearance</p>
<mx-menu-item multi-select checked @click="clickHandler">Show Minimap</mx-menu-item>
<mx-menu-item multi-select @click="clickHandler">Word Wrap</mx-menu-item>
<mx-menu-item @click="clickHandler" label="Email">design@moxiworks.com</mx-menu-item>
<mx-menu-item @click="clickHandler" subtitle="123 Bremerton Pl Ne">
Office One
</mx-menu-item>
</mx-menu>
</div>
<div>
<mx-button ref="menuButton">Open Menu</mx-button>
<mx-menu ref="scrollingMenu">
<mx-menu-item v-for="i in 12" :key="i" checked>Menu Item {{i}}</mx-menu-item>
</mx-menu>
</div> 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
this.$refs.dotsMenu.anchorEl = this.$refs.dotsButton
this.$refs.scrollingMenu.anchorEl = this.$refs.menuButton # Suggestion and autocomplete menus
When the anchorEl contains an <input type=text> or <input type=search>, the menu takes on some
additional behaviors to allow the menu to function as an autocomplete or suggestion menu. These are used internally by the Autocomplete component.
These additional behaviors include:
- The menu stretches the entire width of the
anchorEl. - Typing into the input opens the menu.
- Typing while a menu item is focused restores focus to the input.
- The input's
autocompleteattribute is set tooffto disable the browser's native autocomplete menu.
Setting the autocompleteOnly prop to true causes the top menu item to always be selected by default,
and pressing Enter inside the input will effectively click that item. Leave this set to false to
allow submitting the input value without selecting a menu item.
In the first example below, typing "app" and pressing Enter will log "app" to the console. In the second
example, "Apple" will be logged because the autoCompleteOnly prop causes the first menu item to be
selected on Enter.
<mx-search
ref="search1"
:value="term1"
class="w-288"
placeholder="Fruit"
@input="term1 = $event.target.value"
@keydown.enter="onClickSuggestion($event.target.value, 1)"
/>
<mx-menu ref="menu1">
<mx-menu-item v-for="(suggestion, i) in suggestions1" :key="i" @click="onClickSuggestion(suggestion, 1)">
{{ suggestion }}
</mx-menu-item>
</mx-menu> 2
3
4
5
6
7
8
9
10
11
12
<mx-search
ref="search2"
:value="term2"
class="w-288"
placeholder="Fruit (autocompleteOnly)"
@input="term2 = $event.target.value"
/>
<mx-menu ref="menu2" autocomplete-only>
<mx-menu-item v-for="(suggestion, i) in suggestions2" :key="i" @click="onClickSuggestion(suggestion, 2)">
{{ suggestion }}
</mx-menu-item>
</mx-menu> 2
3
4
5
6
7
8
9
10
11
suggestions1() {
if (!this.term1) return []
return fruits.filter(fruit =>
fruit.toLowerCase().includes(this.term1.toLowerCase())
)
},
suggestions2() {
if (!this.term2) return []
return fruits.filter(fruit =>
fruit.toLowerCase().includes(this.term2.toLowerCase())
)
}, 2
3
4
5
6
7
8
9
10
11
this.$refs.menu1.anchorEl = this.$refs.search1
this.$refs.menu2.anchorEl = this.$refs.search2
this.$refs.menu3.anchorEl = this.$refs.search3 2
onClickSuggestion(suggestion, num) {
console.log(suggestion + ' entered!')
// Clear the input and refocus it
this['term' + num] = ''
this.$nextTick(() => this.$refs['search' + num].querySelector('input').focus())
} 2
3
4
5
# Grouped autocomplete menu with headings
Below is an example of an autocomplete menu that uses headings to show different groups of matches.
<mx-search
ref="search3"
:value="term3"
class="w-288"
placeholder="Fruit or vegetable"
@input="term3 = $event.target.value"
@keydown.enter="onClickSuggestion($event.target.value, 3)"
/>
<mx-menu ref="menu3">
<div role="group" v-for="suggestionGroup in suggestionGroups">
<p :key="suggestionGroup.heading" role="heading" aria-level="2">{{ suggestionGroup.heading }}</p>
<mx-menu-item v-for="(suggestion, i) in suggestionGroup.suggestions" :key="suggestionGroup.heading + i" @click="onClickSuggestion(suggestion, 3)">
{{ suggestion }}
</mx-menu-item>
</div>
</mx-menu> 2
3
4
5
6
7
8
9
10
11
12
13
14
15
suggestionGroups() {
if (!this.term3) return []
const groups = []
const match = item => item.toLowerCase().includes(this.term3.toLowerCase())
const fruitMatches = fruits.filter(match)
const veggieMatches = vegetables.filter(match)
if (fruitMatches.length) groups.push({ heading: 'Fruits', suggestions: fruitMatches })
if (veggieMatches.length) groups.push({ heading: 'Vegetables', suggestions: veggieMatches })
return groups
} 2
3
4
5
6
7
8
9
# mx-menu
# Properties
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
anchorEl | -- | The element to which the menu's position will be anchored | HTMLElement | undefined |
autocompleteOnly | autocomplete-only | If the anchor element contains an input, setting this to true will always select the first menu item when Enter is pressed inside the input. | boolean | false |
isOpen | is-open | This is set to true automatically when the anchorEl is clicked. Dropdown menus read this prop internally for styling purposes. | boolean | false |
offset | -- | An array of offsets in pixels. The first is the "skidding" along the edge of the anchorEl. The second is the distance from the anchorEl. | [number, number] | undefined |
placement | placement | The placement of the menu, relative to the anchorEl. | "auto" \| "auto-end" \| "auto-start" \| "bottom" \| "bottom-end" \| "bottom-start" \| "left" \| "left-end" \| "left-start" \| "right" \| "right-end" \| "right-start" \| "top" \| "top-end" \| "top-start" | 'bottom-start' |
squared | squared | Used for the squared variant styling. | boolean | false |
triggerEl | -- | The element that will open the menu when clicked. If not provided, the anchorEl will be used. | HTMLElement | undefined |
# Events
| Event | Description | Type |
|---|---|---|
mxClose | Emitted when the menu closes. | CustomEvent<void> |
mxOpen | Emitted when the menu opens. | CustomEvent<void> |
# Methods
# closeMenu() => Promise<boolean>
Close the menu. Returns a promise that resolves to false if the menu was already closed.
# Returns
Type: Promise<boolean>
# openMenu() => Promise<boolean>
Open the menu. Returns a promise that resolves to false if the menu was already open.
# Returns
Type: Promise<boolean>
# Dependencies
# Used by
- mx-autocomplete
- mx-block-select
- mx-dropdown-menu
- mx-page-header
- mx-pagination
- mx-table
- mx-table-row
- mx-tabs
- mx-time-picker
# Graph
graph TD;
mx-autocomplete --> mx-menu
mx-block-select --> mx-menu
mx-dropdown-menu --> mx-menu
mx-page-header --> mx-menu
mx-pagination --> mx-menu
mx-table --> mx-menu
mx-table-row --> mx-menu
mx-tabs --> mx-menu
mx-time-picker --> mx-menu
style mx-menu fill:#f9f,stroke:#333,stroke-width:4px
2
3
4
5
6
7
8
9
10
11
If you are having trouble setting a prop or adding an event listener, refer to this page.
# mx-menu
# Properties
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
anchorEl | -- | The element to which the menu's position will be anchored | HTMLElement | undefined |
isOpen | is-open | boolean | false |
# Events
| Event | Description | Type |
|---|---|---|
mxClose | Emitted when the menu closes. | CustomEvent<void> |
mxOpen | Emitted when the menu opens. | CustomEvent<void> |
# Methods
# closeMenu(skipTransition?: boolean) => Promise<boolean>
Close the menu. Returns a promise that resolves to false if the menu was already closed.
# Returns
Type: Promise<boolean>
# openMenu() => Promise<boolean>
Open the menu. Returns a promise that resolves to false if the menu was already open.
# Returns
Type: Promise<boolean>
# toggleMenu() => Promise<(skipTransition?: boolean) => Promise<boolean>>
Collapse/expand the accordion menu.
# Returns
Type: Promise<(skipTransition?: boolean) => Promise<boolean>>
If you are having trouble setting a prop or adding an event listener, refer to this page.
# mx-menu-item
# Properties
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
checked | checked | If multiSelect is false, this will render a checkmark on the right side of the menu item. If both multiSelect and checked are true, then the rendered multi-select checkbox will be checked. | boolean | false |
disabled | disabled | boolean | false | |
icon | icon | The class name of the icon to display on the left. This is sometimes automatically set to null to add an empty icon for alignment purposes (when a sibling menu item has an icon). | string | undefined |
label | label | A label to display above the menu item | string | undefined |
multiSelect | multi-select | Render a checkbox as part of the menu item. On small screens, the checkbox will appear on the left; otherwise, it will be on the right. | boolean | false |
selected | selected | This is automatically set by a parent Dropdown Menu. | boolean | false |
subtitle | subtitle | A subtitle to display below the menu item text | string | undefined |
# Events
| Event | Description | Type |
|---|---|---|
mxClick | Fired when an enabled menu item without a submenu is clicked. Used interally to close all ancestor menus. | CustomEvent<MouseEvent> |
# Methods
# closeAccordion(skipTransition?: boolean) => Promise<boolean>
Close the item's accordion.
# Returns
Type: Promise<boolean>
# closeSubMenu() => Promise<boolean>
Close the item's submenu.
# Returns
Type: Promise<boolean>
# focusMenuItem() => Promise<void>
Focuses the menu item.
# Returns
Type: Promise<void>
# getValue() => Promise<string>
Returns the menu item inner text (excluding any label or subtitle)
# Returns
Type: Promise<string>
# Dependencies
# Used by
# Depends on
# Graph
graph TD;
mx-menu-item --> mx-checkbox
mx-autocomplete --> mx-menu-item
mx-page-header --> mx-menu-item
mx-pagination --> mx-menu-item
mx-table --> mx-menu-item
mx-table-row --> mx-menu-item
mx-tabs --> mx-menu-item
mx-time-picker --> mx-menu-item
style mx-menu-item fill:#f9f,stroke:#333,stroke-width:4px
2
3
4
5
6
7
8
9
10
If you are having trouble setting a prop or adding an event listener, refer to this page.