made with esnextbin
Created
October 19, 2016 12:26
-
-
Save tusharmath/01341c64ad939d545c8a3956a914aac8 to your computer and use it in GitHub Desktop.
esnextbin sketch
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
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>ESNextbin Sketch</title> | |
<!-- put additional styles and scripts here --> | |
</head> | |
<body> | |
<div id="app"></div> | |
</body> | |
</html> |
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 * 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$, | |
} | |
} | |
// VERSION WHERE THE PROPS OF THE MULTISELECT AREN'T WRAPPED IN A STREAM | |
function MultiselectV1({DOM}) { | |
const props = [ | |
{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} | |
] | |
// a stream of arrays of isolated Option components | |
const options = props.map(prop => | |
isolate(Option)({ | |
DOM, | |
props$: most.of(prop) | |
}).tap(x => console.log(x)) | |
); | |
const optionVTrees$ = options.map(sink => sink.DOM) | |
const optionStates$ = options.map(sink => sink.state$) | |
// 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 | |
const states$ = most.combineArray(Array, optionStates$) | |
const vtree$ = most.combineArray(Array, optionVTrees$).combine(Array, states$).map( | |
([optionVtrees, states]) => | |
div('.multiselect', [ | |
ul('.options', optionVtrees), | |
div('.debug', JSON.stringify(states.map(e => e.selected))) | |
]) | |
) | |
const sinks = { | |
DOM: vtree$, | |
optionStates$ | |
}; | |
return sinks; | |
} | |
// VERSION WHERE THE PROPS OF THE MULTISELECT ARE WRAPPED IN A STREAM | |
function MultiselectV2({DOM}) { | |
const 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}]) | |
// a stream of arrays of isolated Option components | |
const options$ = props$.map(props => props.map(prop => | |
isolate(Option)({ | |
DOM, | |
props$: most.of(prop) | |
}) | |
)); | |
// a stream of arrays of virtual tree representations of child Option components | |
const optionsVtree$ = options$.map(options => fp.map(fp.get('DOM'), options)) | |
.tap(x => console.log(x)) | |
.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]) => { | |
return div('.multiselect', [ | |
ul('.options', vtrees), | |
div('.debug', [JSON.stringify(states.map(e => e.selected))]) | |
]) | |
}) | |
const sinks = { | |
DOM: vtree$, | |
optionStates$ | |
}; | |
return sinks; | |
} | |
// SWITCH BETWEEN MultiselectV1 and MultiselectV2 | |
// V1 works correctly but the props and therefore child components aren't | |
// wrapped in a stream. | |
// V2 doesn't works correctly (the diplayed list of booleans doesn't change) | |
// props (list of option data is wrapped within a stream) | |
run(MultiselectV1, { | |
DOM: makeDOMDriver('#app'), | |
}); |
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
{ | |
"name": "esnextbin-sketch", | |
"version": "0.0.0", | |
"dependencies": { | |
"most": "1.0.4", | |
"@cycle/most-run": "4.1.3", | |
"@cycle/dom": "13.0.0", | |
"@cycle/isolate": "1.4.0", | |
"babel-runtime": "6.11.6", | |
"lodash": "4.16.4" | |
} | |
} |
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
'use strict'; | |
var _stringify = require('babel-runtime/core-js/json/stringify'); | |
var _stringify2 = _interopRequireDefault(_stringify); | |
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); | |
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); | |
var _extends2 = require('babel-runtime/helpers/extends'); | |
var _extends3 = _interopRequireDefault(_extends2); | |
var _most = require('most'); | |
var most = _interopRequireWildcard(_most); | |
var _mostRun = require('@cycle/most-run'); | |
var _dom = require('@cycle/dom'); | |
var _fp = require('lodash/fp'); | |
var _fp2 = _interopRequireDefault(_fp); | |
var _isolate = require('@cycle/isolate'); | |
var _isolate2 = _interopRequireDefault(_isolate); | |
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | |
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | |
// props : { selected : Bool, label : String, value: Int} | |
function Option(_ref) { | |
var DOM = _ref.DOM; | |
var props$ = _ref.props$; | |
var click$ = DOM.select('.option').events('click'); | |
// a stream of toggle functions. one for each click | |
var toggle$ = click$.map(function () { | |
return function (bool) { | |
return !bool; | |
}; | |
}); | |
/// stream of toggle functions folded upon the inital value so that clicking the option checks if off and on | |
var selected$ = props$.map(function (prop) { | |
return toggle$.scan(function (b, f) { | |
return f(b); | |
}, prop.selected); | |
}).join(); | |
// a stream of states which has the same structure as props, but toggled 'selected' field according to selected$ stream | |
var state$ = most.combineArray(function (props, selected) { | |
return (0, _extends3.default)({}, props, { selected: selected }); | |
}, [props$, selected$]); | |
// the state mapped to a representation of the option | |
var vtree$ = state$.map(function (state) { | |
return (0, _dom.li)('.option', { class: { selected: state.selected } }, [(0, _dom.input)({ attrs: { type: 'checkbox', checked: state.selected } }), (0, _dom.p)(state.label)]); | |
}); | |
// returns the stream of state$ so that multiselect can output a stream of selected values | |
return { | |
DOM: vtree$, | |
state$: state$ | |
}; | |
} | |
// VERSION WHERE THE PROPS OF THE MULTISELECT AREN'T WRAPPED IN A STREAM | |
function MultiselectV1(_ref2) { | |
var DOM = _ref2.DOM; | |
var props = [{ 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 }]; | |
// a stream of arrays of isolated Option components | |
var options = props.map(function (prop) { | |
return (0, _isolate2.default)(Option)({ | |
DOM: DOM, | |
props$: most.of(prop) | |
}).tap(function (x) { | |
return console.log(x); | |
}); | |
}); | |
var optionVTrees$ = options.map(function (sink) { | |
return sink.DOM; | |
}); | |
var optionStates$ = options.map(function (sink) { | |
return sink.state$; | |
}); | |
// 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 | |
var states$ = most.combineArray(Array, optionStates$); | |
var vtree$ = most.combineArray(Array, optionVTrees$).combine(Array, states$).map(function (_ref3) { | |
var _ref4 = (0, _slicedToArray3.default)(_ref3, 2); | |
var optionVtrees = _ref4[0]; | |
var states = _ref4[1]; | |
return (0, _dom.div)('.multiselect', [(0, _dom.ul)('.options', optionVtrees), (0, _dom.div)('.debug', (0, _stringify2.default)(states.map(function (e) { | |
return e.selected; | |
})))]); | |
}); | |
var sinks = { | |
DOM: vtree$, | |
optionStates$: optionStates$ | |
}; | |
return sinks; | |
} | |
// VERSION WHERE THE PROPS OF THE MULTISELECT ARE WRAPPED IN A STREAM | |
function MultiselectV2(_ref5) { | |
var DOM = _ref5.DOM; | |
var 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 }]); | |
// a stream of arrays of isolated Option components | |
var options$ = props$.map(function (props) { | |
return props.map(function (prop) { | |
return (0, _isolate2.default)(Option)({ | |
DOM: DOM, | |
props$: most.of(prop) | |
}); | |
}); | |
}); | |
// a stream of arrays of virtual tree representations of child Option components | |
var optionsVtree$ = options$.map(function (options) { | |
return _fp2.default.map(_fp2.default.get('DOM'), options); | |
}).tap(function (x) { | |
return console.log(x); | |
}).map(function (arrayOfVtree$) { | |
return most.combineArray(Array, arrayOfVtree$); | |
}).join(); | |
// // a stream of arrays of states of child Option components | |
var optionStates$ = options$.map(function (options) { | |
return _fp2.default.map(_fp2.default.get('state$'), options); | |
}).map(function (arrayOfState$) { | |
return 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 | |
var vtree$ = optionsVtree$.combine(Array, optionStates$).map(function (_ref6) { | |
var _ref7 = (0, _slicedToArray3.default)(_ref6, 2); | |
var vtrees = _ref7[0]; | |
var states = _ref7[1]; | |
return (0, _dom.div)('.multiselect', [(0, _dom.ul)('.options', vtrees), (0, _dom.div)('.debug', [(0, _stringify2.default)(states.map(function (e) { | |
return e.selected; | |
}))])]); | |
}); | |
var sinks = { | |
DOM: vtree$, | |
optionStates$: optionStates$ | |
}; | |
return sinks; | |
} | |
// SWITCH BETWEEN MultiselectV1 and MultiselectV2 | |
// V1 works correctly but the props and therefore child components aren't | |
// wrapped in a stream. | |
// V2 doesn't works correctly (the diplayed list of booleans doesn't change) | |
// props (list of option data is wrapped within a stream) | |
(0, _mostRun.run)(MultiselectV1, { | |
DOM: (0, _dom.makeDOMDriver)('#app') | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment