Skip to content
This repository has been archived by the owner on Nov 30, 2020. It is now read-only.

Commit

Permalink
feat(menu): update to mdc-web v3.1.0 (#388)
Browse files Browse the repository at this point in the history
* feat(menu): update to mdc-web v3.1.0

* test(menu): add snapshots
  • Loading branch information
tychenjiajun committed Aug 16, 2019
1 parent 04e8c90 commit 8e6734e
Show file tree
Hide file tree
Showing 12 changed files with 419 additions and 88 deletions.
3 changes: 0 additions & 3 deletions components/list/ListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,6 @@ export default {
if (this.$slots.graphic) {
this.$slots.graphic.map(n => {
n.elm.classList.add('mdc-list-item__graphic')
if (this.$el.getAttribute('role') === 'menuitem') {
n.elm.classList.add('mdc-menu__selection-group-icon')
}
})
}
if (this.$slots.meta) {
Expand Down
111 changes: 68 additions & 43 deletions components/menu/Menu.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<template>
<div
:tabindex="tabIndex"
class="mdc-menu mdc-menu-surface"
@MDCMenu:selected="onSelect"
>
Expand Down Expand Up @@ -30,8 +29,8 @@ export default {
default: false
},
anchorCorner: {
type: String,
default: ''
type: [Number, String],
default: 0
},
absolutePositionX: {
type: Number,
Expand All @@ -55,7 +54,15 @@ export default {
},
defaultFocusState: {
type: [Number, String],
default: null
default: 1
},
selectedIndex: {
type: Number,
default: -1
},
isHoisted: {
type: Boolean,
default: false
}
},
data () {
Expand All @@ -77,27 +84,31 @@ export default {
if (!this.defaultFocusState) return null
const upperCaseFocusState = String(this.defaultFocusState).toUpperCase()
if (isNaN(this.defaultFocusState) &&
DefaultFocusState.hasOwnProperty(upperCaseFocusState)
) {
if (isNaN(this.defaultFocusState)) {
return DefaultFocusState[upperCaseFocusState]
}
const numberFocusState = Number(this.defaultFocusState)
if (!isNaN(this.defaultFocusState) &&
DefaultFocusState.hasOwnProperty(numberFocusState)
) {
if (!isNaN(this.defaultFocusState)) {
return numberFocusState
}
return null
},
tabIndex () {
if (this.$slots.default[0].componentOptions.tag.toLowerCase() === 'm-list') {
return -1
_anchorCorner () {
if (!this.anchorCorner) return null
const upperCaseFocusState = String(this.anchorCorner).toUpperCase()
if (isNaN(this.anchorCorner)) {
return Corner[upperCaseFocusState]
}
return this.mdcMenu ? (this.mdcMenu.open ? 0 : -1) : (this.open ? 0 : -1)
const numberFocusState = Number(this.anchorCorner)
if (!isNaN(this.anchorCorner)) {
return numberFocusState
}
return null
}
},
watch: {
Expand All @@ -112,14 +123,15 @@ export default {
this.mdcMenu.hoistMenuToBody()
}
},
isHoisted () {
this.mdcMenu.setIsHoisted(this.isHoisted)
},
fixed () {
this.mdcMenu.setFixedPosition(this.fixed)
},
anchorCorner () {
if (this.anchorCorner !== '') {
this.mdcMenu.setAnchorCorner(Corner[this.anchorCorner.toUpperCase()])
} else {
this.mdcMenu.setAnchorCorner(Corner.TOP_START)
if (this._anchorCorner !== null) {
this.mdcMenu.setAnchorCorner(this.anchorCorner)
}
},
absolutePositionX () {
Expand All @@ -142,31 +154,39 @@ export default {
},
'mdcMenu.open' () {
this.model = this.mdcMenu.open
},
selectedIndex () {
if (this.selectedIndex >= 0) this.mdcMenu.setSelectedIndex(this.selectedIndex)
}
},
mounted () {
this.updateSlot()
this.slotObserver = new MutationObserver(() => this.updateSlot())
this.slotObserver.observe(this.$el, {
childList: true,
subtree: true
})
this.mdcMenu = MDCMenu.attachTo(this.$el)
if (this.hoistToBody) {
this.mdcMenu.hoistMenuToBody()
}
this.mdcMenu.setFixedPosition(this.fixed)
if (this.anchorCorner !== '') {
this.mdcMenu.setAnchorCorner(Corner[this.anchorCorner.toUpperCase()])
}
if (this.absolutePositionX !== null || this.absolutePositionY !== null) {
this.mdcMenu.setAbsolutePosition(this.absolutePositionX, this.absolutePositionY)
}
this.mdcMenu.wrapFocus = this.wrapFocus
this.$nextTick(() => {
this.updateSlot()
this.slotObserver = new MutationObserver(() => this.updateSlot())
this.slotObserver.observe(this.$el, {
childList: true,
subtree: true
})
this.mdcMenu = MDCMenu.attachTo(this.$el)
if (this.hoistToBody) {
this.mdcMenu.hoistMenuToBody()
}
this.mdcMenu.setFixedPosition(this.fixed)
if (this._anchorCorner) {
this.mdcMenu.setAnchorCorner(this._anchorCorner)
}
if (this.absolutePositionX !== null || this.absolutePositionY !== null) {
this.mdcMenu.setAbsolutePosition(this.absolutePositionX, this.absolutePositionY)
}
this.mdcMenu.wrapFocus = this.wrapFocus
if (this.focusState !== null) {
this.mdcMenu.setDefaultFocusState(this.focusState)
}
if (this.focusState !== null) {
this.mdcMenu.setDefaultFocusState(this.focusState)
}
this.mdcMenu.setIsHoisted(this.isHoisted)
if (this.selectedIndex >= 0) this.mdcMenu.setSelectedIndex(this.selectedIndex)
})
},
beforeDestroy () {
this.slotObserver.disconnect()
Expand All @@ -176,15 +196,20 @@ export default {
updateSlot () {
if (this.$slots.default) {
this.$slots.default.map(n => {
n.componentInstance.$el.setAttribute('role', 'menu')
n.componentInstance.$el.setAttribute('aria-hidden', 'true')
n.componentInstance.$el.setAttribute('aria-orientation', 'vertical')
if (n.elm) {
n.elm.setAttribute('role', 'menu')
n.elm.setAttribute('aria-hidden', 'true')
n.elm.setAttribute('aria-orientation', 'vertical')
n.elm.querySelectorAll('.mdc-list-item').forEach(i => {
i.setAttribute('role', 'menuitem')
})
}
})
}
},
onSelect (event) {
this.model = false
this.$emit('select', event.detail)
this.$emit('selected', event.detail)
}
}
}
Expand Down
40 changes: 40 additions & 0 deletions components/menu/MenuSelectionGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<ul class="mdc-menu__selection-group">
<slot />
</ul>
</template>

<script>
export default {
data () {
return {
slotObserver: undefined
}
},
mounted () {
this.$nextTick(() => {
this.updateSlot()
this.slotObserver = new MutationObserver(() => this.updateSlot())
this.slotObserver.observe(this.$el, {
childList: true,
subtree: true
})
})
},
methods: {
updateSlot () {
if (this.$slots.default) {
this.$slots.default.forEach(n => {
if (n.elm instanceof Element && n.elm.classList.contains('mdc-list-item')) {
n.elm.querySelector('.mdc-list-item__graphic').classList.add('mdc-menu__selection-group-icon')
}
})
}
}
}
}
</script>

<style scoped>
</style>
76 changes: 56 additions & 20 deletions components/menu/MenuSurface.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import { Corner, MDCMenuSurface } from '@material/menu-surface'
export default {
name: 'MenuSurface',
model: {
prop: 'open',
event: 'change'
Expand All @@ -31,16 +30,24 @@ export default {
default: false
},
anchorCorner: {
type: String,
default: ''
type: [Number, String],
default: 0
},
absolutePositionX: {
type: Number,
default: -1
default: null
},
absolutePositionY: {
type: Number,
default: -1
default: null
},
hoistToBody: {
type: Boolean,
default: false
},
isHoisted: {
type: Boolean,
default: false
}
},
data () {
Expand All @@ -56,45 +63,74 @@ export default {
set (value) {
this.$emit('change', value)
}
},
_anchorCorner () {
if (!this.anchorCorner) return null
const upperCaseFocusState = String(this.anchorCorner).toUpperCase()
if (isNaN(this.anchorCorner)) {
return Corner[upperCaseFocusState]
}
const numberFocusState = Number(this.anchorCorner)
if (!isNaN(this.anchorCorner)) {
return numberFocusState
}
return null
}
},
watch: {
open () {
this.mdcMenuSurface.open = this.open
this.open ? this.mdcMenuSurface.getDefaultFoundation().open() : this.mdcMenuSurface.getDefaultFoundation().close()
},
quickOpen () {
this.mdcMenuSurface.quickOpen = this.quickOpen
},
hoistToBody () {
if (this.hoistToBody) {
this.mdcMenuSurface.hoistMenuToBody()
}
},
isHoisted () {
this.mdcMenuSurface.setIsHoisted(this.isHoisted)
},
fixed () {
this.mdcMenuSurface.setFixedPosition(this.fixed)
},
anchorCorner () {
if (this.anchorCorner !== '') {
this.mdcMenuSurface.setAnchorCorner(Corner[this.anchorCorner.toUpperCase()])
} else {
this.mdcMenuSurface.setAnchorCorner(Corner.TOP_START)
if (this._anchorCorner !== null) {
this.mdcMenuSurface.setAnchorCorner(this.anchorCorner)
}
},
absolutePositionX () {
if (this.absolutePositionX > -1 && this.absolutePositionY > -1) {
if (this.absolutePositionX !== null) {
this.mdcMenuSurface.setAbsolutePosition(this.absolutePositionX, this.absolutePositionY)
}
},
absolutePositionY () {
if (this.absolutePositionX > -1 && this.absolutePositionY > -1) {
if (this.absolutePositionY !== null) {
this.mdcMenuSurface.setAbsolutePosition(this.absolutePositionX, this.absolutePositionY)
}
}
},
mounted () {
this.mdcMenuSurface = MDCMenuSurface.attachTo(this.$el)
this.mdcMenuSurface.setFixedPosition(this.fixed)
if (this.anchorCorner !== '') {
this.mdcMenuSurface.setAnchorCorner(Corner[this.anchorCorner.toUpperCase()])
}
if (this.absolutePositionX > -1 && this.absolutePositionY > -1) {
this.mdcMenuSurface.setAbsolutePosition(this.absolutePositionX, this.absolutePositionY)
}
this.$nextTick(() => {
this.mdcMenuSurface = MDCMenuSurface.attachTo(this.$el)
this.mdcMenuSurface.setFixedPosition(this.fixed)
if (this._anchorCorner) {
this.mdcMenuSurface.setAnchorCorner(this._anchorCorner)
}
if (this.absolutePositionX !== null || this.absolutePositionY !== null) {
this.mdcMenuSurface.setAbsolutePosition(this.absolutePositionX, this.absolutePositionY)
}
if (this.hoistToBody) {
this.mdcMenuSurface.hoistMenuToBody()
}
this.mdcMenuSurface.setIsHoisted(this.isHoisted)
this.open ? this.mdcMenuSurface.getDefaultFoundation().open() : this.mdcMenuSurface.getDefaultFoundation().close()
})
},
beforeDestroy () {
this.mdcMenuSurface.destroy()
Expand Down

0 comments on commit 8e6734e

Please sign in to comment.