Skip to content

Instantly share code, notes, and snippets.

@leevigraham
Last active April 16, 2018 00:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leevigraham/4c234170af4168df2fbd2621b32c8a6e to your computer and use it in GitHub Desktop.
Save leevigraham/4c234170af4168df2fbd2621b32c8a6e to your computer and use it in GitHub Desktop.
<template>
<div>
<div ref="trigger">
<slot name="trigger"
v-bind:isActive="isActive"
v-bind:toggle="toggle"
>
<button v-on:click="toggle">Toggle</button>
</slot>
</div>
<div ref="flyout" v-show="isActive">
<slot></slot>
</div>
</div>
</template>
<script>
import Popper from 'popper.js'
export default {
name: 'flyout',
data: function () {
return {
isActive: false,
referenceElement: null,
popperElement: null,
referenceElementVnode: null,
popperElementVnode: null,
popper: null,
popperOptions:
{
placement: 'bottom-start',
modifiers: {
arrow: {enabled: false},
preventOverflow: {
boundariesElement: 'viewport'
},
flip: {
behavior: ['bottom-start', 'bottom-end', 'top-start', 'top-end'],
boundariesElement: 'viewport'
}
}
}
}
},
// // NOTE: render method is triggered whenever any state changes
// render (createElement) {
//
// let referenceElementVnode = this.$scopedSlots.referenceElement({
// isActive: this.isActive,
// toggle: this.toggle,
// })
//
// referenceElementVnode.data.ref='trigger'
//
// let popperElementVnode = this.$scopedSlots.default({
// isActive: this.isActive,
// toggle: this.toggle
// })
//
// referenceElementVnode.data.ref='flyout'
//
// let root = createElement('div', [referenceElementVnode, popperElementVnode])
// return root
// },
created () {
},
destroyed () {
this.destroyPopper()
},
mounted () {
this.referenceElement = this.$refs.trigger
this.popperElement = this.$refs.flyout
},
watch: {
isActive: function (isActive) {
(isActive) ? this.createPopper() : this.destroyPopper()
}
},
computed: {},
methods: {
toggle () {
this.isActive = !this.isActive
},
createPopper () {
if (this.popper) {
return
}
this.popper = new Popper(
this.referenceElement,
this.popperElement,
this.popperOptions
)
document.addEventListener('click', this.handleDocumentClick)
},
destroyPopper () {
if (!this.popper) {
return
}
this.popper.destroy()
this.popper = null
document.removeEventListener('click', this.handleDocumentClick)
},
handleDocumentClick (e) {
let target = e.target
if (
this.referenceElement === target ||
this.popperElement === target ||
this.referenceElement.contains(target) ||
this.popperElement.contains(target)
) {
return
}
this.isActive = false
}
}
}
</script>
<flyout v-cloak>
<button slot="trigger"
slot-scope="props"
v-on:click="props.toggle()"
v-bind:class="props.isActive ? 'bg-green': 'bg-red'">
Toggle
</button>
<div>
… Dropdown content …
</div>
</flyout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment