@mui/x-data-grid 7.2.0 → 7.3.0

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 (109) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/DataGrid/DataGrid.js +19 -0
  3. package/components/GridPagination.d.ts +4 -1
  4. package/components/GridPagination.js +60 -9
  5. package/components/GridRow.js +1 -0
  6. package/components/GridScrollArea.js +1 -1
  7. package/components/columnHeaders/GridColumnHeaderItem.d.ts +1 -0
  8. package/components/columnHeaders/GridColumnHeaderItem.js +5 -2
  9. package/components/columnHeaders/GridColumnHeaderSeparator.js +1 -1
  10. package/components/containers/GridRootStyles.js +3 -1
  11. package/components/index.d.ts +1 -1
  12. package/components/index.js +1 -1
  13. package/components/panel/GridPanel.js +3 -1
  14. package/constants/gridClasses.d.ts +6 -2
  15. package/constants/gridClasses.js +1 -1
  16. package/hooks/features/columnHeaders/useGridColumnHeaders.js +2 -2
  17. package/hooks/features/columnResize/useGridColumnResize.js +75 -61
  18. package/hooks/features/columns/gridColumnsUtils.d.ts +2 -1
  19. package/hooks/features/columns/gridColumnsUtils.js +4 -3
  20. package/hooks/features/density/useGridDensity.d.ts +1 -1
  21. package/hooks/features/density/useGridDensity.js +30 -4
  22. package/hooks/features/dimensions/gridDimensionsApi.d.ts +5 -1
  23. package/hooks/features/dimensions/useGridDimensions.d.ts +1 -1
  24. package/hooks/features/dimensions/useGridDimensions.js +5 -2
  25. package/hooks/features/editing/useGridCellEditing.js +14 -1
  26. package/hooks/features/export/useGridPrintExport.d.ts +1 -1
  27. package/hooks/features/export/useGridPrintExport.js +2 -2
  28. package/hooks/features/headerFiltering/useGridHeaderFiltering.d.ts +2 -2
  29. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +2 -2
  30. package/hooks/features/pagination/gridPaginationInterfaces.d.ts +14 -2
  31. package/hooks/features/pagination/gridPaginationSelector.d.ts +5 -0
  32. package/hooks/features/pagination/gridPaginationSelector.js +7 -1
  33. package/hooks/features/pagination/gridPaginationUtils.d.ts +1 -2
  34. package/hooks/features/pagination/gridPaginationUtils.js +5 -3
  35. package/hooks/features/pagination/useGridPagination.d.ts +1 -1
  36. package/hooks/features/pagination/useGridPagination.js +5 -1
  37. package/hooks/features/pagination/useGridPaginationMeta.d.ts +4 -0
  38. package/hooks/features/pagination/useGridPaginationMeta.js +77 -0
  39. package/hooks/features/pagination/useGridPaginationModel.js +2 -1
  40. package/hooks/features/pagination/useGridRowCount.d.ts +0 -4
  41. package/hooks/features/pagination/useGridRowCount.js +32 -18
  42. package/hooks/utils/useGridSelector.d.ts +1 -1
  43. package/index.js +1 -1
  44. package/internals/index.d.ts +1 -1
  45. package/internals/utils/propValidation.js +1 -1
  46. package/locales/daDK.js +3 -4
  47. package/models/api/gridApiCommon.d.ts +1 -1
  48. package/models/api/gridLocaleTextApi.d.ts +7 -3
  49. package/models/api/index.d.ts +1 -1
  50. package/models/api/index.js +0 -1
  51. package/models/events/gridEventLookup.d.ts +7 -1
  52. package/models/gridPaginationProps.d.ts +3 -0
  53. package/models/props/DataGridProps.d.ts +26 -8
  54. package/modern/DataGrid/DataGrid.js +19 -0
  55. package/modern/components/GridPagination.js +60 -9
  56. package/modern/components/GridRow.js +1 -0
  57. package/modern/components/GridScrollArea.js +1 -1
  58. package/modern/components/columnHeaders/GridColumnHeaderItem.js +5 -2
  59. package/modern/components/columnHeaders/GridColumnHeaderSeparator.js +1 -1
  60. package/modern/components/containers/GridRootStyles.js +3 -1
  61. package/modern/components/index.js +1 -1
  62. package/modern/components/panel/GridPanel.js +3 -1
  63. package/modern/constants/gridClasses.js +1 -1
  64. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +2 -2
  65. package/modern/hooks/features/columnResize/useGridColumnResize.js +75 -61
  66. package/modern/hooks/features/columns/gridColumnsUtils.js +4 -3
  67. package/modern/hooks/features/density/useGridDensity.js +30 -4
  68. package/modern/hooks/features/dimensions/useGridDimensions.js +5 -2
  69. package/modern/hooks/features/editing/useGridCellEditing.js +14 -1
  70. package/modern/hooks/features/export/useGridPrintExport.js +2 -2
  71. package/modern/hooks/features/pagination/gridPaginationSelector.js +7 -1
  72. package/modern/hooks/features/pagination/gridPaginationUtils.js +5 -3
  73. package/modern/hooks/features/pagination/useGridPagination.js +5 -1
  74. package/modern/hooks/features/pagination/useGridPaginationMeta.js +77 -0
  75. package/modern/hooks/features/pagination/useGridPaginationModel.js +2 -1
  76. package/modern/hooks/features/pagination/useGridRowCount.js +32 -18
  77. package/modern/index.js +1 -1
  78. package/modern/internals/utils/propValidation.js +1 -1
  79. package/modern/locales/daDK.js +3 -4
  80. package/modern/models/api/index.js +0 -1
  81. package/node/DataGrid/DataGrid.js +19 -0
  82. package/node/components/GridPagination.js +59 -8
  83. package/node/components/GridRow.js +1 -0
  84. package/node/components/GridScrollArea.js +1 -1
  85. package/node/components/columnHeaders/GridColumnHeaderItem.js +4 -1
  86. package/node/components/columnHeaders/GridColumnHeaderSeparator.js +1 -1
  87. package/node/components/containers/GridRootStyles.js +3 -1
  88. package/node/components/index.js +27 -10
  89. package/node/components/panel/GridPanel.js +3 -1
  90. package/node/constants/gridClasses.js +1 -1
  91. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +2 -2
  92. package/node/hooks/features/columnResize/useGridColumnResize.js +76 -62
  93. package/node/hooks/features/columns/gridColumnsUtils.js +4 -3
  94. package/node/hooks/features/density/useGridDensity.js +30 -4
  95. package/node/hooks/features/dimensions/useGridDimensions.js +5 -2
  96. package/node/hooks/features/editing/useGridCellEditing.js +14 -1
  97. package/node/hooks/features/export/useGridPrintExport.js +2 -2
  98. package/node/hooks/features/pagination/gridPaginationSelector.js +8 -2
  99. package/node/hooks/features/pagination/gridPaginationUtils.js +6 -4
  100. package/node/hooks/features/pagination/useGridPagination.js +5 -1
  101. package/node/hooks/features/pagination/useGridPaginationMeta.js +87 -0
  102. package/node/hooks/features/pagination/useGridPaginationModel.js +2 -1
  103. package/node/hooks/features/pagination/useGridRowCount.js +30 -15
  104. package/node/index.js +1 -1
  105. package/node/internals/utils/propValidation.js +1 -1
  106. package/node/locales/daDK.js +3 -4
  107. package/node/models/api/index.js +0 -11
  108. package/package.json +1 -1
  109. package/utils/getGridLocalization.d.ts +1 -1
