2
0
mirror of https://github.com/frappe/books.git synced 2025-02-06 05:58:35 +00:00
books/src/components/Popover.vue

93 lines
1.9 KiB
Vue
Raw Normal View History

2019-11-22 00:50:30 +05:30
<template>
<div ref="reference">
2019-11-22 00:50:30 +05:30
<div class="h-full">
<slot name="target" :toggleDropdown="toggleDropdown"></slot>
</div>
<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>
import Popper from 'popper.js';
2019-11-22 00:50:30 +05:30
export default {
name: 'Popover',
props: {
right: Boolean,
popoverClass: [String, Object, Array]
},
2019-11-22 00:50:30 +05:30
data() {
return {
isOpen: false
2019-11-22 00:50:30 +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
}
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: {
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) {
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
}
this.isOpen = false;
this.$emit('close');
2019-11-22 00:50:30 +05:30
}
}
};
</script>