@mui/x-data-grid-pro 5.11.1 → 5.12.2

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 (147) hide show
  1. package/CHANGELOG.md +199 -20
  2. package/DataGridPro/DataGridPro.js +26 -27
  3. package/DataGridPro/useDataGridProComponent.js +1 -8
  4. package/DataGridPro/useDataGridProProps.js +6 -27
  5. package/README.md +2 -2
  6. package/components/DataGridProColumnHeaders.js +10 -7
  7. package/components/DataGridProVirtualScroller.d.ts +1 -1
  8. package/components/DataGridProVirtualScroller.js +6 -3
  9. package/components/GridRowReorderCell.js +6 -6
  10. package/hooks/features/columnPinning/gridColumnPinningInterface.d.ts +6 -0
  11. package/hooks/features/columnPinning/useGridColumnPinning.d.ts +1 -1
  12. package/hooks/features/columnPinning/useGridColumnPinning.js +73 -28
  13. package/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +67 -4
  14. package/hooks/features/columnResize/useGridColumnResize.js +32 -15
  15. package/hooks/features/detailPanel/gridDetailPanelToggleColDef.js +2 -2
  16. package/hooks/features/detailPanel/useGridDetailPanel.d.ts +1 -1
  17. package/hooks/features/detailPanel/useGridDetailPanel.js +78 -18
  18. package/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +5 -2
  19. package/hooks/features/rowReorder/useGridRowReorder.js +5 -1
  20. package/hooks/features/rowReorder/useGridRowReorderPreProcessors.d.ts +2 -2
  21. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -2
  22. package/index.d.ts +0 -2
  23. package/index.js +2 -5
  24. package/internals/index.d.ts +0 -1
  25. package/internals/index.js +0 -1
  26. package/legacy/DataGridPro/DataGridPro.js +26 -27
  27. package/legacy/DataGridPro/useDataGridProComponent.js +1 -8
  28. package/legacy/DataGridPro/useDataGridProProps.js +1 -20
  29. package/legacy/components/DataGridProColumnHeaders.js +10 -7
  30. package/legacy/components/DataGridProVirtualScroller.js +6 -3
  31. package/legacy/components/GridRowReorderCell.js +8 -6
  32. package/legacy/hooks/features/columnPinning/useGridColumnPinning.js +82 -33
  33. package/legacy/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +70 -5
  34. package/legacy/hooks/features/columnResize/useGridColumnResize.js +32 -15
  35. package/legacy/hooks/features/detailPanel/gridDetailPanelToggleColDef.js +3 -1
  36. package/legacy/hooks/features/detailPanel/useGridDetailPanel.js +78 -18
  37. package/legacy/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +5 -2
  38. package/legacy/hooks/features/rowReorder/useGridRowReorder.js +5 -1
  39. package/legacy/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -2
  40. package/legacy/index.js +2 -5
  41. package/legacy/internals/index.js +0 -1
  42. package/legacy/utils/releaseInfo.js +1 -1
  43. package/models/dataGridProProps.d.ts +0 -26
  44. package/models/gridApiPro.d.ts +1 -2
  45. package/models/gridStatePro.d.ts +0 -3
  46. package/modern/DataGridPro/DataGridPro.js +26 -27
  47. package/modern/DataGridPro/useDataGridProComponent.js +1 -8
  48. package/modern/DataGridPro/useDataGridProProps.js +1 -16
  49. package/modern/components/DataGridProColumnHeaders.js +11 -6
  50. package/modern/components/DataGridProVirtualScroller.js +6 -3
  51. package/modern/components/GridRowReorderCell.js +6 -6
  52. package/modern/hooks/features/columnPinning/useGridColumnPinning.js +73 -28
  53. package/modern/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +67 -4
  54. package/modern/hooks/features/columnResize/useGridColumnResize.js +32 -15
  55. package/modern/hooks/features/detailPanel/gridDetailPanelToggleColDef.js +2 -2
  56. package/modern/hooks/features/detailPanel/useGridDetailPanel.js +76 -16
  57. package/modern/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +5 -2
  58. package/modern/hooks/features/rowReorder/useGridRowReorder.js +5 -1
  59. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -2
  60. package/modern/index.js +2 -5
  61. package/modern/internals/index.js +0 -1
  62. package/modern/utils/releaseInfo.js +1 -1
  63. package/node/DataGridPro/DataGridPro.js +26 -27
  64. package/node/DataGridPro/useDataGridProComponent.js +1 -11
  65. package/node/DataGridPro/useDataGridProProps.js +6 -28
  66. package/node/components/DataGridProColumnHeaders.js +11 -7
  67. package/node/components/DataGridProVirtualScroller.js +6 -3
  68. package/node/components/GridRowReorderCell.js +6 -6
  69. package/node/hooks/features/columnPinning/useGridColumnPinning.js +72 -24
  70. package/node/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +68 -5
  71. package/node/hooks/features/columnResize/useGridColumnResize.js +32 -14
  72. package/node/hooks/features/detailPanel/gridDetailPanelToggleColDef.js +2 -2
  73. package/node/hooks/features/detailPanel/useGridDetailPanel.js +76 -17
  74. package/node/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +8 -2
  75. package/node/hooks/features/rowReorder/useGridRowReorder.js +5 -1
  76. package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -1
  77. package/node/index.js +2 -30
  78. package/node/internals/index.js +0 -9
  79. package/node/utils/releaseInfo.js +1 -1
  80. package/package.json +8 -7
  81. package/typeOverloads/modules.d.ts +9 -21
  82. package/utils/releaseInfo.js +1 -1
  83. package/components/GridGroupingColumnLeafCell.d.ts +0 -4
  84. package/components/GridGroupingColumnLeafCell.js +0 -22
  85. package/components/GridGroupingCriteriaCell.d.ts +0 -7
  86. package/components/GridGroupingCriteriaCell.js +0 -78
  87. package/components/GridRowGroupableColumnMenuItems.d.ts +0 -11
  88. package/components/GridRowGroupableColumnMenuItems.js +0 -63
  89. package/components/GridRowGroupingColumnMenuItems.d.ts +0 -11
  90. package/components/GridRowGroupingColumnMenuItems.js +0 -58
  91. package/hooks/features/detailPanel/useGridDetailPanelCache.d.ts +0 -4
  92. package/hooks/features/detailPanel/useGridDetailPanelCache.js +0 -57
  93. package/hooks/features/rowGrouping/createGroupingColDef.d.ts +0 -43
  94. package/hooks/features/rowGrouping/createGroupingColDef.js +0 -318
  95. package/hooks/features/rowGrouping/gridRowGroupingInterfaces.d.ts +0 -37
  96. package/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +0 -1
  97. package/hooks/features/rowGrouping/gridRowGroupingSelector.d.ts +0 -4
  98. package/hooks/features/rowGrouping/gridRowGroupingSelector.js +0 -5
  99. package/hooks/features/rowGrouping/gridRowGroupingUtils.d.ts +0 -27
  100. package/hooks/features/rowGrouping/gridRowGroupingUtils.js +0 -139
  101. package/hooks/features/rowGrouping/index.d.ts +0 -3
  102. package/hooks/features/rowGrouping/index.js +0 -3
  103. package/hooks/features/rowGrouping/useGridRowGrouping.d.ts +0 -11
  104. package/hooks/features/rowGrouping/useGridRowGrouping.js +0 -200
  105. package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.d.ts +0 -4
  106. package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +0 -203
  107. package/legacy/components/GridGroupingColumnLeafCell.js +0 -20
  108. package/legacy/components/GridGroupingCriteriaCell.js +0 -74
  109. package/legacy/components/GridRowGroupableColumnMenuItems.js +0 -61
  110. package/legacy/components/GridRowGroupingColumnMenuItems.js +0 -56
  111. package/legacy/hooks/features/detailPanel/useGridDetailPanelCache.js +0 -57
  112. package/legacy/hooks/features/rowGrouping/createGroupingColDef.js +0 -319
  113. package/legacy/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +0 -1
  114. package/legacy/hooks/features/rowGrouping/gridRowGroupingSelector.js +0 -13
  115. package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +0 -147
  116. package/legacy/hooks/features/rowGrouping/index.js +0 -3
  117. package/legacy/hooks/features/rowGrouping/useGridRowGrouping.js +0 -206
  118. package/legacy/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +0 -217
  119. package/legacy/models/gridGroupingValueGetterParams.js +0 -1
  120. package/models/gridGroupingValueGetterParams.d.ts +0 -31
  121. package/models/gridGroupingValueGetterParams.js +0 -1
  122. package/modern/components/GridGroupingColumnLeafCell.js +0 -20
  123. package/modern/components/GridGroupingCriteriaCell.js +0 -76
  124. package/modern/components/GridRowGroupableColumnMenuItems.js +0 -61
  125. package/modern/components/GridRowGroupingColumnMenuItems.js +0 -56
  126. package/modern/hooks/features/detailPanel/useGridDetailPanelCache.js +0 -57
  127. package/modern/hooks/features/rowGrouping/createGroupingColDef.js +0 -302
  128. package/modern/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +0 -1
  129. package/modern/hooks/features/rowGrouping/gridRowGroupingSelector.js +0 -5
  130. package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +0 -137
  131. package/modern/hooks/features/rowGrouping/index.js +0 -3
  132. package/modern/hooks/features/rowGrouping/useGridRowGrouping.js +0 -192
  133. package/modern/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +0 -203
  134. package/modern/models/gridGroupingValueGetterParams.js +0 -1
  135. package/node/components/GridGroupingColumnLeafCell.js +0 -38
  136. package/node/components/GridGroupingCriteriaCell.js +0 -99
  137. package/node/components/GridRowGroupableColumnMenuItems.js +0 -82
  138. package/node/components/GridRowGroupingColumnMenuItems.js +0 -78
  139. package/node/hooks/features/detailPanel/useGridDetailPanelCache.js +0 -74
  140. package/node/hooks/features/rowGrouping/createGroupingColDef.js +0 -341
  141. package/node/hooks/features/rowGrouping/gridRowGroupingInterfaces.js +0 -5
  142. package/node/hooks/features/rowGrouping/gridRowGroupingSelector.js +0 -18
  143. package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +0 -172
  144. package/node/hooks/features/rowGrouping/index.js +0 -51
  145. package/node/hooks/features/rowGrouping/useGridRowGrouping.js +0 -228
  146. package/node/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +0 -227
  147. package/node/models/gridGroupingValueGetterParams.js +0 -5
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import MuiDivider from '@mui/material/Divider';
4
- import { useGridSelector, gridVisibleColumnDefinitionsSelector, gridColumnsTotalWidthSelector, gridColumnPositionsSelector, gridVisibleColumnFieldsSelector, gridClasses, useGridApiMethod, useGridApiEventHandler } from '@mui/x-data-grid';
4
+ import { useGridSelector, gridVisibleColumnDefinitionsSelector, gridColumnsTotalWidthSelector, gridColumnPositionsSelector, gridVisibleColumnFieldsSelector, gridClasses, useGridApiMethod, useGridApiEventHandler, gridColumnFieldsSelector } from '@mui/x-data-grid';
5
5
  import { useGridRegisterPipeProcessor } from '@mui/x-data-grid/internals';
