import Vue from 'vue'
|
|
const TIMEOUT = 150
|
|
Vue.directive('hover-dropdown', {
|
bind (el, binding, vnode) {
|
const dropdown = vnode.componentInstance
|
const toggle = el.querySelector('.dropdown-toggle')
|
const menu = el.querySelector('.dropdown-menu')
|
let timeout = null
|
let hovered = false
|
|
// Patch hideMenu method
|
const _hideMenu = dropdown.hideMenu
|
dropdown.hideMenu = function () {
|
// Prevent dropdown close
|
if (!hovered) _hideMenu.call(this)
|
else dropdown.visible = true
|
}
|
|
function isStatic () {
|
return window.getComputedStyle(menu, null).getPropertyValue('position') === 'static'
|
}
|
|
function clearCloseTimeout () {
|
if (!timeout) return
|
clearTimeout(timeout)
|
timeout = null
|
}
|
|
function show () {
|
clearCloseTimeout()
|
if (isStatic() || dropdown.visible) return
|
dropdown.$nextTick(() => dropdown.show())
|
}
|
|
function hide () {
|
clearCloseTimeout()
|
if (isStatic()) return
|
|
timeout = setTimeout(() => {
|
clearCloseTimeout()
|
dropdown.hide()
|
}, TIMEOUT)
|
}
|
|
const listeners = {
|
toggleMouseenter: () => {
|
if (!isStatic()) hovered = true
|
show()
|
},
|
toggleMouseleave: () => {
|
hovered = false
|
hide()
|
},
|
menuMouseenter: show,
|
menuMouseleave: hide
|
}
|
|
toggle.addEventListener('mouseenter', listeners.toggleMouseenter)
|
toggle.addEventListener('mouseleave', listeners.toggleMouseleave)
|
menu.addEventListener('mouseenter', listeners.menuMouseenter)
|
menu.addEventListener('mouseleave', listeners.menuMouseleave)
|
|
// Save data
|
el.hoverDropdownDirectiveData = {
|
toggle,
|
menu,
|
clearCloseTimeout,
|
listeners
|
}
|
},
|
unbind (el) {
|
const i = el.hoverDropdownDirectiveData
|
|
if (!i) return
|
|
i.clearCloseTimeout()
|
|
i.toggle.removeEventListener('mouseenter', i.listeners.toggleMouseenter)
|
i.toggle.removeEventListener('mouseleave', i.listeners.toggleMouseleave)
|
i.menu.removeEventListener('mouseenter', i.listeners.menuMouseenter)
|
i.menu.removeEventListener('mouseleave', i.listeners.menuMouseleave)
|
|
el.hoverDropdownDirectiveData = null
|
}
|
})
|