@motorcycle/mostly-dom
Version:
Motorcycle.ts adapter for mostly-dom. Built on @motorcycle/dom.
63 lines • 1.76 kB
JavaScript
import { createDomSource } from '@motorcycle/dom';
import { elementToVNode, init } from 'mostly-dom';
import { drain, hold, map, scan } from '@motorcycle/stream';
import { prop } from '@typed/prelude';
import { vNodeWrapper } from './vNodeWrapper';
var toElement = map(prop('element'));
/**
* Takes an element and returns a DOM component function.
*
* @name makeDomComponent(element: Element): (sinks: DomSinks) => DomSources
* @example
* import {
* makeDomComponent,
* DomSources,
* DomSinks,
* VNode,
* events,
* query,
* div,
* h1,
* button
* } from '@motorcycle/mostly-dom'
* import { run } from '@motorcycle/run'
*
* const element = document.querySelector('#app')
*
* if (!element) throw new Error('unable to find element')
*
* run(Main, makeDomComponent(element))
*
* function Main(sources: DomSources): DomSinks {
* const { dom } = sources
*
* const click$: Stream<Event> = events('click', query('button'))
*
* const amount$: Stream<number> = scan(x => x + 1, 0, click$)
*
* const view$: Stream<VNode> = map(view, amount$)
*
* return { view$ }
* }
*
* function view(amount: number) {
* return div([
* h1(`Clicked ${amount} times`),
* button(`Click me`)
* ])
* }
*/
export function makeDomComponent(element) {
var rootVNode = elementToVNode(element);
var wrapVNode = map(vNodeWrapper(element));
var patch = scan(init(), rootVNode);
return function Dom(sinks) {
var view$ = sinks.view$;
var elementVNode$ = patch(wrapVNode(view$));
var element$ = hold(toElement(elementVNode$));
var dom = createDomSource(element$);
drain(element$);
return { dom: dom };
};
}
//# sourceMappingURL=makeDomComponent.js.map