/** @jsx dom */
/*
Article:

https://dev.to/merri/building-a-jsx-dom-library-part-1-3ga6

Code is split to two parts:

1. Library
2. Application
*/

// --- Library ---

const propsStore = new WeakMap()

function render(element, nextProps) {
    if (!propsStore.has(element)) return
    const props = Object.assign(propsStore.get(element), nextProps)
    Object.assign(element, props)
    return element
}

function dom(component, props, ...children) {
    props = { ...props }
    const element = typeof component === 'function'
        ? component(props)
        : document.createElement(component)
    propsStore.set(element, props)
    Object.assign(element, props)
    return children.reduce(function(el, child) {
        if (child instanceof Node) el.appendChild(child)
        else el.appendChild(document.createTextNode(String(child)))
        return el
    }, element)
}

// --- Application ---

function Component(props) {
    function changeColor() {
        render(ref, { style: 'background: red; padding: 5px;' })
    }

    const ref = (
        <div style={props.style}>
            <h1>Hello world!</h1>
            <button onclick={changeColor}>Change color</button>
        </div>
    )

    return ref
}

const App = <Component style="background: gray; padding: 5px;" />

document.body.appendChild(App)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.