Last active
February 14, 2019 01:37
-
-
Save uchcode/31cb1d039afdfecd7e1b4d06596b1b6b to your computer and use it in GitHub Desktop.
hyperapp web components example
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
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=2"> | |
<meta name="apple-mobile-web-app-capable" content="yes"> | |
<style>body{margin:0;padding:0;}</style> | |
<script type="module"> | |
document.addEventListener('touchmove',e=>e.preventDefault(),{passive:false}) | |
import { h, app } from 'https://unpkg.com/hyperapp?module' | |
!function() { | |
const state = { | |
value: 0, | |
} | |
const actions = { | |
increment: value => state => ({ value: state.value + +value }), | |
decrement: value => state => ({ value: state.value - +value }), | |
crement: value => state => ({ value: +value }), | |
} | |
const view = (light) => (state, actions) => | |
h('div', {}, | |
h('style', {}, '*{touch-action:manipulation;}'), | |
h('input', numberbox(state, actions, light)), | |
h('button', decrement(actions), '-'), | |
h('button', increment(actions), '+'), | |
) | |
const numberbox = (state, actions, light) => ({ | |
value: state.value, | |
oninput: (event) => { | |
if (+event.target.value) actions.crement(event.target.value) | |
}, | |
onupdate: dispatcher(light), | |
}) | |
const increment = ({increment}) => ({ | |
onclick: () => increment(1), | |
}) | |
const decrement = ({decrement}) => ({ | |
onclick: () => decrement(1), | |
}) | |
const changeEvent = new CustomEvent('change') | |
const dispatcher = (light) => (element, oldAttributes) => { | |
const newVal = +element.value | |
const oldVal = +oldAttributes.value | |
if (newVal == oldVal) return | |
light.value = newVal | |
light.dispatchEvent(changeEvent) | |
} | |
customElements.define('hyper-numberbox', class extends HTMLElement { | |
static get observedAttributes() { | |
return ['value'] | |
} | |
attributeChangedCallback(attr, oldValue, newValue) { | |
if (oldValue == newValue) return | |
if (attr == 'value') { | |
this.actions.crement(+newValue) | |
} | |
} | |
constructor() { | |
super() | |
this.attachShadow({mode:'open'}) | |
this.actions = app(state, actions, view(this), this.shadowRoot) | |
} | |
}) | |
}(); | |
// =================== | |
const state = { | |
rate: 109, | |
dollars: 0, | |
yen: 0, | |
} | |
const actions = { | |
setRate: rate => state => ({ | |
rate: +rate, | |
yen : +rate * +state.dollars, | |
}), | |
setDollars: dollars => state => ({ | |
dollars: +dollars, | |
yen : +state.rate * +dollars, | |
}), | |
} | |
const view = (state, actions) => | |
h('div', {}, | |
h('h1', {}, 'Currency converter'), | |
h('h2', {}, '¥ ' + state.yen), | |
h('span', {}, 'rate'), | |
h('hyper-numberbox', rate(state, actions)), | |
h('span', {}, 'dollars'), | |
h('hyper-numberbox', dollars(state, actions)), | |
) | |
const rate = (state, actions) => ({ | |
value: state.rate, | |
onchange: (event) => actions.setRate(event.target.value) | |
}) | |
const dollars = (state, actions) => ({ | |
value: state.dollars, | |
onchange: (event) => actions.setDollars(event.target.value) | |
}) | |
app(state, actions, view, document.body) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment