react-dynamic-virtual-tree
Version:
Library for visualizing nested lists with dynamically changing sizes.
108 lines (107 loc) • 4.49 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { useCallback, useEffect, useRef, useState } from "react";
import { getLevel } from "./layerComponent";
export var mergeVirtualTree = function (prev, next, reInitTrigger) {
var stop = false;
var merge = function (prev, next, skip) {
var _a, _b;
if (skip === void 0) { skip = false; }
if (stop) {
return;
}
if (!skip) {
var defaultHeight = prev.listItem.defaultHeight;
next.listItem.height = prev.listItem.currentHeight === undefined ? defaultHeight : prev.listItem.currentHeight;
next.listItem.defaultHeight = defaultHeight;
}
if (next.listItem.children.length === 0) {
return;
}
var level = getLevel(prev.layer);
var layers = prev.layer.getLayersByLevel(level + 1);
var prevDefaultChildHeight = (_b = (_a = layers === null || layers === void 0 ? void 0 : layers[0]) === null || _a === void 0 ? void 0 : _a.listItem) === null || _b === void 0 ? void 0 : _b.defaultHeight;
if (prevDefaultChildHeight === undefined) {
stop = true;
reInitTrigger();
return;
}
next.layer.children.forEach(function (childLayer) {
var _a;
var prevChildLayer = prev.layer.children.find(function (item) { return item.listItem.id === childLayer.listItem.id; });
if (!prevChildLayer) {
childLayer.listItem.height = prevDefaultChildHeight;
childLayer.listItem.defaultHeight = prevDefaultChildHeight;
merge({
listItem: (_a = layers === null || layers === void 0 ? void 0 : layers[0]) === null || _a === void 0 ? void 0 : _a.listItem,
layer: layers === null || layers === void 0 ? void 0 : layers[0],
}, {
listItem: childLayer.listItem,
layer: childLayer,
}, true);
return;
}
childLayer.listItem.memorizeState(prevChildLayer.listItem.getMemorizedState());
merge({
listItem: prevChildLayer.listItem,
layer: prevChildLayer,
}, {
listItem: childLayer.listItem,
layer: childLayer,
});
});
};
merge(prev, next);
return next;
};
export var Wrapper = function (_a) {
var children = _a.children, virtualTree = _a.virtualTree, containerHeight = _a.height, className = _a.className;
var ref = useRef(null);
var _b = useState(0), height = _b[0], setHeight = _b[1];
var containerHeightRef = useRef(containerHeight);
var handler = useCallback(function () {
var block = ref.current;
if (!block) {
return;
}
virtualTree.pushOffset(virtualTree.getOffset(block.scrollTop, containerHeightRef.current, 20));
}, []);
useEffect(function () {
if (containerHeightRef.current !== containerHeight) {
containerHeightRef.current = containerHeight;
handler();
}
}, [containerHeight]);
useEffect(function () {
var clearFunctions = [];
var clear = virtualTree.onReady(function () {
if (ref.current) {
ref.current.addEventListener("scroll", handler);
setHeight(virtualTree.getTotalHeight());
handler();
var clearOnUpdate = virtualTree.onUpdate(function () {
setHeight(virtualTree.getTotalHeight());
handler();
});
clearFunctions.push(clearOnUpdate);
}
});
clearFunctions.push(clear);
window.addEventListener("resize", handler);
handler();
return function () {
clearFunctions.forEach(function (clear) { return clear(); });
window.removeEventListener("resize", handler);
if (ref.current) {
ref.current.removeEventListener("scroll", handler);
}
};
}, []);
return (_jsx("div", { ref: ref, style: {
height: containerHeight,
position: "relative",
overflow: "auto",
willChange: "transform",
direction: "ltr",
width: "100%",
}, children: _jsx("div", { style: { height: height }, className: className, children: children }) }));
};