# Menus

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.

New… Open…
Save Save As…
Close
<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&hellip;</mx-menu-item>
  <mx-menu-item icon="ph ph-folder-open" @click="clickHandler">Open&hellip;</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&hellip;</mx-menu-item>
  <hr>
  <mx-menu-item @click="clickHandler">Close</mx-menu-item>
</mx-menu>
1
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.

Edit Undo Redo Cut Copy AutoFill Contact… Passwords…
Find & Sort Find… Find Next Find Previous Sort By Name Date Modified Size
<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&hellip;
      </mx-menu-item>
      <mx-menu-item @click="clickHandler">
        Passwords&hellip;
      </mx-menu-item>
    </mx-menu-accordion>
  </mx-menu-item>
  <hr>
  <mx-menu-item>
    Find &amp; Sort
    <mx-menu slot="submenu">
      <mx-menu-item @click="clickHandler">Find&hellip;</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>
1
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
1
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

Show Minimap Word Wrap design@moxiworks.com Office One
Open Menu Menu Item 1Menu Item 2Menu Item 3Menu Item 4Menu Item 5Menu Item 6Menu Item 7Menu Item 8Menu Item 9Menu Item 10Menu Item 11Menu Item 12
<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>
1
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
1

# 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 autocomplete attribute is set to off to 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>
1
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>
1
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())
  )
},
1
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
1
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())
}
1
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>
1
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
}
1
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

# 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
1
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
1
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.