Skip to content

Instantly share code, notes, and snippets.

@tusharmath
Created October 19, 2016 12:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tusharmath/01341c64ad939d545c8a3956a914aac8 to your computer and use it in GitHub Desktop.
Save tusharmath/01341c64ad939d545c8a3956a914aac8 to your computer and use it in GitHub Desktop.
esnextbin sketch
<!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>
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'),
});
{
"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"
}
}
'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