diff --git a/packages/x-data-grid/src/hooks/features/pagination/useGridPaginationModel.ts b/packages/x-data-grid/src/hooks/features/pagination/useGridPaginationModel.ts index b24a73e314b70..d6efed247c3b4 100644 --- a/packages/x-data-grid/src/hooks/features/pagination/useGridPaginationModel.ts +++ b/packages/x-data-grid/src/hooks/features/pagination/useGridPaginationModel.ts @@ -264,8 +264,20 @@ export const useGridPaginationModel = ( [apiRef], ); - const handleSortModelChange = React.useCallback(() => { - apiRef.current.setPage(0); + /** + * Goes to the first row of the grid + */ + const navigateToStart = React.useCallback(() => { + const paginationModel = gridPaginationModelSelector(apiRef); + if (paginationModel.page !== 0) { + apiRef.current.setPage(0); + } + + // If the page was not changed it might be needed to scroll to the top + const scrollPosition = apiRef.current.getScrollPosition(); + if (scrollPosition.top !== 0) { + apiRef.current.scroll({ top: 0 }); + } }, [apiRef]); /** @@ -276,7 +288,6 @@ export const useGridPaginationModel = ( */ const handleFilterModelChange = React.useCallback>( (filterModel) => { - const paginationModel = gridPaginationModelSelector(apiRef); const currentActiveFilters = { ...filterModel, // replace items with the active items @@ -288,12 +299,9 @@ export const useGridPaginationModel = ( } previousFilterModel.current = currentActiveFilters; - - if (paginationModel.page !== 0) { - apiRef.current.setPage(0); - } + navigateToStart(); }, - [apiRef], + [apiRef, navigateToStart], ); useGridApiEventHandler(apiRef, 'viewportInnerSizeChange', handleUpdateAutoPageSize); @@ -302,7 +310,7 @@ export const useGridPaginationModel = ( useGridApiEventHandler( apiRef, 'sortModelChange', - runIf(props.resetPageOnSortFilter, handleSortModelChange), + runIf(props.resetPageOnSortFilter, navigateToStart), ); useGridApiEventHandler( apiRef, diff --git a/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx b/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx index 7f6fa62d97597..65a26af462ac8 100644 --- a/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/pagination.DataGrid.test.tsx @@ -27,13 +27,13 @@ const isJSDOM = /jsdom/.test(window.navigator.userAgent); describe(' - Pagination', () => { const { render } = createRenderer(); - let apiRef: RefObject; + let apiRef: RefObject; function BaselineTestCase(props: Omit & { height?: number }) { const { height = 300, ...other } = props; apiRef = useGridApiRef(); - const basicData = useBasicDemoData(20, 2); + const basicData = useBasicDemoData(100, 2); return (
@@ -632,18 +632,22 @@ describe(' - Pagination', () => { }); describe('resetPageOnSortFilter prop', () => { - it('should reset page to 0 if sort or filter is applied and `resetPageOnSortFilter` is `true`', () => { + it('should reset page to 0 and scroll to top if sort or filter is applied and `resetPageOnSortFilter` is `true`', () => { const { setProps } = render( , ); + const randomScrollTopPostion = 500; + act(() => { apiRef.current?.setPage(1); + apiRef.current!.scroll({ top: randomScrollTopPostion }); }); expect(apiRef.current!.state.pagination.paginationModel.page).to.equal(1); + expect(apiRef.current!.getScrollPosition().top).to.equal(randomScrollTopPostion); act(() => { apiRef.current?.sortColumn('id', 'desc'); @@ -658,8 +662,9 @@ describe(' - Pagination', () => { }); }); - // page stays the same after sorting and filtering + // page and the scroll position stays the same after sorting and filtering expect(apiRef.current!.state.pagination.paginationModel.page).to.equal(1); + expect(apiRef.current!.getScrollPosition().top).to.equal(randomScrollTopPostion); // enable reset setProps({ @@ -671,12 +676,26 @@ describe(' - Pagination', () => { }); // page is reset to 0 after sorting expect(apiRef.current!.state.pagination.paginationModel.page).to.equal(0); + expect(apiRef.current!.getScrollPosition().top).to.equal(0); + + // scroll but stay on the same page + act(() => { + apiRef.current!.scroll({ top: randomScrollTopPostion }); + }); + expect(apiRef.current!.getScrollPosition().top).to.equal(randomScrollTopPostion); + + act(() => { + apiRef.current!.sortColumn('id', 'desc'); + }); + expect(apiRef.current!.getScrollPosition().top).to.equal(0); - // move to the next page again + // move to the next page again and scroll act(() => { apiRef.current?.setPage(1); + apiRef.current!.scroll({ top: randomScrollTopPostion }); }); expect(apiRef.current!.state.pagination.paginationModel.page).to.equal(1); + expect(apiRef.current!.getScrollPosition().top).to.equal(randomScrollTopPostion); act(() => { apiRef.current?.setFilterModel({ @@ -690,8 +709,9 @@ describe(' - Pagination', () => { }); }); - // page is reset to 0 after filtering + // page and scroll position are reset filtering expect(apiRef.current!.state.pagination.paginationModel.page).to.equal(0); + expect(apiRef.current!.getScrollPosition().top).to.equal(0); }); });