-
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
import {
effect,
el,
type ElementSetup,
isReactive,
on,
type ReactiveOrStatic,
} from "../ef.js";
import { type JSXChildren } from "./jsx.js";
export { type JSX } from "./jsx.js";
function setAttribute(el: Element, name: string, value: string | boolean) {
switch (value) {
case true:
el.setAttribute(name, "");
return;
case false:
el.removeAttribute(name);
return;
default:
el.setAttribute(name, value);
}
}
const EVENT_PATTERN = /^on([A-Z][a-zA-Z]*)$/;
/**
* This JSX runtime focuses on attributes, because this docs site will be statically HTML rendered.
*/
export function jsx(
type: string | ((props: any) => Node),
props: {
[key: `on${string}`]: (evt: Event) => void;
} & { [key: string]: ReactiveOrStatic<string | boolean> } & {
children?: JSXChildren;
},
): Node {
if (typeof type === "function") {
return type(props);
}
const { children, ...rest } = props;
const setups = Object.entries(rest).map<ElementSetup<Element>>(
([key, value]) => {
if (typeof value === "function") {
if (EVENT_PATTERN.test(key)) {
const name = key.replace(EVENT_PATTERN, "$1").toLowerCase();
return on(name, value);
}
// ignore invalid
return () => {};
}
if (isReactive(value)) {
return (el) => {
effect(() => {
setAttribute(el, key, value.get());
});
};
}
return (el) => {
setAttribute(el, key, value);
};
},
);
const normalizedChildren = Array.isArray(children)
? children.flat()
: [children];
return el(type, setups, normalizedChildren);
}
export { jsx as jsxs };