Last active
August 31, 2015 14:33
-
-
Save dmitriid/83fb398210e84c9029e2 to your computer and use it in GitHub Desktop.
Cycle.js. Doing it right?
This file contains hidden or 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
/* | |
* This is a simple example taken to extremes (MVI everywhere :) ) | |
* | |
* - Display N div's containing checkboxes | |
* - When a checkbox is clicked: | |
* - a checked checkbox is rendered as checked | |
- checkbox's label reads "Unchecked" or "Checked" | |
- the parent div's background changes based on the | |
status of the checkbox (red for unchecked, green for checked) | |
*/ | |
/*--------------* | |
* main.js | |
*--------------*/ | |
/** @jsx hJSX */ | |
import {hJSX} from '@cycle/dom'; | |
import {run, Rx} from '@cycle/core'; | |
import {makeDOMDriver} from '@cycle/dom'; | |
import row from './table-row.js'; | |
function main({DOM}){ | |
const createRow = (i) => row(DOM, i); | |
let arr = []; | |
for(let i = 0; i <= 5; i++){ arr.push(createRow(i).DOM); } | |
return { | |
DOM: Rx.Observable.just(<div>{arr}</div>) | |
}; | |
} | |
run(main, { | |
DOM: makeDOMDriver('#app') | |
}); | |
/*--------------* | |
* table-row.js | |
*--------------*/ | |
/** @jsx hJSX */ | |
import {hJSX} from '@cycle/dom'; | |
import checkbox from './checkbox.js'; | |
const id = (name) => `div-check-${name}`; | |
function intent(observable){ | |
return { | |
state$: observable.state$ | |
}; | |
} | |
function model(actions){ | |
return actions.state$.map((state) =>{ | |
return { | |
padding: '10px', | |
backgroundColor: state ? 'green': 'red' | |
}; | |
} | |
) | |
} | |
function view(style$, checkDOM$, name){ | |
return style$.combineLatest( | |
checkDOM$, | |
(style, checkVTree) => { | |
return <div style={style} key={id(name)}>{checkVTree}</div>; | |
} | |
); | |
} | |
export default function (DOM, name){ | |
const check = checkbox(DOM, name); | |
const style$ = model(intent(check)); | |
return { | |
DOM: view(style$, check.DOM, name) | |
} | |
} | |
/*--------------* | |
* checkbox.js | |
*--------------*/ | |
/** @jsx hJSX */ | |
import {hJSX} from '@cycle/dom'; | |
import {Rx} from '@cycle/core'; | |
const id = (name) => `check-${name}`; | |
const label = (state) => state ? 'Checked' : 'Unchecked'; | |
function intent(DOM, name){ | |
return { | |
clickStream$: DOM.get(`#${id(name)}`, 'click').map(ev => !ev.target.checked).startWith(true) | |
}; | |
} | |
function model(actions){ | |
return actions.clickStream$.map( | |
state => { | |
console.log(`Got state: ${state}`); | |
return !state; | |
} | |
); | |
} | |
function view(state$, name){ | |
return state$.map(state => { | |
return <span> | |
<input type="checkbox" name={name} id={id(name)} className='.check' | |
key={id(name)} checked={state}/> | |
| |
<label for={id(name)}>{label(state)}</label> | |
</span>; | |
}); | |
} | |
export default function (DOM, name){ | |
const state$ = model(intent(DOM, name)); | |
return { | |
DOM: view(state$, name), | |
state$: state$ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment