-
Notifications
You must be signed in to change notification settings - Fork 0
/
jsx-runtime.ts
96 lines (84 loc) · 2.42 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
import * as html from "https://deno.land/x/hastx@v0.0.10/html.ts";
import * as hast from "./lib/deps/hast.ts";
import type { JSXChild, JSXElement } from "./lib/types.ts";
export type * from "./lib/types.ts";
export type JSXElementProps = Record<string, string> & {
children?: JSXChild | JSXChild[];
};
export type JSXComponentProps = Record<string, unknown> & {
key?: string;
};
export interface JSXComponent {
(props: JSXComponentProps): JSXElement;
}
export interface JSXElementConstructor {
//deno-lint-ignore no-explicit-any
(...args: any[]): JSXElement;
}
declare global {
export namespace JSX {
export type Element = JSXElement;
export type ElementType = keyof html.HTMLElements | JSXElementConstructor;
//deno-lint-ignore no-empty-interface
export interface IntrinsicElements extends html.HTMLElements {}
export interface ElementChildrenAttribute {
//deno-lint-ignore ban-types
children: {};
}
}
}
export function jsx(
component: JSXComponent,
props: JSXComponentProps,
): JSXElement;
export function jsx(element: string, props: JSXElementProps): JSXElement;
export function jsx(
type: string | JSXComponent,
props: JSXElementProps | JSXComponentProps,
key?: string,
): JSXElement {
if (typeof type === "string") {
let tagName = type;
let { children, ...properties } = props as JSXElementProps;
let className = properties.class ? { className: properties.class } : null;
return {
type: "element",
tagName,
properties: { ...properties, ...className },
children: read(children),
};
} else {
return type({ ...props, ...(key ? { key } : {}) });
}
}
export const jsxs = jsx;
export const jsxDEV = jsx;
export function Fragment(
props: { children?: JSXChild | JSXChild[] },
): hast.Root {
let { children = [] } = props;
return {
type: "root",
children: read(children),
};
}
function read(children?: JSXChild | JSXChild[]): (hast.Element | hast.Text)[] {
let nodes = Array.isArray(children) ? children : (children ? [children] : []);
return nodes.flatMap((child = "") => {
switch (typeof child) {
case "number":
case "boolean":
case "string":
return [{
type: "text",
value: String(child),
}];
default:
if (child.type === "root") {
return child.children as Array<hast.Element | hast.Text>;
} else {
return [child];
}
}
});
}