Skip to content

Commit

Permalink
feat(mdc-menu): Support v-model for open/close
Browse files Browse the repository at this point in the history
  • Loading branch information
pgbross authored and pgbross committed Apr 10, 2018
1 parent 5560ea6 commit 1648ef5
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 66 deletions.
53 changes: 18 additions & 35 deletions components/menu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

```html
<mdc-menu-anchor>
<mdc-button raised @click="showMenu">Open Menu</mdc-button>
<mdc-menu ref="menu" @select="onSelect" @cancel="onCancel">
<mdc-button raised @click="open=true">Open Menu</mdc-button>
<mdc-menu v-model="open" @select="onSelect" @cancel="onCancel">
<mdc-menu-item>A Menu Item</mdc-menu-item>
<mdc-menu-item>Another Menu Item</mdc-menu-item>
<mdc-menu-item disabled>Disabled Menu Item</mdc-menu-item>
Expand All @@ -15,10 +15,10 @@

```javascript
var vm = new Vue({
data: {
open: false,
},
methods: {
showMenu() {
this.$refs.menu.show();
},
onSelect(selected) {
console.log('selected index: ' + selected.index);
},
Expand All @@ -29,36 +29,18 @@ var vm = new Vue({
});
```

### Positioning

The menu can either be positioned manually or automatically by anchoring it to an element.

The anchor is a wrapper element that contains the actual visible element to attach to:

```html
<mdc-menu-anchor>
<mdc-button>Menu</mdc-button>
<mdc-menu >
<!-- ... -->
</mdc-menu>
</mdc-menu-anchor>
```

> for manual positioning see the [MDC docs](https://material.io/components/web/catalog/menus/#manual-positioning)
### Props

#### mdc-menu

| props | Type | Default | Description |
| ------------------------ | ------- | --------- | ------------------------------------------------------------- |
| `open-from-top-left` | Boolean | false | overrides opening point |
| `open-from-top-right` | Boolean | false | overrides opening point |
| `open-from-bottom-left` | Boolean | false | overrides opening point |
| `open-from-bottom-right` | Boolean | false | overrides opening point |
| `quick-open` | Boolean | false | sets whether the menu should open and close without animation |
| `anchor-corner` | Number | undefined | set anchor corner alignment of menu corner |
| `anchor-margin` | Object | undefined | set anchor margin of menu (top, right, bottom, left) |
| props | Type | Default | Description |
| --------------- | ----------------- | --------- | ------------------------------------------------------------- |
| `open` | Boolean or Object | false | optional v-model when true opens menu |
| `quick-open` | Boolean | false | sets whether the menu should open and close without animation |
| `anchor-corner` | Number | undefined | set anchor corner alignment of menu corner |
| `anchor-margin` | Object | undefined | set anchor margin of menu (top, right, bottom, left) |

> if open is an object it should set {focusIndex: number} as per [MDC menu docs](https://github.com/material-components/material-components-web/tree/master/packages/mdc-menu)
> for anchor corner and margin see the [MDC docs](https://github.com/material-components/material-components-web/tree/master/packages/mdc-menu#MDCMenu)
Expand All @@ -70,10 +52,11 @@ The anchor is a wrapper element that contains the actual visible element to atta

### Events

| props | arg | Description |
| --------- | -------------------------------------- | ------------------------------------ |
| `@select` | `{ index: Number, item: HTMLElement }` | emitted when a menu item is selected |
| `@cancel` | | emitted when menu is cancelled |
| props | arg | Description |
| --------- | -------------------------------------- | ---------------------------------------------------------- |
| `@change` | Boolean | notify v-model/listeners that menu open state has changed. |
| `@select` | `{ index: Number, item: HTMLElement }` | emitted when a menu item is selected |
| `@cancel` | | emitted when menu is cancelled |

> `select` event data specifies index and item :
Expand Down
34 changes: 22 additions & 12 deletions components/menu/demo.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
<template>
<div class="mdc-demo mdc-demo--container">
<mdc-menu-anchor class="myAnchor">
<mdc-button raised @click="$refs.menu.show()">Open Menu</mdc-button>
<mdc-menu ref="menu">
<mdc-menu-item >A Menu Item</mdc-menu-item>
<mdc-menu-item >Another Menu Item</mdc-menu-item>
<mdc-menu-item disabled >Disabled Menu Item</mdc-menu-item>
<mdc-menu-divider>Another Menu Item</mdc-menu-divider>
<mdc-menu-item >Parted Menu Item</mdc-menu-item>
</mdc-menu>
</mdc-menu-anchor>
</div>
<div class="mdc-demo mdc-demo--container">
<mdc-menu-anchor class="myAnchor">
<mdc-button raised @click="open=true">Open Menu</mdc-button>
<mdc-menu v-model="open">
<mdc-menu-item>A Menu Item</mdc-menu-item>
<mdc-menu-item>Another Menu Item</mdc-menu-item>
<mdc-menu-item disabled>Disabled Menu Item</mdc-menu-item>
<mdc-menu-divider>Another Menu Item</mdc-menu-divider>
<mdc-menu-item>Parted Menu Item</mdc-menu-item>
</mdc-menu>
</mdc-menu-anchor>
</div>
</template>

<script>
export default {
data() {
return {
open: false,
};
},
};
</script>
45 changes: 26 additions & 19 deletions components/menu/mdc-menu.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
<template>
<div ref="root" class="mdc-menu mdc-simple-menu"
:class="classes" :style="styles"
tabindex="-1">
<ul ref="items" class="mdc-simple-menu__items mdc-list"
role="menu" aria-hidden="true">
<slot></slot>
</ul>
</div>
<div ref="root" class="mdc-menu mdc-simple-menu" :class="classes" :style="styles" tabindex="-1">
<ul ref="items" class="mdc-simple-menu__items mdc-list" role="menu" aria-hidden="true">
<slot></slot>
</ul>
</div>
</template>

<script>
Expand All @@ -16,28 +13,32 @@ import { emitCustomEvent } from '../base';
export default {
name: 'mdc-menu',
model: {
prop: 'open',
event: 'change',
},
props: {
'open-from-top-left': Boolean,
'open-from-top-right': Boolean,
'open-from-bottom-left': Boolean,
'open-from-bottom-right': Boolean,
open: [Boolean, Object],
'quick-open': Boolean,
'anchor-corner': [String, Number],
'anchor-margin': Object,
},
data() {
return {
classes: {
'mdc-simple-menu--open-from-top-left': this.openFromTopLeft,
'mdc-simple-menu--open-from-top-right': this.openFromTopRight,
'mdc-simple-menu--open-from-bottom-left': this.openFromBottomLeft,
'mdc-simple-menu--open-from-bottom-right': this.openFromBottomRight,
},
classes: {},
styles: {},
items: [],
};
},
methods: {
onOpen_(value) {
if (value) {
this.foundation.open(typeof value === 'object' ? value : void 0);
} else {
this.foundation.close();
}
},
show(options) {
this.foundation.open(options);
},
Expand All @@ -56,7 +57,10 @@ export default {
this.$emit('update');
};
this.slotObserver = new MutationObserver(() => refreshItems());
this.slotObserver.observe(this.$el, { childList: true, subtree: true });
this.slotObserver.observe(this.$el, {
childList: true,
subtree: true,
});
this._previousFocus = undefined;
Expand Down Expand Up @@ -95,6 +99,7 @@ export default {
index: evtData.index,
item: this.items[evtData.index],
};
this.$emit('change', false);
this.$emit('select', evt);
emitCustomEvent(
this.$el,
Expand All @@ -103,6 +108,7 @@ export default {
);
},
notifyCancel: () => {
this.$emit('change', false);
this.$emit('cancel');
emitCustomEvent(this.$el, MDCMenuFoundation.strings.CANCEL_EVENT, {});
},
Expand Down Expand Up @@ -161,6 +167,7 @@ export default {
}
},
watch: {
open: 'onOpen_',
quickOpen(nv) {
this.foundation.setQuickOpen(nv);
},
Expand Down

0 comments on commit 1648ef5

Please sign in to comment.