11<template >
22 <div
33 v-if =" $slots.trigger"
4- @click =" modal?.show ()" class =" inline-flex items-center cursor-pointer w-full"
4+ @click =" toggleModal ()" class =" inline-flex items-center cursor-pointer w-full"
55 >
66 <slot name =" trigger" ></slot >
77 </div >
88 <Teleport to =" body" >
9- <div ref =" modalEl" tabindex =" -1" aria-hidden =" true" class =" [scrollbar-gutter:stable] hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-full max-h-full" >
10- <div v-bind =" $attrs" class =" relative p-4 max-h-full" >
9+ <div v-show =" isModalOpen" v-if =" !removeFromDom" @click =" backdropClick" v-bind =" $attrs" class =" bg-black/50 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-1rem max-h-full flex" >
1110 <!-- Modal content -->
1211 <div class =" relative bg-lightDialogBackgorund rounded-lg shadow-sm dark:bg-darkDialogBackgorund" >
1312
1413 <!-- Modal body -->
1514 <div class =" p-4 md:p-5 space-y-4 text-lightDialogBodyText dark:text-darkDialogBodyText" >
16- <slot ></slot >
15+ <slot ></slot >
1716 </div >
1817
1918 <!-- Confirmation Modal -->
3433 <Button
3534 @click ="
3635 showConfirmationOnClose = false;
37- modal?.hide ();
36+ close ();
3837 "
3938 >
4039 Confirm
4443 </div >
4544 </div >
4645 </div >
47- </div >
4846 </Teleport >
4947</template >
5048
5149<script setup lang="ts">
5250import Button from " ./Button.vue" ;
5351import { ref , onMounted , nextTick , onUnmounted , computed , type Ref } from ' vue' ;
54- import { Modal } from ' flowbite' ;
5552
56- const modalEl = ref (null );
57- const modal: Ref <Modal | null > = ref (null );
53+ const isModalOpen = ref (false );
5854
59- interface DialogButton {
60- label: string
61- onclick: (dialog : any ) => void
62- options? : Record <string , any >
63- }
55+ const removeFromDom = computed (() => {
56+ return props .removeFromDomOnClose && ! isModalOpen .value ;
57+ })
6458
6559interface DialogProps {
66- buttons? : DialogButton []
6760 clickToCloseOutside? : boolean
6861 beforeCloseFunction? : (() => void | Promise <void >) | null
6962 beforeOpenFunction? : (() => void | Promise <void >) | null
70- closable? : boolean
7163 askForCloseConfirmation? : boolean
7264 closeConfirmationText? : string
65+ removeFromDomOnClose? : boolean
7366}
7467
7568const props = withDefaults (defineProps <DialogProps >(), {
76- buttons : () => [],
7769 clickToCloseOutside: true ,
7870 beforeCloseFunction: null ,
7971 beforeOpenFunction: null ,
80- closable: true ,
8172 askForCloseConfirmation: false ,
8273 closeConfirmationText: ' Are you sure you want to close this dialog?' ,
74+ removeFromDomOnClose: false ,
8375})
8476
85- const buttons = computed <DialogButton []>(() => {
86- if (props .buttons && props .buttons .length > 0 ) {
87- return props .buttons ;
88- }
89- return [
90- {
91- label: ' Close' ,
92- onclick : (dialog : any ) => {
93- if (! props .askForCloseConfirmation ) {
94- dialog .hide ();
95- } else {
96- showConfirmationOnClose .value = true ;
97- }
98- },
99- options: {}
100- }
101- ];
102- });
103-
10477const showConfirmationOnClose = ref (false );
105- onMounted (async () => {
106- // await one tick when all is mounted
107- await nextTick ();
108- modal .value = new Modal (
109- modalEl .value ,
110- {
111- closable: props .closable ,
112- backdrop: props .clickToCloseOutside ? ' dynamic' : ' static' ,
113- onHide : async () => {
114- if (props .beforeCloseFunction ) {
115- await props .beforeCloseFunction ();
116- }
117- },
118- onShow : async () => {
119- if (props .beforeOpenFunction ) {
120- await props .beforeOpenFunction ();
121- }
122- },
123- }
124- );
125- })
12678
127- onUnmounted (() => {
128- // destroy tooltip
129- modal .value ?.destroy ();
130- })
13179
132- function open() {
133- modal .value ?.show ();
80+ async function open() {
81+ await props .beforeOpenFunction ?.();
82+ isModalOpen .value = true ;
13483}
13584
136- function close() {
137- modal .value ?.hide ();
85+ async function close() {
86+ await props .beforeCloseFunction ?.();
87+ isModalOpen .value = false ;
13888}
13989
14090defineExpose ({
@@ -145,11 +95,24 @@ defineExpose({
14595
14696function tryToHideModal() {
14797 if (! props .askForCloseConfirmation ) {
148- modal . value ?. hide ();
98+ close ();
14999 } else {
150100 showConfirmationOnClose .value = true ;
151101 }
152102}
153103
104+ function toggleModal() {
105+ if (isModalOpen .value ) {
106+ tryToHideModal ();
107+ } else {
108+ open ();
109+ }
110+ }
111+
112+ function backdropClick(e : MouseEvent ) {
113+ if (props .clickToCloseOutside && e .target === e .currentTarget ) {
114+ tryToHideModal ();
115+ }
116+ }
154117
155118 </script >
0 commit comments