JSFiddle - React, Tailwind, and code Playground

by Danny Michaelis

Babel + JSX

function constructId( parent ) {
	return `${parent._id}.${Object.keys(parent.components).length}`
}

class cmp {
  constructor(id) {
  	this._id = id || 0;
  	this.components = {};
  }
  
  static render(args) {
  	return { _class: this, args }
  }
  
  tag(template, ...expressions) {
  console.log(this)
    const str = template.reduce((accumulator, part, i) => {
      return accumulator + this.componatize(expressions[i - 1]) + part
    })
    return `<span id="${ this._id }"> ${ str } </span>`
  }
  
  componatize(obj) {
    if ( obj._class) {
         	const id = constructId(this) + obj._class.name
          let found = this.components[ id ];
        if (!found) {      
          found = new obj._class(obj.args);
          found._id = id;
          this.components[ found._id ] = found;
          renderStack[id] = found.prep();
        } else if ( !Object.keys(obj.args).every( key => found[key] === obj.args[key] ) ) {
          	found = new obj._class(obj.args);
            renderStack[id] = found.prep();
        }
        return found.prep();

    }
    return obj
  }
  
  prep() {
  	return this._render();
  }
  _render() {}
}

class App extends cmp {
	constructor( { title } ) {
  	super();
    this.title = title;
  }
  _render() {
  	return this.tag`
    <div>
    	<h1>${this.title}</h1>
    	${ Note.render( { text: 'example' } ) }  
    	${ Note.render( { text: 'example 2' } ) }
    </div>`;
  }
}

class Note extends cmp {
	constructor( { text } ) {
  	super();
    this.text = text;
  }
  _render() {
  	return this.tag`<div>${this.text}</div>`;
  }
}

const renderStack = {}

const master = new cmp('Head');
const res = master.tag`${ App.render( { title: 'App'} ) }`;
console.log(JSON.stringify(renderStack, null, 4))
console.log(res)

const div = document.createElement("div");
div.innerHTML = res;
document.getElementsByTagName('body')[0].appendChild(div);