Skip to content

Commit 502ced1

Browse files
committed
feat: useModal() slots allow passing components directly
1 parent 5b42496 commit 502ced1

File tree

2 files changed

+60
-16
lines changed

2 files changed

+60
-16
lines changed

packages/vue-final-modal/src/Modal.ts

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ export type ComponentProps = ComponentPublicInstance['$props']
55
export type ModalId = number | string | symbol
66
export type StyleValue = string | CSSProperties | (string | CSSProperties)[]
77

8+
export type ModalSlot<T extends Record<string, any> = {}> = string | {
9+
component: Component
10+
attrs?: T
11+
}
12+
813
export type UseModalOptionsPrivate<
914
ModalProps extends ComponentProps = {},
1015
DefaultSlotProps extends ComponentProps = {},
@@ -13,11 +18,8 @@ export type UseModalOptionsPrivate<
1318
component: Component
1419
attrs?: ModalProps
1520
slots?: {
16-
default: string | {
17-
component: Component
18-
attrs?: DefaultSlotProps
19-
}
20-
[key: string]: any
21+
default: ModalSlot<DefaultSlotProps>
22+
[key: string]: ModalSlot
2123
}
2224

2325
id?: symbol
@@ -26,22 +28,32 @@ export type UseModalOptionsPrivate<
2628
resolveClosed?: () => void
2729
}
2830

31+
export type ModalOptions<
32+
ModalProps extends ComponentProps,
33+
DefaultSlotProps extends ComponentProps = {},
34+
> = Pick<
35+
UseModalOptionsPrivate<ModalProps, DefaultSlotProps>,
36+
| 'context'
37+
| 'component'
38+
| 'attrs'
39+
| 'slots'
40+
>
41+
2942
export type UseModalOptions<
3043
ModalProps extends ComponentProps,
3144
DefaultSlotProps extends ComponentProps = {},
32-
> = Pick<
33-
UseModalOptionsPrivate<ModalProps, DefaultSlotProps>,
34-
| 'context'
35-
| 'component'
36-
| 'attrs'
37-
| 'slots'
38-
>
45+
> = Omit<ModalOptions<ModalProps, DefaultSlotProps>, 'slots'> & {
46+
slots?: {
47+
default: ModalSlot<DefaultSlotProps> | Component
48+
[key: string]: ModalSlot | Component
49+
}
50+
}
3951

4052
export type UseModalReturnType<ModalProps extends ComponentProps, DefaultSlotProps extends ComponentProps> = {
41-
options: UseModalOptions<ModalProps, DefaultSlotProps>
53+
options: ModalOptions<ModalProps, DefaultSlotProps>
4254
open: () => Promise<string>
4355
close: () => Promise<string>
44-
patchOptions: (options: UseModalOptions<ModalProps, DefaultSlotProps>) => void
56+
patchOptions: (options: ModalOptions<ModalProps, DefaultSlotProps>) => void
4557
destroy: () => void
4658
}
4759

packages/vue-final-modal/src/useApi.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { tryOnUnmounted } from '@vueuse/core'
2-
import { computed, inject, reactive, useAttrs } from 'vue'
2+
import type { Component } from 'vue'
3+
import { computed, inject, markRaw, reactive, useAttrs } from 'vue'
34
import type CoreModal from './components/CoreModal/CoreModal.vue'
45
import { internalVfmSymbol, vfmSymbol } from './injectionSymbols'
56
import type { ComponentProps, InternalVfm, UseModalOptions, UseModalOptionsPrivate, UseModalReturnType, Vfm } from './Modal'
7+
import { isString } from './utils'
68

79
/**
810
* Returns the vfm instance. Equivalent to using `$vfm` inside
@@ -26,10 +28,40 @@ function defineModal<
2628
ModalProps extends ComponentProps,
2729
DefaultSlotProps extends ComponentProps = {},
2830
>(_options: UseModalOptions<ModalProps, DefaultSlotProps>): UseModalReturnType<ModalProps, DefaultSlotProps> {
31+
const { component, slots: innerSlots, ...rest } = _options
32+
33+
const slots = typeof innerSlots !== 'undefined'
34+
? Object.fromEntries<string | {
35+
component: Component
36+
attrs?: any
37+
}>(
38+
Object.entries(innerSlots).map(([name, maybeComponent]) => {
39+
if (isString(maybeComponent))
40+
return [name, maybeComponent]
41+
42+
if ('component' in maybeComponent) {
43+
return [name, {
44+
component: markRaw(maybeComponent.component),
45+
attrs: maybeComponent.attrs,
46+
}] as const
47+
}
48+
49+
return [
50+
name,
51+
{
52+
component: markRaw(maybeComponent),
53+
},
54+
] as const
55+
}),
56+
)
57+
: undefined
58+
2959
const options = reactive({
3060
id: Symbol('useModal'),
3161
modelValue: false,
32-
..._options,
62+
component: markRaw(component),
63+
slots,
64+
...rest,
3365
}) as UseModalOptionsPrivate<ModalProps, DefaultSlotProps>
3466

3567
if (!options.context)

0 commit comments

Comments
 (0)