-
-
Save staltz/b9850c4e620946edf14e to your computer and use it in GitHub Desktop.
Hierarchical Cycle.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Rx} from '@cycle/core' | |
import {h} from '@cycle/dom' | |
import _ from 'lodash' | |
import makeSlider from './slider' | |
function makeBMICalculator(namespace) { | |
const name = _.last(namespace) | |
const model = (weightState$, heightState$) => { | |
return Rx.Observable.combineLatest(weightState$, heightState$, | |
(weightState, heightState) => { | |
let heightMeters = heightState.value * 0.01 | |
let bmi = Math.round(weightState.value / (heightMeters * heightMeters)) | |
return {bmi} | |
}) | |
.shareReplay(1) | |
} | |
const view = (state$, weightVTree$, heightVTree$) => state$.map(({bmi}) => { | |
return h('div' + name, [ | |
weightVTree$, | |
heightVTree$, | |
h('h2', 'BMI is ' + bmi) | |
]) | |
}) | |
return function minimain(DOM) { | |
const weightSlider = makeSlider(namespace.concat('.weight')) | |
const heightSlider = makeSlider(namespace.concat('.height')) | |
const weightProps$ = Rx.Observable.just( | |
{label: 'Weight', unit: 'kg', initial: 75, min: 40, max: 150} | |
) | |
const heightProps$ = Rx.Observable.just( | |
{label: 'Height', unit: 'cm', initial: 170, min: 130, max: 210} | |
) | |
const {DOM: weightVTree$, state$: weightState$} = weightSlider(DOM, weightProps$) | |
const {DOM: heightVTree$, state$: heightState$} = heightSlider(DOM, heightProps$) | |
return { | |
DOM: view(model(weightState$, heightState$), weightVTree$, heightVTree$) | |
} | |
} | |
} | |
export default makeBMICalculator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Rx} from '@cycle/core' | |
import {h} from '@cycle/dom' | |
import _ from 'lodash' | |
import makeBMICalculator from '../components/bmi-calculator' | |
function makeBMIPage(namespace) { | |
const name = _.last(namespace) | |
const view = (calcVTree$) => Rx.Observable.just( | |
h('div' + name, [ | |
calcVTree$ | |
]) | |
) | |
return function minimain(DOM) { | |
const calc = makeBMICalculator(namespace.concat('.bmi-calculator')) | |
const calcVTree$ = calc(DOM).DOM | |
return { | |
DOM: view(calcVTree$) | |
} | |
} | |
} | |
export default makeBMIPage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Rx, run} from '@cycle/core' | |
import {makeDOMDriver} from '@cycle/dom' | |
import makeBMIPage from './pages/bmi-page' | |
function main({DOM}) { | |
const bmiPage = makeBMIPage(['.bmi-page']) | |
return bmiPage(DOM) | |
} | |
const drivers = { | |
DOM: makeDOMDriver('.js-container') | |
} | |
run(main, drivers) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Rx} from '@cycle/core' | |
import {h} from '@cycle/dom' | |
import _ from 'lodash' | |
function makeSlider(namespace) { | |
const name = _.last(namespace) | |
const intent = (DOM) => ({ | |
change$: DOM.get(`${namespace.join(' ')} input`, 'input') | |
.map(ev => ev.target.value) | |
}) | |
const model = (actions, props$) => ( | |
props$.map(({initial}) => initial).first() | |
.concat(actions.change$) | |
.combineLatest(props$, (value, props) => ({ | |
value, | |
unit: props.unit, | |
min: props.min, | |
max: props.max, | |
label: props.label | |
})) | |
.shareReplay(1) | |
) | |
const view = (state$) => state$.map(({value, unit, label, min, max}) => { | |
return h(`div${name}`, [ | |
`${label} ${value}${unit}`, | |
h('input', {type: 'range', min, max, value}) | |
]) | |
}) | |
return function minimain(DOM, props$) { | |
const state$ = model(intent(DOM), props$) | |
return { | |
DOM: view(state$), | |
state$ | |
} | |
} | |
} | |
export default makeSlider |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment