Evolui
⚠️ this is experimental! ⚠️
A 8kb
template library that magically understands Promises and Observables.
Evolui takes care of refreshing your UI when promises and observables emit new values.
You can only care about where the data should be displayed.
Get it
npm install --save evolui
Promises
import html, { render } from 'evolui'
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
render(
html`
<p>
Hello, ${delay(1000).then(() => 'World!')}
</p>
`,
document.body
)
Observables
import html, { render } from 'evolui'
import { Observable } from 'rxjs'
render(
html`
<p>
Hello, ${Observable.interval(1000)
.take(4)
.map(index => ['.', '..', '...', 'World!'][index])}
</p>
`,
document.body
)
Concept
The main goal of evolui is to make dealing with observables as easy as dealing with regular values.
Observables are a great way to represent values that change over time. The hard part though is combining them and managing subscriptions. This is where evolui comes in handy. Evolui understand any combination of Array
s, Promise
s and Observable
s, so you never have to worry on the way you should combine them before putting them inside your template.
html`
<div>
${'' /* this will return an array of observables. */}
${'' /* Don't panic! evolui understands that as well */}
${[1, 2, 3].map(
id => html`
<h1>${Observable.fromPromise(
fetch(`https://swapi.co/api/people/${id}`)
.then(res => res.json())
.then(character => character.name)
).startWith('Loading...')}</h1>
`
)}
</div>
`
Animations
Evolui exports a spring animation helper called ease.
ease: (stiffness: number, damping: number) => number => Observable<number>
You just have to add .switchMap(ease(<stiffness>, <damping>))
to any of your observable to make it animated.
import html, { render, ease } from 'evolui'
import { Observable } from 'rxjs'
const position$ = new Observable(observer => {
observer.next({ x: 0, y: 0 })
window.addEventListener('click', e => {
observer.next({ x: e.clientX, y: e.clientY })
})
})
render(
html`
<div>
<div
class="circle"
style="transform: translate(
${position$.map(m => m.x).switchMap(ease(120, 18))}px,
${position$.map(m => m.y).switchMap(ease(120, 18))}px
);" />
</div>
`,
document.body
)
More examples
To see more example, visite the example
folder.
Contributing
If you find this interesting and you want to contribute, don't hesitate to open an issue or to reach me out on twitter @GabrielVergnaud!