JSFiddle - React, Tailwind, and code Playground

by koehr

HTML

<div id="content"></div>

JavaScript

const Register = {}

function reactive (name, obj) {
  const wrapped = {}

  for (let key in obj) {
    const descriptor = Object.getOwnPropertyDescriptor(obj, key)
    if (!descriptor.configurable) return

    let value = descriptor.value
    const getter = descriptor.get
    const setter = descriptor.set

    Object.defineProperty(wrapped, key, {
      enumerable: true,
      configurable: true,
      get: function reactiveGetter () {
        return getter ? getter.call(obj) : value
      },
      set: function reactiveSetter (newValue) {
        if (setter) setter.call(obj, newValue)
        else value = newValue
        Register[name].render()
      }
    })
  }

  return wrapped
}

function registerComponent (name, component) {
  if (Register[name]) throw 'Component already registered!'
  else {
    Register[name] = component
    component.data = reactive(name, component.data)
    component.render()
  }
}

const component = {
  el: document.getElementById('content'),
  data: { name: 'World' },
  render: function () {
    console.log('component renders', this.data)
    this.el.innerHTML = `<h1>Hello ${this.data.name}</h1>`
  }
}
registerComponent('foo', component)
component.data.name = 'Universe'