Skip to content

Commit eb536c4

Browse files
cherniavskiiweb-flow
authored andcommitted
[DataGrid] Fix scroll jump with dynamic row height (#16763)
1 parent f96e87e commit eb536c4

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

packages/x-data-grid/src/hooks/features/rows/useGridRowsMeta.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
} from '../dimensions/gridDimensionsSelectors';
2323
import { getValidRowHeight, getRowHeightWarning } from './gridRowsUtils';
2424
import type { HeightEntry } from './gridRowsMetaInterfaces';
25-
25+
import { gridFocusedVirtualCellSelector } from '../virtualization/gridFocusedVirtualCellSelector';
2626
/* eslint-disable no-underscore-dangle */
2727

2828
export const rowsMetaStateInitializer: GridStateInitializer = (state, props, apiRef) => {
@@ -262,6 +262,13 @@ export const useGridRowsMeta = (
262262
? entry.borderBoxSize[0].blockSize
263263
: entry.contentRect.height;
264264
const rowId = (entry.target as any).__mui_id;
265+
const focusedVirtualRowId = gridFocusedVirtualCellSelector(apiRef)?.id;
266+
if (focusedVirtualRowId === rowId && height === 0) {
267+
// Focused virtual row has 0 height.
268+
// We don't want to store it to avoid scroll jumping.
269+
// https://github.com/mui/mui-x/issues/14726
270+
return;
271+
}
265272
apiRef.current.unstable_storeRowHeightMeasurement(rowId, height);
266273
}
267274
if (!isHeightMetaValid.current) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as React from 'react';
2+
import { DataGrid } from '@mui/x-data-grid';
3+
4+
const rows = [
5+
{ id: 0 },
6+
{ id: 1 },
7+
{ id: 2 },
8+
{ id: 3 },
9+
{ id: 4 },
10+
{ id: 5 },
11+
{ id: 6 },
12+
{ id: 7 },
13+
{ id: 8 },
14+
{ id: 9 },
15+
{ id: 10 },
16+
{ id: 11 },
17+
{ id: 12 },
18+
{ id: 13 },
19+
{ id: 14 },
20+
{ id: 15 },
21+
{ id: 16 },
22+
{ id: 17 },
23+
{ id: 18 },
24+
{ id: 19 },
25+
{ id: 20 },
26+
];
27+
28+
export default function DynamicRowHeight() {
29+
return (
30+
<div style={{ height: 300, width: 400 }}>
31+
<DataGrid rows={rows} columns={[{ field: 'id' }]} getRowHeight={() => 'auto'} />
32+
</div>
33+
);
34+
}

test/e2e/index.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,39 @@ async function initializeEnvironment(
600600
});
601601
expect(scrollTop).not.to.equal(0);
602602
});
603+
604+
// https://github.com/mui/mui-x/issues/14726
605+
it('should not cause scroll jumping when the focused cell is outside of the viewport', async () => {
606+
await renderFixture('DataGrid/DynamicRowHeight');
607+
608+
await page.click('[role="row"][data-id="2"] [role="gridcell"][data-field="id"]');
609+
610+
const scrollPositions: number[] = [];
611+
await page.exposeFunction('storeScrollPosition', async (scrollTop: number) => {
612+
scrollPositions.push(scrollTop);
613+
});
614+
await page.evaluate(() => {
615+
const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!;
616+
virtualScroller.addEventListener('scroll', () => {
617+
// @ts-ignore
618+
window.storeScrollPosition(virtualScroller.scrollTop);
619+
});
620+
});
621+
622+
await page.mouse.wheel(0, 150);
623+
await page.waitForTimeout(500);
624+
625+
const hadScrollJump = scrollPositions.some((scrollTop, index) => {
626+
if (index === 0) {
627+
return false;
628+
}
629+
// When scrolling down, the scrollTop should be always decreasing
630+
const prevScrollTop = scrollPositions[index - 1];
631+
return scrollTop < prevScrollTop;
632+
});
633+
634+
expect(hadScrollJump).to.equal(false, `Scroll jumped, scrollPositions: ${scrollPositions}`);
635+
});
603636
});
604637

605638
describe('<DatePicker />', () => {

0 commit comments

Comments
 (0)