@mui/x-data-grid 6.20.1 → 6.20.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/DataGrid/DataGrid.js +5 -0
  3. package/components/GridPagination.js +2 -7
  4. package/components/panel/GridPanel.js +4 -1
  5. package/hooks/features/export/useGridPrintExport.js +8 -4
  6. package/hooks/features/pagination/gridPaginationInterfaces.d.ts +19 -2
  7. package/hooks/features/pagination/gridPaginationSelector.d.ts +5 -0
  8. package/hooks/features/pagination/gridPaginationSelector.js +8 -2
  9. package/hooks/features/pagination/useGridPagination.d.ts +1 -6
  10. package/hooks/features/pagination/useGridPagination.js +9 -159
  11. package/hooks/features/pagination/useGridPaginationModel.d.ts +11 -0
  12. package/hooks/features/pagination/useGridPaginationModel.js +176 -0
  13. package/hooks/features/pagination/useGridRowCount.d.ts +8 -0
  14. package/hooks/features/pagination/useGridRowCount.js +97 -0
  15. package/index.js +1 -1
  16. package/legacy/DataGrid/DataGrid.js +5 -0
  17. package/legacy/components/GridPagination.js +2 -7
  18. package/legacy/components/panel/GridPanel.js +4 -1
  19. package/legacy/hooks/features/export/useGridPrintExport.js +10 -4
  20. package/legacy/hooks/features/pagination/gridPaginationSelector.js +11 -3
  21. package/legacy/hooks/features/pagination/useGridPagination.js +9 -161
  22. package/legacy/hooks/features/pagination/useGridPaginationModel.js +182 -0
  23. package/legacy/hooks/features/pagination/useGridRowCount.js +101 -0
  24. package/legacy/index.js +1 -1
  25. package/models/events/gridEventLookup.d.ts +6 -0
  26. package/models/props/DataGridProps.d.ts +5 -0
  27. package/modern/DataGrid/DataGrid.js +5 -0
  28. package/modern/components/GridPagination.js +2 -4
  29. package/modern/components/panel/GridPanel.js +4 -1
  30. package/modern/hooks/features/export/useGridPrintExport.js +8 -4
  31. package/modern/hooks/features/pagination/gridPaginationSelector.js +8 -2
  32. package/modern/hooks/features/pagination/useGridPagination.js +8 -151
  33. package/modern/hooks/features/pagination/useGridPaginationModel.js +171 -0
  34. package/modern/hooks/features/pagination/useGridRowCount.js +94 -0
  35. package/modern/index.js +1 -1
  36. package/node/DataGrid/DataGrid.js +5 -0
  37. package/node/components/GridPagination.js +1 -3
  38. package/node/components/panel/GridPanel.js +4 -1
  39. package/node/hooks/features/export/useGridPrintExport.js +8 -4
  40. package/node/hooks/features/pagination/gridPaginationSelector.js +8 -2
  41. package/node/hooks/features/pagination/useGridPagination.js +9 -155
  42. package/node/hooks/features/pagination/useGridPaginationModel.js +182 -0
  43. package/node/hooks/features/pagination/useGridRowCount.js +103 -0
  44. package/node/index.js +1 -1
  45. package/package.json +1 -1
