Skip to content

Instantly share code, notes, and snippets.

@MarekZeman91
Last active February 20, 2025 03:15
Show Gist options
  • Save MarekZeman91/b74d31eda1001f8380109ab5c1606108 to your computer and use it in GitHub Desktop.
Save MarekZeman91/b74d31eda1001f8380109ab5c1606108 to your computer and use it in GitHub Desktop.
One of the laziest EL implementations, but with cache
export function el<K extends keyof HTMLElementTagNameMap>(
nodeName: K,
props?: Record<string, any>,
children?: (string | number | boolean | Node)[],
): HTMLElementTagNameMap[K];
export function el<T extends HTMLElement>(
nodeName: string,
props?: Record<string, any>,
children?: (string | number | boolean | Node)[],
): T;
export function el(
nodeName: string,
props: Record<string, any> = {},
children: (string | number | boolean | Node)[] = [],
): HTMLElement {
const {
class: className,
style = {},
data = {},
dataset = {},
...rest
} = props;
rest.className = [className ?? '', rest.className ?? ''].join(' ').trim();
const element = (
el.cache[nodeName] ||
(el.cache[nodeName] = document.createElement(nodeName))
).cloneNode(false) as HTMLElement;
Object.assign(element.style, style);
Object.assign(element.dataset, data, dataset);
for (const [key, value] of Object.entries(rest)) {
if (key.startsWith('on') && typeof value === 'function') {
element.addEventListener(key.slice(2).toLowerCase(), value);
} else if (key in element) {
(element as any)[key] = value;
} else {
element.setAttribute(key, String(value));
}
}
element.append(...(children as any[]));
return element;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment