2019-11-22 00:50:30 +05:30
|
|
|
<template>
|
2019-12-11 14:35:46 +05:30
|
|
|
<div ref="reference">
|
2019-11-22 00:50:30 +05:30
|
|
|
<div class="h-full">
|
|
|
|
<slot name="target" :toggleDropdown="toggleDropdown"></slot>
|
|
|
|
</div>
|
2019-12-11 14:35:46 +05:30
|
|
|
<portal to="popovers">
|
|
|
|
<div
|
|
|
|
ref="popover"
|
|
|
|
:class="popoverClass"
|
|
|
|
class="mt-1 bg-white rounded-5px border min-w-40 shadow-md"
|
|
|
|
v-show="isOpen"
|
|
|
|
>
|
|
|
|
<slot name="content" :toggleDropdown="toggleDropdown"></slot>
|
|
|
|
</div>
|
|
|
|
</portal>
|
2019-11-22 00:50:30 +05:30
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2019-12-11 14:35:46 +05:30
|
|
|
import Popper from 'popper.js';
|
|
|
|
|
2019-11-22 00:50:30 +05:30
|
|
|
export default {
|
|
|
|
name: 'Popover',
|
2019-12-11 14:35:46 +05:30
|
|
|
props: {
|
|
|
|
right: Boolean,
|
|
|
|
popoverClass: [String, Object, Array]
|
|
|
|
},
|
2019-11-22 00:50:30 +05:30
|
|
|
data() {
|
|
|
|
return {
|
2019-12-11 14:35:46 +05:30
|
|
|
isOpen: false
|
2019-11-22 00:50:30 +05:30
|
|
|
};
|
|
|
|
},
|
2019-12-11 14:35:46 +05:30
|
|
|
mounted() {
|
|
|
|
let listener = e => {
|
|
|
|
let $els = [this.$refs.reference, this.$refs.popover];
|
|
|
|
let insideClick = $els.some(
|
|
|
|
$el => $el && (e.target === $el || $el.contains(e.target))
|
|
|
|
);
|
|
|
|
if (insideClick) {
|
|
|
|
return;
|
2019-11-22 00:50:30 +05:30
|
|
|
}
|
2019-12-11 14:35:46 +05:30
|
|
|
this.close();
|
|
|
|
};
|
|
|
|
document.addEventListener('click', listener);
|
|
|
|
this.$once('hook:beforeDestroy', () => {
|
|
|
|
document.removeEventListener('click', listener);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
beforeDestroy() {
|
|
|
|
this.popper.destroy();
|
2019-11-22 00:50:30 +05:30
|
|
|
},
|
|
|
|
methods: {
|
2019-12-11 14:35:46 +05:30
|
|
|
setupPopper() {
|
|
|
|
if (!this.popper) {
|
|
|
|
this.popper = new Popper(this.$refs.reference, this.$refs.popover, {
|
|
|
|
placement: this.right ? 'bottom-end' : 'bottom-start'
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.popper.scheduleUpdate();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
toggleDropdown(flag) {
|
2019-11-22 00:50:30 +05:30
|
|
|
if (flag == null) {
|
2019-12-11 14:35:46 +05:30
|
|
|
flag = !this.isOpen;
|
|
|
|
}
|
|
|
|
flag = Boolean(flag);
|
|
|
|
if (flag) {
|
|
|
|
this.open();
|
|
|
|
} else {
|
|
|
|
this.close();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
open() {
|
|
|
|
if (this.isOpen) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.isOpen = true;
|
|
|
|
this.$nextTick(() => {
|
|
|
|
this.setupPopper();
|
|
|
|
});
|
|
|
|
this.$emit('open');
|
|
|
|
},
|
|
|
|
close() {
|
|
|
|
if (!this.isOpen) {
|
|
|
|
return;
|
2019-11-22 00:50:30 +05:30
|
|
|
}
|
2019-12-11 14:35:46 +05:30
|
|
|
this.isOpen = false;
|
|
|
|
this.$emit('close');
|
2019-11-22 00:50:30 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|