Skip to content

Instantly share code, notes, and snippets.

@mikaelbr
Created October 8, 2019 20:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikaelbr/6c31b691c6c6ea90c02a4012dd6143cc to your computer and use it in GitHub Desktop.
Save mikaelbr/6c31b691c6c6ea90c02a4012dd6143cc to your computer and use it in GitHub Desktop.
Complete code example for blogpost "Using JSX for your own lightweight declarative library": https://medium.com/@mikaelbrevik/using-jsx-for-your-own-lightweight-declarative-library-a773d3796475
// Using an IIFE to hide some implementation details.
// If you use a bundler this should be it's own file.
const createElement = (function() {
const isEvent = (k, v) => k.startsWith("on") && typeof v === "function";
const eventName = k => k.substr(2).toLowerCase();
const isString = s => typeof s === "string";
const isFunction = s => typeof s === "function";
function attrs(el, props) {
// Remember, JSX sets props to `null` if nothing is defined, so in that case we just return el
if (!props) {
return el;
}
// For every passed prop, we get key and value
for (let [k, val] of Object.entries(props)) {
// Check if it starts with `on`. Then we assume it is an event and add an event listener.
if (isEvent(k)) {
el.addEventListener(eventName(k), val);
}
// If the key is class, we use classList to add one or many CSS classes
else if (k === "class") {
const classes = Array.isArray(val) ? val : [val];
el.classList.add(...classes);
}
// Of finally, if not class nor event, we set attribute using the setAttribute function.
else {
el.setAttribute(k, val);
}
}
return el;
}
return function createElement(tag, props, ...children) {
if (isFunction(tag)) {
return tag({ ...props, children });
}
const el = attrs(document.createElement(tag), props);
children.flat().forEach(child => {
const node = !isString(child) ? child : document.createTextNode(child);
el.appendChild(node);
});
return el;
};
})();
function Header({ id, children }) {
return <h1 id={id}>Title: {children}</h1>;
}
const list = (
<div>
<Header id="myHeader">My important title</Header>
<ul>
<li>Peter</li>
<li>Paul</li>
<li>Mary</li>
</ul>
</div>
);
document.body.appendChild(list);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment