46 lines
1.2 KiB
JavaScript
46 lines
1.2 KiB
JavaScript
import { serialize } from "./serialize.mjs";
|
|
export function createElement(tree) {
|
|
if (!tree.type) {
|
|
if (Array.isArray(tree)) {
|
|
const frag = document.createDocumentFragment();
|
|
frag.replaceChildren(...tree.map((leaf) => createElement(leaf)));
|
|
return frag;
|
|
}
|
|
return document.createTextNode(tree);
|
|
} else {
|
|
const el = document.createElement(tree.type);
|
|
/**
|
|
* handle props
|
|
*/
|
|
if (tree.props) {
|
|
Object.entries(tree.props).forEach(([prop, value]) => {
|
|
const domProp = prop.toLowerCase();
|
|
if (domProp === "style" && typeof value === "object" && !!value) {
|
|
applyStyles(el, value);
|
|
} else if (prop in el) {
|
|
el[prop] = value;
|
|
} else if (domProp in el) {
|
|
el[domProp] = value;
|
|
} else {
|
|
el.setAttribute(prop, serialize(value));
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* handle children
|
|
*/
|
|
tree.children?.forEach((child) => {
|
|
const childEl = createElement(child);
|
|
if (childEl instanceof Node) {
|
|
el.appendChild(childEl);
|
|
}
|
|
});
|
|
return el;
|
|
}
|
|
}
|
|
|
|
function applyStyles(el, styleObj) {
|
|
Object.entries(styleObj).forEach(([rule, value]) => {
|
|
if (rule in el.style && value) el.style[rule] = value;
|
|
});
|
|
}
|