6
6
  import { GridColumnPinningMenuItems } from '../../../components/GridColumnPinningMenuItems';
7
7
  import { GridPinnedPosition } from './gridColumnPinningInterface';
@@ -13,9 +13,12 @@ const Divider = () => /*#__PURE__*/_jsx(MuiDivider, {
13
13
  onClick: event => event.stopPropagation()
14
14
  });
15
15
 
16
- export const columnPinningStateInitializer = (state, props) => {
16
+ export const columnPinningStateInitializer = (state, props, apiRef) => {
17
17
  var _props$initialState;
18
18
 
19
+ apiRef.current.unstable_caches.columnPinning = {
20
+ orderedFieldsBeforePinningColumns: null
21
+ };
19
22
  let model;
20
23
 
21
24
  if (props.disableColumnPinning) {
@@ -186,7 +189,7 @@ export const useGridColumnPinning = (apiRef, props) => {
186
189
  useGridRegisterPipeProcessor(apiRef, 'canBeReordered', checkIfCanBeReordered);
187
190
  useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
188
191
  useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
189
- apiRef.current.unstable_updateControlState({
192
+ apiRef.current.unstable_registerControlState({
190
193
  stateId: 'pinnedColumns',
191
194
  propModel: props.pinnedColumns,
192
195
  propOnChange: props.onPinnedColumnsChange,
@@ -205,34 +208,20 @@ export const useGridColumnPinning = (apiRef, props) => {
205
208
  return;
206
209
  }
207
210
 
208
- apiRef.current.setState(state => {
209
- const otherSide = side === GridPinnedPosition.right ? GridPinnedPosition.left : GridPinnedPosition.right;
210
-
211
- const newPinnedColumns = _extends({}, state.pinnedColumns, {
212
- [side]: [...(state.pinnedColumns[side] || []), field],
213
- [otherSide]: (state.pinnedColumns[otherSide] || []).filter(column => column !== field)
214
- });
215
-
216
- return _extends({}, state, {
217
- pinnedColumns: newPinnedColumns
218
- });
219
- });
220
- apiRef.current.forceUpdate();
221
- }, [apiRef, checkIfEnabled]);
211
+ const otherSide = side === GridPinnedPosition.right ? GridPinnedPosition.left : GridPinnedPosition.right;
212
+ const newPinnedColumns = {
213
+ [side]: [...(pinnedColumns[side] || []), field],
214
+ [otherSide]: (pinnedColumns[otherSide] || []).filter(column => column !== field)
215
+ };
216
+ apiRef.current.setPinnedColumns(newPinnedColumns);
217
+ }, [apiRef, checkIfEnabled, pinnedColumns]);
222
218
  const unpinColumn = React.useCallback(field => {
223
219
  checkIfEnabled('unpinColumn');
224
- apiRef.current.setState(state => {
225
- const newPinnedColumns = _extends({}, state.pinnedColumns, {
226
- left: (state.pinnedColumns.left || []).filter(column => column !== field),
227
- right: (state.pinnedColumns.right || []).filter(column => column !== field)
228
- });
229
-
230
- return _extends({}, state, {
231
- pinnedColumns: newPinnedColumns
232
- });
220
+ apiRef.current.setPinnedColumns({
221
+ left: (pinnedColumns.left || []).filter(column => column !== field),
222
+ right: (pinnedColumns.right || []).filter(column => column !== field)
233
223
  });
234
- apiRef.current.forceUpdate();
235
- }, [apiRef, checkIfEnabled]);
224
+ }, [apiRef, checkIfEnabled, pinnedColumns.left, pinnedColumns.right]);
236
225
  const getPinnedColumns = React.useCallback(() => {
237
226
  checkIfEnabled('getPinnedColumns');
238
227
  return gridPinnedColumnsSelector(apiRef.current.state);
@@ -266,6 +255,62 @@ export const useGridColumnPinning = (apiRef, props) => {
266
255
  isColumnPinned
267
256
  };
268
257
  useGridApiMethod(apiRef, columnPinningApi, 'columnPinningApi');
258
+ const handleColumnOrderChange = React.useCallback(params => {
259
+ if (!apiRef.current.unstable_caches.columnPinning.orderedFieldsBeforePinningColumns) {
260
+ return;
261
+ }
262
+
263
+ const {
264
+ field,
265
+ targetIndex,
266
+ oldIndex
267
+ } = params;
268
+ const delta = targetIndex > oldIndex ? 1 : -1;
269
+ const latestColumnFields = gridColumnFieldsSelector(apiRef);
270
+ /**
271
+ * When a column X is reordered to somewhere else, the position where this column X is dropped
272
+ * on must be moved to left or right to make room for it. The ^^^ below represents the column
273
+ * which gave space to receive X.
274
+ *
275
+ * | X | B | C | D | -> | B | C | D | X | (e.g. X moved to after D, so delta=1)
276
+ * ^^^ ^^^
277
+ *
278
+ * | A | B | C | X | -> | X | A | B | C | (e.g. X moved before A, so delta=-1)
279
+ * ^^^ ^^^
280
+ *
281
+ * If column P is pinned, it will not move to provide space. However, it will jump to the next
282
+ * non-pinned column.
283
+ *
284
+ * | X | B | P | D | -> | B | D | P | X | (e.g. X moved to after D, with P pinned)
285
+ * ^^^ ^^^
286
+ */
287
+
288
+ const siblingField = latestColumnFields[targetIndex - delta];
289
+ const newOrderedFieldsBeforePinningColumns = [...apiRef.current.unstable_caches.columnPinning.orderedFieldsBeforePinningColumns]; // The index to start swapping fields
290
+
291
+ let i = newOrderedFieldsBeforePinningColumns.findIndex(column => column === field); // The index of the field to swap with
292
+
293
+ let j = i + delta; // When to stop swapping fields.
294
+ // We stop one field before because the swap is done with i + 1 (if delta=1)
295
+
296
+ const stop = newOrderedFieldsBeforePinningColumns.findIndex(column => column === siblingField);
297
+
298
+ while (delta > 0 ? i < stop : i > stop) {
299
+ // If the field to swap with is a pinned column, jump to the next
300
+ while (apiRef.current.isColumnPinned(newOrderedFieldsBeforePinningColumns[j])) {
301
+ j += delta;
302
+ }
303
+
304
+ const temp = newOrderedFieldsBeforePinningColumns[i];
305
+ newOrderedFieldsBeforePinningColumns[i] = newOrderedFieldsBeforePinningColumns[j];
306
+ newOrderedFieldsBeforePinningColumns[j] = temp;
307
+ i = j;
308
+ j = i + delta;
309
+ }
310
+
311
+ apiRef.current.unstable_caches.columnPinning.orderedFieldsBeforePinningColumns = newOrderedFieldsBeforePinningColumns;
312
+ }, [apiRef]);
313
+ useGridApiEventHandler(apiRef, 'columnOrderChange', handleColumnOrderChange);
269
314
  React.useEffect(() => {
270
315
  if (props.pinnedColumns) {
271
316
  apiRef.current.setPinnedColumns(props.pinnedColumns);
@@ -23,23 +23,86 @@ export const useGridColumnPinningPreProcessors = (apiRef, props) => {
23
23
  pinnedColumns = gridPinnedColumnsSelector(initializedState);
24
24
  }
25
25
 
26
+ const prevAllPinnedColumns = React.useRef();
26
27
  const reorderPinnedColumns = React.useCallback(columnsState => {
27
28
  if (columnsState.all.length === 0 || disableColumnPinning) {
28
29
  return columnsState;
29
30
  }
30
31
 
31
32
  const [leftPinnedColumns, rightPinnedColumns] = filterColumns(pinnedColumns, columnsState.all);
33
+ let newOrderedFields;
34
+ const allPinnedColumns = [...leftPinnedColumns, ...rightPinnedColumns];
35
+ const {
36
+ orderedFieldsBeforePinningColumns
37
+ } = apiRef.current.unstable_caches.columnPinning;
32
38
 
33
- if (leftPinnedColumns.length === 0 && rightPinnedColumns.length === 0) {
34
- return columnsState;
39
+ if (orderedFieldsBeforePinningColumns) {
40
+ newOrderedFields = new Array(columnsState.all.length).fill(null);
41
+ const newOrderedFieldsBeforePinningColumns = [...newOrderedFields]; // Contains the fields not added to the orderedFields array yet
42
+
43
+ const remainingFields = [...columnsState.all]; // First, we check if the column was unpinned since the last processing.
44
+ // If yes and it still exists, we move it back to the same position it was before pinning
45
+
46
+ prevAllPinnedColumns.current.forEach(field => {
47
+ if (!allPinnedColumns.includes(field) && columnsState.lookup[field]) {
48
+ // Get the position before pinning
49
+ const index = orderedFieldsBeforePinningColumns.indexOf(field);
50
+ newOrderedFields[index] = field;
51
+ newOrderedFieldsBeforePinningColumns[index] = field; // This field was already consumed so we prevent from being added again
52
+
53
+ remainingFields.splice(remainingFields.indexOf(field), 1);
54
+ }
55
+ }); // For columns still pinned, we keep stored their original positions
56
+
57
+ allPinnedColumns.forEach(field => {
58
+ let index = orderedFieldsBeforePinningColumns.indexOf(field); // If index = -1, the pinned field didn't exist in the last processing, it's possibly being added now
59
+ // If index >= newOrderedFieldsBeforePinningColumns.length, then one or more columns were removed
60
+ // In both cases, use the position from the columns array
61
+ // TODO: detect removed columns and decrease the positions after it
62
+
63
+ if (index === -1 || index >= newOrderedFieldsBeforePinningColumns.length) {
64
+ index = columnsState.all.indexOf(field);
65
+ } // The fallback above may make the column to be inserted in a position already occupied
66
+ // In this case, put it in any empty slot available
67
+
68
+
69
+ if (newOrderedFieldsBeforePinningColumns[index] !== null) {
70
+ index = 0;
71
+
72
+ while (newOrderedFieldsBeforePinningColumns[index] !== null) {
73
+ index += 1;
74
+ }
75
+ }
76
+
77
+ newOrderedFields[index] = field;
78
+ newOrderedFieldsBeforePinningColumns[index] = field; // This field was already consumed so we prevent from being added again
79
+
80
+ remainingFields.splice(remainingFields.indexOf(field), 1);
81
+ }); // The fields remaining are those that're neither pinnned nor were unpinned
82
+ // For these, we spread them across both arrays making sure to not override existing values
83
+
84
+ let i = 0;
85
+ remainingFields.forEach(field => {
86
+ while (newOrderedFieldsBeforePinningColumns[i] !== null) {
87
+ i += 1;
88
+ }
89
+
90
+ newOrderedFieldsBeforePinningColumns[i] = field;
91
+ newOrderedFields[i] = field;
92
+ });
93
+ apiRef.current.unstable_caches.columnPinning.orderedFieldsBeforePinningColumns = newOrderedFieldsBeforePinningColumns;
94
+ } else {
95
+ newOrderedFields = [...columnsState.all];
96
+ apiRef.current.unstable_caches.columnPinning.orderedFieldsBeforePinningColumns = [...columnsState.all];
35
97
  }
36
98
 
37
- const centerColumns = columnsState.all.filter(field => {
99
+ prevAllPinnedColumns.current = allPinnedColumns;
100
+ const centerColumns = newOrderedFields.filter(field => {
38
101
  return !leftPinnedColumns.includes(field) && !rightPinnedColumns.includes(field);
39
102
  });
40
103
  return _extends({}, columnsState, {
41
104
  all: [...leftPinnedColumns, ...centerColumns, ...rightPinnedColumns]
42
105
  });
43
- }, [disableColumnPinning, pinnedColumns]);
106
+ }, [apiRef, disableColumnPinning, pinnedColumns]);
44
107
  useGridRegisterPipeProcessor(apiRef, 'hydrateColumns', reorderPinnedColumns);
45
108
  };
@@ -1,8 +1,9 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { ownerDocument, useEventCallback } from '@mui/material/utils';
4
- import { gridClasses, GridColumnHeaderSeparatorSides, useGridApiEventHandler, useGridApiOptionHandler, useGridNativeEventListener, useGridLogger } from '@mui/x-data-grid';
4
+ import { gridClasses, useGridApiEventHandler, useGridApiOptionHandler, useGridNativeEventListener, useGridLogger } from '@mui/x-data-grid';
5
5
  import { clamp, findParentElementFromClassName } from '@mui/x-data-grid/internals';
6
+ import { useTheme } from '@mui/material/styles';
6
7
  import { findGridCellElementsFromCol, getFieldFromHeaderElem, findHeaderElementFromField } from '../../../utils/domUtils';
7
8
  // TODO: remove support for Safari < 13.
8
9
  // https://caniuse.com/#search=touch-action
@@ -50,10 +51,10 @@ function trackFinger(event, currentTouchId) {
50
51
  };
51
52
  }
52
53
 
53
- function computeNewWidth(initialOffsetToSeparator, clickX, columnBounds, separatorSide) {
54
+ function computeNewWidth(initialOffsetToSeparator, clickX, columnBounds, resizeDirection) {
54
55
  let newWidth = initialOffsetToSeparator;
55
56
 
56
- if (separatorSide === GridColumnHeaderSeparatorSides.Right) {
57
+ if (resizeDirection === 'Right') {
57
58
  newWidth += clickX - columnBounds.left;
58
59
  } else {
59
60
  newWidth += columnBounds.right - clickX;
@@ -62,16 +63,31 @@ function computeNewWidth(initialOffsetToSeparator, clickX, columnBounds, separat
62
63
  return newWidth;
63
64
  }
64
65
 
65
- function computeOffsetToSeparator(clickX, columnBounds, separatorSide) {
66
- if (separatorSide === GridColumnHeaderSeparatorSides.Left) {
66
+ function computeOffsetToSeparator(clickX, columnBounds, resizeDirection) {
67
+ if (resizeDirection === 'Left') {
67
68
  return clickX - columnBounds.left;
68
69
  }
69
70
 
70
71
  return columnBounds.right - clickX;
71
72
  }
72
73
 
73
- function getSeparatorSide(element) {
74
- return element.classList.contains(gridClasses['columnSeparator--sideRight']) ? GridColumnHeaderSeparatorSides.Right : GridColumnHeaderSeparatorSides.Left;
74
+ function flipResizeDirection(side) {
75
+ if (side === 'Right') {
76
+ return 'Left';
77
+ }
78
+
79
+ return 'Right';
80
+ }
81
+
82
+ function getResizeDirection(element, direction) {
83
+ const side = element.classList.contains(gridClasses['columnSeparator--sideRight']) ? 'Right' : 'Left';
84
+
85
+ if (direction === 'rtl') {
86
+ // Resizing logic should be mirrored in the RTL case
87
+ return flipResizeDirection(side);
88
+ }
89
+
90
+ return side;
75
91
  }
76
92
 
77
93
  export const columnResizeStateInitializer = state => _extends({}, state, {
@@ -88,12 +104,13 @@ export const useGridColumnResize = (apiRef, props) => {
88
104
  const logger = useGridLogger(apiRef, 'useGridColumnResize');
89
105
  const colDefRef = React.useRef();
90
106
  const colElementRef = React.useRef();
91
- const colCellElementsRef = React.useRef(); // To improve accessibility, the separator has padding on both sides.
107
+ const colCellElementsRef = React.useRef();
108
+ const theme = useTheme(); // To improve accessibility, the separator has padding on both sides.
92
109
  // Clicking inside the padding area should be treated as a click in the separator.
93
110
  // This ref stores the offset between the click and the separator.
94
111
 
95
112
  const initialOffsetToSeparator = React.useRef();
96
- const separatorSide = React.useRef();
113
+ const resizeDirection = React.useRef();
97
114
  const stopResizeEventTimeout = React.useRef();
98
115
  const touchId = React.useRef();
99
116
 
@@ -152,7 +169,7 @@ export const useGridColumnResize = (apiRef, props) => {
152
169
  return;
153
170
  }
154
171
 
155
- let newWidth = computeNewWidth(initialOffsetToSeparator.current, nativeEvent.clientX, colElementRef.current.getBoundingClientRect(), separatorSide.current);
172
+ let newWidth = computeNewWidth(initialOffsetToSeparator.current, nativeEvent.clientX, colElementRef.current.getBoundingClientRect(), resizeDirection.current);
156
173
  newWidth = clamp(newWidth, colDefRef.current.minWidth, colDefRef.current.maxWidth);
157
174
  updateWidth(newWidth);
158
175
  const params = {
@@ -188,8 +205,8 @@ export const useGridColumnResize = (apiRef, props) => {
188
205
  colCellElementsRef.current = findGridCellElementsFromCol(colElementRef.current, apiRef.current);
189
206
  const doc = ownerDocument(apiRef.current.rootElementRef.current);
190
207
  doc.body.style.cursor = 'col-resize';
191
- separatorSide.current = getSeparatorSide(event.currentTarget);
192
- initialOffsetToSeparator.current = computeOffsetToSeparator(event.clientX, colElementRef.current.getBoundingClientRect(), separatorSide.current);
208
+ resizeDirection.current = getResizeDirection(event.currentTarget, theme.direction);
209
+ initialOffsetToSeparator.current = computeOffsetToSeparator(event.clientX, colElementRef.current.getBoundingClientRect(), resizeDirection.current);
193
210
  doc.addEventListener('mousemove', handleResizeMouseMove);
194
211
  doc.addEventListener('mouseup', handleResizeMouseUp);
195
212
  });
@@ -222,7 +239,7 @@ export const useGridColumnResize = (apiRef, props) => {
222
239
  return;
223
240
  }
224
241
 
225
- let newWidth = computeNewWidth(initialOffsetToSeparator.current, finger.x, colElementRef.current.getBoundingClientRect(), separatorSide.current);
242
+ let newWidth = computeNewWidth(initialOffsetToSeparator.current, finger.x, colElementRef.current.getBoundingClientRect(), resizeDirection.current);
226
243
  newWidth = clamp(newWidth, colDefRef.current.minWidth, colDefRef.current.maxWidth);
227
244
  updateWidth(newWidth);
228
245
  const params = {
@@ -263,8 +280,8 @@ export const useGridColumnResize = (apiRef, props) => {
263
280
  colDefRef.current = colDef;
264
281
  colElementRef.current = findHeaderElementFromField((_apiRef$current$colum2 = apiRef.current.columnHeadersElementRef) == null ? void 0 : _apiRef$current$colum2.current, colDef.field);
265
282
  colCellElementsRef.current = findGridCellElementsFromCol(colElementRef.current, apiRef.current);
266
- separatorSide.current = getSeparatorSide(event.target);
267
- initialOffsetToSeparator.current = computeOffsetToSeparator(touch.clientX, colElementRef.current.getBoundingClientRect(), separatorSide.current);
283
+ resizeDirection.current = getResizeDirection(event.target, theme.direction);
284
+ initialOffsetToSeparator.current = computeOffsetToSeparator(touch.clientX, colElementRef.current.getBoundingClientRect(), resizeDirection.current);
268
285
  const doc = ownerDocument(event.currentTarget);
269
286
  doc.addEventListener('touchmove', handleTouchMove);
270
287
  doc.addEventListener('touchend', handleTouchEnd);
@@ -7,7 +7,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
7
7
  export const GRID_DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';
8
8
  export const GRID_DETAIL_PANEL_TOGGLE_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
9
9
  field: GRID_DETAIL_PANEL_TOGGLE_FIELD,
10
- headerName: '',
11
10
  type: 'detailPanelToggle',
12
11
  editable: false,
13
12
  sortable: false,
@@ -22,5 +21,6 @@ export const GRID_DETAIL_PANEL_TOGGLE_COL_DEF = _extends({}, GRID_STRING_COL_DEF
22
21
  const expandedRowIds = gridDetailPanelExpandedRowIdsSelector(params.api.state);
23
22
  return expandedRowIds.includes(params.id);
24
23
  },
25
- renderCell: params => /*#__PURE__*/_jsx(GridDetailPanelToggleCell, _extends({}, params))
24
+ renderCell: params => /*#__PURE__*/_jsx(GridDetailPanelToggleCell, _extends({}, params)),
25
+ renderHeader: () => null
26
26
  });
@@ -3,4 +3,4 @@ import { GridStateInitializer } from '@mui/x-data-grid/internals';
3
3
  import { GridApiPro } from '../../../models/gridApiPro';
4
4
  import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
5
5
  export declare const detailPanelStateInitializer: GridStateInitializer<Pick<DataGridProProcessedProps, 'initialState' | 'detailPanelExpandedRowIds'>>;
6
- export declare const useGridDetailPanel: (apiRef: React.MutableRefObject<GridApiPro>, props: Pick<DataGridProProcessedProps, 'initialState' | 'getDetailPanelContent' | 'getDetailPanelHeight' | 'detailPanelExpandedRowIds' | 'onDetailPanelExpandedRowIdsChange' | 'pagination' | 'paginationMode'>) => void;
6
+ export declare const useGridDetailPanel: (apiRef: React.MutableRefObject<GridApiPro>, props: Pick<DataGridProProcessedProps, 'getDetailPanelContent' | 'getDetailPanelHeight' | 'detailPanelExpandedRowIds' | 'onDetailPanelExpandedRowIdsChange'>) => void;
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { useGridSelector, useGridApiEventHandler, useGridApiMethod } from '@mui/x-data-grid';
3
+ import { useGridSelector, useGridApiEventHandler, useGridApiMethod, gridRowIdsSelector } from '@mui/x-data-grid';
4
4
  import { useGridRegisterPipeProcessor } from '@mui/x-data-grid/internals';
5
5
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from './gridDetailPanelToggleColDef';
6
6
  import { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector } from './gridDetailPanelSelector';
@@ -13,6 +13,35 @@ export const detailPanelStateInitializer = (state, props) => {
13
13
  }
14
14
  });
15
15
  };
16
+
17
+ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight) {
18
+ if (typeof getDetailPanelContent !== 'function') {
19
+ return {};
20
+ } // TODO change to lazy approach using a Proxy
21
+ // only call getDetailPanelContent when asked for an id
22
+
23
+
24
+ const rowIds = gridRowIdsSelector(apiRef);
25
+ const contentCache = rowIds.reduce((acc, id) => {
26
+ const params = apiRef.current.getRowParams(id);
27
+ acc[id] = getDetailPanelContent(params);
28
+ return acc;
29
+ }, {});
30
+ const heightCache = rowIds.reduce((acc, id) => {
31
+ if (contentCache[id] == null) {
32
+ return acc;
33
+ }
34
+
35
+ const params = apiRef.current.getRowParams(id);
36
+ acc[id] = getDetailPanelHeight(params);
37
+ return acc;
38
+ }, {});
39
+ return {
40
+ contentCache,
41
+ heightCache
42
+ };
43
+ }
44
+
16
45
  export const useGridDetailPanel = (apiRef, props) => {
17
46
  const expandedRowIds = useGridSelector(apiRef, gridDetailPanelExpandedRowIdsSelector);
18
47
  const contentCache = useGridSelector(apiRef, gridDetailPanelExpandedRowsContentCacheSelector);
@@ -51,23 +80,7 @@ export const useGridDetailPanel = (apiRef, props) => {
51
80
  }, [apiRef, props.getDetailPanelContent]);
52
81
  useGridApiEventHandler(apiRef, 'cellClick', handleCellClick);
53
82
  useGridApiEventHandler(apiRef, 'cellKeyDown', handleCellKeyDown);
54
- const addDetailHeight = React.useCallback((initialValue, row) => {
55
- var _heightCache$row$id;
56
-
57
- if (expandedRowIds.length === 0 || !expandedRowIds.includes(row.id)) {
58
- return _extends({}, initialValue, {
59
- detail: 0
60
- });
61
- }
62
-
63
- const heightCache = gridDetailPanelExpandedRowsHeightCacheSelector(apiRef.current.state);
64
- return _extends({}, initialValue, {
65
- detail: (_heightCache$row$id = heightCache[row.id]) != null ? _heightCache$row$id : 0 // Fallback to zero because the cache might not be ready yet (e.g. page was changed)
66
-
67
- });
68
- }, [apiRef, expandedRowIds]);
69
- useGridRegisterPipeProcessor(apiRef, 'rowHeight', addDetailHeight);
70
- apiRef.current.unstable_updateControlState({
83
+ apiRef.current.unstable_registerControlState({
71
84
  stateId: 'detailPanels',
72
85
  propModel: props.detailPanelExpandedRowIds,
73
86
  propOnChange: props.onDetailPanelExpandedRowIdsChange,
@@ -114,4 +127,51 @@ export const useGridDetailPanel = (apiRef, props) => {
114
127
  }
115
128
  }
116
129
  }, [apiRef, props.detailPanelExpandedRowIds]);
130
+ const updateCachesAndForceUpdate = React.useCallback(() => {
131
+ apiRef.current.setState(state => {
132
+ return _extends({}, state, {
133
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight))
134
+ });
135
+ });
136
+ apiRef.current.forceUpdate();
137
+ }, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]);
138
+ useGridApiEventHandler(apiRef, 'sortedRowsSet', updateCachesAndForceUpdate);
139
+ const previousGetDetailPanelContentProp = React.useRef();
140
+ const previousGetDetailPanelHeightProp = React.useRef();
141
+ const updateCachesIfNeeded = React.useCallback(() => {
142
+ if (props.getDetailPanelContent === previousGetDetailPanelContentProp.current && props.getDetailPanelHeight === previousGetDetailPanelHeightProp.current) {
143
+ return;
144
+ }
145
+
146
+ apiRef.current.setState(state => {
147
+ return _extends({}, state, {
148
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight))
149
+ });
150
+ });
151
+ previousGetDetailPanelContentProp.current = props.getDetailPanelContent;
152
+ previousGetDetailPanelHeightProp.current = props.getDetailPanelHeight;
153
+ }, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]);
154
+ const addDetailHeight = React.useCallback((initialValue, row) => {
155
+ var _heightCache$row$id;
156
+
157
+ if (!expandedRowIds || expandedRowIds.length === 0 || !expandedRowIds.includes(row.id)) {
158
+ return _extends({}, initialValue, {
159
+ detail: 0
160
+ });
161
+ }
162
+
163
+ updateCachesIfNeeded();
164
+ const heightCache = gridDetailPanelExpandedRowsHeightCacheSelector(apiRef.current.state);
165
+ return _extends({}, initialValue, {
166
+ detail: (_heightCache$row$id = heightCache[row.id]) != null ? _heightCache$row$id : 0 // Fallback to zero because the cache might not be ready yet (e.g. page was changed)
167
+
168
+ });
169
+ }, [apiRef, expandedRowIds, updateCachesIfNeeded]);
170
+ useGridRegisterPipeProcessor(apiRef, 'rowHeight', addDetailHeight);
171
+ const isFirstRender = React.useRef(true);
172
+
173
+ if (isFirstRender.current) {
174
+ isFirstRender.current = false;
175
+ updateCachesIfNeeded();
176
+ }
117
177
  };
@@ -1,3 +1,4 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
1
2
  import * as React from 'react';
2
3
  import { useGridRegisterPipeProcessor } from '@mui/x-data-grid/internals';
3
4
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD, GRID_DETAIL_PANEL_TOGGLE_COL_DEF } from './gridDetailPanelToggleColDef';
@@ -21,8 +22,10 @@ export const useGridDetailPanelPreProcessors = (apiRef, props) => {
21
22
 
22
23
 
23
24
  columnsState.all = [GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.all];
24
- columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = GRID_DETAIL_PANEL_TOGGLE_COL_DEF;
25
+ columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = _extends({}, GRID_DETAIL_PANEL_TOGGLE_COL_DEF, {
26
+ headerName: apiRef.current.getLocaleText('detailPanelToggle')
27
+ });
25
28
  return columnsState;
26
- }, [props.getDetailPanelContent]);
29
+ }, [apiRef, props.getDetailPanelContent]);
27
30
  useGridRegisterPipeProcessor(apiRef, 'hydrateColumns', addToggleColumn);
28
31
  };
@@ -60,6 +60,10 @@ export const useGridRowReorder = (apiRef, props) => {
60
60
  originRowIndex.current = apiRef.current.getRowIndex(params.id);
61
61
  }, [isRowReorderDisabled, classes.rowDragging, logger, apiRef]);
62
62
  const handleDragOver = React.useCallback((params, event) => {
63
+ if (dragRowId === '') {
64
+ return;
65
+ }
66
+
63
67
  logger.debug(`Dragging over row ${params.id}`);
64
68
  event.preventDefault(); // Prevent drag events propagation.
65
69
  // For more information check here https://github.com/mui/mui-x/issues/2680.
@@ -75,7 +79,7 @@ export const useGridRowReorder = (apiRef, props) => {
75
79
  // Call the gridEditRowsStateSelector directly to avoid infnite loop
76
80
  const editRowsState = gridEditRowsStateSelector(apiRef.current.state);
77
81
 
78
- if (isRowReorderDisabled || Object.keys(editRowsState).length !== 0) {
82
+ if (dragRowId === '' || isRowReorderDisabled || Object.keys(editRowsState).length !== 0) {
79
83
  return;
80
84
  }
81
85
 
@@ -1,4 +1,4 @@
1
1
  import * as React from 'react';
2
- import { GridApiCommunity } from '@mui/x-data-grid/internals';
3
2
  import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
4
- export declare const useGridRowReorderPreProcessors: (apiRef: React.MutableRefObject<GridApiCommunity>, props: DataGridProProcessedProps) => void;
3
+ import { GridApiPro } from '../../../models/gridApiPro';
4
+ export declare const useGridRowReorderPreProcessors: (apiRef: React.MutableRefObject<GridApiPro>, props: DataGridProProcessedProps) => void;
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["hideDescendantCount"];
4
4
  import * as React from 'react';
5
- import { gridRowIdsSelector, gridRowTreeSelector, useFirstRender } from '@mui/x-data-grid';
5
+ import { gridRowIdsSelector, gridRowTreeSelector, useFirstRender, GRID_CHECKBOX_SELECTION_FIELD } from '@mui/x-data-grid';
6
6
  import { useGridRegisterPipeProcessor, useGridRegisterStrategyProcessor } from '@mui/x-data-grid/internals';
7
7
  import { GRID_TREE_DATA_GROUPING_COL_DEF, GRID_TREE_DATA_GROUPING_COL_DEF_FORCED_PROPERTIES } from './gridTreeDataGroupColDef';
8
8
  import { filterRowTreeFromTreeData, TREE_DATA_STRATEGY } from './gridTreeDataUtils';
@@ -61,7 +61,7 @@ export const useGridTreeDataPreProcessors = (apiRef, props) => {
61
61
  columnsState.lookup[groupingColDefField] = newGroupingColumn;
62
62
 
63
63
  if (prevGroupingColumn == null) {
64
- const index = columnsState.all[0] === '__check__' ? 1 : 0;
64
+ const index = columnsState.all[0] === GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
65
65
  columnsState.all = [...columnsState.all.slice(0, index), groupingColDefField, ...columnsState.all.slice(index)];
66
66
  }
67
67
  } else if (!shouldHaveGroupingColumn && prevGroupingColumn) {
package/index.d.ts CHANGED
@@ -17,5 +17,3 @@ export * from './utils';
17
17
  export type { DataGridProProps, GridExperimentalProFeatures } from './models/dataGridProProps';
18
18
  export { useGridApiContext, useGridApiRef, useGridRootProps } from './typeOverloads/reexports';
19
19
  export type { GridApiRef, GridApi, GridInitialState, GridState } from './typeOverloads/reexports';
20
- export * from './hooks/features/rowGrouping';
21
- export * from './models/gridGroupingValueGetterParams';
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.11.1
1
+ /** @license MUI v5.12.2
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -18,7 +18,4 @@ export * from './hooks';
18
18
  export * from './models';
19
19
  export * from './components';
20
20
  export * from './utils';
21
- export { useGridApiContext, useGridApiRef, useGridRootProps } from './typeOverloads/reexports';
22
- // We export them from here to avoid export duplication between pro and premium
23
- export * from './hooks/features/rowGrouping';
24
- export * from './models/gridGroupingValueGetterParams';
21
+ export { useGridApiContext, useGridApiRef, useGridRootProps } from './typeOverloads/reexports';
@@ -6,7 +6,6 @@ export { useGridColumnPinning, columnPinningStateInitializer, } from '../hooks/f
6
6
  export { useGridColumnPinningPreProcessors } from '../hooks/features/columnPinning/useGridColumnPinningPreProcessors';
7
7
  export { useGridColumnReorder, columnReorderStateInitializer, } from '../hooks/features/columnReorder/useGridColumnReorder';
8
8
  export { useGridDetailPanel, detailPanelStateInitializer, } from '../hooks/features/detailPanel/useGridDetailPanel';
9
- export { useGridDetailPanelCache } from '../hooks/features/detailPanel/useGridDetailPanelCache';
10
9
  export { useGridDetailPanelPreProcessors } from '../hooks/features/detailPanel/useGridDetailPanelPreProcessors';
11
10
  export { useGridInfiniteLoader } from '../hooks/features/infiniteLoader/useGridInfiniteLoader';
12
11
  export { useGridRowReorder } from '../hooks/features/rowReorder/useGridRowReorder';
@@ -6,7 +6,6 @@ export { useGridColumnPinning, columnPinningStateInitializer } from '../hooks/fe
6
6
  export { useGridColumnPinningPreProcessors } from '../hooks/features/columnPinning/useGridColumnPinningPreProcessors';
7
7
  export { useGridColumnReorder, columnReorderStateInitializer } from '../hooks/features/columnReorder/useGridColumnReorder';
8
8
  export { useGridDetailPanel, detailPanelStateInitializer } from '../hooks/features/detailPanel/useGridDetailPanel';
9
- export { useGridDetailPanelCache } from '../hooks/features/detailPanel/useGridDetailPanelCache';
10
9
  export { useGridDetailPanelPreProcessors } from '../hooks/features/detailPanel/useGridDetailPanelPreProcessors';
11
10
  export { useGridInfiniteLoader } from '../hooks/features/infiniteLoader/useGridInfiniteLoader';
12
11
  export { useGridRowReorder } from '../hooks/features/rowReorder/useGridRowReorder';