@benev/slate
Version:
frontend web stuff
64 lines (54 loc) • 1.86 kB
text/typescript
import {Part, render} from "lit"
import {AsyncDirective, DirectiveResult, directive} from "lit/async-directive.js"
import {Context} from "../context.js"
import {Shell} from "../parts/shell.js"
import {UseLightView} from "../parts/use/tailored.js"
import {SlateView} from "../parts/slate_view_element.js"
import {debounce} from "../../tools/debounce/debounce.js"
import {usekey} from "../parts/use/parts/utils/usekey.js"
import {LightViewRenderer, RenderResult} from "../parts/types.js"
import {Reactivity, setup_reactivity} from "../parts/setup_reactivity.js"
export const prepare_light_view = (
<C extends Context>(shell: Shell<C>) =>
<P extends any[]>(renderer: LightViewRenderer<C, P>) =>
directive(class extends AsyncDirective {
#props?: P
#element = document.createElement(SlateView.tag) as SlateView
#render_into_element(template: RenderResult) {
render(template, this.#element)
this.#use[usekey].afterRender()
return this.#element
}
#rerender = debounce(0, () => {
if (this.#props && this.isConnected)
this.setValue(this.#render_into_element(this.render(...this.#props!)))
})
#use = new UseLightView(this.#element, this.#rerender, shell.context)
#rend = this.#use[usekey].wrap(renderer(this.#use))
#reactivity?: Reactivity<P> = setup_reactivity<P>(
this.#rend,
this.#rerender,
)
update(_: Part, props: P) {
return this.#render_into_element(this.render(...props))
}
render(...props: P) {
this.#props = props
return this.#reactivity?.render(...props)
}
reconnected() {
this.#use[usekey].reconnect()
this.#reactivity = setup_reactivity<P>(
this.#rend,
this.#rerender,
)
}
disconnected() {
this.#use[usekey].disconnect()
if (this.#reactivity) {
this.#reactivity.stop()
this.#reactivity = undefined
}
}
}) as (...props: P) => DirectiveResult<any>
)