Skip to content

Commit

Permalink
[DataGrid] Fix reset of virtualPage (#1451)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtassone authored Apr 21, 2021
1 parent e8b8b8d commit 18cd8e1
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import * as React from 'react';
import { GRID_DATA_CONTAINER_CSS_CLASS } from '../../constants/cssClassesConstants';
import { useGridState } from '../../hooks/features/core/useGridState';
import { useGridSelector } from '../../hooks/features/core/useGridSelector';
import {
gridDataContainerSizesSelector,
gridScrollBarSizeSelector,
} from '../../hooks/root/gridContainerSizesSelector';
import { classnames } from '../../utils';
import { GridApiContext } from '../GridApiContext';

Expand All @@ -9,14 +13,15 @@ type GridDataContainerProps = React.HTMLAttributes<HTMLDivElement>;
export function GridDataContainer(props: GridDataContainerProps) {
const { className, ...other } = props;
const apiRef = React.useContext(GridApiContext);
const [gridState] = useGridState(apiRef!);
const dataContainerSizes = useGridSelector(apiRef!, gridDataContainerSizesSelector);
const scrollBar = useGridSelector(apiRef!, gridScrollBarSizeSelector);

const style: any = {
minWidth: gridState.containerSizes?.dataContainerSizes?.width,
minWidth: dataContainerSizes?.width,
};

if (gridState.scrollBar.hasScrollY) {
style.minHeight = gridState.containerSizes?.dataContainerSizes?.height!;
if (scrollBar.hasScrollY) {
style.minHeight = dataContainerSizes?.height!;
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ export const useGridVirtualRows = (
logger.debug(`Changing page from ${page} to ${nextPage}`);
requireRerender = true;
} else {
if (!containerProps.isVirtualized && page > 0) {
logger.debug(`Virtualization disabled, setting virtualPage to 0`);
setRenderingState({ virtualPage: 0 });
}

scrollTo(scrollParams);
}
setRenderingState({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { createSelector } from 'reselect';
import { ElementSize } from '../../models/elementSize';
import { GridContainerProps } from '../../models/gridContainerProps';
import { GridState } from '../features/core/gridState';

export const gridContainerSizesSelector = (state: GridState) => state.containerSizes;
export const gridViewportSizesSelector = (state: GridState) => state.viewportSizes;
export const gridScrollBarSizeSelector = (state: GridState) => state.scrollBar;

export const gridDataContainerSizesSelector = createSelector<
GridState,
GridContainerProps | null,
ElementSize | null
>(gridContainerSizesSelector, (containerSizes) =>
containerSizes == null ? null : containerSizes.dataContainerSizes,
);
export const gridDataContainerHeightSelector = createSelector<
GridState,
GridContainerProps | null,
Expand Down
28 changes: 28 additions & 0 deletions packages/grid/x-grid/src/tests/rows.XGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,34 @@ describe('<XGrid /> - Rows', () => {
expect(isVirtualized).to.equal(false);
});

it('should set the virtual page to 0 when resetting rows to a non virtualized length', () => {
const { setProps } = render(<TestCaseVirtualization nbRows={996} hideFooter height={600} />);

const gridWindow = document.querySelector('.MuiDataGrid-window')!;
gridWindow.scrollTop = 10e6; // scroll to the bottom
gridWindow.dispatchEvent(new Event('scroll'));

let lastCell = document.querySelector('[role="row"]:last-child [role="cell"]:first-child')!;
expect(lastCell).to.have.text('995');

let virtualPage = apiRef!.current!.getState().rendering!.virtualPage;
expect(virtualPage).to.equal(98);

setProps({ nbRows: 9 });

lastCell = document.querySelector('[role="row"]:last-child [role="cell"]:first-child')!;
expect(lastCell).to.have.text('8');

const renderingZone = document.querySelector('.MuiDataGrid-renderingZone')! as HTMLElement;
expect(renderingZone.children.length).to.equal(9);

virtualPage = apiRef!.current!.getState().rendering!.virtualPage;
expect(virtualPage).to.equal(0);

const isVirtualized = apiRef!.current!.getState().containerSizes!.isVirtualized;
expect(isVirtualized).to.equal(false);
});

describe('Pagination', () => {
it('should render only the pageSize', () => {
render(<TestCaseVirtualization pagination pageSize={32} />);
Expand Down
41 changes: 40 additions & 1 deletion packages/storybook/src/stories/grid-rows.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Alert from '@material-ui/lab/Alert';
import * as React from 'react';
import Alert from '@material-ui/lab/Alert';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import Popper from '@material-ui/core/Popper';
Expand Down Expand Up @@ -875,3 +875,42 @@ export function EditCellWithMessageGrid() {
</div>
);
}

export function SwitchVirtualization() {
const { data, setRowLength } = useDemoData({
dataSet: 'Commodity',
rowLength: 200,
maxColumns: 20,
});

const handleButtonClick = (nbRows: number) => {
setRowLength(nbRows);
};

React.useLayoutEffect(() => {
const window = document.querySelector('.MuiDataGrid-window');
if (window) {
window!.scrollTo(0, 5000);
}
});

return (
<div
style={{
display: 'flex',
flexDirection: 'column',
flex: 1,
height: '100%',
width: '100%',
}}
>
<div>
<Button onClick={() => handleButtonClick(9)}>9 items</Button>
<Button onClick={() => handleButtonClick(100)}>100 items</Button>
</div>
<div style={{ width: '100%', height: 500 }}>
<XGrid rows={data.rows} columns={data.columns} />
</div>
</div>
);
}

0 comments on commit 18cd8e1

Please sign in to comment.