Skip to content

Commit

Permalink
async resize (#1336)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock authored May 13, 2024
1 parent 3dd8588 commit 58acf8b
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions src/client/stdlib/resize.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
// TODO Automatically disconnect the observer when the returned DIV is detached.
export function resize(run: (width: number, height: number) => Node, invalidation?: Promise<void>): Node {
export function resize(
render: (width: number, height: number) => Node | null | Promise<Node | null>,
invalidation?: Promise<void>
): Node {
const div = document.createElement("div");
div.style.position = "relative";
if (run.length !== 1) div.style.height = "100%";
const observer = new ResizeObserver(([entry]) => {
if (render.length !== 1) div.style.height = "100%";
let currentRender = 0;
let currentDisplay = 0;
const observer = new ResizeObserver(async ([entry]) => {
const {width, height} = entry.contentRect;
const childRender = ++currentRender;
const child = width > 0 ? await render(width, height) : null; // don’t render if detached
if (currentDisplay > childRender) return; // ignore stale renders
currentDisplay = childRender;
while (div.lastChild) div.lastChild.remove();
if (width > 0) {
const child = run(width, height);
// prevent feedback loop if height is used
if (run.length !== 1 && isElement(child)) child.style.position = "absolute";
div.append(child);
}
if (child == null) return; // clear if nullish
if (render.length !== 1 && isElement(child)) child.style.position = "absolute"; // prevent feedback loop if height is used
div.append(child);
});
observer.observe(div);
invalidation?.then(() => observer.disconnect());
Expand Down

0 comments on commit 58acf8b

Please sign in to comment.