1
1
<script setup lang="ts">
2
- import { computed , nextTick , onBeforeUnmount , onMounted , ref , toRef , useAttrs , watch } from ' vue'
2
+ import { computed , getCurrentInstance , nextTick , onBeforeUnmount , onMounted , ref , useAttrs , watch } from ' vue'
3
3
import { vueFinalModalProps } from ' ./VueFinalModalProps'
4
4
import { useTransition } from ' ./useTransition'
5
5
import { useToClose } from ' ./useToClose'
@@ -9,9 +9,10 @@ import { useLockScroll } from './useBodyScrollLock'
9
9
import { useZIndex } from ' ./useZIndex'
10
10
import { vVisible } from ' ./vVisible'
11
11
import { arrayMoveItemToLast , arrayRemoveItem , noop , once } from ' ~/utils'
12
- import { type Modal } from ' ~/Modal'
12
+ import { type ModalExposed } from ' ~/Modal'
13
13
import { useSwipeToClose } from ' ~/useSwipeToClose'
14
14
import { useVfm } from ' ~/useApi'
15
+ import { getModalExposed } from ' ~/plugin'
15
16
16
17
export interface VueFinalModalEmits {
17
18
(e : ' update:modelValue' , modelValue : boolean ): void
@@ -31,6 +32,8 @@ const attrs = useAttrs()
31
32
32
33
defineOptions ({ inheritAttrs: false })
33
34
35
+ const instance = getCurrentInstance ()
36
+
34
37
defineSlots <{
35
38
' default' (): void
36
39
' swipe-banner' (): void
@@ -77,7 +80,7 @@ const {
77
80
resolveToggle (' opened' )
78
81
},
79
82
onLeave() {
80
- arrayRemoveItem (openedModals , modalInstance )
83
+ arrayRemoveItem (openedModals , instance )
81
84
resetZIndex ()
82
85
enableBodyScroll ()
83
86
emit (' closed' )
@@ -93,24 +96,7 @@ const {
93
96
onTouchStartSwipeBanner,
94
97
} = useSwipeToClose (props , { vfmContentEl , modelValueLocal })
95
98
96
- const hideOverlay = toRef (props , ' hideOverlay' )
97
- const overlayBehavior = toRef (props , ' overlayBehavior' )
98
- const modalInstance = computed <Modal >(() => ({
99
- modalId: props .modalId ,
100
- hideOverlay ,
101
- overlayBehavior ,
102
- overlayVisible ,
103
- toggle(show ? : boolean ): Promise <string > {
104
- return new Promise ((resolve ) => {
105
- resolveToggle = once ((res : string ) => resolve (res ))
106
-
107
- const value = typeof show === ' boolean' ? show : ! modelValueLocal .value
108
- modelValueLocal .value = value
109
- })
110
- },
111
- }))
112
-
113
- const index = computed (() => openedModals .indexOf (modalInstance ))
99
+ const index = computed (() => instance ? openedModals .indexOf (instance ) : - 1 )
114
100
115
101
watch ([() => props .zIndexFn , index ], () => {
116
102
if (! visible .value )
@@ -119,7 +105,7 @@ watch([() => props.zIndexFn, index], () => {
119
105
})
120
106
121
107
onMounted (() => {
122
- arrayMoveItemToLast (modals , modalInstance )
108
+ arrayMoveItemToLast (modals , instance )
123
109
})
124
110
125
111
if (props .modelValue )
@@ -130,8 +116,8 @@ function open(): boolean {
130
116
emit (' beforeOpen' , { stop : () => shouldStop = true })
131
117
if (shouldStop )
132
118
return false
133
- arrayMoveItemToLast (openedModals , modalInstance )
134
- arrayMoveItemToLast (openedModalOverlays , modalInstance )
119
+ arrayMoveItemToLast (openedModals , instance )
120
+ arrayMoveItemToLast (openedModalOverlays , instance )
135
121
openLastOverlay ()
136
122
enterTransition ()
137
123
return true
@@ -142,7 +128,7 @@ function close(): boolean {
142
128
emit (' beforeClose' , { stop : () => shouldStop = true })
143
129
if (shouldStop )
144
130
return false
145
- arrayRemoveItem (openedModalOverlays , modalInstance )
131
+ arrayRemoveItem (openedModalOverlays , instance )
146
132
openLastOverlay ()
147
133
blur ()
148
134
leaveTransition ()
@@ -151,21 +137,46 @@ function close(): boolean {
151
137
152
138
onBeforeUnmount (() => {
153
139
enableBodyScroll ()
154
- arrayRemoveItem (modals , modalInstance )
155
- arrayRemoveItem (openedModals , modalInstance )
140
+ arrayRemoveItem (modals , instance )
141
+ arrayRemoveItem (openedModals , instance )
156
142
blur ()
157
143
openLastOverlay ()
158
144
})
159
145
160
146
async function openLastOverlay() {
161
147
await nextTick ()
162
148
// Found the modals which has overlay and has `auto` overlayBehavior
163
- const openedModalsOverlaysAuto = openedModalOverlays .filter (modal => modal .value .overlayBehavior .value === ' auto' && ! modal .value .hideOverlay ?.value )
149
+ const openedModalsOverlaysAuto = openedModalOverlays .filter ((modal ) => {
150
+ const modalExposed = getModalExposed (modal )
151
+ return modalExposed ?.value .overlayBehavior === ' auto' && ! modalExposed ?.value .hideOverlay
152
+ })
164
153
// Only keep the last overlay open
165
154
openedModalsOverlaysAuto .forEach ((modal , index ) => {
166
- modal .value .overlayVisible .value = index === openedModalsOverlaysAuto .length - 1
155
+ const modalExposed = getModalExposed (modal )
156
+ if (! modalExposed ?.value )
157
+ return
158
+ modalExposed .value .overlayVisible = index === openedModalsOverlaysAuto .length - 1
167
159
})
168
160
}
161
+
162
+ const modalExposed = computed <ModalExposed >(() => ({
163
+ modalId: props .modalId ,
164
+ hideOverlay: props .hideOverlay ,
165
+ overlayBehavior: props .overlayBehavior ,
166
+ overlayVisible: overlayVisible .value ,
167
+ toggle(show ? : boolean ): Promise <string > {
168
+ return new Promise ((resolve ) => {
169
+ resolveToggle = once ((res : string ) => resolve (res ))
170
+
171
+ const value = typeof show === ' boolean' ? show : ! modelValueLocal .value
172
+ modelValueLocal .value = value
173
+ })
174
+ },
175
+ }))
176
+
177
+ defineExpose ({
178
+ modalExposed ,
179
+ })
169
180
</script >
170
181
171
182
<template >
@@ -185,7 +196,7 @@ async function openLastOverlay() {
185
196
@mouseup.self =" () => onMouseupRoot()"
186
197
@mousedown.self =" e => onMousedown(e)"
187
198
>
188
- <Transition v-if =" !hideOverlay" v-bind =" ( overlayTransition as object) " v-on =" overlayListeners" >
199
+ <Transition v-if =" !hideOverlay" v-bind =" overlayTransition as object" v-on =" overlayListeners" >
189
200
<div
190
201
v-if =" displayDirective !== 'if' || overlayVisible"
191
202
v-show =" displayDirective !== 'show' || overlayVisible"
@@ -196,7 +207,7 @@ async function openLastOverlay() {
196
207
aria-hidden =" true"
197
208
/>
198
209
</Transition >
199
- <Transition v-bind =" ( contentTransition as object) " v-on =" contentListeners" >
210
+ <Transition v-bind =" contentTransition as object" v-on =" contentListeners" >
200
211
<div
201
212
v-if =" displayDirective !== 'if' || contentVisible"
202
213
v-show =" displayDirective !== 'show' || contentVisible"
0 commit comments