Skip to content

Commit b0836bb

Browse files
committed
fix: adjust virtual scrolling logic to handle fixed-height grids correctly
1 parent 72a60c2 commit b0836bb

2 files changed

Lines changed: 16 additions & 6 deletions

File tree

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,11 @@ export class GridSizeStore {
108108

109109
const fullHeight = bodyViewportHeight + headerViewportHeight;
110110

111-
// clientHeight is vertical-only (excludes horizontal scrollbar overflow).
112-
// scrollHeight would be inflated by many-column grids and produce false positives.
113-
const overflows = gridContainer.clientHeight < fullHeight;
111+
// If content already overflows the container (fixed-height grid), do not subtract the
112+
// pre-fetch offset — that would hide the last rows and trigger the next page too early.
113+
// Only subtract the offset when the grid does not yet overflow (auto-height grid) so
114+
// that we create a small synthetic overflow that makes the body scrollable.
115+
const overflows = gridContainer.scrollHeight > fullHeight;
114116
this.gridContainerHeight = fullHeight - (overflows ? 0 : VIRTUAL_SCROLLING_OFFSET);
115117
this.lockedAtLayoutKey = currentKey;
116118
}

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ interface RefsOptions {
7676
rowCount?: number;
7777
headerHeight?: number;
7878
containerClientHeight?: number;
79+
containerScrollHeight?: number;
7980
bodyScrollHeight?: number;
8081
bodyClientHeight?: number;
8182
}
@@ -86,12 +87,19 @@ function setupRefs(store: GridSizeStore, options: RefsOptions = {}): void {
8687
rowCount = 10,
8788
headerHeight = 50,
8889
containerClientHeight = 1000,
90+
containerScrollHeight,
8991
bodyScrollHeight,
9092
bodyClientHeight
9193
} = options;
9294

9395
const container = document.createElement("div");
9496
Object.defineProperty(container, "clientHeight", { value: containerClientHeight, configurable: true });
97+
// Default scrollHeight to rowHeight * rowCount + headerHeight (= fullHeight at first lock,
98+
// before the container is constrained).
99+
Object.defineProperty(container, "scrollHeight", {
100+
value: containerScrollHeight ?? rowHeight * rowCount + headerHeight,
101+
configurable: true
102+
});
95103
(store.gridContainerRef as MutableRefObject<HTMLDivElement>).current = container;
96104

97105
const body = document.createElement("div");
@@ -173,10 +181,10 @@ describe("GridSizeStore.lockGridContainerHeight()", () => {
173181
expect(store.gridContainerHeight).not.toBe(heightWithPageSize3);
174182
});
175183

176-
it("does not subtract offset when container height is smaller than full content height (overflow case)", () => {
184+
it("does not subtract offset when container scrollHeight exceeds full content height (fixed-height grid)", () => {
177185
const { store } = buildStore({ pageSize: 3, columnCount: 2 });
178-
// fullHeight = 3×40 + 50 = 170px; container is only 100px → overflows
179-
setupRefs(store, { rowHeight: 40, rowCount: 3, headerHeight: 50, containerClientHeight: 100 });
186+
// fullHeight = 3×40 + 50 = 170px; scrollHeight 200 > fullHeight → overflows → no offset
187+
setupRefs(store, { rowHeight: 40, rowCount: 3, headerHeight: 50, containerScrollHeight: 200 });
180188

181189
store.lockGridContainerHeight();
182190

0 commit comments

Comments
 (0)