1
- import type { Component , Raw , Ref } from 'vue'
2
- import { markRaw , reactive } from 'vue'
1
+ import type { Component , Ref } from 'vue'
2
+ import { markRaw } from 'vue'
3
3
import { Modal } from './Modal'
4
- import type { ModalData , ModalId , ModalProps } from './Modal'
4
+ import type { ModalData , ModalId , ModalProps , ModalScope } from './Modal'
5
5
import type { ModalsConfig } from './config'
6
6
import type { ComponentOrImport , ComponentProps , LazyComponent , ModalConfirmProps } from './types'
7
+ import { State } from './State'
7
8
8
9
export type ModalOpenOptions < Props = ModalProps > = Partial < ModalData < Props > > & {
9
10
fetchData ?: ( ) => Promise < ModalProps | undefined >
10
11
}
11
12
12
- interface ComponentData {
13
- loader : LazyComponent
14
- component ?: Component
15
- }
16
-
17
13
export class ModalManager {
18
- list = reactive < Raw < Modal > [ ] > ( [ ] )
19
- content ?: Ref < HTMLElement | undefined >
14
+ private readonly state : State
15
+ private scopeId ?: ModalScope
16
+
17
+ constructor ( options ?: Partial < ModalsConfig > , state ?: State ) {
18
+ this . state = state || new State ( options )
19
+ }
20
+
21
+ get list ( ) {
22
+ return this . state . list
23
+ }
20
24
21
- private modalId = 1
22
- private components = new Map < string , ComponentData > ( )
25
+ get options ( ) {
26
+ return this . state . options
27
+ }
28
+
29
+ get content ( ) {
30
+ return this . state . content
31
+ }
23
32
24
- constructor ( public options : ModalsConfig ) { }
33
+ set content ( value : Ref < HTMLElement | undefined > | undefined ) {
34
+ this . state . content = value
35
+ }
25
36
26
37
getComponent ( name : string ) : ComponentOrImport {
27
- const component = this . components . get ( name )
38
+ const component = this . state . components . get ( name )
28
39
29
40
if ( ! component ) {
30
41
throw new Error ( `Component "${ name } " not found` )
@@ -49,7 +60,7 @@ export class ModalManager {
49
60
}
50
61
51
62
registerComponent ( name : string , loader : LazyComponent , preload = false ) {
52
- this . components . set ( name , { loader } )
63
+ this . state . components . set ( name , { loader } )
53
64
54
65
if ( preload ) {
55
66
const result = this . getComponent ( name )
@@ -112,10 +123,11 @@ export class ModalManager {
112
123
component : ComponentOrImport < C > ,
113
124
options : ModalOpenOptions < ComponentProps < C > > = { } ,
114
125
) {
115
- const mergedOptions = Object . assign ( {
116
- id : this . modalId ++ ,
126
+ const mergedOptions : ModalData = Object . assign ( {
127
+ id : this . state . modalId ++ ,
117
128
props : { } ,
118
129
listeners : { } ,
130
+ scope : this . scopeId ,
119
131
} , this . options , options )
120
132
121
133
const existingModal : Modal < T > | undefined = this . get ( mergedOptions . id )
@@ -162,6 +174,24 @@ export class ModalManager {
162
174
return true
163
175
}
164
176
177
+ closeScope ( ) {
178
+ if ( ! this . scopeId ) {
179
+ return
180
+ }
181
+
182
+ for ( const modal of this . list ) {
183
+ if ( modal . scope === this . scopeId ) {
184
+ this . close ( modal )
185
+ }
186
+ }
187
+ }
188
+
189
+ closeAll ( ) {
190
+ for ( const modal of this . list ) {
191
+ this . close ( modal )
192
+ }
193
+ }
194
+
165
195
confirm < T = boolean > ( props : ModalConfirmProps ) {
166
196
return this . open < T > ( this . getComponent ( 'confirm' ) , {
167
197
props,
@@ -172,4 +202,11 @@ export class ModalManager {
172
202
const prototype : any = ModalManager . prototype
173
203
prototype [ name ] = def
174
204
}
205
+
206
+ scope ( scopeId : ModalScope ) {
207
+ const scope = new ModalManager ( undefined , this . state )
208
+ scope . scopeId = scopeId
209
+
210
+ return scope
211
+ }
175
212
}
0 commit comments