@@ -8,6 +8,7 @@ exports.useGridColumnResize = exports.columnResizeStateInitializer = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  var React = _interopRequireWildcard(require("react"));
10
10
  var _utils = require("@mui/utils");
11
+ var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef"));
11
12
  var _styles = require("@mui/material/styles");
12
13
  var _domUtils = require("../../../utils/domUtils");
13
14
  var _gridColumnResizeApi = require("./gridColumnResizeApi");
@@ -182,26 +183,34 @@ const columnResizeStateInitializer = state => (0, _extends2.default)({}, state,
182
183
  resizingColumnField: ''
183
184
  }
184
185
  });
186
+ exports.columnResizeStateInitializer = columnResizeStateInitializer;
187
+ function createResizeRefs() {
188
+ return {
189
+ colDef: undefined,
190
+ initialColWidth: 0,
191
+ initialTotalWidth: 0,
192
+ previousMouseClickEvent: undefined,
193
+ columnHeaderElement: undefined,
194
+ headerFilterElement: undefined,
195
+ groupHeaderElements: [],
196
+ cellElements: [],
197
+ leftPinnedCellsAfter: [],
198
+ rightPinnedCellsBefore: [],
199
+ fillerLeft: undefined,
200
+ fillerRight: undefined,
201
+ leftPinnedHeadersAfter: [],
202
+ rightPinnedHeadersBefore: []
203
+ };
204
+ }
205
+
185
206
  /**
186
207
  * @requires useGridColumns (method, event)
187
208
  * TODO: improve experience for last column
188
209
  */
