Skip to content

Commit ee11efe

Browse files
committed
refactor: rename useC2v to useVNode
1 parent a79cd54 commit ee11efe

File tree

14 files changed

+128
-133
lines changed

14 files changed

+128
-133
lines changed

docs/content/2.get-started/1.guide/4.types.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ The exported types in VueFinalModal.
88
export type ModalId = number | string | symbol
99
```
1010
11-
## C2VOptions
11+
## CreateVNodeOptions
1212
1313
```ts
14-
export type C2VOptions<T extends Component> = {
14+
export type CreateVNodeOptions<T extends Component> = {
1515
component: T
1616
attrs?: ComponentProps<T>
1717
slots?: {
18-
[K in keyof ComponentSlots<T>]?: string | Component | C2VOptions<Component>
18+
[K in keyof ComponentSlots<T>]?: string | Component | CreateVNodeOptions<Component>
1919
}
2020
}
2121
```
@@ -29,7 +29,7 @@ export type UseModalOptions<T extends Component> = {
2929
component?: T
3030
attrs?: ComponentProps<T>
3131
slots?: {
32-
[K in keyof ComponentSlots<T>]?: string | Component | C2VOptions<Component>
32+
[K in keyof ComponentSlots<T>]?: string | Component | CreateVNodeOptions<Component>
3333
}
3434
}
3535
```

docs/content/3.api/2.composables/1.use-modal.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,15 @@ const modalInstance = useModal({
115115
#### with `Component`, `Props` and `Events`
116116

117117
```ts
118-
import { VueFinalModal, useModal, c2v } from 'vue-final-modal'
118+
import { VueFinalModal, useModal, h } from 'vue-final-modal'
119119
// ModalContent is the component you want to put into the modal content
120120
import ModalContent from './ModalContent.vue'
121121

122122
const modalInstance = useModal({
123123
component: VueFinalModal,
124124
attrs: { ... },
125125
slots: {
126-
default: c2v({
126+
default: h({
127127
component: ModalContent,
128128
attrs: {
129129
// Bind ModalContent props
@@ -137,7 +137,7 @@ const modalInstance = useModal({
137137
```
138138

139139
::alert{type=info}
140-
`c2v()` is a function that provides better DX for type checking. It just returns the same object you passed in.
140+
`h()` is a function that provides better DX for type checking. It just returns the same object you passed in.
141141
::
142142

143143
## Type Declarations

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import type { VNodesContainer } from './useVNodesContainer'
55
export type ModalId = number | string | symbol
66
export type StyleValue = string | CSSProperties | (string | CSSProperties)[]
77

8-
export type C2VOptions<T extends Component> = {
8+
export type CreateVNodeOptions<T extends Component> = {
99
component: T
1010
attrs?: ComponentProps<T>
1111
slots?: {
12-
[K in keyof ComponentSlots<T>]?: string | Component | C2VOptions<Component>
12+
[K in keyof ComponentSlots<T>]?: string | Component | CreateVNodeOptions<Component>
1313
}
1414
}
1515

@@ -19,7 +19,7 @@ export type UseModalOptions<T extends Component> = {
1919
component?: T
2020
attrs?: ComponentProps<T>
2121
slots?: {
22-
[K in keyof ComponentSlots<T>]?: string | Component | C2VOptions<Component>
22+
[K in keyof ComponentSlots<T>]?: string | Component | CreateVNodeOptions<Component>
2323
}
2424
}
2525

packages/vue-final-modal/src/components/DynamicModal.ts

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import type { Component, PropType } from 'vue'
22
import { defineComponent, h } from 'vue'
3-
import type { C2VOptions, UseModalOptions, UseModalOptionsPrivate } from '..'
4-
import { isString, objectEntries } from '~/utils'
5-
import { getSlots, isC2VOptions } from '~/useC2v'
3+
import type { UseModalOptions, UseModalOptionsPrivate } from '..'
4+
import { getSlots } from '~/useVNode'
65

76
export const DynamicModal = defineComponent({
87
name: 'DynamicModal',
@@ -16,31 +15,24 @@ export const DynamicModal = defineComponent({
1615
function renderDynamicModal(modal: (UseModalOptions<Component> & UseModalOptionsPrivate)) {
1716
if (!modal.component)
1817
return null
19-
const slots = objectEntries(modal.slots || {}).reduce((acc, cur) => {
20-
const slotName = cur[0] as string
21-
const slot = cur[1] as string | Component | C2VOptions<Component>
22-
if (isString(slot))
23-
acc[slotName] = () => h('div', { innerHTML: slot })
24-
else if (isC2VOptions(slot))
25-
acc[slotName] = () => h(slot.component, slot.attrs, slot.slots ? getSlots(slot.slots) : undefined)
26-
else
27-
acc[slotName] = () => h(slot)
28-
return acc
29-
}, {} as any)
3018

31-
return h(modal.component, {
32-
'modelValue': modal.modelValue,
33-
'displayDirective': modal?.keepAlive ? 'show' : undefined,
34-
...(typeof modal.attrs === 'object' ? modal.attrs : {}),
35-
'onUpdate:modelValue': (value: boolean) => {
36-
modal.modelValue = value
37-
const onUpdateModelValue = modal.attrs?.['onUpdate:modelValue']
38-
if (onUpdateModelValue)
39-
onUpdateModelValue(value)
19+
return h(
20+
modal.component,
21+
{
22+
'modelValue': modal.modelValue,
23+
'displayDirective': modal?.keepAlive ? 'show' : undefined,
24+
...(typeof modal.attrs === 'object' ? modal.attrs : {}),
25+
'onUpdate:modelValue': (value: boolean) => {
26+
modal.modelValue = value
27+
const onUpdateModelValue = modal.attrs?.['onUpdate:modelValue']
28+
if (onUpdateModelValue)
29+
onUpdateModelValue(value)
30+
},
31+
'on_closed': () => modal?.resolveClosed?.(),
32+
'on_opened': () => modal?.resolveOpened?.(),
4033
},
41-
'on_closed': () => modal?.resolveClosed?.(),
42-
'on_opened': () => modal?.resolveOpened?.(),
43-
}, slots)
34+
getSlots(modal.slots || {}),
35+
)
4436
}
4537

4638
return () => renderDynamicModal(props.modal)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export { vueFinalModalProps } from './components/VueFinalModal/VueFinalModalProp
2121
export type { VueFinalModalEmits } from './components/VueFinalModal/VueFinalModal.vue'
2222

2323
/** Composables */
24-
export { useC2v, c2v } from './useC2v'
24+
export { createVNode, useVNode, h } from './useVNode'
2525
export { useVfm } from './useVfm'
2626
export { useModal } from './useModal'
2727
export { useVfmAttrs } from './useVfmAttrs'

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

Lines changed: 0 additions & 53 deletions
This file was deleted.

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

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import type { Component } from 'vue'
22
import { h, markRaw, reactive } from 'vue'
3-
import { tryOnUnmounted } from '@vueuse/core'
43
import { isString, objectEntries } from './utils'
54
import { DynamicModal } from './components/DynamicModal'
6-
import { isC2VOptions } from './useC2v'
7-
import { pushVNode, removeVNode } from './useVfm'
8-
import type { C2VOptions, UseModalOptions, UseModalOptionsPrivate, UseModalReturnType } from '.'
5+
import { isVNodeOptions, useVNode } from './useVNode'
6+
import type { CreateVNodeOptions, UseModalOptions, UseModalOptionsPrivate, UseModalReturnType } from '.'
97
import { VueFinalModal } from '.'
108

119
/**
@@ -25,20 +23,20 @@ export function useModal<T extends Component = typeof VueFinalModal>(_options: U
2523

2624
const vNode = h(DynamicModal, { modal: options, key: id })
2725

28-
tryOnUnmounted(() => {
29-
tryRemoveVNode()
26+
const { show, hide } = useVNode(vNode, {
27+
tryOnUnmounted: () => tryRemoveVNode(),
3028
})
3129

3230
if (options.modelValue === true)
33-
pushVNode(vNode)
31+
show()
3432

3533
function open(): Promise<string> {
3634
if (options.modelValue)
3735
return Promise.resolve('[Vue Final Modal] modal is already opened.')
3836

3937
tryRemoveVNode()
4038
options.modelValue = true
41-
pushVNode(vNode)
39+
show()
4240

4341
return new Promise((resolve) => {
4442
options.resolveOpened = () => resolve('opened')
@@ -61,7 +59,7 @@ export function useModal<T extends Component = typeof VueFinalModal>(_options: U
6159
function tryRemoveVNode() {
6260
if (options.keepAlive)
6361
return
64-
removeVNode(vNode)
62+
hide()
6563
}
6664

6765
function patchOptions(_options: Partial<UseModalOptions<T>>) {
@@ -81,7 +79,7 @@ export function useModal<T extends Component = typeof VueFinalModal>(_options: U
8179
const originSlot = options.slots![name]
8280
if (isString(originSlot))
8381
options.slots![name] = slot
84-
else if (isC2VOptions(originSlot) && isC2VOptions(slot))
82+
else if (isVNodeOptions(originSlot) && isVNodeOptions(slot))
8583
patchComponentOptions(originSlot, slot)
8684
else
8785
options.slots![name] = slot
@@ -94,7 +92,7 @@ export function useModal<T extends Component = typeof VueFinalModal>(_options: U
9492
open,
9593
close,
9694
patchOptions,
97-
destroy: () => removeVNode(vNode),
95+
destroy: () => hide(),
9896
}
9997
}
10098

@@ -107,7 +105,7 @@ function withMarkRaw<T extends Component>(options: Partial<UseModalOptions<T>>,
107105
if (isString(maybeComponent))
108106
return [name, maybeComponent] as const
109107

110-
if (isC2VOptions(maybeComponent)) {
108+
if (isVNodeOptions(maybeComponent)) {
111109
return [name, {
112110
...maybeComponent,
113111
component: markRaw(maybeComponent.component),
@@ -125,8 +123,8 @@ function withMarkRaw<T extends Component>(options: Partial<UseModalOptions<T>>,
125123
}
126124

127125
function patchComponentOptions<T extends Component>(
128-
options: UseModalOptions<T> | C2VOptions<Component>,
129-
newOptions: Partial<UseModalOptions<T>> | C2VOptions<Component>,
126+
options: UseModalOptions<T> | CreateVNodeOptions<Component>,
127+
newOptions: Partial<UseModalOptions<T>> | CreateVNodeOptions<Component>,
130128
) {
131129
if (newOptions.component)
132130
options.component = newOptions.component
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import type { Component, VNode } from 'vue'
2+
import { h as _h, isVNode } from 'vue'
3+
import { tryOnUnmounted } from '@vueuse/core'
4+
import type { CreateVNodeOptions } from './Modal'
5+
import { useSsrVfm, useVfm } from './useVfm'
6+
import type { ComponentSlots } from './Component'
7+
import { isString, objectEntries } from './utils'
8+
9+
/**
10+
* Create a dynamic vNode.
11+
*/
12+
export function createVNode<T extends Component>(options: CreateVNodeOptions<T>) {
13+
const id = Symbol(__DEV__ ? 'createVNode' : '')
14+
const vNode = _h(options.component, { key: id, ...options.attrs }, options.slots)
15+
return vNode
16+
}
17+
18+
/**
19+
* Create a dynamic vNode.
20+
*/
21+
export function h<T extends Component>(options: CreateVNodeOptions<T>) {
22+
return options
23+
}
24+
25+
async function pushVNode(vNode: VNode) {
26+
const vfm = await useSsrVfm()
27+
vfm.vNodesContainer.push(vNode)
28+
}
29+
30+
async function removeVNode(vNode: VNode) {
31+
const vfm = useVfm()
32+
vfm.vNodesContainer.remove(vNode)
33+
}
34+
35+
export function useVNode(vNode: VNode, options?: {
36+
tryOnUnmounted?: (vNode: VNode) => void
37+
}) {
38+
tryOnUnmounted(() => options?.tryOnUnmounted?.(vNode))
39+
return {
40+
show: () => pushVNode(vNode),
41+
hide: () => removeVNode(vNode),
42+
}
43+
}
44+
45+
export function isVNodeOptions<T extends Component>(value: unknown): value is CreateVNodeOptions<T> {
46+
if (typeof value === 'object' && value !== null)
47+
return 'component' in value
48+
else
49+
return false
50+
}
51+
52+
export function getSlots<T extends Component>(slots?: {
53+
[K in keyof ComponentSlots<T>]?: string | Component | CreateVNodeOptions<Component>
54+
}) {
55+
return objectEntries(slots || {}).reduce<Record<string, () => VNode>>((acc, cur) => {
56+
const slotName = cur[0] as string
57+
const slot = cur[1] as string | Component | CreateVNodeOptions<Component>
58+
if (isString(slot))
59+
acc[slotName] = () => _h('div', { innerHTML: slot })
60+
else if (isVNodeOptions(slot))
61+
acc[slotName] = () => _h(slot.component, slot.attrs, slot.slots ? getSlots(slot.slots) : undefined)
62+
else if (isVNode(slot))
63+
// acc[slotName] = () => slot
64+
return acc
65+
else
66+
acc[slotName] = () => _h(slot)
67+
return acc
68+
}, {})
69+
}

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { VNode } from 'vue'
21
import { nextTick } from 'vue'
32
import type { Vfm } from './Modal'
43
import { activeVfm, getActiveVfm } from './plugin'
@@ -31,13 +30,3 @@ export async function useSsrVfm(): Promise<Vfm> {
3130
return useVfm()
3231
}
3332
}
34-
35-
export async function pushVNode(vNode: VNode) {
36-
const vfm = await useSsrVfm()
37-
vfm.vNodesContainer.push(vNode)
38-
}
39-
40-
export function removeVNode(vNode: VNode): void {
41-
const vfm = useVfm()
42-
vfm.vNodesContainer.remove(vNode)
43-
}

0 commit comments

Comments
 (0)