Skip to content

Commit 4fb5d61

Browse files
committed
feat(vue-jsx-vapor): support functional props for h
1 parent 2a414fa commit 4fb5d61

File tree

1 file changed

+34
-13
lines changed
  • packages/vue-jsx-vapor/src/core

1 file changed

+34
-13
lines changed

packages/vue-jsx-vapor/src/core/h.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N
5555

5656
type RawProps = Record<string, any>
5757

58+
type ResolveProps<T> = T extends null | undefined ? T : () => T | T
59+
5860
// The following is a series of overloads for providing props validation of
5961
// manually written render functions.
6062

@@ -65,15 +67,15 @@ export function h<K extends keyof HTMLElementTagNameMap>(
6567
): Block
6668
export function h<K extends keyof HTMLElementTagNameMap>(
6769
type: K,
68-
props?: (RawProps & HTMLElementEventHandler) | null,
70+
props?: ResolveProps<RawProps & HTMLElementEventHandler> | null,
6971
children?: RawChildren | RawSlots,
7072
): Block
7173

7274
// custom element
7375
export function h(type: string, children?: RawChildren): Block
7476
export function h(
7577
type: string,
76-
props?: RawProps | null,
78+
props?: ResolveProps<RawProps> | null,
7779
children?: RawChildren | RawSlots,
7880
): Block
7981

@@ -92,7 +94,7 @@ export function h(
9294
export function h(type: typeof Fragment, children?: NodeArrayChildren): Block
9395
export function h(
9496
type: typeof Fragment,
95-
props?: { key?: PropertyKey; ref?: VNodeRef } | null,
97+
props?: ResolveProps<{ key?: PropertyKey; ref?: VNodeRef }> | null,
9698
children?: NodeArrayChildren,
9799
): Block
98100

@@ -107,7 +109,7 @@ export function h(
107109
export function h(type: typeof Suspense, children?: RawChildren): Block
108110
export function h(
109111
type: typeof Suspense,
110-
props?: (RawProps & SuspenseProps) | null,
112+
props?: ResolveProps<RawProps & SuspenseProps> | null,
111113
children?: RawChildren | RawSlots,
112114
): Block
113115

@@ -119,7 +121,7 @@ export function h<
119121
S extends Record<string, any> = any,
120122
>(
121123
type: FunctionalComponent<P, E, S>,
122-
props?: (RawProps & P) | ({} extends P ? null : never),
124+
props?: ResolveProps<(RawProps & P) | ({} extends P ? null : never)>,
123125
children?: RawChildren | IfAny<S, RawSlots, S>,
124126
): Block
125127

@@ -142,16 +144,17 @@ export function h<P>(
142144
| ComponentOptions<P>
143145
| Constructor<P>
144146
| DefineComponent<P>,
145-
props?: (RawProps & P) | ({} extends P ? null : never),
147+
props?: ResolveProps<(RawProps & P) | ({} extends P ? null : never)>,
146148
children?: RawChildren | RawSlots,
147149
): Block
148150

149151
export function h(type: any, propsOrChildren?: any, children?: any) {
150152
const l = arguments.length
151153
if (l === 2) {
152154
if (
153-
typeof propsOrChildren === 'object' &&
154-
!Array.isArray(propsOrChildren)
155+
(typeof propsOrChildren === 'object' &&
156+
!Array.isArray(propsOrChildren)) ||
157+
typeof propsOrChildren === 'function'
155158
) {
156159
// single block without props
157160
if (isBlock(propsOrChildren)) {
@@ -161,10 +164,7 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
161164
}
162165

163166
// props without children
164-
return createComponentWithFallback(
165-
type,
166-
propsOrChildren ? { $: [() => propsOrChildren] } : null,
167-
)
167+
return createComponentWithFallback(type, resolveProps(propsOrChildren))
168168
} else {
169169
// omit props
170170
return createComponentWithFallback(type, null, {
@@ -177,7 +177,7 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
177177
}
178178
return createComponentWithFallback(
179179
type,
180-
propsOrChildren ? { $: [() => propsOrChildren] } : null,
180+
resolveProps(propsOrChildren),
181181
children
182182
? typeof children === 'object' && !Array.isArray(children)
183183
? children
@@ -188,3 +188,24 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
188188
)
189189
}
190190
}
191+
192+
function resolveProps(
193+
props?: Record<string, any> | (() => Record<string, any>),
194+
) {
195+
if (props) {
196+
if (typeof props === 'function') {
197+
return { $: [props] }
198+
}
199+
const resolvedProps: Record<string, any> = {}
200+
// eslint-disable-next-line no-restricted-syntax
201+
for (const key in props) {
202+
if (typeof props[key] === 'function' || key === '$') {
203+
resolvedProps[key] = props[key]
204+
} else {
205+
resolvedProps[key] = () => props[key]
206+
}
207+
}
208+
return resolvedProps
209+
}
210+
return null
211+
}

0 commit comments

Comments
 (0)