import { h, withState, mount, sequence2, RxAble } from 'rx' const imbricatedMaps = withState(1, counter => [ counterComponent({ value: counter, onSub: () => counter.update(n => n - 1), onAdd: () => counter.update(n => n + 1) }), counter.map(c1 => { console.log('c1') return [ h('div', 'Inside first count'), counter.map(c2 => { console.log('c2') return h('div', `Inside second count ${c2}`) }) ] }) ]) const flatMap = withState(1, counter => [ counterComponent({ value: counter, onSub: () => counter.update(n => n - 1), onAdd: () => counter.update(n => n + 1) }), counter.flatMap(c1 => { console.log('c1') return counter.map(c2 => { console.log('c2') return h('div', `Inside second count ${c2}`) }) }) ]) const checkbox = withState(false, checked => [ checkboxComponent({ label: 'Checkbox', isChecked: checked, onCheck: (isChecked: boolean) => checked.update(_ => isChecked), }), checked.map(isChecked => isChecked ? 'C’est coché!' : 'Ça n’est pas coché') ]) const rxChildren = withState(3, count => [ h('input', { type: 'number', value: count, onchange: (event: Event) => count.update(_ => parseInt((event.target as HTMLInputElement).value)) }), h('div', 'FOO'), count.map(n => Array(n).fill(null).map((_, i) => h('div', `A ${i}!`))), h('div', 'BAR'), count.map(n => Array(n).fill(null).map((_, i) => h('div', `B ${i}!`))), h('div', 'BAZ') ]) const nodesCancel = withState(false, checked => [ checkboxComponent({ label: 'Checkbox', isChecked: checked, onCheck: (isChecked: boolean) => checked.update(_ => isChecked), }), checked.map(isChecked => isChecked ? rxChildren : undefined) ]) const counters = withState>([], counters => { return [ counterComponent({ value: counters.map(cs => cs.length), onSub: () => counters.update(cs => cs.slice(0, -1)), onAdd: () => counters.update(cs => cs.concat(0)) }), h('hr'), h('div', { style: 'margin-top: 1rem' }, counters.map(cs => cs.map((c, i) => counterComponent({ value: c, onSub: () => counters.update(cs => { cs[i] = c - 1 return cs }), onAdd: () => counters.update(cs => { cs[i] = c + 1 return cs }) }) ) )) ] }) const rows = withState(1, count => [ h('input', { type: 'number', value: count, onchange: (event: Event) => count.update(_ => parseInt((event.target as HTMLInputElement).value)) }), count.map(n => Array(n).fill(null).map((_, i) => h('div', i))) ]) const chrono = withState(false, isChecked => [ checkboxComponent({ label: 'Show counter', isChecked, onCheck: b => isChecked.update(_ => b) }), isChecked.map(b => b && withState(0, elapsed => { const interval = window.setInterval( () => elapsed.update(n => n + 1), 1000 ) return h( 'div', { onunmount: () => clearInterval(interval) }, elapsed ) })) ]) const doubleMapChild = withState(true, isEven => withState('', search => { const books = [...Array(50).keys()] const filteredBooks = isEven.flatMap(f => search.map(s => books.filter(b => (f ? b % 2 === 0 : b % 2 === 1) && (s === '' || b.toString().includes(s))))) return [ checkboxComponent({ label: 'Even?', isChecked: isEven, onCheck: checked => isEven.update(_ => checked) }), h( 'input', { oninput: (event: Event) => search.update(_ => (event.target as HTMLInputElement).value) , style: 'margin-left: 1rem' } ), h('hr'), isEven.map(b => b ? filteredBooks.map(xs => `isEven (${xs.length})`) : filteredBooks.map(xs => `isOdd (${xs.length})`) ), h('hr'), filteredBooks.map(bs => bs.map(b => h('div', b))), h('hr') ] }) ) const seq = withState(0, a => withState(0, b => withState(0, c => [ counterComponent({ value: a, onSub: () => a.update(n => n - 1), onAdd: () => a.update(n => n + 1) }), counterComponent({ value: b, onSub: () => b.update(n => n - 1), onAdd: () => b.update(n => n + 1) }), counterComponent({ value: c, onSub: () => c.update(n => n - 1), onAdd: () => c.update(n => n + 1) }), sequence2([a, b, c]).map(xs => xs.reduce((a, b) => a + b, 0)) ]) ) ) const indirectCheckbox = withState(false, checked => [ checkboxComponent({ label: 'C1', isChecked: checked, onCheck: (b: boolean) => checked.update(_ => b) }), checkboxComponent({ label: 'C2', isChecked: checked, onCheck: (b: boolean) => checked.update(_ => b) }) ]) const view = h('main', h('h1', 'Rx'), indirectCheckbox ) mount(view) // Checkbox interface CheckboxParams { label: RxAble isChecked: RxAble onCheck: (isChecked: boolean) => void } function checkboxComponent({ label, isChecked, onCheck }: CheckboxParams) { return h('label', h('input', { type: 'checkbox', onchange: (event: Event) => onCheck((event.target as HTMLInputElement).checked), checked: isChecked, } ), label ) } // Counter interface CounterParams { value: RxAble onAdd: () => void onSub: () => void } function counterComponent({ value, onAdd, onSub}: CounterParams) { return h('div', [ h('span', { style: 'margin-right: 5px' }, value), h('button', { onclick: () => onSub() }, '-'), h('button', { onclick: () => onAdd() }, '+'), ] ) }