Last active
May 30, 2017 02:24
-
-
Save AutoSponge/722f0276f2da4e0a8506182a5910cb0a to your computer and use it in GitHub Desktop.
set-state-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 { h, Component } from 'preact' | |
import style from './style' | |
import state from 'set-state' | |
const toInteger = n => (isNaN(n) ? 0 : parseInt(n || 0, 10)) | |
// raw count state with default | |
const count = state(0) | |
// collects events used to set count | |
const setCount = state() | |
// projection of count as integer | |
const $count = count.map(toInteger) | |
// collects events used to increment count | |
const inc = state() | |
// plucks the new value from the event | |
setCount.pluck('target.value').on(count) | |
// increments the current count | |
inc.on(() => count($count() + 1)) | |
// you can manipulate this from the console to trigger re-render | |
window.count = count | |
class StatefulInput extends Component { | |
componentDidMount () { | |
const { value } = this.props | |
this.cancel = state.combine({ value }).on(this, 'setState') | |
} | |
componentWillUnmount () { | |
this.cancel() | |
} | |
render (props, state) { | |
return <input {...props} {...state} /> | |
} | |
} | |
export default class Home extends Component { | |
render () { | |
return ( | |
<div class={style.home}> | |
<h1>Home</h1> | |
<StatefulInput | |
class={style.stateful} | |
onInput={setCount} | |
value={$count} | |
/> | |
<button class={style.stateful} onClick={inc}>add 1</button> | |
</div> | |
) | |
} | |
} |
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
const morph = require('nanomorph') | |
const html = require('bel') | |
const state = require('set-state') | |
const root = document.body.appendChild(html`<div></div>`) | |
const toInteger = n => (isNaN(n) ? 0 : parseInt(n, 10)) | |
const count = state(0) | |
const setCount = state() | |
const $count = count.map(toInteger) | |
const inc = state() | |
const oninput = e => setCount(e) | |
setCount.pluck('target.value').on(count) | |
inc.on(() => count($count() + 1)) | |
// you can play with the state in the console | |
window.count = count | |
count.on(console.log.bind(console, 'value:')) | |
const input = props => | |
state.combine(props) | |
.reduce((from, {value, oninput}) => { | |
const to = html`<input ${{value, oninput}}>` | |
return morph(from || to, to) | |
}) | |
.valueOf() | |
morph( | |
root, | |
html` | |
<div> | |
${input({ value: $count, oninput })} | |
<button onclick=${inc}>add 1</button> | |
</div> | |
` | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment