@mui/x-data-grid 6.0.0-beta.2 → 6.0.0-beta.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 (132) hide show
  1. package/CHANGELOG.md +164 -0
  2. package/colDef/gridSingleSelectColDef.d.ts +2 -2
  3. package/colDef/gridSingleSelectColDef.js +4 -1
  4. package/components/GridPagination.d.ts +3 -3
  5. package/components/GridRow.js +2 -6
  6. package/components/cell/GridActionsCell.js +24 -13
  7. package/components/cell/GridActionsCellItem.d.ts +5 -5
  8. package/components/cell/GridActionsCellItem.js +6 -3
  9. package/components/cell/GridEditInputCell.d.ts +1 -1
  10. package/components/cell/GridEditSingleSelectCell.d.ts +1 -1
  11. package/components/cell/GridEditSingleSelectCell.js +16 -9
  12. package/components/columnHeaders/ColumnHeaderMenuIcon.js +5 -4
  13. package/components/columnHeaders/GridColumnHeaderFilterIconButton.js +6 -6
  14. package/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -4
  15. package/components/panel/GridColumnsPanel.js +1 -0
  16. package/components/panel/GridPanel.d.ts +1 -1
  17. package/components/panel/GridPanelWrapper.d.ts +4 -0
  18. package/components/panel/GridPanelWrapper.js +15 -5
  19. package/components/panel/filterPanel/GridFilterForm.js +8 -8
  20. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +16 -9
  21. package/components/panel/filterPanel/GridFilterInputSingleSelect.d.ts +1 -1
  22. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +17 -8
  23. package/components/panel/filterPanel/filterPanelUtils.d.ts +2 -1
  24. package/components/panel/filterPanel/filterPanelUtils.js +3 -0
  25. package/components/toolbar/GridToolbar.d.ts +1 -1
  26. package/components/toolbar/GridToolbarColumnsButton.d.ts +1 -1
  27. package/components/toolbar/GridToolbarDensitySelector.d.ts +1 -1
  28. package/components/toolbar/GridToolbarExport.d.ts +1 -1
  29. package/components/toolbar/GridToolbarExportContainer.d.ts +1 -1
  30. package/components/toolbar/GridToolbarFilterButton.d.ts +1 -1
  31. package/components/toolbar/GridToolbarFilterButton.js +10 -7
  32. package/components/toolbar/GridToolbarQuickFilter.js +6 -6
  33. package/constants/defaultGridSlotsComponents.js +2 -0
  34. package/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -3
  35. package/hooks/features/editing/useGridCellEditing.js +4 -1
  36. package/hooks/features/editing/useGridEditing.js +1 -1
  37. package/hooks/features/editing/useGridRowEditing.js +3 -0
  38. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +71 -10
  39. package/hooks/features/scroll/useGridScroll.js +7 -3
  40. package/hooks/features/virtualization/useGridVirtualScroller.js +30 -7
  41. package/index.js +1 -1
  42. package/internals/index.d.ts +2 -1
  43. package/internals/index.js +1 -0
  44. package/legacy/colDef/gridSingleSelectColDef.js +4 -1
  45. package/legacy/components/GridRow.js +2 -6
  46. package/legacy/components/cell/GridActionsCell.js +28 -17
  47. package/legacy/components/cell/GridActionsCellItem.js +6 -3
  48. package/legacy/components/cell/GridEditSingleSelectCell.js +16 -9
  49. package/legacy/components/columnHeaders/ColumnHeaderMenuIcon.js +5 -4
  50. package/legacy/components/columnHeaders/GridColumnHeaderFilterIconButton.js +6 -6
  51. package/legacy/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -4
  52. package/legacy/components/panel/GridColumnsPanel.js +1 -0
  53. package/legacy/components/panel/GridPanelWrapper.js +15 -4
  54. package/legacy/components/panel/filterPanel/GridFilterForm.js +8 -8
  55. package/legacy/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +16 -9
  56. package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +17 -8
  57. package/legacy/components/panel/filterPanel/filterPanelUtils.js +3 -0
  58. package/legacy/components/toolbar/GridToolbarFilterButton.js +8 -2
  59. package/legacy/components/toolbar/GridToolbarQuickFilter.js +6 -6
  60. package/legacy/constants/defaultGridSlotsComponents.js +2 -0
  61. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -3
  62. package/legacy/hooks/features/editing/useGridCellEditing.js +4 -1
  63. package/legacy/hooks/features/editing/useGridEditing.js +1 -1
  64. package/legacy/hooks/features/editing/useGridRowEditing.js +3 -0
  65. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +69 -10
  66. package/legacy/hooks/features/scroll/useGridScroll.js +7 -3
  67. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +30 -7
  68. package/legacy/index.js +1 -1
  69. package/legacy/internals/index.js +1 -0
  70. package/legacy/utils/domUtils.js +8 -6
  71. package/models/api/gridEditingApi.d.ts +2 -2
  72. package/models/colDef/gridColDef.d.ts +18 -5
  73. package/models/colDef/index.d.ts +1 -1
  74. package/models/gridFilterOperator.d.ts +6 -0
  75. package/models/gridSlotsComponent.d.ts +5 -0
  76. package/models/gridSlotsComponentsProps.d.ts +1 -0
  77. package/modern/colDef/gridSingleSelectColDef.js +4 -1
  78. package/modern/components/GridRow.js +2 -6
  79. package/modern/components/cell/GridActionsCell.js +23 -13
  80. package/modern/components/cell/GridActionsCellItem.js +5 -3
  81. package/modern/components/cell/GridEditSingleSelectCell.js +15 -9
  82. package/modern/components/columnHeaders/ColumnHeaderMenuIcon.js +4 -4
  83. package/modern/components/columnHeaders/GridColumnHeaderFilterIconButton.js +4 -4
  84. package/modern/components/columnHeaders/GridColumnHeaderSortIcon.js +4 -4
  85. package/modern/components/panel/GridColumnsPanel.js +1 -0
  86. package/modern/components/panel/GridPanelWrapper.js +15 -5
  87. package/modern/components/panel/filterPanel/GridFilterForm.js +4 -4
  88. package/modern/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +14 -8
  89. package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +17 -8
  90. package/modern/components/panel/filterPanel/filterPanelUtils.js +3 -0
  91. package/modern/components/toolbar/GridToolbarFilterButton.js +7 -1
  92. package/modern/components/toolbar/GridToolbarQuickFilter.js +4 -4
  93. package/modern/constants/defaultGridSlotsComponents.js +2 -0
  94. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -3
  95. package/modern/hooks/features/editing/useGridCellEditing.js +4 -1
  96. package/modern/hooks/features/editing/useGridEditing.js +1 -1
  97. package/modern/hooks/features/editing/useGridRowEditing.js +3 -0
  98. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +71 -10
  99. package/modern/hooks/features/scroll/useGridScroll.js +7 -3
  100. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +30 -7
  101. package/modern/index.js +1 -1
  102. package/modern/internals/index.js +1 -0
  103. package/modern/utils/domUtils.js +8 -6
  104. package/node/colDef/gridSingleSelectColDef.js +3 -0
  105. package/node/components/GridRow.js +2 -6
  106. package/node/components/cell/GridActionsCell.js +23 -13
  107. package/node/components/cell/GridActionsCellItem.js +5 -3
  108. package/node/components/cell/GridEditSingleSelectCell.js +14 -8
  109. package/node/components/columnHeaders/ColumnHeaderMenuIcon.js +4 -4
  110. package/node/components/columnHeaders/GridColumnHeaderFilterIconButton.js +4 -4
  111. package/node/components/columnHeaders/GridColumnHeaderSortIcon.js +4 -4
  112. package/node/components/panel/GridColumnsPanel.js +1 -0
  113. package/node/components/panel/GridPanelWrapper.js +16 -6
  114. package/node/components/panel/filterPanel/GridFilterForm.js +4 -4
  115. package/node/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +13 -7
  116. package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +16 -7
  117. package/node/components/panel/filterPanel/filterPanelUtils.js +4 -0
  118. package/node/components/toolbar/GridToolbarFilterButton.js +7 -1
  119. package/node/components/toolbar/GridToolbarQuickFilter.js +4 -4
  120. package/node/constants/defaultGridSlotsComponents.js +2 -0
  121. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +4 -2
  122. package/node/hooks/features/editing/useGridCellEditing.js +4 -1
  123. package/node/hooks/features/editing/useGridEditing.js +1 -1
  124. package/node/hooks/features/editing/useGridRowEditing.js +3 -0
  125. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +71 -10
  126. package/node/hooks/features/scroll/useGridScroll.js +7 -3
  127. package/node/hooks/features/virtualization/useGridVirtualScroller.js +30 -7
  128. package/node/index.js +1 -1
  129. package/node/internals/index.js +7 -0
  130. package/node/utils/domUtils.js +8 -6
  131. package/package.json +3 -3
  132. package/utils/domUtils.js +8 -6
@@ -1,5 +1,6 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
2
  import * as React from 'react';
3
+ import { useTheme } from '@mui/material/styles';
3
4
  import { gridVisibleColumnDefinitionsSelector } from '../columns/gridColumnsSelector';
4
5
  import { useGridLogger } from '../../utils/useGridLogger';
5
6
  import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
@@ -18,6 +19,38 @@ function enrichPageRowsWithPinnedRows(apiRef, rows) {
18
19
  var pinnedRows = gridPinnedRowsSelector(apiRef) || {};
19
20
  return [].concat(_toConsumableArray(pinnedRows.top || []), _toConsumableArray(rows), _toConsumableArray(pinnedRows.bottom || []));
20
21
  }
22
+ var getLeftColumnIndex = function getLeftColumnIndex(_ref) {
23
+ var currentColIndex = _ref.currentColIndex,
24
+ firstColIndex = _ref.firstColIndex,
25
+ lastColIndex = _ref.lastColIndex,
26
+ direction = _ref.direction;
27
+ if (direction === 'rtl') {
28
+ if (currentColIndex < lastColIndex) {
29
+ return currentColIndex + 1;
30
+ }
31
+ } else if (direction === 'ltr') {
32
+ if (currentColIndex > firstColIndex) {
33
+ return currentColIndex - 1;
34
+ }
35
+ }
36
+ return null;
37
+ };
38
+ var getRightColumnIndex = function getRightColumnIndex(_ref2) {
39
+ var currentColIndex = _ref2.currentColIndex,
40
+ firstColIndex = _ref2.firstColIndex,
41
+ lastColIndex = _ref2.lastColIndex,
42
+ direction = _ref2.direction;
43
+ if (direction === 'rtl') {
44
+ if (currentColIndex > firstColIndex) {
45
+ return currentColIndex - 1;
46
+ }
47
+ } else if (direction === 'ltr') {
48
+ if (currentColIndex < lastColIndex) {
49
+ return currentColIndex + 1;
50
+ }
51
+ }
52
+ return null;
53
+ };
21
54
 
22
55
  /**
23
56
  * @requires useGridSorting (method) - can be after
@@ -31,6 +64,7 @@ function enrichPageRowsWithPinnedRows(apiRef, rows) {
31
64
  export var useGridKeyboardNavigation = function useGridKeyboardNavigation(apiRef, props) {
32
65
  var logger = useGridLogger(apiRef, 'useGridKeyboardNavigation');
33
66
  var initialCurrentPageRows = useGridVisibleRows(apiRef, props).rows;
67
+ var theme = useTheme();
34
68
  var currentPageRows = React.useMemo(function () {
35
69
  return enrichPageRowsWithPinnedRows(apiRef, initialCurrentPageRows);
36
70
  }, [apiRef, initialCurrentPageRows]);
@@ -114,15 +148,27 @@ export var useGridKeyboardNavigation = function useGridKeyboardNavigation(apiRef
114
148
  }
115
149
  case 'ArrowRight':
116
150
  {
117
- if (colIndexBefore < lastColIndex) {
118
- goToHeader(colIndexBefore + 1, event);
151
+ var rightColIndex = getRightColumnIndex({
152
+ currentColIndex: colIndexBefore,
153
+ firstColIndex: firstColIndex,
154
+ lastColIndex: lastColIndex,
155
+ direction: theme.direction
156
+ });
157
+ if (rightColIndex !== null) {
158
+ goToHeader(rightColIndex, event);
119
159
  }
120
160
  break;
121
161
  }
122
162
  case 'ArrowLeft':
123
163
  {
124
- if (colIndexBefore > firstColIndex) {
125
- goToHeader(colIndexBefore - 1, event);
164
+ var leftColIndex = getLeftColumnIndex({
165
+ currentColIndex: colIndexBefore,
166
+ firstColIndex: firstColIndex,
167
+ lastColIndex: lastColIndex,
168
+ direction: theme.direction
169
+ });
170
+ if (leftColIndex !== null) {
171
+ goToHeader(leftColIndex, event);
126
172
  }
127
173
  break;
128
174
  }
@@ -170,7 +216,7 @@ export var useGridKeyboardNavigation = function useGridKeyboardNavigation(apiRef
170
216
  if (shouldPreventDefault) {
171
217
  event.preventDefault();
172
218
  }
173
- }, [apiRef, currentPageRows.length, goToCell, getRowIdFromIndex, goToHeader, goToGroupHeader]);
219
+ }, [apiRef, currentPageRows.length, theme.direction, goToCell, getRowIdFromIndex, goToHeader, goToGroupHeader]);
174
220
  var focusedColumnGroup = useGridSelector(apiRef, unstable_gridFocusColumnGroupHeaderSelector);
175
221
  var handleColumnGroupHeaderKeyDown = React.useCallback(function (params, event) {
176
222
  var dimensions = apiRef.current.getRootDimensions();
@@ -279,6 +325,7 @@ export var useGridKeyboardNavigation = function useGridKeyboardNavigation(apiRef
279
325
  if (currentPageRows.length === 0 || !dimensions) {
280
326
  return;
281
327
  }
328
+ var direction = theme.direction;
282
329
  var viewportPageSize = apiRef.current.getViewportPageSize();
283
330
  var colIndexBefore = params.field ? apiRef.current.getColumnIndex(params.field) : 0;
284
331
  var rowIndexBefore = currentPageRows.findIndex(function (row) {
@@ -309,15 +356,27 @@ export var useGridKeyboardNavigation = function useGridKeyboardNavigation(apiRef
309
356
  }
310
357
  case 'ArrowRight':
311
358
  {
312
- if (colIndexBefore < lastColIndex) {
313
- goToCell(colIndexBefore + 1, getRowIdFromIndex(rowIndexBefore), 'right');
359
+ var rightColIndex = getRightColumnIndex({
360
+ currentColIndex: colIndexBefore,
361
+ firstColIndex: firstColIndex,
362
+ lastColIndex: lastColIndex,
363
+ direction: direction
364
+ });
365
+ if (rightColIndex !== null) {
366
+ goToCell(rightColIndex, getRowIdFromIndex(rowIndexBefore), direction === 'rtl' ? 'left' : 'right');
314
367
  }
315
368
  break;
316
369
  }
317
370
  case 'ArrowLeft':
318
371
  {
319
- if (colIndexBefore > firstColIndex) {
320
- goToCell(colIndexBefore - 1, getRowIdFromIndex(rowIndexBefore));
372
+ var leftColIndex = getLeftColumnIndex({
373
+ currentColIndex: colIndexBefore,
374
+ firstColIndex: firstColIndex,
375
+ lastColIndex: lastColIndex,
376
+ direction: direction
377
+ });
378
+ if (leftColIndex !== null) {
379
+ goToCell(leftColIndex, getRowIdFromIndex(rowIndexBefore), direction === 'rtl' ? 'right' : 'left');
321
380
  }
322
381
  break;
323
382
  }
@@ -390,7 +449,7 @@ export var useGridKeyboardNavigation = function useGridKeyboardNavigation(apiRef
390
449
  if (shouldPreventDefault) {
391
450
  event.preventDefault();
392
451
  }
393
- }, [apiRef, currentPageRows, getRowIdFromIndex, goToCell, goToHeader]);
452
+ }, [apiRef, currentPageRows, theme.direction, getRowIdFromIndex, goToCell, goToHeader]);
394
453
  useGridApiEventHandler(apiRef, 'columnHeaderKeyDown', handleColumnHeaderKeyDown);
395
454
  useGridApiEventHandler(apiRef, 'columnGroupHeaderKeyDown', handleColumnGroupHeaderKeyDown);
396
455
  useGridApiEventHandler(apiRef, 'cellKeyDown', handleCellKeyDown);
@@ -1,5 +1,6 @@
1
1
  import _typeof from "@babel/runtime/helpers/esm/typeof";
2
2
  import * as React from 'react';
3
+ import { useTheme } from '@mui/material/styles';
3
4
  import { useGridLogger } from '../../utils/useGridLogger';
4
5
  import { gridColumnPositionsSelector, gridVisibleColumnDefinitionsSelector } from '../columns/gridColumnsSelector';
5
6
  import { useGridSelector } from '../../utils/useGridSelector';
@@ -41,6 +42,7 @@ function scrollIntoView(dimensions) {
41
42
  * @requires useGridColumnSpanning (method)
42
43
  */
