hyperapp-customelements
is a tiny (3KB) Web Components Custom Elements library based on hyperapp
.
Define Custom Elements that:
- work in all evergreen browsers and IE10.
- are based on hyperapp so you get
- a beautifully simple API
- a functional paradigm
- immutable state data
- Virtual DOM updates
- provide a solid migration path to Custom Elements V1
See it in action here
const define = require('hyperapp-customelements')
const MyElement = define({
// Required
name: 'my-element',
view () {
// Any `h()` returning function including JSX or a transformed `hyperviews` template
},
// Optional
state: {
// Initial hyperapp state
},
actions: {
// Hyperapp actions
},
constructor () {
// Wired actions are now available as `this.actions`
},
// Attributes to observe.
// Each item in the array must be a string or an object.
// Use an object to provide a conversion function.
// The function is used to convert the value from a string when reflecting to state
// E.g ['title', { max: Number }, { show: Boolean }, { custom: (value) => {...} }, 'another']
observedAttributes: Array,
attributeChangedCallback (name, oldValue, newValue) {
// Invoked when an observed attribute changes.
// Attribute changes are reflected to state by default.
// It's therefore not always necessary to provide this function.
// Set `mapAttrsToState` to `false` to update state manually.
},
connectedCallback () {
// Invoked when the element is inserted into the document
},
disconnectedCallback () {
// Invoked when the element is removed from the document
},
//...any other properties/methods are added to the element prototype
})
Then use declaratively
<my-element></my-element>
or programmatically
const myElement = new MyElement()
document.body.appendChild(myElement)
const define = require('hyperapp-customelements')
define({
name: 'x-counter',
state: {
counter: 0
},
actions: {
down: value => state => ({ count: state.count - value }),
up: value => state => ({ count: state.count + value })
},
view: (state, actions) => (
<div>
<h1>{state.count}</h1>
<button onclick={() => actions.down(1)} disabled={state.count <= 0}>ー</button>
<button onclick={() => actions.up(1)} disabled={state.count >= state.max}>+</button>
</div>
),
observedAttributes: [{ max: Number }]
})
<x-counter max="10"></x-counter>
You may notice that the API looks like Custom Elements V1, however the decision was taken to initially target Custom Elements V0 but with a V1 flavour so, when V1 is widely supported, the upgrade will be simple. See this article for more information. Huge thanks to Andrea Giammarchi for all his work in this area.