JSFiddle - React, Tailwind, and code Playground
by koehr
HTML
The classic:
<div id="content">…loading</div>
<div id="content2"></div>
JavaScript
const arrayFunctions = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
function reactiveArray(ary, callback) {
const wrapped = ary.slice()
arrayFunctions.forEach(function(fn) {
const original = Array.prototype[fn]
Object.defineProperty(wrapped, fn, {
value: function() {
console.log('feelin manipulative?')
const result = original.apply(this, arguments)
callback()
return result
}
})
})
return wrapped
}
function reactive(obj, callback) {
if (typeof obj !== 'object') return obj
if (Array.isArray(obj)) return reactiveArray(obj, callback)
const wrapped = {}
for (let key in obj) {
let value = obj[key]
if (Array.isArray(value)) {
value = reactiveArray(value, callback)
} else if (typeof value === 'object') {
value = reactive(value, callback)
}
Object.defineProperty(wrapped, key, {
get: function reactiveGetter() {
return value
},
set: function reactiveGetter(newValue) {
console.log('setting value from', value, 'to', newValue)
value = reactive(newValue, callback)
callback()
}
})
}
return wrapped
}
function createComponent (obj) {
const data = obj.data || {}
const render = obj.render.bind(obj)
obj.data = reactive(data, render)
obj.render() // sneaked in an initial render call
return obj
}
const helloComponent = createComponent({
el: document.getElementById('content'),
data: {
name: {}
},
render: function () {
console.log('rendering helloComponent')
this.el.innerHTML = `<h1>Hello ${this.data.name.first} ${this.data.name.last}</h1>`
}
})
const lipsumComponent = createComponent({
el: document.getElementById('content2'),
data: {
content: []
},
render: function () {
console.log('rendering lipsumComponent')
const elements = this.data.content.map(function(el) {
const tag = el[0], text = el[1]
return...