-
Notifications
You must be signed in to change notification settings - Fork 0
/
jsx-runtime.ts
106 lines (86 loc) · 2.18 KB
/
jsx-runtime.ts
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { TypeOf } from '@sgrud/core';
import { elementClose, elementOpen, text } from 'incremental-dom';
declare global {
/**
* Intrinsic JSX namespace.
*
* @see https://www.typescriptlang.org/docs/handbook/jsx.html
*/
namespace JSX {
/**
* Intrinsic JSX element type helper representing an array of bound
* `incremental-dom` calls.
*/
type Element = (() => Node)[];
/**
* Intrinsic list of known JSX elements, comprised of the global
* `HTMLElementTagNameMap`.
*/
type IntrinsicElements = {
[K in keyof HTMLElementTagNameMap]: Partial<HTMLElementTagNameMap[K]> & {
key?: string | number | null;
};
};
}
}
/**
* @param type - Element type.
* @param props - Element properties.
* @param ref - Element rendering key.
* @returns Array of bound calls.
*/
export function createElement(
type: keyof JSX.IntrinsicElements | Function,
props?: Record<string, any>,
ref?: string | number | null
): JSX.Element {
if (TypeOf.function(type)) {
return type(props);
}
const attributes = [];
const children = [];
const element = [];
for (const key in props) {
switch (key) {
case 'children':
children.push(...[props[key]].flat(Infinity).filter(Boolean));
break;
case 'className':
attributes.push('class', props[key]);
break;
case 'key':
ref ??= props[key];
break;
default:
attributes.push(key, props[key]);
break;
}
}
element.push(elementOpen.bind(null, type, ref, null, ...attributes));
for (const child of children) {
if (TypeOf.function(child)) {
element.push(child);
} else {
element.push(text.bind(null, child));
}
}
element.push(elementClose.bind(null, type));
return element;
}
/**
* @param props - Fragment properties.
* @returns Array of bound calls.
*/
export function createFragment(props?: Record<string, any>): JSX.Element {
const fragment = [];
if (props?.children) {
fragment.push(...[props.children].flat(Infinity).filter(Boolean));
}
return fragment;
}
export {
JSX,
createElement as jsx,
createElement as jsxs,
createFragment as Fragment
};