Skip to content

Commit c6856ed

Browse files
committed
feat: smart viewport in virtual scrolling
1 parent b953a32 commit c6856ed

1 file changed

Lines changed: 24 additions & 3 deletions

File tree

packages/pluggableWidgets/datagrid-web/src/model/stores/GridSize.store.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@ export class GridSizeStore {
8282
this.columnSizes = sizes;
8383
}
8484

85+
/**
86+
* Computes the total viewport height of visible rows based on the current page size.
87+
* @returns {number} Total height in pixels of visible rows, or 0 if no rows present.
88+
*/
89+
computeBodyViewport(): number {
90+
const rows = Array.from(this.gridBodyRef.current?.children ?? []);
91+
if (rows.length === 0) {
92+
return 0;
93+
}
94+
95+
const pageSize = this.pageSizeAtom.get();
96+
const visibleRows = rows.slice(0, pageSize);
97+
const totalHeight = visibleRows.reduce((sum, row) => {
98+
const rowHeight = row.children[0]?.clientHeight ?? 0;
99+
return sum + rowHeight;
100+
}, 0);
101+
return totalHeight;
102+
}
103+
85104
lockGridBodyHeight(): void {
86105
if (!this.hasVirtualScrolling || !this.hasMoreItems) {
87106
return;
@@ -100,19 +119,21 @@ export class GridSizeStore {
100119
return;
101120
}
102121

122+
const viewportHeight = this.computeBodyViewport();
123+
103124
// Don't lock height before the grid body has rendered content.
104125
// clientHeight is 0 when the element has no layout yet, which would
105126
// produce a negative height and break scrolling.
106-
if (gridBody.clientHeight <= 0) {
127+
if (viewportHeight <= 0) {
107128
return;
108129
}
109130

110131
// If content already overflows the container (fixed-height grid), do not subtract the
111132
// pre-fetch offset — that would hide the last rows and trigger the next page too early.
112133
// Only subtract the offset when the grid does not yet overflow (auto-height grid) so
113134
// that we create a small synthetic overflow that makes the body scrollable.
114-
const overflows = gridBody.scrollHeight > gridBody.clientHeight;
115-
this.gridBodyHeight = gridBody.clientHeight - (overflows ? 0 : VIRTUAL_SCROLLING_OFFSET);
135+
const overflows = gridBody.scrollHeight > viewportHeight;
136+
this.gridBodyHeight = viewportHeight - (overflows ? 0 : VIRTUAL_SCROLLING_OFFSET);
116137
this.lockedAtPageSize = currentPageSize;
117138
}
118139
}

0 commit comments

Comments
 (0)