<div id="app"></div>
const xs = window.xstream.default;

const { div, label, input, button, p, makeDOMDriver } = CycleDOM;
const isolate = CycleIsolate.default;
function view(state$) {
  return state$.map(state => {
    return div(".labeled-slider", [
      label(".label", `${state.label}: ${state.value} ${state.unit}`),
      input(".slider", {
        attrs: {
          type: "range",
          min: state.min,
          max: state.max,
          value: state.value
        }
      })
    ]);
  });
}
function intent(sources) {
  const domSource = sources.DOM;
  const value$ = domSource
    .select(".slider")
    .events("input")
    .map(ev => ev.target.value);
  return { value: value$ };
}
function model(intents, props) {
  const { value } = intents;
  return props
    .map(props =>
      value.startWith(props.init).map(value => ({ ...props, value }))
    )
    .flatten()
    .remember();
}
function Slider(sources) {
  const actions = intent(sources);
  const state$ = model(actions, sources.props);
  const vdom$ = view(state$);
  return {
    DOM: vdom$,
    value: state$.map(state => state.value)
  };
}
function main(sources) {
  const weightProps = xs.of({
    label: "Weight",
    min: 40,
    max: 100,
    init: 58,
    unit: "kg"
  });
  const weightSlider = isolate(Slider, ".weight");
  const weightSinks = weightSlider({
    ...sources,
    props: weightProps
  });
  const heightProps = xs.of({
    label: "Height",
    min: 140,
    max: 220,
    init: 165,
    unit: "cm"
  });
  const heightSlider = isolate(Slider, ".height");
  const heightSinks = heightSlider({
    ...sources,
    props: heightProps
  });
  const bmi$ = xs
    .combine(weightSinks.value, heightSinks.value)
    .map(([weight, height]) => {
      const hm = height * 0.01;
      const bmi = Math.round(weight / (hm * hm));
      return bmi;
    });

  const vdom$ = xs
    .combine(weightSinks.DOM, heightSinks.DOM, bmi$)
    .map(([weightVDOM, heightVDOM, bmi]) =>
      div([weightVDOM, heightVDOM, p(label(`BMI: ${bmi}`))])
    );
  return { DOM: vdom$ };
}

const drivers = {
  DOM: makeDOMDriver("#app")
};

Cycle.run(main, drivers);
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/xstream@11.7.0/dist/xstream.min.js
  2. https://unpkg.com/@cycle/run@4.4.0/dist/cycle-run.min.js
  3. https://unpkg.com/@cycle/dom@20.4.0/dist/cycle-dom.min.js
  4. https://unpkg.com/@cycle/isolate@3.4.0/dist/cycle-isolate.min.js