@@ -0,0 +1,101 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { gridFilteredTopLevelRowCountSelector } from '../filter';
4
+ import { useGridLogger, useGridSelector, useGridApiMethod } from '../../utils';
5
+ import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
6
+ import { gridPaginationRowCountSelector } from './gridPaginationSelector';
7
+ import { noRowCountInServerMode } from './gridPaginationUtils';
8
+
9
+ /**
10
+ * @requires useGridFilter (state)
11
+ * @requires useGridDimensions (event) - can be after
12
+ */
13
+ export var useGridRowCount = function useGridRowCount(apiRef, props) {
14
+ var _props$initialState2;
15
+ var logger = useGridLogger(apiRef, 'useGridRowCount');
16
+ var visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
17
+ var rowCount = useGridSelector(apiRef, gridPaginationRowCountSelector);
18
+ apiRef.current.registerControlState({
19
+ stateId: 'paginationRowCount',
20
+ propModel: props.rowCount,
21
+ propOnChange: props.onRowCountChange,
22
+ stateSelector: gridPaginationRowCountSelector,
23
+ changeEvent: 'rowCountChange'
24
+ });
25
+
26
+ /**
27
+ * API METHODS
28
+ */
29
+ var setRowCount = React.useCallback(function (newRowCount) {
30
+ if (rowCount === newRowCount) {
31
+ return;
32
+ }
33
+ logger.debug("Setting 'rowCount' to", newRowCount);
34
+ apiRef.current.setState(function (state) {
35
+ return _extends({}, state, {
36
+ pagination: _extends({}, state.pagination, {
37
+ rowCount: newRowCount
38
+ })
39
+ });
40
+ });
41
+ }, [apiRef, logger, rowCount]);
42
+ var paginationRowCountApi = {
43
+ setRowCount: setRowCount
44
+ };
45
+ useGridApiMethod(apiRef, paginationRowCountApi, 'public');
46
+
47
+ /**
48
+ * PRE-PROCESSING
49
+ */
50
+ var stateExportPreProcessing = React.useCallback(function (prevState, context) {
51
+ var _props$initialState;
52
+ var exportedRowCount = gridPaginationRowCountSelector(apiRef);
53
+ var shouldExportRowCount =
54
+ // Always export if the `exportOnlyDirtyModels` property is not activated
55
+ !context.exportOnlyDirtyModels ||
56
+ // Always export if the `rowCount` is controlled
57
+ props.rowCount != null ||
58
+ // Always export if the `rowCount` has been initialized
59
+ ((_props$initialState = props.initialState) == null || (_props$initialState = _props$initialState.pagination) == null ? void 0 : _props$initialState.rowCount) != null;
60
+ if (!shouldExportRowCount) {
61
+ return prevState;
62
+ }
63
+ return _extends({}, prevState, {
64
+ pagination: _extends({}, prevState.pagination, {
65
+ rowCount: exportedRowCount
66
+ })
67
+ });
68
+ }, [apiRef, props.rowCount, (_props$initialState2 = props.initialState) == null || (_props$initialState2 = _props$initialState2.pagination) == null ? void 0 : _props$initialState2.rowCount]);
69
+ var stateRestorePreProcessing = React.useCallback(function (params, context) {
70
+ var _context$stateToResto;
71
+ var restoredRowCount = (_context$stateToResto = context.stateToRestore.pagination) != null && _context$stateToResto.rowCount ? context.stateToRestore.pagination.rowCount : gridPaginationRowCountSelector(apiRef);
72
+ apiRef.current.setState(function (state) {
73
+ return _extends({}, state, {
74
+ pagination: _extends({}, state.pagination, {
75
+ rowCount: restoredRowCount
76
+ })
77
+ });
78
+ });
79
+ return params;
80
+ }, [apiRef]);
81
+ useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
82
+ useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
83
+
84
+ /**
85
+ * EFFECTS
86
+ */
87
+ React.useEffect(function () {
88
+ if (process.env.NODE_ENV !== 'production') {
89
+ if (props.paginationMode === 'server' && props.rowCount == null) {
90
+ noRowCountInServerMode();
91
+ }
92
+ }
93
+ }, [props.rowCount, props.paginationMode]);
94
+ React.useEffect(function () {
95
+ if (props.paginationMode === 'client') {
96
+ apiRef.current.setRowCount(visibleTopLevelRowCount);
97
+ } else if (props.rowCount != null) {
98
+ apiRef.current.setRowCount(props.rowCount);
99
+ }
100
+ }, [apiRef, visibleTopLevelRowCount, props.paginationMode, props.rowCount]);
101
+ };
package/legacy/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.20.1
2
+ * @mui/x-data-grid v6.20.4
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -369,6 +369,12 @@ export interface GridControlledStateEventLookup {
369
369
  columnVisibilityModelChange: {
370
370
  params: GridColumnVisibilityModel;
371
371
  };
372
+ /**
373
+ * Fired when the row count change.
374
+ */
375
+ rowCountChange: {
376
+ params: number;
377
+ };
372
378
  }
