Skip to content

Instantly share code, notes, and snippets.

💜
Testing statuses

Mikael Brevik mikaelbr

💜
Testing statuses
Block or report user

Report or block mikaelbr

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
@mikaelbr
mikaelbr / own-jsx-final.js
Created Oct 8, 2019
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
View own-jsx-final.js
// 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
View own-jsx-16.js
// ... inside our createElement when adding children:
children.flat().forEach(child => {
const node = !isString(child) ? child : document.createTextNode(child);
el.appendChild(node);
});
// ... createElement continues
View own-jsx-15.js
const isFunction = s => typeof s === "function";
function createElement(tag, props, ...children) {
// If first argument is function, we know it is custom component,
// So call it as a function, passing the props with children as a property.
// Using spread like this will work when props is `null` also
if (isFunction(tag)) {
return tag({ ...props, children });
}
View own-jsx-13.js
let myHeader = <Header id="myHeader">My important title</Header>;
// Which outputs
let myHeader = createElement(
Header,
{
id: "myHeader"
},
"My important title"
);
View own-jsx-14.js
function Header(props) {
return <h1 id={props.id}>Title: {props.children}</h1>;
}
// Or with destructuring
function Header({ id, children }) {
return <h1 id={id}>Title: {children}</h1>;
}
View own-jsx-12.js
const button = <button onClick={() => console.log("Hello!")}>Click me</button>;
document.body.appendChild(button);
// When clicked:
//> Hello!
//> Hello!
View own-jsx-11.js
function createElement(tag, props, ...children) {
const el = attrs(document.createElement(tag), props);
// ... rest of the implementation here
return el;
}
View own-jsx-10.js
const isEvent = (k, v) => k.startsWith("on") && typeof v === "function";
const eventName = k => k.substr(2).toLowerCase();
const isString = s => typeof s === "string";
function attrs(el, props) {
// Remember, JSX sets props to `null` if nothing is defined, so in that case, we just return unchanged el
if (!props) {
return el;
}
View own-jsx-9.js
const isString = s => typeof s === "string";
function createElement(tag, props, ...children) {
const el = document.createElement(tag);
// Iterate thorugh all rest arguments as children.
children.forEach(child => {
// If string, we make it a text node.
const node = !isString(child) ? child : document.createTextNode(child);
// Add the child to the newly created elements.
View own-jsx-8.js
function createElement(tag, props, ...children) {
// Create a new html node element.
const el = document.createElement(tag);
// just take the first child for now
el.textContent = children[0];
return el;
}
const h1 = <h1>Hello, World</h1>;
//> <h1>Hello, World</h1>
You can’t perform that action at this time.