1
1
import { isString , tryOnUnmounted } from '@vueuse/core'
2
2
import { computed , inject , markRaw , reactive , useAttrs } from 'vue'
3
+ import type { Component , Raw } from 'vue'
3
4
import VueFinalModal from './components/VueFinalModal/VueFinalModal.vue'
4
5
import type CoreModal from './components/CoreModal/CoreModal.vue'
5
6
import { internalVfmSymbol , vfmSymbol } from './injectionSymbols'
6
- import type { ComponentProps , IOverloadedUseModalFn , InternalVfm , UseModalOptions , UseModalOptionsPrivate , UseModalOptionsSlots , UseModalReturnType , Vfm } from './Modal'
7
+
8
+ import type { ComponentProps , IOverloadedUseModalFn , InternalVfm , ModalSlot , ModalSlotOptions , UseModalOptions , UseModalOptionsPrivate , UseModalReturnType , Vfm } from './Modal'
7
9
8
10
/**
9
11
* Returns the vfm instance. Equivalent to using `$vfm` inside
@@ -20,12 +22,12 @@ export function useInternalVfm(): InternalVfm {
20
22
return inject ( internalVfmSymbol ) !
21
23
}
22
24
23
- function withMarkRaw ( options : Partial < UseModalOptions > ) {
25
+ function withMarkRaw ( options : Partial < UseModalOptions > , DefaultComponent : Component = VueFinalModal ) {
24
26
const { component, slots : innerSlots , ...rest } = options
25
27
26
28
const slots = typeof innerSlots === 'undefined'
27
29
? { }
28
- : Object . fromEntries < UseModalOptionsSlots [ 'slots' ] > ( Object . entries ( innerSlots ) . map ( ( [ name , maybeComponent ] ) => {
30
+ : Object . fromEntries < ModalSlot > ( Object . entries ( innerSlots ) . map ( ( [ name , maybeComponent ] ) => {
29
31
if ( isString ( maybeComponent ) )
30
32
return [ name , maybeComponent ] as const
31
33
@@ -41,7 +43,7 @@ function withMarkRaw(options: Partial<UseModalOptions>) {
41
43
42
44
return {
43
45
...rest ,
44
- component : markRaw ( component || VueFinalModal ) ,
46
+ component : markRaw ( component || DefaultComponent ) ,
45
47
slots,
46
48
}
47
49
}
@@ -83,13 +85,21 @@ export const useModal: IOverloadedUseModalFn = function (_options: UseModalOptio
83
85
}
84
86
85
87
function patchOptions ( _options : Partial < UseModalOptions > ) {
86
- const _patchOptions = withMarkRaw ( _options )
87
- if ( _patchOptions ?. attrs )
88
- Object . assign ( options . attrs || { } , _patchOptions . attrs )
89
- if ( _patchOptions ?. component )
90
- Object . assign ( options . component || { } , _patchOptions . component )
91
- if ( _patchOptions ?. slots )
92
- Object . assign ( options . slots || { } , _patchOptions . slots )
88
+ const { slots, ...rest } = withMarkRaw ( _options , options . component )
89
+
90
+ // patch options.component and options.attrs
91
+ patchComponentOptions ( options , rest )
92
+
93
+ // patch options.slots
94
+ if ( slots ) {
95
+ Object . entries ( slots ) . forEach ( ( [ name , slot ] ) => {
96
+ const originSlot = options . slots ! [ name ]
97
+ if ( isModalSlotOptions ( originSlot ) && isModalSlotOptions ( slot ) )
98
+ patchComponentOptions ( originSlot , slot )
99
+ else
100
+ options . slots ! [ name ] = slot
101
+ } )
102
+ }
93
103
}
94
104
95
105
function destroy ( ) : void {
@@ -115,6 +125,31 @@ export const useModal: IOverloadedUseModalFn = function (_options: UseModalOptio
115
125
return modal
116
126
}
117
127
128
+ function patchAttrs < T extends Record < string , any > > ( attrs : T , newAttrs : Partial < T > ) : T {
129
+ Object . entries ( newAttrs ) . forEach ( ( [ key , value ] ) => {
130
+ attrs [ key as keyof T ] = value
131
+ } )
132
+
133
+ return attrs
134
+ }
135
+
136
+ type ComponentOptions = {
137
+ component ?: Raw < Component >
138
+ attrs ?: Record < string , any >
139
+ }
140
+
141
+ function patchComponentOptions ( options : ComponentOptions , newOptions : ComponentOptions ) {
142
+ if ( newOptions . component )
143
+ options . component = newOptions . component
144
+
145
+ if ( newOptions . attrs )
146
+ patchAttrs ( options . attrs ! , newOptions . attrs )
147
+ }
148
+
149
+ function isModalSlotOptions ( value : any ) : value is ModalSlotOptions {
150
+ return 'component' in value || 'attrs' in value
151
+ }
152
+
118
153
export function pickModalProps ( props : any , modalProps : any ) {
119
154
return Object . keys ( modalProps ) . reduce ( ( acc , propName ) => {
120
155
acc [ propName ] = props [ propName ]
0 commit comments