dex/src/lib/dom.js
chris cd2655011f Scaffold Pokedex PWA (Vite + Workbox)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 10:54:36 -04:00

46 lines
1.4 KiB
JavaScript

/**
* Tiny DOM helpers — enough structure to avoid a framework without the
* ergonomics falling apart.
*
* el('div', { class: 'card', onclick: fn }, 'text', childNode)
*/
export function el(tag, props = {}, ...children) {
const node = document.createElement(tag);
for (const [key, value] of Object.entries(props || {})) {
if (value == null || value === false) continue;
if (key === 'class') node.className = value;
else if (key === 'dataset') Object.assign(node.dataset, value);
else if (key === 'html') node.innerHTML = value;
else if (key.startsWith('on') && typeof value === 'function') {
node.addEventListener(key.slice(2).toLowerCase(), value);
} else if (key in node) {
try {
node[key] = value;
} catch {
node.setAttribute(key, value);
}
} else {
node.setAttribute(key, value);
}
}
append(node, children);
return node;
}
export function append(node, children) {
for (const child of children.flat(Infinity)) {
if (child == null || child === false) continue;
node.append(child.nodeType ? child : document.createTextNode(String(child)));
}
}
export function clear(node) {
node.replaceChildren();
return node;
}
/** Run a cleanup fn when the view node is torn down by the router. */
export function onTeardown(viewNode, fn) {
viewNode.addEventListener('view:teardown', fn, { once: true });
}