feat: render scalable Alta site and group hierarchy

This commit is contained in:
2026-08-20 01:15:01 +00:00
parent c65a813e5f
commit 8d256cd4ab
12 changed files with 614 additions and 164 deletions
+11 -2
View File
@@ -133,7 +133,7 @@
}
const model = options.model;
const view = options.view;
const rowHeight = Number.isFinite(options.rowHeight) ? options.rowHeight : 28;
const rowHeight = Number.isFinite(options.rowHeight) ? options.rowHeight : 30;
const overscan = Number.isInteger(options.overscan) ? options.overscan : 16;
const searchRunner = options.searchRunner || treeApi.createSearchRunner({ scheduler: options.scheduler, chunkSize: options.chunkSize });
let state = createInitialState(options.initialState);
@@ -149,6 +149,15 @@
selectedKey: state.selectedKey,
matchCameraKeys: state.searchQuery ? state.searchCameraKeys : null,
});
const activeIndex = rows.findIndex((row) => row.key === state.activeKey);
if (activeIndex >= 0 && state.viewportHeight > 0) {
const activeTop = activeIndex * rowHeight;
const activeBottom = activeTop + rowHeight;
let scrollTop = state.scrollTop;
if (activeTop < scrollTop) scrollTop = activeTop;
else if (activeBottom > scrollTop + state.viewportHeight) scrollTop = activeBottom - state.viewportHeight;
if (scrollTop !== state.scrollTop) state = Object.assign({}, state, { scrollTop });
}
const window = treeApi.calculateVirtualWindow(rows, {
scrollTop: state.scrollTop, viewportHeight: state.viewportHeight, rowHeight, overscan,
});
@@ -188,7 +197,7 @@
commit();
return Object.freeze({
dispatch, search, getState: () => state, getSnapshot: () => lastSnapshot,
dispatch, search, refresh: commit, getState: () => state, getSnapshot: () => lastSnapshot,
destroy() { searchRunner.cancel(); },
});
}