Skip to content

Commit 58acf8b

Browse files
authored
async resize (#1336)
1 parent 3dd8588 commit 58acf8b

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/client/stdlib/resize.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
// TODO Automatically disconnect the observer when the returned DIV is detached.
2-
export function resize(run: (width: number, height: number) => Node, invalidation?: Promise<void>): Node {
2+
export function resize(
3+
render: (width: number, height: number) => Node | null | Promise<Node | null>,
4+
invalidation?: Promise<void>
5+
): Node {
36
const div = document.createElement("div");
47
div.style.position = "relative";
5-
if (run.length !== 1) div.style.height = "100%";
6-
const observer = new ResizeObserver(([entry]) => {
8+
if (render.length !== 1) div.style.height = "100%";
9+
let currentRender = 0;
10+
let currentDisplay = 0;
11+
const observer = new ResizeObserver(async ([entry]) => {
712
const {width, height} = entry.contentRect;
13+
const childRender = ++currentRender;
14+
const child = width > 0 ? await render(width, height) : null; // don’t render if detached
15+
if (currentDisplay > childRender) return; // ignore stale renders
16+
currentDisplay = childRender;
817
while (div.lastChild) div.lastChild.remove();
9-
if (width > 0) {
10-
const child = run(width, height);
11-
// prevent feedback loop if height is used
12-
if (run.length !== 1 && isElement(child)) child.style.position = "absolute";
13-
div.append(child);
14-
}
18+
if (child == null) return; // clear if nullish
19+
if (render.length !== 1 && isElement(child)) child.style.position = "absolute"; // prevent feedback loop if height is used
20+
div.append(child);
1521
});
1622
observer.observe(div);
1723
invalidation?.then(() => observer.disconnect());

0 commit comments

Comments
 (0)