-
Notifications
You must be signed in to change notification settings - Fork 171
Expand file tree
/
Copy pathrender.ts
More file actions
63 lines (55 loc) · 2.42 KB
/
render.ts
File metadata and controls
63 lines (55 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import React from 'react';
import * as ReactJSX from 'react/jsx-runtime';
import type { RenderType, RenderResult, DirectComponent, LegacyDirectComponent } from './render.types';
import { extractChildren, splitPropsAndChildren } from '../utilities/typeUtils';
export type CustomRender = () => RenderResult;
export function asDirectComponent<TProps>(type: RenderType): DirectComponent<TProps> | undefined {
if (typeof type === 'function' && (type as DirectComponent<TProps>)._callDirect) {
return type as DirectComponent<TProps>;
}
return undefined;
}
function asLegacyDirectComponent<TProps>(type: RenderType): LegacyDirectComponent<TProps> | undefined {
if (typeof type === 'function' && (type as LegacyDirectComponent<TProps>)._canCompose) {
return type as LegacyDirectComponent<TProps>;
}
return undefined;
}
export function renderForJsxRuntime<TProps>(
type: React.ElementType,
props: TProps,
key?: React.Key,
jsxFn?: typeof ReactJSX.jsx,
): RenderResult {
const legacyDirect = asLegacyDirectComponent(type);
if (legacyDirect) {
const [rest, children] = splitPropsAndChildren(props);
const newProps = { ...rest, key };
return legacyDirect(newProps, ...React.Children.toArray(children)) as RenderResult;
}
const directComponent = asDirectComponent<TProps>(type);
if (directComponent) {
const newProps = { ...props, key };
return directComponent(newProps);
}
// auto-detect whether to use jsx or jsxs based on number of children, 0 or 1 = jsx, more than 1 = jsxs
if (!jsxFn) {
if (React.Children.count(extractChildren(props)) > 1) {
jsxFn = ReactJSX.jsxs;
} else {
jsxFn = ReactJSX.jsx;
}
}
// Extract key from props to avoid React 19 warning about spreading key prop
const { key: propsKey, ...propsWithoutKey } = props as any;
// Use explicitly passed key, or fall back to key from props
const finalKey = key ?? propsKey;
// now call the appropriate jsx function to render the component
return jsxFn(type, propsWithoutKey, finalKey);
}
export function renderForClassicRuntime<TProps>(type: RenderType, props: TProps, ...children: React.ReactNode[]): RenderResult {
// if it is a non-string type with _canCompose set just call the function directly, otherwise call createElement as normal
const propsWithChildren = { children, ...props };
return renderForJsxRuntime(type as React.ElementType, propsWithChildren);
}
export const renderSlot = renderForClassicRuntime;