373
379
  export interface GridControlledStateReasonLookup {
374
380
  filter: 'upsertFilterItem' | 'upsertFilterItems' | 'deleteFilterItem' | 'changeLogicOperator' | 'restoreState';
@@ -569,6 +569,11 @@ export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel =
569
569
  * @param {GridCallbackDetails} details Additional details for this callback.
570
570
  */
571
571
  onPaginationModelChange?: (model: GridPaginationModel, details: GridCallbackDetails) => void;
572
+ /**
573
+ * Callback fired when the row count has changed.
574
+ * @param {number} count Updated row count.
575
+ */
576
+ onRowCountChange?: (count: number) => void;
572
577
  /**
573
578
  * Callback fired when the preferences panel is closed.
574
579
  * @param {GridPreferencePanelParams} params With all properties from [[GridPreferencePanelParams]].
@@ -495,6 +495,11 @@ DataGridRaw.propTypes = {
495
495
  * @param {GridCallbackDetails} details Additional details for this callback.
496
496
  */
497
497
  onRowClick: PropTypes.func,
498
+ /**
499
+ * Callback fired when the row count has changed.
500
+ * @param {number} count Updated row count.
501
+ */
502
+ onRowCountChange: PropTypes.func,
498
503
  /**
499
504
  * Callback fired when a double click event comes from a row container element.
500
505
  * @param {GridRowParams} params With all properties from [[RowParams]].
@@ -6,8 +6,7 @@ import { styled } from '@mui/material/styles';
6
6
  import { useGridSelector } from '../hooks/utils/useGridSelector';
7
7
  import { useGridApiContext } from '../hooks/utils/useGridApiContext';
8
8
  import { useGridRootProps } from '../hooks/utils/useGridRootProps';
9
- import { gridFilteredTopLevelRowCountSelector } from '../hooks/features/filter';
10
- import { gridPaginationModelSelector } from '../hooks/features/pagination/gridPaginationSelector';
9
+ import { gridPaginationModelSelector, gridPaginationRowCountSelector } from '../hooks/features/pagination/gridPaginationSelector';
11
10
  import { jsx as _jsx } from "react/jsx-runtime";
12
11
  const GridPaginationRoot = styled(TablePagination)(({
13
12
  theme
@@ -32,8 +31,7 @@ const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(pro
32
31
  const apiRef = useGridApiContext();
33
32
  const rootProps = useGridRootProps();
34
33
  const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
35
- const visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
36
- const rowCount = React.useMemo(() => rootProps.rowCount ?? visibleTopLevelRowCount ?? 0, [rootProps.rowCount, visibleTopLevelRowCount]);
34
+ const rowCount = useGridSelector(apiRef, gridPaginationRowCountSelector);
37
35
  const lastPage = React.useMemo(() => Math.floor(rowCount / (paginationModel.pageSize || 1)), [rowCount, paginationModel.pageSize]);
38
36
  const handlePageSizeChange = React.useCallback(event => {
39
37
  const pageSize = Number(event.target.value);
@@ -56,7 +56,10 @@ const GridPanel = /*#__PURE__*/React.forwardRef((props, ref) => {
56
56
  }, [apiRef]);
57
57
  const modifiers = React.useMemo(() => [{
58
58
  name: 'flip',
59
- enabled: false
59
+ enabled: true,
60
+ options: {
61
+ rootBoundary: 'document'
62
+ }
60
63
  }, {
61
64
  name: 'isPlaced',
62
65
  enabled: true,
@@ -8,7 +8,7 @@ import { gridClasses } from '../../../constants/gridClasses';
8
8
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
9
9
  import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector';
10
10
  import { getColumnsToExport } from './utils';
11
- import { mergeStateWithPaginationModel } from '../pagination/useGridPagination';
11
+ import { getDerivedPaginationModel } from '../pagination/useGridPaginationModel';
12
12
  import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
13
13
  import { GridPrintExportMenuItem } from '../../../components/toolbar/GridToolbarExport';
14
14
  import { getTotalHeaderHeight } from '../columns/gridColumnsUtils';
@@ -222,9 +222,13 @@ export const useGridPrintExport = (apiRef, props) => {
222
222
  page: 0,
223
223
  pageSize: visibleRowCount
224
224
  };
225
- apiRef.current.updateControlState('pagination',
226
- // Using signature `DataGridPro` to allow more than 100 rows in the print export
227
- mergeStateWithPaginationModel(visibleRowCount, 'DataGridPro', paginationModel));
225
+ apiRef.current.setState(state => _extends({}, state, {
226
+ pagination: _extends({}, state.pagination, {
227
+ paginationModel: getDerivedPaginationModel(state.pagination,
228
+ // Using signature `DataGridPro` to allow more than 100 rows in the print export
229
+ 'DataGridPro', paginationModel)
230
+ })
231
+ }));
228
232
  apiRef.current.forceUpdate();
229
233
  }
230
234
  await updateGridColumnsForPrint(options?.fields, options?.allColumns, options?.includeCheckboxes);
@@ -1,5 +1,5 @@
1
1
  import { createSelector, createSelectorMemoized } from '../../../utils/createSelector';
2
- import { gridFilteredTopLevelRowCountSelector, gridExpandedSortedRowEntriesSelector, gridExpandedSortedRowIdsSelector, gridFilteredSortedTopLevelRowEntriesSelector } from '../filter/gridFilterSelector';
2
+ import { gridExpandedSortedRowEntriesSelector, gridExpandedSortedRowIdsSelector, gridFilteredSortedTopLevelRowEntriesSelector } from '../filter/gridFilterSelector';
3
3
  import { gridRowMaximumTreeDepthSelector, gridRowTreeSelector } from '../rows/gridRowsSelector';
4
4
  import { getPageCount } from './gridPaginationUtils';
5
5
 
@@ -15,6 +15,12 @@ export const gridPaginationSelector = state => state.pagination;
15
15
  */
16
16
  export const gridPaginationModelSelector = createSelector(gridPaginationSelector, pagination => pagination.paginationModel);
17
17
 
18
+ /**
19
+ * Get the row count
20
+ * @category Pagination
21
+ */
22
+ export const gridPaginationRowCountSelector = createSelector(gridPaginationSelector, pagination => pagination.rowCount);
23
+
18
24
  /**
19
25
  * Get the index of the page to render if the pagination is enabled
20
26
  * @category Pagination
@@ -31,7 +37,7 @@ export const gridPageSizeSelector = createSelector(gridPaginationModelSelector,
31
37
  * Get the amount of pages needed to display all the rows if the pagination is enabled
32
38
  * @category Pagination
33
39
  */
34
- export const gridPageCountSelector = createSelector(gridPaginationModelSelector, gridFilteredTopLevelRowCountSelector, (paginationModel, visibleTopLevelRowCount) => getPageCount(visibleTopLevelRowCount, paginationModel.pageSize));
40
+ export const gridPageCountSelector = createSelector(gridPageSizeSelector, gridPaginationRowCountSelector, (pageSize, rowCount) => getPageCount(rowCount, pageSize));
35
41
 
36
42
  /**
37
43
  * Get the index of the first and the last row to include in the current page if the pagination is enabled.
@@ -1,167 +1,24 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import * as React from 'react';
3
- import { gridFilteredTopLevelRowCountSelector } from '../filter';
4
- import { gridDensityFactorSelector } from '../density';
5
- import { useGridLogger, useGridSelector, useGridApiMethod, useGridApiEventHandler } from '../../utils';
6
- import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
7
- import { gridPaginationModelSelector } from './gridPaginationSelector';
8
- import { calculatePinnedRowsHeight } from '../rows/gridRowsUtils';
9
- import { getPageCount, noRowCountInServerMode, defaultPageSize, throwIfPageSizeExceedsTheLimit, getDefaultGridPaginationModel, getValidPage } from './gridPaginationUtils';
2
+ import { throwIfPageSizeExceedsTheLimit, getDefaultGridPaginationModel } from './gridPaginationUtils';
3
+ import { useGridPaginationModel } from './useGridPaginationModel';
4
+ import { useGridRowCount } from './useGridRowCount';
10
5
  export const paginationStateInitializer = (state, props) => {
11
6
  const paginationModel = _extends({}, getDefaultGridPaginationModel(props.autoPageSize), props.paginationModel ?? props.initialState?.pagination?.paginationModel);
12
7
  throwIfPageSizeExceedsTheLimit(paginationModel.pageSize, props.signature);
8
+ const rowCount = props.rowCount ?? props.initialState?.pagination?.rowCount ?? 0;
13
9
  return _extends({}, state, {
14
10
  pagination: {
15
- paginationModel
11
+ paginationModel,
12
+ rowCount
16
13
  }
17
14
  });
18
15
  };
19
- export const mergeStateWithPaginationModel = (rowCount, signature, paginationModelProp) => paginationState => {
20
- let paginationModel = paginationState.paginationModel;
21
- const pageSize = paginationModelProp?.pageSize ?? paginationModel.pageSize;
22
- const pageCount = getPageCount(rowCount, pageSize);
23
- if (paginationModelProp && (paginationModelProp?.page !== paginationModel.page || paginationModelProp?.pageSize !== paginationModel.pageSize)) {
24
- paginationModel = paginationModelProp;
25
- }
26
- const validPage = getValidPage(paginationModel.page, pageCount);
27
- if (validPage !== paginationModel.page) {
28
- paginationModel = _extends({}, paginationModel, {
29
- page: validPage
30
- });
31
- }
32
- throwIfPageSizeExceedsTheLimit(paginationModel.pageSize, signature);
33
- return {
34
- paginationModel
35
- };
36
- };
37
16
 
38
17
  /**
39
18
  * @requires useGridFilter (state)
40
19
  * @requires useGridDimensions (event) - can be after
41
20
  */
42
21
  export const useGridPagination = (apiRef, props) => {
43
- const logger = useGridLogger(apiRef, 'useGridPagination');
44
- const visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
45
- const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
46
- const rowHeight = Math.floor(props.rowHeight * densityFactor);
47
- apiRef.current.registerControlState({
48
- stateId: 'pagination',
49
- propModel: props.paginationModel,
50
- propOnChange: props.onPaginationModelChange,
51
- stateSelector: gridPaginationModelSelector,
52
- changeEvent: 'paginationModelChange'
53
- });
54
-
55
- /**
56
- * API METHODS
57
- */
58
- const setPage = React.useCallback(page => {
59
- const currentModel = gridPaginationModelSelector(apiRef);
60
- if (page === currentModel.page) {
61
- return;
62
- }
63
- logger.debug(`Setting page to ${page}`);
64
- apiRef.current.setPaginationModel({
65
- page,
66
- pageSize: currentModel.pageSize
67
- });
68
- }, [apiRef, logger]);
69
- const setPageSize = React.useCallback(pageSize => {
70
- const currentModel = gridPaginationModelSelector(apiRef);
71
- if (pageSize === currentModel.pageSize) {
72
- return;
73
- }
74
- logger.debug(`Setting page size to ${pageSize}`);
75
- apiRef.current.setPaginationModel({
76
- pageSize,
77
- page: currentModel.page
78
- });
79
- }, [apiRef, logger]);
80
- const setPaginationModel = React.useCallback(paginationModel => {
81
- const currentModel = gridPaginationModelSelector(apiRef);
82
- if (paginationModel === currentModel) {
83
- return;
84
- }
85
- logger.debug("Setting 'paginationModel' to", paginationModel);
86
- apiRef.current.updateControlState('pagination', mergeStateWithPaginationModel(props.rowCount ?? visibleTopLevelRowCount, props.signature, paginationModel), 'setPaginationModel');
87
- apiRef.current.forceUpdate();
88
- }, [apiRef, logger, props.rowCount, props.signature, visibleTopLevelRowCount]);
89
- const pageApi = {
90
- setPage,
91
- setPageSize,
92
- setPaginationModel
93
- };
94
- useGridApiMethod(apiRef, pageApi, 'public');
95
-
96
- /**
97
- * PRE-PROCESSING
98
- */
99
- const stateExportPreProcessing = React.useCallback((prevState, context) => {
100
- const paginationModel = gridPaginationModelSelector(apiRef);
101
- const shouldExportPaginationModel =
102
- // Always export if the `exportOnlyDirtyModels` property is not activated
103
- !context.exportOnlyDirtyModels ||
104
- // Always export if the `paginationModel` is controlled
105
- props.paginationModel != null ||
106
- // Always export if the `paginationModel` has been initialized
107
- props.initialState?.pagination?.paginationModel != null ||
108
- // Export if `page` or `pageSize` is not equal to the default value
109
- paginationModel.page !== 0 && paginationModel.pageSize !== defaultPageSize(props.autoPageSize);
110
- if (!shouldExportPaginationModel) {
111
- return prevState;
112
- }
113
- return _extends({}, prevState, {
114
- pagination: _extends({}, prevState.pagination, {
115
- paginationModel
116
- })
117
- });
118
- }, [apiRef, props.paginationModel, props.initialState?.pagination?.paginationModel, props.autoPageSize]);
119
- const stateRestorePreProcessing = React.useCallback((params, context) => {
120
- const paginationModel = context.stateToRestore.pagination?.paginationModel ? _extends({}, getDefaultGridPaginationModel(props.autoPageSize), context.stateToRestore.pagination?.paginationModel) : gridPaginationModelSelector(apiRef);
121
- apiRef.current.updateControlState('pagination', mergeStateWithPaginationModel(props.rowCount ?? visibleTopLevelRowCount, props.signature, paginationModel), 'stateRestorePreProcessing');
122
- return params;
123
- }, [apiRef, props.autoPageSize, props.rowCount, props.signature, visibleTopLevelRowCount]);
124
- useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
125
- useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
126
-
127
- /**
128
- * EVENTS
129
- */
130
- const handlePaginationModelChange = () => {
131
- const paginationModel = gridPaginationModelSelector(apiRef);
132
- if (apiRef.current.virtualScrollerRef?.current) {
133
- apiRef.current.scrollToIndexes({
134
- rowIndex: paginationModel.page * paginationModel.pageSize
135
- });
136
- }
137
- apiRef.current.forceUpdate();
138
- };
139
- const handleUpdateAutoPageSize = React.useCallback(() => {
140
- const dimensions = apiRef.current.getRootDimensions();
141
- if (!props.autoPageSize || !dimensions) {
142
- return;
143
- }
144
- const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
145
- const maximumPageSizeWithoutScrollBar = Math.floor((dimensions.viewportInnerSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom) / rowHeight);
146
- apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
147
- }, [apiRef, props.autoPageSize, rowHeight]);
148
- useGridApiEventHandler(apiRef, 'viewportInnerSizeChange', handleUpdateAutoPageSize);
149
- useGridApiEventHandler(apiRef, 'paginationModelChange', handlePaginationModelChange);
150
-
151
- /**
152
- * EFFECTS
153
- */
154
- React.useEffect(() => {
155
- if (process.env.NODE_ENV !== 'production') {
156
- if (props.paginationMode === 'server' && props.rowCount == null) {
157
- noRowCountInServerMode();
158
- }
159
- }
160
- }, [props.rowCount, props.paginationMode]);
161
- React.useEffect(() => {
162
- apiRef.current.updateControlState('pagination', mergeStateWithPaginationModel(props.rowCount ?? visibleTopLevelRowCount, props.signature, props.paginationModel));
163
- }, [apiRef, props.paginationModel, props.rowCount, props.paginationMode, visibleTopLevelRowCount, props.signature]);
164
- React.useEffect(() => {
165
- handleUpdateAutoPageSize();
166
- }, [handleUpdateAutoPageSize]);
22
+ useGridPaginationModel(apiRef, props);
23
+ useGridRowCount(apiRef, props);
167
24
  };
@@ -0,0 +1,171 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { gridDensityFactorSelector } from '../density';
4
+ import { calculatePinnedRowsHeight } from '../rows/gridRowsUtils';
5
+ import { useGridLogger, useGridSelector, useGridApiMethod, useGridApiEventHandler } from '../../utils';
6
+ import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
7
+ import { gridPageCountSelector, gridPaginationModelSelector } from './gridPaginationSelector';
8
+ import { getPageCount, defaultPageSize, throwIfPageSizeExceedsTheLimit, getDefaultGridPaginationModel, getValidPage } from './gridPaginationUtils';
9
+ export const getDerivedPaginationModel = (paginationState, signature, paginationModelProp) => {
10
+ let paginationModel = paginationState.paginationModel;
11
+ const rowCount = paginationState.rowCount;
12
+ const pageSize = paginationModelProp?.pageSize ?? paginationModel.pageSize;
13
+ const pageCount = getPageCount(rowCount, pageSize);
14
+ if (paginationModelProp && (paginationModelProp?.page !== paginationModel.page || paginationModelProp?.pageSize !== paginationModel.pageSize)) {
15
+ paginationModel = paginationModelProp;
16
+ }
17
+ const validPage = getValidPage(paginationModel.page, pageCount);
18
+ if (validPage !== paginationModel.page) {
19
+ paginationModel = _extends({}, paginationModel, {
20
+ page: validPage
21
+ });
22
+ }
23
+ throwIfPageSizeExceedsTheLimit(paginationModel.pageSize, signature);
24
+ return paginationModel;
25
+ };
26
+
27
+ /**
28
+ * @requires useGridFilter (state)
29
+ * @requires useGridDimensions (event) - can be after
30
+ */
31
+ export const useGridPaginationModel = (apiRef, props) => {
32
+ const logger = useGridLogger(apiRef, 'useGridPaginationModel');
33
+ const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
34
+ const rowHeight = Math.floor(props.rowHeight * densityFactor);
35
+ apiRef.current.registerControlState({
36
+ stateId: 'paginationModel',
37
+ propModel: props.paginationModel,
38
+ propOnChange: props.onPaginationModelChange,
39
+ stateSelector: gridPaginationModelSelector,
40
+ changeEvent: 'paginationModelChange'
41
+ });
42
+
43
+ /**
44
+ * API METHODS
45
+ */
46
+ const setPage = React.useCallback(page => {
47
+ const currentModel = gridPaginationModelSelector(apiRef);
48
+ if (page === currentModel.page) {
49
+ return;
50
+ }
51
+ logger.debug(`Setting page to ${page}`);
52
+ apiRef.current.setPaginationModel({
53
+ page,
54
+ pageSize: currentModel.pageSize
55
+ });
56
+ }, [apiRef, logger]);
57
+ const setPageSize = React.useCallback(pageSize => {
58
+ const currentModel = gridPaginationModelSelector(apiRef);
59
+ if (pageSize === currentModel.pageSize) {
60
+ return;
61
+ }
62
+ logger.debug(`Setting page size to ${pageSize}`);
63
+ apiRef.current.setPaginationModel({
64
+ pageSize,
65
+ page: currentModel.page
66
+ });
67
+ }, [apiRef, logger]);
68
+ const setPaginationModel = React.useCallback(paginationModel => {
69
+ const currentModel = gridPaginationModelSelector(apiRef);
70
+ if (paginationModel === currentModel) {
71
+ return;
72
+ }
73
+ logger.debug("Setting 'paginationModel' to", paginationModel);
74
+ apiRef.current.setState(state => _extends({}, state, {
75
+ pagination: _extends({}, state.pagination, {
76
+ paginationModel: getDerivedPaginationModel(state.pagination, props.signature, paginationModel)
77
+ })
78
+ }));
79
+ }, [apiRef, logger, props.signature]);
80
+ const paginationModelApi = {
81
+ setPage,
82
+ setPageSize,
83
+ setPaginationModel
84
+ };
85
+ useGridApiMethod(apiRef, paginationModelApi, 'public');
86
+
87
+ /**
88
+ * PRE-PROCESSING
89
+ */
90
+ const stateExportPreProcessing = React.useCallback((prevState, context) => {
91
+ const paginationModel = gridPaginationModelSelector(apiRef);
92
+ const shouldExportPaginationModel =
93
+ // Always export if the `exportOnlyDirtyModels` property is not activated
94
+ !context.exportOnlyDirtyModels ||
95
+ // Always export if the `paginationModel` is controlled
96
+ props.paginationModel != null ||
97
+ // Always export if the `paginationModel` has been initialized
98
+ props.initialState?.pagination?.paginationModel != null ||
99
+ // Export if `page` or `pageSize` is not equal to the default value
100
+ paginationModel.page !== 0 && paginationModel.pageSize !== defaultPageSize(props.autoPageSize);
101
+ if (!shouldExportPaginationModel) {
102
+ return prevState;
103
+ }
104
+ return _extends({}, prevState, {
105
+ pagination: _extends({}, prevState.pagination, {
106
+ paginationModel
107
+ })
108
+ });
109
+ }, [apiRef, props.paginationModel, props.initialState?.pagination?.paginationModel, props.autoPageSize]);
110
+ const stateRestorePreProcessing = React.useCallback((params, context) => {
111
+ const paginationModel = context.stateToRestore.pagination?.paginationModel ? _extends({}, getDefaultGridPaginationModel(props.autoPageSize), context.stateToRestore.pagination?.paginationModel) : gridPaginationModelSelector(apiRef);
112
+ apiRef.current.setState(state => _extends({}, state, {
113
+ pagination: _extends({}, state.pagination, {
114
+ paginationModel: getDerivedPaginationModel(state.pagination, props.signature, paginationModel)
115
+ })
116
+ }));
117
+ return params;
118
+ }, [apiRef, props.autoPageSize, props.signature]);
119
+ useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
120
+ useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
121
+
122
+ /**
123
+ * EVENTS
124
+ */
125
+ const handlePaginationModelChange = () => {
126
+ const paginationModel = gridPaginationModelSelector(apiRef);
127
+ if (apiRef.current.virtualScrollerRef?.current) {
128
+ apiRef.current.scrollToIndexes({
129
+ rowIndex: paginationModel.page * paginationModel.pageSize
130
+ });
131
+ }
132
+ };
133
+ const handleUpdateAutoPageSize = React.useCallback(() => {
134
+ if (!props.autoPageSize) {
135
+ return;
136
+ }
137
+ const dimensions = apiRef.current.getRootDimensions() || {
138
+ viewportInnerSize: {
139
+ height: 0
140
+ }
141
+ };
142
+ const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
143
+ const maximumPageSizeWithoutScrollBar = Math.floor((dimensions.viewportInnerSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom) / rowHeight);
144
+ apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
145
+ }, [apiRef, props.autoPageSize, rowHeight]);
146
+ const handleRowCountChange = React.useCallback(newRowCount => {
147
+ if (newRowCount == null) {
148
+ return;
149
+ }
150
+ const paginationModel = gridPaginationModelSelector(apiRef);
151
+ const pageCount = gridPageCountSelector(apiRef);
152
+ if (paginationModel.page > pageCount - 1) {
153
+ apiRef.current.setPage(Math.max(0, pageCount - 1));
154
+ }
155
+ }, [apiRef]);
156
+ useGridApiEventHandler(apiRef, 'viewportInnerSizeChange', handleUpdateAutoPageSize);
157
+ useGridApiEventHandler(apiRef, 'paginationModelChange', handlePaginationModelChange);
158
+ useGridApiEventHandler(apiRef, 'rowCountChange', handleRowCountChange);
159
+
160
+ /**
161
+ * EFFECTS
162
+ */
163
+ React.useEffect(() => {
164
+ apiRef.current.setState(state => _extends({}, state, {
165
+ pagination: _extends({}, state.pagination, {
166
+ paginationModel: getDerivedPaginationModel(state.pagination, props.signature, props.paginationModel)
167
+ })
168
+ }));
169
+ }, [apiRef, props.paginationModel, props.paginationMode, props.signature]);
170
+ React.useEffect(handleUpdateAutoPageSize, [handleUpdateAutoPageSize]);
171
+ };