reconcileNodes
Updates one region of parent's children from the nodes prev to the nodes next, keeping every node that stays and moving as few as possible: the list reconciliation insert performs for arrays (and so for For).
Updates one region of parent's children from the nodes prev to the nodes next, keeping every
node that stays and moving as few as possible: the list reconciliation insert performs for arrays
(and so for For). Use it in a custom list renderer.
Preconditions: prev are the nodes this region owns, in DOM order and all children of parent;
next holds no duplicates; end is the node after the region (null for the end of parent).
Strategy, in three steps:
- Trim the common prefix and suffix: appends, prepends, and removals at either end touch only the nodes that changed (no move at all).
- Remove the nodes that left the value. A node that is still present is never removed.
- Place the rest from the end of
nextbackwards. Nodes on a longest increasing subsequence of surviving positions stay where they are; every other node is moved (or inserted) directly before the node that follows it innext. Moves usemoveBeforewhen the parent has it, which keeps focus and iframe state, andinsertBeforeotherwise. Each node moves at most once, and the number of moves is minimal for the surviving order.
Import#
ts
import { reconcileNodes } from "@shadow-js/web/extend";
Signature#
ts
function reconcileNodes(
parent: Node,
prev: readonly Node[],
next: readonly Node[],
end: Node | null,
): void
Parameters#
| Name | Description |
|---|---|
parent |
The parent of the region. |
prev |
The nodes the region holds now, in DOM order, all children of parent. |
next |
The nodes the region must hold, in order, without duplicates. A node of prev that is not in next is removed; a node of next that is not in prev is inserted. |
end |
The node right after the region; null when the region runs to the end of parent. |
Examples#
ts
import { reconcileNodes } from "@shadow-js/web/extend";
const item = (text: string): HTMLLIElement =>
Object.assign(document.createElement("li"), { textContent: text });
const list = document.createElement("ul");
const a = item("a");
const b = item("b");
const c = item("c");
list.append(a, b, c);
reconcileNodes(list, [a, b, c], [c, a], null); // removes b, moves c before a