UNPKG

@thi.ng/rdom

Version:

Lightweight, reactive, VDOM-less UI/DOM components with async lifecycle and @thi.ng/hiccup compatible

85 lines (84 loc) 2.14 kB
import { isString } from "@thi.ng/checks/is-string"; import { $compile } from "./compile.js"; import { Component } from "./component.js"; import { __nextID } from "./idgen.js"; import { __initList } from "./internal/list.js"; import { $subWithID } from "./sub.js"; const $list = (src, opts) => $subWithID(src, new List(opts), __nextID("list", src)); class List extends Component { constructor(opts) { super(); this.opts = opts; } opts; prev; items; anchor; offset = 0; numChildren = -1; async mount(parent, index, state) { this.prev = []; this.items = []; const { el, anchor } = __initList(parent, index, this.opts); this.el = el; this.anchor = anchor; this.update(state); return this.el; } async unmount() { this.items.forEach((c) => c.unmount()); if (isString(this.opts.el)) this.$remove(); this.anchor?.remove(); this.el = void 0; this.items = void 0; this.prev = void 0; } async update(curr) { if (!curr) return; const { opts: { item: ctor, equiv = (a, b) => a === b }, items, prev, el: parent, anchor } = this; const nb = curr.length; let na = prev.length; let n = Math.min(na, nb); let offset = this.offset; const children = parent.childNodes; if (anchor && children.length !== this.numChildren) { this.numChildren = children.length; this.offset = offset = [...children].indexOf(anchor); } for (let i = 0; i < n; i++) { if (!equiv(prev[i], curr[i])) { await items[i].unmount(); const val = curr[i]; const child = $compile(ctor(val)); await child.mount(parent, i + offset); items[i] = child; prev[i] = val; } } if (na < nb) { for (; n < nb; n++) { const val = curr[n]; const child = $compile(ctor(val)); await child.mount(parent, n + offset); items[n] = child; prev[n] = val; } } else { while (--na >= nb) { await items[na].unmount(); items.pop(); prev.pop(); } } } } export { $list, List };