43
44
  export var useGridScroll = function useGridScroll(apiRef, props) {
45
+ var theme = useTheme();
44
46
  var logger = useGridLogger(apiRef, 'useGridScroll');
45
47
  var colRef = apiRef.current.columnHeadersElementRef;
46
48
  var virtualScrollerRef = apiRef.current.virtualScrollerRef;
@@ -68,9 +70,10 @@ export var useGridScroll = function useGridScroll(apiRef, props) {
68
70
  if (typeof cellWidth === 'undefined') {
69
71
  cellWidth = visibleColumns[params.colIndex].computedWidth;
70
72
  }
73
+ // When using RTL, `scrollLeft` becomes negative, so we must ensure that we only compare values.
71
74
  scrollCoordinates.left = scrollIntoView({
72
75
  clientHeight: virtualScrollerRef.current.clientWidth,
73
- scrollTop: virtualScrollerRef.current.scrollLeft,
76
+ scrollTop: Math.abs(virtualScrollerRef.current.scrollLeft),
74
77
  offsetHeight: cellWidth,
75
78
  offsetTop: columnPositions[params.colIndex]
76
79
  });
@@ -100,8 +103,9 @@ export var useGridScroll = function useGridScroll(apiRef, props) {
100
103
  }, [logger, apiRef, virtualScrollerRef, props.pagination, visibleSortedRows]);
101
104
  var scroll = React.useCallback(function (params) {
102
105
  if (virtualScrollerRef.current && params.left != null && colRef.current) {
106
+ var direction = theme.direction === 'rtl' ? -1 : 1;
103
107
  colRef.current.scrollLeft = params.left;
104
- virtualScrollerRef.current.scrollLeft = params.left;
108
+ virtualScrollerRef.current.scrollLeft = direction * params.left;
105
109
  logger.debug("Scrolling left: ".concat(params.left));
106
110
  }
107
111
  if (virtualScrollerRef.current && params.top != null) {
@@ -109,7 +113,7 @@ export var useGridScroll = function useGridScroll(apiRef, props) {
109
113
  logger.debug("Scrolling top: ".concat(params.top));
110
114
  }
111
115
  logger.debug("Scrolling, updating container, and viewport");
112
- }, [virtualScrollerRef, colRef, logger]);
116
+ }, [virtualScrollerRef, theme.direction, colRef, logger]);
113
117
  var getScrollPosition = React.useCallback(function () {
114
118
  if (!(virtualScrollerRef != null && virtualScrollerRef.current)) {
115
119
  return {
@@ -7,6 +7,7 @@ var _excluded = ["style"],
7
7
  import * as React from 'react';
8
8
  import * as ReactDOM from 'react-dom';
9
9
  import { unstable_useForkRef as useForkRef, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
10
+ import { useTheme } from '@mui/material/styles';
10
11
  import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext';
11
12
  import { useGridRootProps } from '../../utils/useGridRootProps';
12
13
  import { useGridSelector } from '../../utils/useGridSelector';
@@ -38,7 +39,7 @@ export function binarySearch(offset, positions) {
38
39
  }
39
40
  function exponentialSearch(offset, positions, index) {
40
41
  var interval = 1;
41
- while (index < positions.length && positions[index] < offset) {
42
+ while (index < positions.length && Math.abs(positions[index]) < offset) {
42
43
  index += interval;
43
44
  interval *= 2;
44
45
  }
@@ -52,6 +53,12 @@ export var getRenderableIndexes = function getRenderableIndexes(_ref) {
52
53
  maxLastIndex = _ref.maxLastIndex;
53
54
  return [clamp(firstIndex - buffer, minFirstIndex, maxLastIndex), clamp(lastIndex + buffer, minFirstIndex, maxLastIndex)];
54
55
  };
56
+ var areRenderContextsEqual = function areRenderContextsEqual(context1, context2) {
57
+ if (context1 === context2) {
58
+ return true;
59
+ }
60
+ return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
61
+ };
55
62
  export var useGridVirtualScroller = function useGridVirtualScroller(props) {
56
63
  var _currentPage$range3, _currentPage$range4;
57
64
  var apiRef = useGridPrivateApiContext();
@@ -65,6 +72,7 @@ export var useGridVirtualScroller = function useGridVirtualScroller(props) {
65
72
  _props$renderZoneMaxC = props.renderZoneMaxColumnIndex,
66
73
  renderZoneMaxColumnIndex = _props$renderZoneMaxC === void 0 ? visibleColumns.length : _props$renderZoneMaxC,
67
74
  getRowProps = props.getRowProps;
75
+ var theme = useTheme();
68
76
  var columnPositions = useGridSelector(apiRef, gridColumnPositionsSelector);
69
77
  var columnsTotalWidth = useGridSelector(apiRef, gridColumnsTotalWidthSelector);
70
78
  var cellFocus = useGridSelector(apiRef, gridFocusCellSelector);
@@ -149,8 +157,8 @@ export var useGridVirtualScroller = function useGridVirtualScroller(props) {
149
157
  hasRowWithAutoHeight = apiRef.current.rowHasAutoHeight(row.id);
150
158
  }
151
159
  if (!hasRowWithAutoHeight) {
152
- firstColumnIndex = binarySearch(left, columnPositions);
153
- lastColumnIndex = binarySearch(left + containerDimensions.width, columnPositions);
160
+ firstColumnIndex = binarySearch(Math.abs(left), columnPositions);
161
+ lastColumnIndex = binarySearch(Math.abs(left) + containerDimensions.width, columnPositions);
154
162
  }
155
163
  return {
156
164
  firstRowIndex: firstRowIndex,
@@ -180,7 +188,7 @@ export var useGridVirtualScroller = function useGridVirtualScroller(props) {
180
188
  height: params.height
181
189
  });
182
190
  }, []);
183
- useGridApiEventHandler(apiRef, 'resize', handleResize);
191
+ useGridApiEventHandler(apiRef, 'debouncedResize', handleResize);
184
192
  var updateRenderZonePosition = React.useCallback(function (nextRenderContext) {
185
193
  var _getRenderableIndexes3 = getRenderableIndexes({
186
194
  firstIndex: nextRenderContext.firstRowIndex,
@@ -208,8 +216,9 @@ export var useGridVirtualScroller = function useGridVirtualScroller(props) {
208
216
  lastRowToRender: lastRowToRender,
209
217
  visibleRows: currentPage.rows
210
218
  });
219
+ var direction = theme.direction === 'ltr' ? 1 : -1;
211
220
  var top = gridRowsMetaSelector(apiRef.current.state).positions[firstRowToRender];
212
- var left = gridColumnPositionsSelector(apiRef)[firstColumnToRender]; // Call directly the selector because it might be outdated when this method is called
221
+ var left = direction * gridColumnPositionsSelector(apiRef)[firstColumnToRender]; // Call directly the selector because it might be outdated when this method is called
213
222
  renderZoneRef.current.style.transform = "translate3d(".concat(left, "px, ").concat(top, "px, 0px)");
214
223
  if (typeof onRenderZonePositioning === 'function') {
215
224
  onRenderZonePositioning({
@@ -217,8 +226,12 @@ export var useGridVirtualScroller = function useGridVirtualScroller(props) {
217
226
  left: left
218
227
  });
219
228
  }
220
- }, [apiRef, currentPage.rows, onRenderZonePositioning, renderZoneMinColumnIndex, renderZoneMaxColumnIndex, rootProps.columnBuffer, rootProps.rowBuffer]);
229
+ }, [apiRef, currentPage.rows, onRenderZonePositioning, renderZoneMinColumnIndex, renderZoneMaxColumnIndex, rootProps.columnBuffer, rootProps.rowBuffer, theme.direction]);
221
230
  var updateRenderContext = React.useCallback(function (nextRenderContext) {
231
+ if (prevRenderContext.current && areRenderContextsEqual(nextRenderContext, prevRenderContext.current)) {
232
+ updateRenderZonePosition(nextRenderContext);
233
+ return;
234
+ }
222
235
  setRenderContext(nextRenderContext);
223
236
  updateRenderZonePosition(nextRenderContext);
224
237
  var _getRenderableIndexes7 = getRenderableIndexes({
@@ -261,9 +274,19 @@ export var useGridVirtualScroller = function useGridVirtualScroller(props) {
261
274
  scrollPosition.current.left = scrollLeft;
262
275
 
263
276
  // On iOS and macOS, negative offsets are possible when swiping past the start
264
- if (scrollLeft < 0 || scrollTop < 0 || !prevRenderContext.current) {
277
+ if (!prevRenderContext.current || scrollTop < 0) {
265
278
  return;
266
279
  }
280
+ if (theme.direction === 'ltr') {
281
+ if (scrollLeft < 0) {
282
+ return;
283
+ }
284
+ }
285
+ if (theme.direction === 'rtl') {
286
+ if (scrollLeft > 0) {
287
+ return;
288
+ }
289
+ }
267
290
 
268
291
  // When virtualization is disabled, the context never changes during scroll
269
292
  var nextRenderContext = disableVirtualization ? prevRenderContext.current : computeRenderContext();
package/legacy/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.0.0-beta.2
2
+ * @mui/x-data-grid v6.0.0-beta.4
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -18,6 +18,7 @@ export { useGridCsvExport } from '../hooks/features/export/useGridCsvExport';
18
18
  export { useGridPrintExport } from '../hooks/features/export/useGridPrintExport';
19
19
  export { useGridFilter, filterStateInitializer } from '../hooks/features/filter/useGridFilter';
20
20
  export { passFilterLogic } from '../hooks/features/filter/gridFilterUtils';
21
+ export { isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
21
22
  export { useGridFocus, focusStateInitializer } from '../hooks/features/focus/useGridFocus';
22
23
  export { useGridKeyboardNavigation } from '../hooks/features/keyboardNavigation/useGridKeyboardNavigation';
23
24
  export { useGridPagination, paginationStateInitializer } from '../hooks/features/pagination/useGridPagination';
@@ -25,15 +25,17 @@ function escapeOperandAttributeSelector(operand) {
25
25
  export function getGridColumnHeaderElement(root, field) {
26
26
  return root.querySelector("[role=\"columnheader\"][data-field=\"".concat(escapeOperandAttributeSelector(field), "\"]"));
27
27
  }
28
+ function getGridRowElementSelector(id) {
29
+ return ".".concat(gridClasses.row, "[data-id=\"").concat(escapeOperandAttributeSelector(String(id)), "\"]");
30
+ }
28
31
  export function getGridRowElement(root, id) {
29
- return root.querySelector(".".concat(gridClasses.row, "[data-id=\"").concat(escapeOperandAttributeSelector(String(id)), "\"]"));
32
+ return root.querySelector(getGridRowElementSelector(id));
30
33
  }
31
34
  export function getGridCellElement(root, _ref) {
32
35
  var id = _ref.id,
33
36
  field = _ref.field;
34
- var row = getGridRowElement(root, id);
35
- if (!row) {
36
- return null;
37
- }
38
- return row.querySelector(".".concat(gridClasses.cell, "[data-field=\"").concat(escapeOperandAttributeSelector(field), "\"]"));
37
+ var rowSelector = getGridRowElementSelector(id);
38
+ var cellSelector = ".".concat(gridClasses.cell, "[data-field=\"").concat(escapeOperandAttributeSelector(field), "\"]");
39
+ var selector = "".concat(rowSelector, " ").concat(cellSelector);
40
+ return root.querySelector(selector);
39
41
  }
@@ -39,9 +39,9 @@ export interface GridEditingSharedApi {
39
39
  * In row editing, `field` is ignored and all fields are considered.
40
40
  * @param {GridRowId} id The row id being edited.
41
41
  * @param {string} field The field being edited.
42
- * @ignore - do not document.
42
+ * @returns {GridRowModel} The row with edited values.
43
43
  */
44
- unstable_getRowWithUpdatedValues: (id: GridRowId, field: string) => GridRowModel;
44
+ getRowWithUpdatedValues: (id: GridRowId, field: string) => GridRowModel;
45
45
  /**
46
46
  * Gets the meta information for the edit cell.
47
47
  * @param {GridRowId} id The row id being edited.
@@ -106,10 +106,6 @@ export interface GridBaseColDef<R extends GridValidRowModel = GridValidRowModel,
106
106
  * @default 'string'
107
107
  */
108
108
  type?: GridColType;
109
- /**
110
- * To be used in combination with `type: 'singleSelect'`. This is an array (or a function returning an array) of the possible cell values and labels.
111
- */
112
- valueOptions?: Array<ValueOptions> | ((params: GridValueOptionsParams<R>) => Array<ValueOptions>);
113
109
  /**
114
110
  * Allows to align the column values in cells.
115
111
  */
@@ -227,6 +223,9 @@ export interface GridBaseColDef<R extends GridValidRowModel = GridValidRowModel,
227
223
  */
228
224
  colSpan?: number | ((params: GridCellParams<R, V, F>) => number | undefined);
229
225
  }
226
+ /**
227
+ * Column Definition interface used for columns with the `actions` type.
228
+ */
230
229
  export interface GridActionsColDef<R extends GridValidRowModel = any, V = any, F = V> extends GridBaseColDef<R, V, F> {
231
230
  /**
232
231
  * Type allows to merge this object with a default definition [[GridColDef]].
@@ -240,10 +239,24 @@ export interface GridActionsColDef<R extends GridValidRowModel = any, V = any, F
240
239
  */
241
240
  getActions: (params: GridRowParams<R>) => React.ReactElement<GridActionsCellItemProps>[];
242
241
  }
242
+ /**
243
+ * Column Definition interface used for columns with the `singleSelect` type.
244
+ */
245
+ export interface GridSingleSelectColDef<R extends GridValidRowModel = any, V = any, F = V> extends GridBaseColDef<R, V, F> {
246
+ /**
247
+ * Type allows to merge this object with a default definition [[GridColDef]].
248
+ * @default 'singleSelect'
249
+ */
250
+ type: 'singleSelect';
251
+ /**
252
+ * To be used in combination with `type: 'singleSelect'`. This is an array (or a function returning an array) of the possible cell values and labels.
253
+ */
254
+ valueOptions?: Array<ValueOptions> | ((params: GridValueOptionsParams<R>) => Array<ValueOptions>);
255
+ }
243
256
  /**
244
257
  * Column Definition interface.
245
258
  */
246
- export type GridColDef<R extends GridValidRowModel = any, V = any, F = V> = GridBaseColDef<R, V, F> | GridActionsColDef<R, V, F>;
259
+ export type GridColDef<R extends GridValidRowModel = any, V = any, F = V> = GridBaseColDef<R, V, F> | GridActionsColDef<R, V, F> | GridSingleSelectColDef<R, V, F>;
247
260
  export type GridColTypeDef<V = any, F = V> = Omit<GridBaseColDef<any, V, F>, 'field'> & {
248
261
  extendType?: GridNativeColTypes;
249
262
  };
@@ -1,3 +1,3 @@
1
- export type { GridAlignment, ValueOptions, GridKeyValue, GridColDef, GridColTypeDef, GridColumnsMeta, } from './gridColDef';
1
+ export type { GridAlignment, ValueOptions, GridKeyValue, GridColDef, GridColTypeDef, GridColumnsMeta, GridSingleSelectColDef, GridActionsColDef, } from './gridColDef';
2
2
  export * from './gridColType';
3
3
  export * from './gridColumnTypesRecord';
@@ -32,6 +32,12 @@ export interface GridFilterOperator<R extends GridValidRowModel = any, V = any,
32
32
  * The props to pass to the input component in the filter panel for this filter operator.
33
33
  */
34
34
  InputComponentProps?: Record<string, any>;
35
+ /**
36
+ * Converts the value of a filter item to a human-readable form.
37
+ * @param {GridFilterItem['value']} value The filter item value.
38
+ * @returns {string} The value formatted to be displayed in the UI of filter button tooltip.
39
+ */
40
+ getValueAsString?: (value: GridFilterItem['value']) => string;
35
41
  /**
36
42
  * If `false`, filter operator doesn't require user-entered value to work.
37
43
  * Usually should be set to `false` for filter operators that don't have `InputComponent` (for example `isEmpty`)
@@ -35,6 +35,11 @@ export interface GridSlotsComponent extends GridIconSlotsComponent {
35
35
  * @default Button
36
36
  */
37
37
  BaseButton: React.JSXElementConstructor<any>;
38
+ /**
39
+ * The custom IconButton component used in the grid.
40
+ * @default IconButton
41
+ */
42
+ BaseIconButton: React.JSXElementConstructor<any>;
38
43
  /**
39
44
  * The custom Tooltip component used in the grid.
40
45
  * @default Tooltip
@@ -8,6 +8,7 @@ export interface GridSlotsComponentsProps {
8
8
  baseSelect?: any;
9
9
  baseSwitch?: any;
10
10
  baseButton?: any;
11
+ baseIconButton?: any;
11
12
  basePopper?: any;
12
13
  baseTooltip?: any;
13
14
  cell?: any;
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { GRID_STRING_COL_DEF } from './gridStringColDef';
3
3
  import { renderEditSingleSelectCell } from '../components/cell/GridEditSingleSelectCell';
4
4
  import { getGridSingleSelectOperators } from './gridSingleSelectOperators';
5
- import { getLabelFromValueOption } from '../components/panel/filterPanel/filterPanelUtils';
5
+ import { getLabelFromValueOption, isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
6
6
  const isArrayOfObjects = options => {
7
7
  return typeof options[0] === 'object';
8
8
  };
@@ -16,6 +16,9 @@ export const GRID_SINGLE_SELECT_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
16
16
  api
17
17
  } = params;
18
18
  const colDef = params.api.getColumn(field);
19
+ if (!isSingleSelectColDef(colDef)) {
20
+ return '';
21
+ }
19
22
  let valueOptions;
20
23
  if (typeof colDef.valueOptions === 'function') {
21
24
  valueOptions = colDef.valueOptions({
@@ -199,11 +199,7 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
199
199
  classNames.push(clsx(gridClasses['cell--withRenderer'], rootProps.classes?.['cell--withRenderer']));
200
200
  }
201
201
  if (editCellState != null && column.renderEditCell) {
202
- let updatedRow = row;
203
- if (apiRef.current.unstable_getRowWithUpdatedValues) {
204
- // Only the new editing API has this method
205
- updatedRow = apiRef.current.unstable_getRowWithUpdatedValues(rowId, column.field);
206
- }
202
+ const updatedRow = apiRef.current.getRowWithUpdatedValues(rowId, column.field);
207
203
  const editCellStateRest = _objectWithoutPropertiesLoose(editCellState, _excluded2);
208
204
  const params = _extends({}, cellParams, {
209
205
  row: updatedRow
@@ -245,7 +241,7 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
245
241
  }, rootProps.componentsProps?.cell, {
246
242
  children: content
247
243
  }), column.field);
248
- }, [apiRef, cellTabIndex, editRowsState, cellFocus, rootProps, row, rowHeight, rowId, treeDepth, sortModel.length]);
244
+ }, [apiRef, cellTabIndex, editRowsState, cellFocus, rootProps, rowHeight, rowId, treeDepth, sortModel.length]);
249
245
  const sizes = apiRef.current.unstable_getRowInternalSizes(rowId);
250
246
  let minHeight = rowHeight;
251
247
  if (minHeight === 'auto' && sizes) {
@@ -3,8 +3,8 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  const _excluded = ["colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "focusElementRef"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
- import IconButton from '@mui/material/IconButton';
7
6
  import MenuList from '@mui/material/MenuList';
7
+ import { useTheme } from '@mui/material/styles';
8
8
  import { unstable_useId as useId } from '@mui/utils';
9
9
  import { gridClasses } from '../../constants/gridClasses';
10
10
  import { GridMenu } from '../menu/GridMenu';
@@ -30,9 +30,17 @@ function GridActionsCell(props) {
30
30
  const buttonRef = React.useRef(null);
31
31
  const ignoreCallToFocus = React.useRef(false);
32
32
  const touchRippleRefs = React.useRef({});
33
+ const theme = useTheme();
33
34
  const menuId = useId();
34
35
  const buttonId = useId();
35
36
  const rootProps = useGridRootProps();
37
+ if (!hasActions(colDef)) {
38
+ throw new Error('MUI: Missing the `getActions` property in the `GridColDef`.');
39
+ }
40
+ const options = colDef.getActions(apiRef.current.getRowParams(id));
41
+ const iconButtons = options.filter(option => !option.props.showInMenu);
42
+ const menuButtons = options.filter(option => option.props.showInMenu);
43
+ const numberOfButtons = iconButtons.length + (menuButtons.length ? 1 : 0);
36
44
  React.useLayoutEffect(() => {
37
45
  if (!hasFocus) {
38
46
  Object.entries(touchRippleRefs.current).forEach(([index, ref]) => {
@@ -68,13 +76,6 @@ function GridActionsCell(props) {
68
76
  }
69
77
  }
70
78
  }), []);
71
- if (!hasActions(colDef)) {
72
- throw new Error('MUI: Missing the `getActions` property in the `GridColDef`.');
73
- }
74
- const options = colDef.getActions(apiRef.current.getRowParams(id));
75
- const iconButtons = options.filter(option => !option.props.showInMenu);
76
- const menuButtons = options.filter(option => option.props.showInMenu);
77
- const numberOfButtons = iconButtons.length + (menuButtons.length ? 1 : 0);
78
79
  React.useEffect(() => {
79
80
  if (focusedButtonIndex >= numberOfButtons) {
80
81
  setFocusedButtonIndex(numberOfButtons - 1);
@@ -104,9 +105,17 @@ function GridActionsCell(props) {
104
105
  }
105
106
  let newIndex = focusedButtonIndex;
106
107
  if (event.key === 'ArrowRight') {
107
- newIndex += 1;
108
+ if (theme.direction === 'rtl') {
109
+ newIndex -= 1;
110
+ } else {
111
+ newIndex += 1;
112
+ }
108
113
  } else if (event.key === 'ArrowLeft') {
109
- newIndex -= 1;
114
+ if (theme.direction === 'rtl') {
115
+ newIndex += 1;
116
+ } else {
117
+ newIndex -= 1;
118
+ }
110
119
  }
111
120
  if (newIndex < 0 || newIndex >= numberOfButtons) {
112
121
  return; // We're already in the first or last item = do nothing and let the grid listen the event
@@ -138,7 +147,7 @@ function GridActionsCell(props) {
138
147
  touchRippleRef: handleTouchRippleRef(index),
139
148
  onClick: handleButtonClick(index, button.props.onClick),
140
149
  tabIndex: focusedButtonIndex === index ? tabIndex : -1
141
- })), menuButtons.length > 0 && buttonId && /*#__PURE__*/_jsx(IconButton, {
150
+ })), menuButtons.length > 0 && buttonId && /*#__PURE__*/_jsx(rootProps.components.BaseIconButton, _extends({
142
151
  ref: buttonRef,
143
152
  id: buttonId,
144
153
  "aria-label": apiRef.current.getLocaleText('actionsCellMore'),
@@ -149,11 +158,12 @@ function GridActionsCell(props) {
149
158
  size: "small",
150
159
  onClick: showMenu,
151
160
  touchRippleRef: handleTouchRippleRef(buttonId),
152
- tabIndex: focusedButtonIndex === iconButtons.length ? tabIndex : -1,
161
+ tabIndex: focusedButtonIndex === iconButtons.length ? tabIndex : -1
162
+ }, rootProps.componentsProps?.baseIconButton, {
153
163
  children: /*#__PURE__*/_jsx(rootProps.components.MoreActionsIcon, {
154
164
  fontSize: "small"
155
165
  })
156
- }), menuButtons.length > 0 && /*#__PURE__*/_jsx(GridMenu, {
166
+ })), menuButtons.length > 0 && /*#__PURE__*/_jsx(GridMenu, {
157
167
  onClickAway: hideMenu,
158
168
  onClick: hideMenu,
159
169
  open: open,
@@ -3,9 +3,9 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  const _excluded = ["label", "icon", "showInMenu", "onClick"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
- import IconButton from '@mui/material/IconButton';
7
6
  import MenuItem from '@mui/material/MenuItem';
8
7
  import ListItemIcon from '@mui/material/ListItemIcon';
8
+ import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
10
  import { jsxs as _jsxs } from "react/jsx-runtime";
11
11
  const GridActionsCellItem = /*#__PURE__*/React.forwardRef((props, ref) => {
@@ -16,19 +16,21 @@ const GridActionsCellItem = /*#__PURE__*/React.forwardRef((props, ref) => {
16
16
  onClick
17
17
  } = props,
18
18
  other = _objectWithoutPropertiesLoose(props, _excluded);
19
+ const rootProps = useGridRootProps();
19
20
  const handleClick = event => {
20
21
  if (onClick) {
21
22
  onClick(event);
22
23
  }
23
24
  };
24
25
  if (!showInMenu) {
25
- return /*#__PURE__*/_jsx(IconButton, _extends({
26
+ return /*#__PURE__*/_jsx(rootProps.components.BaseIconButton, _extends({
26
27
  ref: ref,
27
28
  size: "small",
28
29
  role: "menuitem",
29
30
  "aria-label": label
30
31
  }, other, {
31
- onClick: handleClick,
32
+ onClick: handleClick
33
+ }, rootProps.componentsProps?.baseIconButton, {
32
34
  children: /*#__PURE__*/React.cloneElement(icon, {
33
35
  fontSize: 'small'
34
36
  })
@@ -8,7 +8,7 @@ import MenuItem from '@mui/material/MenuItem';
8
8
  import { isEscapeKey } from '../../utils/keyboardUtils';
9
9
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
10
10
  import { GridEditModes } from '../../models/gridEditRowModel';
11
- import { getLabelFromValueOption, getValueFromValueOptions } from '../panel/filterPanel/filterPanelUtils';
11
+ import { getLabelFromValueOption, getValueFromValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
12
12
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  function isKeyboardEvent(event) {
@@ -35,15 +35,26 @@ function GridEditSingleSelectCell(props) {
35
35
  const [open, setOpen] = React.useState(initialOpen);
36
36
  const baseSelectProps = rootProps.componentsProps?.baseSelect || {};
37
37
  const isSelectNative = baseSelectProps.native ?? false;
38
+ useEnhancedEffect(() => {
39
+ if (hasFocus) {
40
+ inputRef.current?.focus();
41
+ }
42
+ }, [hasFocus]);
43
+ if (!isSingleSelectColDef(colDef)) {
44
+ return null;
45
+ }
38
46
  let valueOptions;
39
- if (typeof colDef.valueOptions === 'function') {
40
- valueOptions = colDef.valueOptions({
47
+ if (typeof colDef?.valueOptions === 'function') {
48
+ valueOptions = colDef?.valueOptions({
41
49
  id,
42
50
  row,
43
51
  field
44
52
  });
45
53
  } else {
46
- valueOptions = colDef.valueOptions;
54
+ valueOptions = colDef?.valueOptions;
55
+ }
56
+ if (!valueOptions) {
57
+ return null;
47
58
  }
48
59
  const handleChange = async event => {
49
60
  setOpen(false);
@@ -78,11 +89,6 @@ function GridEditSingleSelectCell(props) {
78
89
  }
79
90
  setOpen(true);
80
91
  };
81
- useEnhancedEffect(() => {
82
- if (hasFocus) {
83
- inputRef.current.focus();
84
- }
85
- }, [hasFocus]);
86
92
  const OptionComponent = isSelectNative ? 'option' : MenuItem;
87
93
  return /*#__PURE__*/_jsx(rootProps.components.BaseSelect, _extends({
88
94
  ref: ref,