UNPKG

zk-desktop-ui

Version:

ZKTeco UI Components

158 lines (139 loc) 4.24 kB
import PopperJS from './popper' import { PopupManager } from 'vue-popup' PopupManager.zIndex = 2000 /** * @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper. * @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper. * @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -right), left(-start, -end) * @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative). * @param {Boolean} [visible=false] Visibility of the popup element. * @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style. */ export default { props: { placement: { type: String, default: 'bottom' }, boundariesPadding: { type: Number, default: 5 }, reference: {}, popper: {}, offset: { default: 0 }, value: Boolean, visibleArrow: Boolean, transition: String, appendToBody: { type: Boolean, default: true }, options: { type: Object, default() { return { gpuAcceleration: false } } } }, data() { return { showPopper: false } }, watch: { value: { immediate: true, handler(val) { this.showPopper = val this.$emit('input', val) } }, showPopper(val) { val ? this.updatePopper() : this.destroyPopper() this.$emit('input', val) } }, methods: { createPopper() { if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) { return } const options = this.options const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper let reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference if (!reference && this.$slots.reference && this.$slots.reference[0]) { reference = this.referenceElm = this.$slots.reference[0].elm } if (!popper || !reference) return if (this.visibleArrow) this.appendArrow(popper) if (this.appendToBody) document.body.appendChild(this.popperElm) if (this.popperJS && this.popperJS.destroy) { this.popperJS.destroy() } options.placement = this.placement options.offset = this.offset this.popperJS = new PopperJS(reference, popper, options) this.popperJS.onCreate(_ => { this.$emit('created', this) this.resetTransformOrigin() this.$nextTick(this.updatePopper) }) this.popperJS._popper.style.zIndex = PopupManager.nextZIndex() }, updatePopper() { this.popperJS ? this.popperJS.update() : this.createPopper() }, doDestroy() { /* istanbul ignore if */ if (this.showPopper || !this.popperJS) return this.popperJS.destroy() this.popperJS = null }, destroyPopper() { if (this.popperJS) { this.resetTransformOrigin() } }, resetTransformOrigin() { let placementMap = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' } let placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0] let origin = placementMap[placement] this.popperJS._popper.style.transformOrigin = ['top', 'bottom'].indexOf(placement) > -1 ? `center ${ origin }` : `${ origin } center` }, appendArrow(element) { let hash if (this.appended) { return } this.appended = true for (let item in element.attributes) { if (/^_v-/.test(element.attributes[item].name)) { hash = element.attributes[item].name break } } const arrow = document.createElement('div') if (hash) { arrow.setAttribute(hash, '') } arrow.setAttribute('x-arrow', '') arrow.className = 'popper__arrow' element.appendChild(arrow) } }, beforeDestroy() { this.doDestroy() this.popperElm && this.popperElm.parentNode === document.body && document.body.removeChild(this.popperElm) } }