189
- exports.columnResizeStateInitializer = columnResizeStateInitializer;
190
210
  const useGridColumnResize = (apiRef, props) => {
191
211
  const theme = (0, _styles.useTheme)();
192
212
  const logger = (0, _utils2.useGridLogger)(apiRef, 'useGridColumnResize');
193
- const colDefRef = React.useRef();
194
- const previousMouseClickEvent = React.useRef();
195
- const columnHeaderElementRef = React.useRef();
196
- const headerFilterElementRef = React.useRef();
197
- const groupHeaderElementsRef = React.useRef([]);
198
- const cellElementsRef = React.useRef([]);
199
- const leftPinnedCellsAfterRef = React.useRef([]);
200
- const rightPinnedCellsBeforeRef = React.useRef([]);
201
- const fillerLeftRef = React.useRef();
202
- const fillerRightRef = React.useRef();
203
- const leftPinnedHeadersAfterRef = React.useRef([]);
204
- const rightPinnedHeadersBeforeRef = React.useRef([]);
213
+ const refs = (0, _useLazyRef.default)(createResizeRefs).current;
205
214
 
206
215
  // To improve accessibility, the separator has padding on both sides.
207
216
  // Clicking inside the padding area should be treated as a click in the separator.
@@ -211,22 +220,25 @@ const useGridColumnResize = (apiRef, props) => {
211
220
  const stopResizeEventTimeout = (0, _useTimeout.useTimeout)();
212
221
  const touchId = React.useRef();
213
222
  const updateWidth = newWidth => {
214
- logger.debug(`Updating width to ${newWidth} for col ${colDefRef.current.field}`);
215
- const prevWidth = columnHeaderElementRef.current.offsetWidth;
223
+ logger.debug(`Updating width to ${newWidth} for col ${refs.colDef.field}`);
224
+ const prevWidth = refs.columnHeaderElement.offsetWidth;
216
225
  const widthDiff = newWidth - prevWidth;
217
- colDefRef.current.computedWidth = newWidth;
218
- colDefRef.current.width = newWidth;
219
- colDefRef.current.flex = 0;
220
- columnHeaderElementRef.current.style.width = `${newWidth}px`;
221
- columnHeaderElementRef.current.style.minWidth = `${newWidth}px`;
222
- columnHeaderElementRef.current.style.maxWidth = `${newWidth}px`;
223
- const headerFilterElement = headerFilterElementRef.current;
226
+ const columnWidthDiff = newWidth - refs.initialColWidth;
227
+ const newTotalWidth = refs.initialTotalWidth + columnWidthDiff;
228
+ apiRef.current.rootElementRef?.current?.style.setProperty('--DataGrid-rowWidth', `${newTotalWidth}px`);
229
+ refs.colDef.computedWidth = newWidth;
230
+ refs.colDef.width = newWidth;
231
+ refs.colDef.flex = 0;
232
+ refs.columnHeaderElement.style.width = `${newWidth}px`;
233
+ refs.columnHeaderElement.style.minWidth = `${newWidth}px`;
234
+ refs.columnHeaderElement.style.maxWidth = `${newWidth}px`;
235
+ const headerFilterElement = refs.headerFilterElement;
224
236
  if (headerFilterElement) {
225
237
  headerFilterElement.style.width = `${newWidth}px`;
226
238
  headerFilterElement.style.minWidth = `${newWidth}px`;
227
239
  headerFilterElement.style.maxWidth = `${newWidth}px`;
228
240
  }
229
- groupHeaderElementsRef.current.forEach(element => {
241
+ refs.groupHeaderElements.forEach(element => {
230
242
  const div = element;
231
243
  let finalWidth;
232
244
  if (div.getAttribute('aria-colspan') === '1') {
@@ -240,7 +252,7 @@ const useGridColumnResize = (apiRef, props) => {
240
252
  div.style.minWidth = finalWidth;
241
253
  div.style.maxWidth = finalWidth;
242
254
  });
243
- cellElementsRef.current.forEach(element => {
255
+ refs.cellElements.forEach(element => {
244
256
  const div = element;
245
257
  let finalWidth;
246
258
  if (div.getAttribute('aria-colspan') === '1') {
@@ -252,22 +264,22 @@ const useGridColumnResize = (apiRef, props) => {
252
264
  }
253
265
  div.style.setProperty('--width', finalWidth);
254
266
  });
255
- const pinnedPosition = apiRef.current.unstable_applyPipeProcessors('isColumnPinned', false, colDefRef.current.field);
267
+ const pinnedPosition = apiRef.current.unstable_applyPipeProcessors('isColumnPinned', false, refs.colDef.field);
256
268
  if (pinnedPosition === _gridColumnsInterfaces.GridPinnedColumnPosition.LEFT) {
257
- updateProperty(fillerLeftRef.current, 'width', widthDiff);
258
- leftPinnedCellsAfterRef.current.forEach(cell => {
269
+ updateProperty(refs.fillerLeft, 'width', widthDiff);
270
+ refs.leftPinnedCellsAfter.forEach(cell => {
259
271
  updateProperty(cell, 'left', widthDiff);
260
272
  });
261
- leftPinnedHeadersAfterRef.current.forEach(header => {
273
+ refs.leftPinnedHeadersAfter.forEach(header => {
262
274
  updateProperty(header, 'left', widthDiff);
263
275
  });
264
276
  }
265
277
  if (pinnedPosition === _gridColumnsInterfaces.GridPinnedColumnPosition.RIGHT) {
266
- updateProperty(fillerRightRef.current, 'width', widthDiff);
267
- rightPinnedCellsBeforeRef.current.forEach(cell => {
278
+ updateProperty(refs.fillerRight, 'width', widthDiff);
279
+ refs.rightPinnedCellsBefore.forEach(cell => {
268
280
  updateProperty(cell, 'right', widthDiff);
269
281
  });
270
- rightPinnedHeadersBeforeRef.current.forEach(header => {
282
+ refs.rightPinnedHeadersBefore.forEach(header => {
271
283
  updateProperty(header, 'right', widthDiff);
272
284
  });
273
285
  }
@@ -277,21 +289,21 @@ const useGridColumnResize = (apiRef, props) => {
277
289
  stopListening();
278
290
 
279
291
  // Prevent double-clicks from being interpreted as two separate clicks
280
- if (previousMouseClickEvent.current) {
281
- const prevEvent = previousMouseClickEvent.current;
292
+ if (refs.previousMouseClickEvent) {
293
+ const prevEvent = refs.previousMouseClickEvent;
282
294
  const prevTimeStamp = prevEvent.timeStamp;
283
295
  const prevClientX = prevEvent.clientX;
284
296
  const prevClientY = prevEvent.clientY;
285
297
 
286
298
  // Check if the current event is part of a double-click
287
299
  if (nativeEvent.timeStamp - prevTimeStamp < 300 && nativeEvent.clientX === prevClientX && nativeEvent.clientY === prevClientY) {
288
- previousMouseClickEvent.current = undefined;
300
+ refs.previousMouseClickEvent = undefined;
289
301
  return;
290
302
  }
291
303
  }
292
- if (colDefRef.current) {
293
- apiRef.current.setColumnWidth(colDefRef.current.field, colDefRef.current.width);
294
- logger.debug(`Updating col ${colDefRef.current.field} with new width: ${colDefRef.current.width}`);
304
+ if (refs.colDef) {
305
+ apiRef.current.setColumnWidth(refs.colDef.field, refs.colDef.width);
306
+ logger.debug(`Updating col ${refs.colDef.field} with new width: ${refs.colDef.width}`);
295
307
  }
296
308
  stopResizeEventTimeout.start(0, () => {
297
309
  apiRef.current.publishEvent('columnResizeStop', null, nativeEvent);
@@ -299,23 +311,25 @@ const useGridColumnResize = (apiRef, props) => {
299
311
  };
300
312
  const storeReferences = (colDef, separator, xStart) => {
301
313
  const root = apiRef.current.rootElementRef.current;
302
- colDefRef.current = colDef;
303
- columnHeaderElementRef.current = (0, _domUtils.findHeaderElementFromField)(apiRef.current.columnHeadersContainerRef.current, colDef.field);
314
+ refs.initialColWidth = colDef.computedWidth;
315
+ refs.initialTotalWidth = apiRef.current.getRootDimensions().rowWidth;
316
+ refs.colDef = colDef;
317
+ refs.columnHeaderElement = (0, _domUtils.findHeaderElementFromField)(apiRef.current.columnHeadersContainerRef.current, colDef.field);
304
318
  const headerFilterElement = root.querySelector(`.${_gridClasses.gridClasses.headerFilterRow} [data-field="${colDef.field}"]`);
305
319
  if (headerFilterElement) {
306
- headerFilterElementRef.current = headerFilterElement;
320
+ refs.headerFilterElement = headerFilterElement;
307
321
  }
308
- groupHeaderElementsRef.current = (0, _domUtils.findGroupHeaderElementsFromField)(apiRef.current.columnHeadersContainerRef?.current, colDef.field);
309
- cellElementsRef.current = (0, _domUtils.findGridCellElementsFromCol)(columnHeaderElementRef.current, apiRef.current);
310
- fillerLeftRef.current = (0, _domUtils.findGridElement)(apiRef.current, 'filler--pinnedLeft');
311
- fillerRightRef.current = (0, _domUtils.findGridElement)(apiRef.current, 'filler--pinnedRight');
312
- const pinnedPosition = apiRef.current.unstable_applyPipeProcessors('isColumnPinned', false, colDefRef.current.field);
313
- leftPinnedCellsAfterRef.current = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.LEFT ? [] : (0, _domUtils.findLeftPinnedCellsAfterCol)(apiRef.current, columnHeaderElementRef.current);
314
- rightPinnedCellsBeforeRef.current = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.RIGHT ? [] : (0, _domUtils.findRightPinnedCellsBeforeCol)(apiRef.current, columnHeaderElementRef.current);
315
- leftPinnedHeadersAfterRef.current = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.LEFT ? [] : (0, _domUtils.findLeftPinnedHeadersAfterCol)(apiRef.current, columnHeaderElementRef.current);
316
- rightPinnedHeadersBeforeRef.current = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.RIGHT ? [] : (0, _domUtils.findRightPinnedHeadersBeforeCol)(apiRef.current, columnHeaderElementRef.current);
322
+ refs.groupHeaderElements = (0, _domUtils.findGroupHeaderElementsFromField)(apiRef.current.columnHeadersContainerRef?.current, colDef.field);
323
+ refs.cellElements = (0, _domUtils.findGridCellElementsFromCol)(refs.columnHeaderElement, apiRef.current);
324
+ refs.fillerLeft = (0, _domUtils.findGridElement)(apiRef.current, 'filler--pinnedLeft');
325
+ refs.fillerRight = (0, _domUtils.findGridElement)(apiRef.current, 'filler--pinnedRight');
326
+ const pinnedPosition = apiRef.current.unstable_applyPipeProcessors('isColumnPinned', false, refs.colDef.field);
327
+ refs.leftPinnedCellsAfter = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.LEFT ? [] : (0, _domUtils.findLeftPinnedCellsAfterCol)(apiRef.current, refs.columnHeaderElement);
328
+ refs.rightPinnedCellsBefore = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.RIGHT ? [] : (0, _domUtils.findRightPinnedCellsBeforeCol)(apiRef.current, refs.columnHeaderElement);
329
+ refs.leftPinnedHeadersAfter = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.LEFT ? [] : (0, _domUtils.findLeftPinnedHeadersAfterCol)(apiRef.current, refs.columnHeaderElement);
330
+ refs.rightPinnedHeadersBefore = pinnedPosition !== _gridColumnsInterfaces.GridPinnedColumnPosition.RIGHT ? [] : (0, _domUtils.findRightPinnedHeadersBeforeCol)(apiRef.current, refs.columnHeaderElement);
317
331
  resizeDirection.current = getResizeDirection(separator, theme.direction);
318
- initialOffsetToSeparator.current = computeOffsetToSeparator(xStart, columnHeaderElementRef.current.getBoundingClientRect(), resizeDirection.current);
332
+ initialOffsetToSeparator.current = computeOffsetToSeparator(xStart, refs.columnHeaderElement.getBoundingClientRect(), resizeDirection.current);
319
333
  };
320
334
  const handleResizeMouseUp = (0, _utils.unstable_useEventCallback)(finishResize);
321
335
  const handleResizeMouseMove = (0, _utils.unstable_useEventCallback)(nativeEvent => {
@@ -324,12 +338,12 @@ const useGridColumnResize = (apiRef, props) => {
324
338
  handleResizeMouseUp(nativeEvent);
325
339
  return;
326
340
  }
327
- let newWidth = computeNewWidth(initialOffsetToSeparator.current, nativeEvent.clientX, columnHeaderElementRef.current.getBoundingClientRect(), resizeDirection.current);
328
- newWidth = (0, _utils3.clamp)(newWidth, colDefRef.current.minWidth, colDefRef.current.maxWidth);
341
+ let newWidth = computeNewWidth(initialOffsetToSeparator.current, nativeEvent.clientX, refs.columnHeaderElement.getBoundingClientRect(), resizeDirection.current);
342
+ newWidth = (0, _utils3.clamp)(newWidth, refs.colDef.minWidth, refs.colDef.maxWidth);
329
343
  updateWidth(newWidth);
330
344
  const params = {
331
- element: columnHeaderElementRef.current,
332
- colDef: colDefRef.current,
345
+ element: refs.columnHeaderElement,
346
+ colDef: refs.colDef,
333
347
  width: newWidth
334
348
  };
335
349
  apiRef.current.publishEvent('columnResize', params, nativeEvent);
@@ -352,12 +366,12 @@ const useGridColumnResize = (apiRef, props) => {
352
366
  handleTouchEnd(nativeEvent);
353
367
  return;
354
368
  }
355
- let newWidth = computeNewWidth(initialOffsetToSeparator.current, finger.x, columnHeaderElementRef.current.getBoundingClientRect(), resizeDirection.current);
356
- newWidth = (0, _utils3.clamp)(newWidth, colDefRef.current.minWidth, colDefRef.current.maxWidth);
369
+ let newWidth = computeNewWidth(initialOffsetToSeparator.current, finger.x, refs.columnHeaderElement.getBoundingClientRect(), resizeDirection.current);
370
+ newWidth = (0, _utils3.clamp)(newWidth, refs.colDef.minWidth, refs.colDef.maxWidth);
357
371
  updateWidth(newWidth);
358
372
  const params = {
359
- element: columnHeaderElementRef.current,
360
- colDef: colDefRef.current,
373
+ element: refs.columnHeaderElement,
374
+ colDef: refs.colDef,
361
375
  width: newWidth
362
376
  };
363
377
  apiRef.current.publishEvent('columnResize', params, nativeEvent);
@@ -401,10 +415,10 @@ const useGridColumnResize = (apiRef, props) => {
401
415
  setTimeout(() => {
402
416
  doc.removeEventListener('click', preventClick, true);
403
417
  }, 100);
404
- if (columnHeaderElementRef.current) {
405
- columnHeaderElementRef.current.style.pointerEvents = 'unset';
418
+ if (refs.columnHeaderElement) {
419
+ refs.columnHeaderElement.style.pointerEvents = 'unset';
406
420
  }
407
- }, [apiRef, columnHeaderElementRef, handleResizeMouseMove, handleResizeMouseUp, handleTouchMove, handleTouchEnd]);
421
+ }, [apiRef, refs, handleResizeMouseMove, handleResizeMouseUp, handleTouchMove, handleTouchEnd]);
408
422
  const handleResizeStart = React.useCallback(({
409
423
  field
410
424
  }) => {
@@ -445,7 +459,7 @@ const useGridColumnResize = (apiRef, props) => {
445
459
  storeReferences(colDef, event.currentTarget, event.clientX);
446
460
  const doc = (0, _utils.unstable_ownerDocument)(apiRef.current.rootElementRef.current);
447
461
  doc.body.style.cursor = 'col-resize';
448
- previousMouseClickEvent.current = event.nativeEvent;
462
+ refs.previousMouseClickEvent = event.nativeEvent;
449
463
  doc.addEventListener('mousemove', handleResizeMouseMove);
450
464
  doc.addEventListener('mouseup', handleResizeMouseUp);
451
465
 
@@ -319,10 +319,11 @@ function getFirstNonSpannedColumnToRender({
319
319
  }
320
320
  return firstNonSpannedColumnToRender;
321
321
  }
322
- function getTotalHeaderHeight(apiRef, headerHeight) {
322
+ function getTotalHeaderHeight(apiRef, props) {
323
323
  const densityFactor = (0, _densitySelector.gridDensityFactorSelector)(apiRef);
324
324
  const maxDepth = (0, _gridColumnGroupsSelector.gridColumnGroupsHeaderMaxDepthSelector)(apiRef);
325
325
  const isHeaderFilteringEnabled = (0, _gridHeaderFilteringSelectors.gridHeaderFilteringEnabledSelector)(apiRef);
326
- const multiplicationFactor = isHeaderFilteringEnabled ? 2 : 1;
327
- return Math.floor(headerHeight * densityFactor) * ((maxDepth ?? 0) + multiplicationFactor);
326
+ const columnHeadersHeight = Math.floor(props.columnHeaderHeight * densityFactor);
327
+ const filterHeadersHeight = isHeaderFilteringEnabled ? Math.floor((props.headerFilterHeight ?? props.columnHeaderHeight) * densityFactor) : 0;
328
+ return columnHeadersHeight * (1 + (maxDepth ?? 0)) + filterHeadersHeight;
328
329
  }
@@ -11,6 +11,7 @@ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallb
11
11
  var _useGridLogger = require("../../utils/useGridLogger");
12
12
  var _useGridApiMethod = require("../../utils/useGridApiMethod");
13
13
  var _densitySelector = require("./densitySelector");
14
+ var _pipeProcessing = require("../../core/pipeProcessing");
14
15
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
15
16
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
16
17
  const densityStateInitializer = (state, props) => (0, _extends2.default)({}, state, {
@@ -36,14 +37,39 @@ const useGridDensity = (apiRef, props) => {
36
37
  density: newDensity
37
38
  }));
38
39
  });
40
+ const densityApi = {
41
+ setDensity
42
+ };
43
+ (0, _useGridApiMethod.useGridApiMethod)(apiRef, densityApi, 'public');
44
+ const stateExportPreProcessing = React.useCallback((prevState, context) => {
45
+ const exportedDensity = (0, _densitySelector.gridDensitySelector)(apiRef.current.state);
46
+ const shouldExportRowCount =
47
+ // Always export if the `exportOnlyDirtyModels` property is not activated
48
+ !context.exportOnlyDirtyModels ||
49
+ // Always export if the `density` is controlled
50
+ props.density != null ||
51
+ // Always export if the `density` has been initialized
52
+ props.initialState?.density != null;
53
+ if (!shouldExportRowCount) {
54
+ return prevState;
55
+ }
56
+ return (0, _extends2.default)({}, prevState, {
57
+ density: exportedDensity
58
+ });
59
+ }, [apiRef, props.density, props.initialState?.density]);
60
+ const stateRestorePreProcessing = React.useCallback((params, context) => {
61
+ const restoredDensity = context.stateToRestore?.density ? context.stateToRestore.density : (0, _densitySelector.gridDensitySelector)(apiRef.current.state);
62
+ apiRef.current.setState(state => (0, _extends2.default)({}, state, {
63
+ density: restoredDensity
64
+ }));
65
+ return params;
66
+ }, [apiRef]);
67
+ (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing);
68
+ (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'restoreState', stateRestorePreProcessing);
39
69
  React.useEffect(() => {
40
70
  if (props.density) {
41
71
  apiRef.current.setDensity(props.density);
42
72
  }
43
73
  }, [apiRef, props.density]);
44
- const densityApi = {
45
- setDensity
46
- };
47
- (0, _useGridApiMethod.useGridApiMethod)(apiRef, densityApi, 'public');
48
74
  };
49
75
  exports.useGridDensity = useGridDensity;
@@ -39,6 +39,7 @@ const EMPTY_DIMENSIONS = {
39
39
  hasScrollY: false,
40
40
  scrollbarSize: 0,
41
41
  headerHeight: 0,
42
+ headerFilterHeight: 0,
42
43
  rowWidth: 0,
43
44
  rowHeight: 0,
44
45
  columnsTotalWidth: 0,
@@ -64,8 +65,9 @@ function useGridDimensions(apiRef, props) {
64
65
  const densityFactor = (0, _utils2.useGridSelector)(apiRef, _density.gridDensityFactorSelector);
65
66
  const rowHeight = Math.floor(props.rowHeight * densityFactor);
66
67
  const headerHeight = Math.floor(props.columnHeaderHeight * densityFactor);
68
+ const headerFilterHeight = Math.floor((props.headerFilterHeight ?? props.columnHeaderHeight) * densityFactor);
67
69
  const columnsTotalWidth = roundToDecimalPlaces((0, _columns.gridColumnsTotalWidthSelector)(apiRef), 6);
68
- const headersTotalHeight = (0, _gridColumnsUtils.getTotalHeaderHeight)(apiRef, props.columnHeaderHeight);
70
+ const headersTotalHeight = (0, _gridColumnsUtils.getTotalHeaderHeight)(apiRef, props);
69
71
  const leftPinnedWidth = pinnedColumns.left.reduce((w, col) => w + col.computedWidth, 0);
70
72
  const rightPinnedWidth = pinnedColumns.right.reduce((w, col) => w + col.computedWidth, 0);
71
73
  const [savedSize, setSavedSize] = React.useState();
@@ -187,6 +189,7 @@ function useGridDimensions(apiRef, props) {
187
189
  hasScrollY,
188
190
  scrollbarSize,
189
191
  headerHeight,
192
+ headerFilterHeight,
190
193
  rowWidth,
191
194
  rowHeight,
192
195
  columnsTotalWidth,
@@ -202,7 +205,7 @@ function useGridDimensions(apiRef, props) {
202
205
  apiRef.current.publishEvent('viewportInnerSizeChange', newDimensions.viewportInnerSize);
203
206
  }
204
207
  apiRef.current.updateRenderContext?.();
205
- }, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, rowHeight, headerHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
208
+ }, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, rowHeight, headerHeight, headerFilterHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
206
209
  const apiPublic = {
207
210
  resize,
208
211
  getRootDimensions
@@ -162,13 +162,26 @@ const useGridCellEditing = (apiRef, props) => {
162
162
  cellToFocusAfter
163
163
  });
164
164
  }, [apiRef]);
165
+ const runIfNoFieldErrors = callback => async (...args) => {
166
+ if (callback) {
167
+ const {
168
+ id,
169
+ field
170
+ } = args[0];
171
+ const editRowsState = apiRef.current.state.editRows;
172
+ const hasFieldErrors = editRowsState[id][field]?.error;
173
+ if (!hasFieldErrors) {
174
+ callback(...args);
175
+ }
176
+ }
177
+ };
165
178
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellDoubleClick', runIfEditModeIsCell(handleCellDoubleClick));
166
179
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellFocusOut', runIfEditModeIsCell(handleCellFocusOut));
167
180
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellKeyDown', runIfEditModeIsCell(handleCellKeyDown));
168
181
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellEditStart', runIfEditModeIsCell(handleCellEditStart));
169
182
  (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellEditStop', runIfEditModeIsCell(handleCellEditStop));
170
183
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'cellEditStart', props.onCellEditStart);
171
- (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'cellEditStop', props.onCellEditStop);
184
+ (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'cellEditStop', runIfNoFieldErrors(props.onCellEditStop));
172
185
  const getCellMode = React.useCallback((id, field) => {
173
186
  const editingState = (0, _gridEditingSelectors.gridEditRowsStateSelector)(apiRef.current.state);
174
187
  const isEditing = editingState[id] && editingState[id][field];
@@ -116,7 +116,7 @@ const useGridPrintExport = (apiRef, props) => {
116
116
  }
117
117
 
118
118
  // Expand container height to accommodate all rows
119
- const computedTotalHeight = rowsMeta.currentPageTotalHeight + (0, _gridColumnsUtils.getTotalHeaderHeight)(apiRef, props.columnHeaderHeight) + gridToolbarElementHeight + gridFooterElementHeight;
119
+ const computedTotalHeight = rowsMeta.currentPageTotalHeight + (0, _gridColumnsUtils.getTotalHeaderHeight)(apiRef, props) + gridToolbarElementHeight + gridFooterElementHeight;
120
120
  gridClone.style.height = `${computedTotalHeight}px`;
121
121
  // The height above does not include grid border width, so we need to exclude it
122
122
  gridClone.style.boxSizing = 'content-box';
@@ -190,7 +190,7 @@ const useGridPrintExport = (apiRef, props) => {
190
190
  printWindow.contentWindow.print();
191
191
  });
192
192
  }
193
- }, [apiRef, doc, props.columnHeaderHeight]);
193
+ }, [apiRef, doc, props]);
194
194
  const handlePrintWindowAfterPrint = React.useCallback(printWindow => {
195
195
  // Remove the print iframe
196
196
  doc.current.body.removeChild(printWindow);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.gridPaginationSelector = exports.gridPaginationRowRangeSelector = exports.gridPaginationRowCountSelector = exports.gridPaginationModelSelector = exports.gridPaginatedVisibleSortedGridRowIdsSelector = exports.gridPaginatedVisibleSortedGridRowEntriesSelector = exports.gridPageSizeSelector = exports.gridPageSelector = exports.gridPageCountSelector = void 0;
6
+ exports.gridPaginationSelector = exports.gridPaginationRowRangeSelector = exports.gridPaginationRowCountSelector = exports.gridPaginationModelSelector = exports.gridPaginationMetaSelector = exports.gridPaginatedVisibleSortedGridRowIdsSelector = exports.gridPaginatedVisibleSortedGridRowEntriesSelector = exports.gridPageSizeSelector = exports.gridPageSelector = exports.gridPageCountSelector = void 0;
7
7
  var _createSelector = require("../../../utils/createSelector");
8
8
  var _gridFilterSelector = require("../filter/gridFilterSelector");
9
9
  var _gridRowsSelector = require("../rows/gridRowsSelector");
@@ -27,6 +27,12 @@ const gridPaginationModelSelector = exports.gridPaginationModelSelector = (0, _c
27
27
  */
28
28
  const gridPaginationRowCountSelector = exports.gridPaginationRowCountSelector = (0, _createSelector.createSelector)(gridPaginationSelector, pagination => pagination.rowCount);
29
29
 
30
+ /**
31
+ * Get the pagination meta
32
+ * @category Pagination
33
+ */
34
+ const gridPaginationMetaSelector = exports.gridPaginationMetaSelector = (0, _createSelector.createSelector)(gridPaginationSelector, pagination => pagination.meta);
35
+
30
36
  /**
31
37
  * Get the index of the page to render if the pagination is enabled
32
38
  * @category Pagination
@@ -43,7 +49,7 @@ const gridPageSizeSelector = exports.gridPageSizeSelector = (0, _createSelector.
43
49
  * Get the amount of pages needed to display all the rows if the pagination is enabled
44
50
  * @category Pagination
45
51
  */
46
- const gridPageCountSelector = exports.gridPageCountSelector = (0, _createSelector.createSelector)(gridPageSizeSelector, gridPaginationRowCountSelector, (pageSize, rowCount) => (0, _gridPaginationUtils.getPageCount)(rowCount, pageSize));
52
+ const gridPageCountSelector = exports.gridPageCountSelector = (0, _createSelector.createSelector)(gridPaginationModelSelector, gridPaginationRowCountSelector, (paginationModel, rowCount) => (0, _gridPaginationUtils.getPageCount)(rowCount, paginationModel.pageSize, paginationModel.page));
47
53
 
48
54
  /**
49
55
  * Get the index of the first and the last row to include in the current page if the pagination is enabled.
@@ -3,20 +3,22 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.throwIfPageSizeExceedsTheLimit = exports.noRowCountInServerMode = exports.getValidPage = exports.getPageCount = exports.getDefaultGridPaginationModel = exports.defaultPageSize = void 0;
7
- var _warning = require("../../../utils/warning");
6
+ exports.throwIfPageSizeExceedsTheLimit = exports.getValidPage = exports.getPageCount = exports.getDefaultGridPaginationModel = exports.defaultPageSize = void 0;
8
7
  var _utils = require("../../utils");
9
8
  const MAX_PAGE_SIZE = 100;
10
9
  const defaultPageSize = autoPageSize => autoPageSize ? 0 : 100;
11
10
  exports.defaultPageSize = defaultPageSize;
12
- const getPageCount = (rowCount, pageSize) => {
11
+ const getPageCount = (rowCount, pageSize, page) => {
13
12
  if (pageSize > 0 && rowCount > 0) {
14
13
  return Math.ceil(rowCount / pageSize);
15
14
  }
15
+ if (rowCount === -1) {
16
+ // With unknown row-count, we can assume a page after the current one
17
+ return page + 2;
18
+ }
16
19
  return 0;
17
20
  };
18
21
  exports.getPageCount = getPageCount;
19
- const noRowCountInServerMode = exports.noRowCountInServerMode = (0, _warning.buildWarning)(["MUI X: the 'rowCount' prop is undefined while using paginationMode='server'", 'For more detail, see http://mui.com/components/data-grid/pagination/#basic-implementation'], 'error');
20
22
  const getDefaultGridPaginationModel = autoPageSize => ({
21
23
  page: 0,
22
24
  pageSize: autoPageSize ? 0 : 100
@@ -9,14 +9,17 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
9
9
  var _gridPaginationUtils = require("./gridPaginationUtils");
10
10
  var _useGridPaginationModel = require("./useGridPaginationModel");
11
11
  var _useGridRowCount = require("./useGridRowCount");
12
+ var _useGridPaginationMeta = require("./useGridPaginationMeta");
12
13
  const paginationStateInitializer = (state, props) => {
13
14
  const paginationModel = (0, _extends2.default)({}, (0, _gridPaginationUtils.getDefaultGridPaginationModel)(props.autoPageSize), props.paginationModel ?? props.initialState?.pagination?.paginationModel);
14
15
  (0, _gridPaginationUtils.throwIfPageSizeExceedsTheLimit)(paginationModel.pageSize, props.signature);
15
16
  const rowCount = props.rowCount ?? props.initialState?.pagination?.rowCount;
17
+ const meta = props.paginationMeta ?? props.initialState?.pagination?.meta ?? {};
16
18
  return (0, _extends2.default)({}, state, {
17
19
  pagination: {
18
20
  paginationModel,
19
- rowCount
21
+ rowCount,
22
+ meta
20
23
  }
21
24
  });
22
25
  };
@@ -27,6 +30,7 @@ const paginationStateInitializer = (state, props) => {
27
30
  */
28
31
  exports.paginationStateInitializer = paginationStateInitializer;
29
32
  const useGridPagination = (apiRef, props) => {
33
+ (0, _useGridPaginationMeta.useGridPaginationMeta)(apiRef, props);
30
34
  (0, _useGridPaginationModel.useGridPaginationModel)(apiRef, props);
31
35
  (0, _useGridRowCount.useGridRowCount)(apiRef, props);
32
36
  };
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useGridPaginationMeta = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var React = _interopRequireWildcard(require("react"));
10
+ var _utils = require("../../utils");
11
+ var _pipeProcessing = require("../../core/pipeProcessing");
12
+ var _gridPaginationSelector = require("./gridPaginationSelector");
13
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
+ const useGridPaginationMeta = (apiRef, props) => {
16
+ const logger = (0, _utils.useGridLogger)(apiRef, 'useGridPaginationMeta');
17
+ const paginationMeta = (0, _utils.useGridSelector)(apiRef, _gridPaginationSelector.gridPaginationMetaSelector);
18
+ apiRef.current.registerControlState({
19
+ stateId: 'paginationMeta',
20
+ propModel: props.paginationMeta,
21
+ propOnChange: props.onPaginationMetaChange,
22
+ stateSelector: _gridPaginationSelector.gridPaginationMetaSelector,
23
+ changeEvent: 'paginationMetaChange'
24
+ });
25
+
26
+ /**
27
+ * API METHODS
28
+ */
29
+ const setPaginationMeta = React.useCallback(newPaginationMeta => {
30
+ if (paginationMeta === newPaginationMeta) {
31
+ return;
32
+ }
33
+ logger.debug("Setting 'paginationMeta' to", newPaginationMeta);
34
+ apiRef.current.setState(state => (0, _extends2.default)({}, state, {
35
+ pagination: (0, _extends2.default)({}, state.pagination, {
36
+ meta: newPaginationMeta
37
+ })
38
+ }));
39
+ }, [apiRef, logger, paginationMeta]);
40
+ const paginationMetaApi = {
41
+ setPaginationMeta
42
+ };
43
+ (0, _utils.useGridApiMethod)(apiRef, paginationMetaApi, 'public');
44
+
45
+ /**
46
+ * PRE-PROCESSING
47
+ */
48
+ const stateExportPreProcessing = React.useCallback((prevState, context) => {
49
+ const exportedPaginationMeta = (0, _gridPaginationSelector.gridPaginationMetaSelector)(apiRef);
50
+ const shouldExportRowCount =
51
+ // Always export if the `exportOnlyDirtyModels` property is not activated
52
+ !context.exportOnlyDirtyModels ||
53
+ // Always export if the `paginationMeta` is controlled
54
+ props.paginationMeta != null ||
55
+ // Always export if the `paginationMeta` has been initialized
56
+ props.initialState?.pagination?.meta != null;
57
+ if (!shouldExportRowCount) {
58
+ return prevState;
59
+ }
60
+ return (0, _extends2.default)({}, prevState, {
61
+ pagination: (0, _extends2.default)({}, prevState.pagination, {
62
+ meta: exportedPaginationMeta
63
+ })
64
+ });
65
+ }, [apiRef, props.paginationMeta, props.initialState?.pagination?.meta]);
66
+ const stateRestorePreProcessing = React.useCallback((params, context) => {
67
+ const restoredPaginationMeta = context.stateToRestore.pagination?.meta ? context.stateToRestore.pagination.meta : (0, _gridPaginationSelector.gridPaginationMetaSelector)(apiRef);
68
+ apiRef.current.setState(state => (0, _extends2.default)({}, state, {
69
+ pagination: (0, _extends2.default)({}, state.pagination, {
70
+ meta: restoredPaginationMeta
71
+ })
72
+ }));
73
+ return params;
74
+ }, [apiRef]);
75
+ (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing);
76
+ (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'restoreState', stateRestorePreProcessing);
77
+
78
+ /**
79
+ * EFFECTS
80
+ */
81
+ React.useEffect(() => {
82
+ if (props.paginationMeta) {
83
+ apiRef.current.setPaginationMeta(props.paginationMeta);
84
+ }
85
+ }, [apiRef, props.paginationMeta]);
86
+ };
87
+ exports.useGridPaginationMeta = useGridPaginationMeta;
@@ -18,7 +18,8 @@ const getDerivedPaginationModel = (paginationState, signature, paginationModelPr
18
18
  let paginationModel = paginationState.paginationModel;
19
19
  const rowCount = paginationState.rowCount;
20
20
  const pageSize = paginationModelProp?.pageSize ?? paginationModel.pageSize;
21
- const pageCount = (0, _gridPaginationUtils.getPageCount)(rowCount, pageSize);
21
+ const page = paginationModelProp?.page ?? paginationModel.page;
22
+ const pageCount = (0, _gridPaginationUtils.getPageCount)(rowCount, pageSize, page);
22
23
  if (paginationModelProp && (paginationModelProp?.page !== paginationModel.page || paginationModelProp?.pageSize !== paginationModel.pageSize)) {
23
24
  paginationModel = paginationModelProp;
24
25
  }