54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import type { TreeNode, TreeNodeType } from "@/types/database";
|
|
|
|
export const SIDEBAR_TREE_ROW_HEIGHT = 28;
|
|
export const SIDEBAR_TREE_SCROLL_BUFFER = 600;
|
|
export const SIDEBAR_TREE_PRERENDER_COUNT = 48;
|
|
|
|
export interface FlatTreeNode {
|
|
node: TreeNode;
|
|
depth: number;
|
|
id: string;
|
|
type: TreeNodeType;
|
|
}
|
|
|
|
function walk(children: TreeNode[], depth: number, result: FlatTreeNode[]) {
|
|
for (const node of children) {
|
|
result.push({ node, depth, id: node.id, type: node.type });
|
|
if (node.isExpanded && node.children) {
|
|
walk(node.children, depth + 1, result);
|
|
}
|
|
}
|
|
}
|
|
|
|
export function flattenTree(nodes: TreeNode[]): FlatTreeNode[] {
|
|
const result: FlatTreeNode[] = [];
|
|
walk(nodes, 0, result);
|
|
return result;
|
|
}
|
|
|
|
export function shouldVirtualizeFlatTree(count: number): boolean {
|
|
return count > 0;
|
|
}
|
|
|
|
export function shouldAutoScrollExpandedTreeNode(type: TreeNodeType): boolean {
|
|
return type !== "connection" && type !== "connection-group";
|
|
}
|
|
|
|
export function scrollTopForExpandedTreeNode(options: { expandedIndex: number; insertedRowCount: number; currentScrollTop: number; viewportHeight: number; rowHeight?: number }): number {
|
|
const rowHeight = options.rowHeight ?? SIDEBAR_TREE_ROW_HEIGHT;
|
|
if (options.expandedIndex < 0 || options.insertedRowCount <= 0 || options.viewportHeight <= 0) {
|
|
return options.currentScrollTop;
|
|
}
|
|
|
|
const visibleRowCapacity = Math.max(1, Math.floor(options.viewportHeight / rowHeight) - 1);
|
|
const rowsToReveal = Math.min(options.insertedRowCount, visibleRowCapacity);
|
|
const expandedContentBottom = (options.expandedIndex + 1 + rowsToReveal) * rowHeight;
|
|
const viewportBottom = options.currentScrollTop + options.viewportHeight;
|
|
|
|
if (expandedContentBottom <= viewportBottom) {
|
|
return options.currentScrollTop;
|
|
}
|
|
|
|
return Math.max(0, expandedContentBottom - options.viewportHeight);
|
|
}
|