Created
October 8, 2019 20:21
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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