frontend/src/components/misc/popup.vue

66 lines
1.1 KiB
Vue

<template>
<slot name="trigger" :isOpen="open" :toggle="toggle"></slot>
<div class="popup" :class="{'is-open': open}" ref="popup">
<slot/>
</div>
</template>
<script>
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {onBeforeUnmount, onMounted, ref} from 'vue'
export default {
setup() {
const open = ref(false)
const popup = ref(null)
const toggle = () => {
open.value = !open.value
}
const hidePopup = e => {
if (!open.value) {
return
}
// we actually want to use popup.$el, not its value.
// eslint-disable-next-line vue/no-ref-as-operand
closeWhenClickedOutside(e, popup.$el, () => {
open.value = false
})
}
onMounted(() => {
document.addEventListener('click', hidePopup)
})
onBeforeUnmount(() => {
document.removeEventListener('click', hidePopup)
})
return {
open,
toggle,
}
},
}
</script>
<style scoped lang="scss">
.popup {
transition: opacity $transition;
opacity: 0;
height: 0;
overflow: hidden;
position: absolute;
top: 1rem;
margin: 0 !important;
&.is-open {
opacity: 1;
height: auto;
margin: 1rem 0 !important;
}
}
</style>