UPDATED Here is a codesandbox recreating the issue - Modal Does not hide: https://codesandbox.io/s/vue3-popperjs-modal-64762?file=/src/components/Modal.vue
I am new to Vue and cannot figure out how to Close the modal from the Hide Modal button within the component. I am using Vue.js and Popper.js for a modal/dropdown component.
I have tried emitting, rels and passing a prop but cannot get it to function correctly. I stripped it down to the shell code below.
** Main Component **
<template>
<div>
<Head title="Main" />
<div class="flex items-center">
<div class="flex">
<dropdown :auto-close="false" class="focus:z-10 px-4 hover:bg-gray-100 focus:border-white rounded-l focus:ring md:px-6" placement="auto">
<template #default>
<div class="flex">
<button id="open" class="btn-indigo" type="button">Open Modal</button>
</div>
</template>
<template #dropdown>
<div class="mt-2 px-4 py-6 w-screen bg-white rounded shadow-xl" style="maxWidth: 600px">
<h1>Modal Content</h1>
<button id="close" class="btn-indigo" type="button">Hide Modal</button>
</div>
</template>
</dropdown>
</div>
</div>
</div>
</template>
<script>
import { Head } from '@inertiajs/inertia-vue3'
import Dropdown from '@/Shared/Dropdown'
export default {
components: {
Head,
Dropdown,
},
}
</script>
** And Dropdown Component **
<template>
<button type="button" @click="show = true">
<slot />
<teleport v-if="show" to="#dropdown">
<div>
<div style="position: fixed; top: 0; right: 0; left: 0; bottom: 0; z-index: 99998; background: black; opacity: 0.2" @click="show = false" />
<div ref="dropdown" style="position: absolute; z-index: 99999" @click.stop="show = !autoClose">
<slot name="dropdown" />
</div>
</div>
</teleport>
</button>
</template>
<script>
import { createPopper } from '@popperjs/core'
export default {
props: {
placement: {
type: String,
default: 'bottom-end',
},
autoClose: {
type: Boolean,
default: true,
},
},
data() {
return {
show: false,
}
},
watch: {
show(show) {
if (show) {
this.$nextTick(() => {
this.popper = createPopper(this.$el, this.$refs.dropdown, {
placement: this.placement,
modifiers: [
{
name: 'preventOverflow',
options: {
altBoundary: true,
},
},
],
})
})
} else if (this.popper) {
setTimeout(() => this.popper.destroy(), 100)
}
},
},
mounted() {
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
this.show = false
}
})
},
}
</script>