Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as most from 'most';
- import {run} from '@cycle/most-run';
- import {div, input, p, makeDOMDriver, li, ul, span, h2} from '@cycle/dom';
- import fp from 'lodash/fp'
- import isolate from '@cycle/isolate'
- // props : { selected : Bool, label : String, value: Int}
- function Option({DOM, props$}) {
- const click$ = DOM.select('.option').events('click')
- // a stream of toggle functions. one for each click
- const toggle$ = click$
- .map(() => bool => !bool)
- /// stream of toggle functions folded upon the inital value so that clicking the option checks if off and on
- const selected$ = props$.map(prop => toggle$.scan((b, f) => f(b), prop.selected)).join()
- // a stream of states which has the same structure as props, but toggled 'selected' field according to selected$ stream
- const state$ = most.combineArray((props, selected) => ({...props, selected}), [props$, selected$])
- // the state mapped to a representation of the option
- const vtree$ = state$.map(state => {
- return li('.option', {class: {selected: state.selected}}, [
- input({attrs: {type: 'checkbox', checked: state.selected}}),
- p(state.label),
- ])
- })
- // returns the stream of state$ so that multiselect can output a stream of selected values
- return {
- DOM: vtree$,
- state$,
- }
- }
- function Multiselect({DOM, props$}) {
- // a stream of arrays of isolated Option components
- const options$ = props$.map(
- options =>
- options.map(it =>
- isolate(Option)({DOM, props$: most.of(it)})))
- // Option({DOM, props$: most.of(it)}))) // comment above line and uncomment this one. Without isolation the component doesn't work correctly, but the states are updated
- // a stream of arrays of virtual tree representations of child Option components
- const optionsVtree$ = options$.map(options => fp.map(fp.get('DOM'), options))
- .map(arrayOfVtree$ => most.combineArray(Array, arrayOfVtree$))
- .join()
- // a stream of arrays of states of child Option components
- const optionStates$ = options$.map(options => fp.map(fp.get('state$'), options))
- .map(arrayOfState$ => most.combineArray(Array, arrayOfState$))
- .join()
- // .map(fp.filter(fp.get('selected')))
- // here the virtual trees of options are combined with the state stream so that I can log the state. I only use the virtual dom trees
- const vtree$ = optionsVtree$.combine(Array, optionStates$).map(([vtrees, states]) => {
- console.log(states.map(state => state.selected)); // this always prints the initial states
- // console.log(vtrees); // but the vtrees do change
- return div('.multiselect', [
- ul('.options', vtrees)
- ])
- })
- const sinks = {
- DOM: vtree$,
- optionStates$
- };
- return sinks;
- }
- run(Multiselect, {
- DOM: makeDOMDriver('#app'),
- props$: () => most.of([
- {value: 0, label: 'Option 1', selected: false},
- {value: 1, label: 'Option 2', selected: false},
- {value: 2, label: 'Option 3', selected: false},
- {value: 3, label: 'Option 4', selected: false},
- ])
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement