@thi.ng/rdom
Version:
Lightweight, reactive, VDOM-less UI/DOM components with async lifecycle and @thi.ng/hiccup compatible
71 lines (70 loc) • 1.72 kB
JavaScript
import { $compile } from "./compile.js";
import { Component } from "./component.js";
import { __nextID } from "./idgen.js";
import { $subWithID } from "./sub.js";
const $list = (src, tag, attribs, ctor, equiv) => $subWithID(
src,
new List(tag, attribs, ctor, equiv),
__nextID("list", src)
);
class List extends Component {
constructor(tag, attribs, ctor, equiv = (a, b) => a === b) {
super();
this.tag = tag;
this.attribs = attribs;
this.ctor = ctor;
this.equiv = equiv;
}
prev;
items;
async mount(parent, index, state) {
this.prev = [];
this.items = [];
this.el = this.$el(this.tag, this.attribs, null, parent, index);
this.update(state);
return this.el;
}
async unmount() {
this.items.forEach((c) => c.unmount());
this.$remove();
this.el = void 0;
this.items = void 0;
this.prev = void 0;
}
async update(curr) {
if (!curr) return;
const { ctor, equiv, items, prev, el: parent } = this;
const nb = curr.length;
let na = prev.length;
let n = Math.min(na, nb);
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);
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, -1);
items[n] = child;
prev[n] = val;
}
} else {
while (--na >= nb) {
await items[na].unmount();
items.pop();
prev.pop();
}
}
}
}
export {
$list,
List
};