Skip to content

Instantly share code, notes, and snippets.

@reu
Last active January 4, 2023 00:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save reu/ee72845c23c607b47cc5ae4a6be502ff to your computer and use it in GitHub Desktop.
Save reu/ee72845c23c607b47cc5ae4a6be502ff to your computer and use it in GitHub Desktop.
HTML builder DSL
import { h1, div, p } from "./html";
div([
h1({ class: "title" }, "Title"),
p("A nice text"),
]);
const array = obj => Array.isArray(obj) ? obj : [obj];
const createElement = (tag, { attributes = {}, children = [], content = null } = {}) => {
const element = document.createElement(tag);
for (let attribute in attributes) element.setAttribute(attribute, attributes[attribute]);
children.forEach(child => element.appendChild(child));
if (content) element.innerHTML = content;
return element;
}
const createTag = tag => (arg1, arg2) => {
if (Array.isArray(arg1) || arg1 instanceof Element) {
return createElement(tag, { children: array(arg1) });
} else if (typeof arg1 === "string") {
return createElement(tag, { content: arg1 });
} else if (typeof arg1 === "object") {
if (typeof arg2 === "string") {
return createElement(tag, { attributes: arg1, content: arg2 });
} else if (arg2 != null) {
return createElement(tag, { attributes: arg1, children: array(arg2) });
} else {
return createElement(tag, { attributes: arg1 });
}
}
};
const htmlDSL = new Proxy(createTag, {
get: (target, tag) => target(tag),
});
export default htmlDSL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment