Skip to content

Instantly share code, notes, and snippets.

@marvinhagemeister
Last active September 24, 2023 19:00
Show Gist options
  • Save marvinhagemeister/feb97ca91c556736d4e3e9d8c07bdeb8 to your computer and use it in GitHub Desktop.
Save marvinhagemeister/feb97ca91c556736d4e3e9d8c07bdeb8 to your computer and use it in GitHub Desktop.
JSX DOM
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="module">
import htm from "https://esm.sh/htm@3.1.1";
function factory(type, props, ...children) {
if (typeof type === "function") {
props.children = !props.children ? children : props.children;
return type(props);
} else {
const el = document.createElement(type);
for (const prop in props) {
if (prop === "children") children = props[prop];
el.setAttribute(prop, props[prop]);
}
// Normalize children
const normalized = [];
normalizeChildren(normalized, children);
for (let i = 0; i < normalized.length; i++) {
const child = normalized[i];
el.appendChild(child);
}
return el;
}
}
function normalizeChildren(arr, child) {
// Ignore these
if (child == null || typeof child === "boolean") {
return;
}
if (Array.isArray(child)) {
for (let i = 0; i < child.length; i++) {
normalizeChildren(arr, child[i]);
}
} else if (typeof child === "object") {
arr.push(child);
} else {
arr.push(new Text(child));
}
}
const html = htm.bind(factory);
function Foo(props) {
return html`<p>component children: ${props.children}</p>`;
}
const root = html`<div id="foo">
<h1>JSX DOM</h1>
<p>Foo component follows</p>
<${Foo} id="foo">
<span>child</span>
<//>
</div>`;
document.getElementById("app").appendChild(root);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment