JSFiddle - React, Tailwind, and code Playground

by graphettion

HTML

This
<input type="text" id="a-text"> plus this
<input type="text" id="b-text">=
<input type="text" id="c-text" readonly>, fool!

Babel + JSX

function observable(value) {
  const listeners = [];

  function notify(newValue) {
    listeners.forEach(function(listener) {
      listener(newValue);
    });
  }

  function accessor(newValue) {
    if (arguments.length && newValue !== value) {
      value = newValue;
      notify(newValue);
    }
    return value;
  }

  accessor.subscribe = function(listener) {
    listeners.push(listener);
  };

  return accessor;
}

function computed(calculation, dependencies) {
  const value = observable(calculation());

  function listener(v) {
    value(calculation());
  }
  dependencies.forEach(function(dependency) {
    dependency.subscribe(listener);
  });

  function getter() {
    return value();
  }
  getter.subscribe = value.subscribe;

  return getter;
}

function bindValue(input, observable) {
  const initial = observable();
  input.value = initial;
  observable.subscribe(function() {
    input.value = observable();
  });

  let converter = function(v) {
    return v;
  };
  if (typeof initial == 'number') {
    converter = function(n) {
      return isNaN(n = parseFloat(n)) ? 0 : n;
    };
  }

  input.addEventListener('input', function() {
    observable(converter(input.value));
  });
}

const aText = document.getElementById('a-text'),
  bText = document.getElementById('b-text'),
  cText = document.getElementById('c-text');

const a = observable(3),
  b = observable(2),
  c = computed(function() {
    return a() + b();
  }, [a, b]);

bindValue(aText, a);
bindValue(bText, b);
bindValue(cText, c);