@mui/x-data-grid-premium 6.9.0 → 6.9.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 (39) hide show
  1. package/CHANGELOG.md +136 -8
  2. package/DataGridPremium/DataGridPremium.js +4 -1
  3. package/DataGridPremium/useDataGridPremiumComponent.js +1 -1
  4. package/README.md +1 -1
  5. package/hooks/features/aggregation/wrapColumnWithAggregation.js +28 -11
  6. package/hooks/features/cellSelection/useGridCellSelection.js +128 -11
  7. package/hooks/features/export/serializer/excelSerializer.js +2 -2
  8. package/hooks/features/rowGrouping/createGroupingColDef.js +3 -24
  9. package/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -3
  10. package/index.js +1 -1
  11. package/legacy/DataGridPremium/DataGridPremium.js +4 -1
  12. package/legacy/DataGridPremium/useDataGridPremiumComponent.js +1 -1
  13. package/legacy/hooks/features/aggregation/wrapColumnWithAggregation.js +28 -11
  14. package/legacy/hooks/features/cellSelection/useGridCellSelection.js +122 -11
  15. package/legacy/hooks/features/export/serializer/excelSerializer.js +2 -2
  16. package/legacy/hooks/features/rowGrouping/createGroupingColDef.js +3 -28
  17. package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -3
  18. package/legacy/index.js +1 -1
  19. package/legacy/utils/releaseInfo.js +1 -1
  20. package/modern/DataGridPremium/DataGridPremium.js +4 -1
  21. package/modern/DataGridPremium/useDataGridPremiumComponent.js +1 -1
  22. package/modern/hooks/features/aggregation/wrapColumnWithAggregation.js +28 -11
  23. package/modern/hooks/features/cellSelection/useGridCellSelection.js +121 -8
  24. package/modern/hooks/features/export/serializer/excelSerializer.js +2 -2
  25. package/modern/hooks/features/rowGrouping/createGroupingColDef.js +2 -22
  26. package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -3
  27. package/modern/index.js +1 -1
  28. package/modern/utils/releaseInfo.js +1 -1
  29. package/node/DataGridPremium/DataGridPremium.js +4 -1
  30. package/node/DataGridPremium/useDataGridPremiumComponent.js +1 -1
  31. package/node/hooks/features/aggregation/wrapColumnWithAggregation.js +28 -11
  32. package/node/hooks/features/cellSelection/useGridCellSelection.js +120 -7
  33. package/node/hooks/features/export/serializer/excelSerializer.js +2 -2
  34. package/node/hooks/features/rowGrouping/createGroupingColDef.js +2 -22
  35. package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -3
  36. package/node/index.js +1 -1
  37. package/node/utils/releaseInfo.js +1 -1
  38. package/package.json +4 -4
  39. package/utils/releaseInfo.js +1 -1
@@ -4,7 +4,7 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4
4
  import _typeof from "@babel/runtime/helpers/esm/typeof";
5
5
  import _extends from "@babel/runtime/helpers/esm/extends";
6
6
  import * as React from 'react';
7
- import { useEventCallback } from '@mui/material/utils';
7
+ import { ownerDocument, useEventCallback } from '@mui/material/utils';
8
8
  import { isNavigationKey, serializeCellValue, useGridRegisterPipeProcessor, useGridVisibleRows } from '@mui/x-data-grid-pro/internals';
9
9
  import { useGridApiEventHandler, useGridApiMethod, GRID_ACTIONS_COLUMN_TYPE, GRID_CHECKBOX_SELECTION_COL_DEF, GRID_DETAIL_PANEL_TOGGLE_FIELD, gridRowsDataRowIdToIdLookupSelector, gridClasses, gridFocusCellSelector } from '@mui/x-data-grid-pro';
10
10
  import { gridCellSelectionStateSelector } from './gridCellSelectionSelector';
@@ -17,10 +17,15 @@ export var cellSelectionStateInitializer = function cellSelectionStateInitialize
17
17
  function isKeyboardEvent(event) {
18
18
  return !!event.key;
19
19
  }
20
+ var AUTO_SCROLL_SENSITIVITY = 50; // The distance from the edge to start scrolling
21
+ var AUTO_SCROLL_SPEED = 20; // The speed to scroll once the mouse enters the sensitivity area
22
+
20
23
  export var useGridCellSelection = function useGridCellSelection(apiRef, props) {
21
24
  var visibleRows = useGridVisibleRows(apiRef, props);
22
25
  var cellWithVirtualFocus = React.useRef();
23
26
  var lastMouseDownCell = React.useRef();
27
+ var mousePosition = React.useRef(null);
28
+ var autoScrollRAF = React.useRef();
24
29
  var ignoreValueFormatterProp = props.unstable_ignoreValueFormatterDuringExport;
25
30
  var ignoreValueFormatter = (_typeof(ignoreValueFormatterProp) === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.clipboardExport : ignoreValueFormatterProp) || false;
26
31
  var clipboardCopyCellDelimiter = props.clipboardCopyCellDelimiter;
@@ -130,8 +135,16 @@ export var useGridCellSelection = function useGridCellSelection(apiRef, props) {
130
135
  }
131
136
  return params.rowNode.type !== 'pinnedRow';
132
137
  }, [apiRef]);
133
- var handleCellMouseDown = React.useCallback(function (params, event) {
138
+ var handleMouseUp = useEventCallback(function () {
134
139
  var _apiRef$current$rootE, _apiRef$current$rootE2;
140
+ lastMouseDownCell.current = null;
141
+ (_apiRef$current$rootE = apiRef.current.rootElementRef) == null ? void 0 : (_apiRef$current$rootE2 = _apiRef$current$rootE.current) == null ? void 0 : _apiRef$current$rootE2.classList.remove(gridClasses['root--disableUserSelection']);
142
+
143
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
144
+ stopAutoScroll();
145
+ });
146
+ var handleCellMouseDown = React.useCallback(function (params, event) {
147
+ var _apiRef$current$rootE3, _apiRef$current$rootE4, _apiRef$current$rootE5;
135
148
  // Skip if the click comes from the right-button or, only on macOS, Ctrl is pressed
136
149
  // Fix for https://github.com/mui/mui-x/pull/6567#issuecomment-1329155578
137
150
  var isMacOs = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0;
@@ -146,20 +159,82 @@ export var useGridCellSelection = function useGridCellSelection(apiRef, props) {
146
159
  id: params.id,
147
160
  field: params.field
148
161
  };
149
- (_apiRef$current$rootE = apiRef.current.rootElementRef) == null ? void 0 : (_apiRef$current$rootE2 = _apiRef$current$rootE.current) == null ? void 0 : _apiRef$current$rootE2.classList.add(gridClasses['root--disableUserSelection']);
150
- }, [apiRef, hasClickedValidCellForRangeSelection]);
151
- var handleCellMouseUp = React.useCallback(function () {
152
- var _apiRef$current$rootE3, _apiRef$current$rootE4;
153
- lastMouseDownCell.current = null;
154
- (_apiRef$current$rootE3 = apiRef.current.rootElementRef) == null ? void 0 : (_apiRef$current$rootE4 = _apiRef$current$rootE3.current) == null ? void 0 : _apiRef$current$rootE4.classList.remove(gridClasses['root--disableUserSelection']);
155
- }, [apiRef]);
162
+ (_apiRef$current$rootE3 = apiRef.current.rootElementRef) == null ? void 0 : (_apiRef$current$rootE4 = _apiRef$current$rootE3.current) == null ? void 0 : _apiRef$current$rootE4.classList.add(gridClasses['root--disableUserSelection']);
163
+ var document = ownerDocument((_apiRef$current$rootE5 = apiRef.current.rootElementRef) == null ? void 0 : _apiRef$current$rootE5.current);
164
+ document.addEventListener('mouseup', handleMouseUp, {
165
+ once: true
166
+ });
167
+ }, [apiRef, handleMouseUp, hasClickedValidCellForRangeSelection]);
168
+ var stopAutoScroll = React.useCallback(function () {
169
+ if (autoScrollRAF.current) {
170
+ cancelAnimationFrame(autoScrollRAF.current);
171
+ autoScrollRAF.current = null;
172
+ }
173
+ }, []);
156
174
  var handleCellFocusIn = React.useCallback(function (params) {
157
175
  cellWithVirtualFocus.current = {
158
176
  id: params.id,
159
177
  field: params.field
160
178
  };
161
179
  }, []);
180
+ var startAutoScroll = React.useCallback(function () {
181
+ var _apiRef$current$virtu, _apiRef$current$virtu2, _apiRef$current$virtu3;
182
+ if (autoScrollRAF.current) {
183
+ return;
184
+ }
185
+ if (!((_apiRef$current$virtu = apiRef.current.virtualScrollerRef) != null && _apiRef$current$virtu.current)) {
186
+ return;
187
+ }
188
+ var virtualScrollerRect = (_apiRef$current$virtu2 = apiRef.current.virtualScrollerRef) == null ? void 0 : (_apiRef$current$virtu3 = _apiRef$current$virtu2.current) == null ? void 0 : _apiRef$current$virtu3.getBoundingClientRect();
189
+ if (!virtualScrollerRect) {
190
+ return;
191
+ }
192
+ function autoScroll() {
193
+ var _apiRef$current$virtu4;
194
+ if (!mousePosition.current || !((_apiRef$current$virtu4 = apiRef.current.virtualScrollerRef) != null && _apiRef$current$virtu4.current)) {
195
+ return;
196
+ }
197
+ var _mousePosition$curren = mousePosition.current,
198
+ mouseX = _mousePosition$curren.x,
199
+ mouseY = _mousePosition$curren.y;
200
+ var height = virtualScrollerRect.height,
201
+ width = virtualScrollerRect.width;
202
+ var deltaX = 0;
203
+ var deltaY = 0;
204
+ var factor = 0;
205
+ var dimensions = apiRef.current.getRootDimensions();
206
+ if (mouseY <= AUTO_SCROLL_SENSITIVITY && dimensions != null && dimensions.hasScrollY) {
207
+ // When scrolling up, the multiplier increases going closer to the top edge
208
+ factor = (AUTO_SCROLL_SENSITIVITY - mouseY) / -AUTO_SCROLL_SENSITIVITY;
209
+ deltaY = AUTO_SCROLL_SPEED;
210
+ } else if (mouseY >= height - AUTO_SCROLL_SENSITIVITY && dimensions != null && dimensions.hasScrollY) {
211
+ // When scrolling down, the multiplier increases going closer to the bottom edge
212
+ factor = (mouseY - (height - AUTO_SCROLL_SENSITIVITY)) / AUTO_SCROLL_SENSITIVITY;
213
+ deltaY = AUTO_SCROLL_SPEED;
214
+ } else if (mouseX <= AUTO_SCROLL_SENSITIVITY && dimensions != null && dimensions.hasScrollX) {
215
+ // When scrolling left, the multiplier increases going closer to the left edge
216
+ factor = (AUTO_SCROLL_SENSITIVITY - mouseX) / -AUTO_SCROLL_SENSITIVITY;
217
+ deltaX = AUTO_SCROLL_SPEED;
218
+ } else if (mouseX >= width - AUTO_SCROLL_SENSITIVITY && dimensions != null && dimensions.hasScrollX) {
219
+ // When scrolling right, the multiplier increases going closer to the right edge
220
+ factor = (mouseX - (width - AUTO_SCROLL_SENSITIVITY)) / AUTO_SCROLL_SENSITIVITY;
221
+ deltaX = AUTO_SCROLL_SPEED;
222
+ }
223
+ if (deltaX !== 0 || deltaY !== 0) {
224
+ var _apiRef$current$virtu5 = apiRef.current.virtualScrollerRef.current,
225
+ scrollLeft = _apiRef$current$virtu5.scrollLeft,
226
+ scrollTop = _apiRef$current$virtu5.scrollTop;
227
+ apiRef.current.scroll({
228
+ top: scrollTop + deltaY * factor,
229
+ left: scrollLeft + deltaX * factor
230
+ });
231
+ }
232
+ autoScrollRAF.current = requestAnimationFrame(autoScroll);
233
+ }
234
+ autoScroll();
235
+ }, [apiRef]);
162
236
  var handleCellMouseOver = React.useCallback(function (params, event) {
237
+ var _apiRef$current$virtu6, _apiRef$current$virtu7;
163
238
  if (!lastMouseDownCell.current) {
164
239
  return;
165
240
  }
@@ -169,7 +244,31 @@ export var useGridCellSelection = function useGridCellSelection(apiRef, props) {
169
244
  id: id,
170
245
  field: field
171
246
  }, event.ctrlKey || event.metaKey);
172
- }, [apiRef]);
247
+ var virtualScrollerRect = (_apiRef$current$virtu6 = apiRef.current.virtualScrollerRef) == null ? void 0 : (_apiRef$current$virtu7 = _apiRef$current$virtu6.current) == null ? void 0 : _apiRef$current$virtu7.getBoundingClientRect();
248
+ if (!virtualScrollerRect) {
249
+ return;
250
+ }
251
+ var height = virtualScrollerRect.height,
252
+ width = virtualScrollerRect.width,
253
+ x = virtualScrollerRect.x,
254
+ y = virtualScrollerRect.y;
255
+ var mouseX = event.clientX - x;
256
+ var mouseY = event.clientY - y;
257
+ mousePosition.current = {
258
+ x: mouseX,
259
+ y: mouseY
260
+ };
261
+ var hasEnteredVerticalSensitivityArea = mouseY <= AUTO_SCROLL_SENSITIVITY || mouseY >= height - AUTO_SCROLL_SENSITIVITY;
262
+ var hasEnteredHorizontalSensitivityArea = mouseX <= AUTO_SCROLL_SENSITIVITY || mouseX >= width - AUTO_SCROLL_SENSITIVITY;
263
+ var hasEnteredSensitivityArea = hasEnteredVerticalSensitivityArea || hasEnteredHorizontalSensitivityArea;
264
+ if (hasEnteredSensitivityArea) {
265
+ // Mouse has entered the sensitity area for the first time
266
+ startAutoScroll();
267
+ } else {
268
+ // Mouse has left the sensitivity area while auto scroll is on
269
+ stopAutoScroll();
270
+ }
271
+ }, [apiRef, startAutoScroll, stopAutoScroll]);
173
272
  var handleCellClick = useEventCallback(function (params, event) {
174
273
  var id = params.id,
175
274
  field = params.field;
@@ -228,6 +327,10 @@ export var useGridCellSelection = function useGridCellSelection(apiRef, props) {
228
327
  id: visibleRows.rows[endRowIndex].id,
229
328
  field: visibleColumns[endColumnIndex].field
230
329
  };
330
+ apiRef.current.scrollToIndexes({
331
+ rowIndex: endRowIndex,
332
+ colIndex: endColumnIndex
333
+ });
231
334
  var id = params.id,
232
335
  field = params.field;
233
336
  apiRef.current.unstable_selectCellRange({
@@ -239,13 +342,21 @@ export var useGridCellSelection = function useGridCellSelection(apiRef, props) {
239
342
  useGridApiEventHandler(apiRef, 'cellFocusIn', runIfCellSelectionIsEnabled(handleCellFocusIn));
240
343
  useGridApiEventHandler(apiRef, 'cellKeyDown', runIfCellSelectionIsEnabled(handleCellKeyDown));
241
344
  useGridApiEventHandler(apiRef, 'cellMouseDown', runIfCellSelectionIsEnabled(handleCellMouseDown));
242
- useGridApiEventHandler(apiRef, 'cellMouseUp', runIfCellSelectionIsEnabled(handleCellMouseUp));
243
345
  useGridApiEventHandler(apiRef, 'cellMouseOver', runIfCellSelectionIsEnabled(handleCellMouseOver));
244
346
  React.useEffect(function () {
245
347
  if (props.unstable_cellSelectionModel) {
246
348
  apiRef.current.unstable_setCellSelectionModel(props.unstable_cellSelectionModel);
247
349
  }
248
350
  }, [apiRef, props.unstable_cellSelectionModel]);
351
+ React.useEffect(function () {
352
+ var _apiRef$current$rootE6;
353
+ var rootRef = (_apiRef$current$rootE6 = apiRef.current.rootElementRef) == null ? void 0 : _apiRef$current$rootE6.current;
354
+ return function () {
355
+ stopAutoScroll();
356
+ var document = ownerDocument(rootRef);
357
+ document.removeEventListener('mouseup', handleMouseUp);
358
+ };
359
+ }, [apiRef, handleMouseUp, stopAutoScroll]);
249
360
  var checkIfCellIsSelected = React.useCallback(function (isSelected, _ref5) {
250
361
  var id = _ref5.id,
251
362
  field = _ref5.field;
@@ -131,7 +131,7 @@ export var serializeRow = function serializeRow(id, columns, api, defaultValueOp
131
131
  {
132
132
  // Excel does not do any timezone conversion, so we create a date using UTC instead of local timezone
133
133
  // Solution from: https://github.com/exceljs/exceljs/issues/486#issuecomment-432557582
134
- // About Date.UTC(): https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
134
+ // About Date.UTC(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
135
135
  var value = api.getCellParams(id, column.field).value;
136
136
  // value may be `undefined` in auto-generated grouping rows
137
137
  if (!value) {
@@ -174,7 +174,7 @@ export var serializeColumn = function serializeColumn(column, columnsStyles) {
174
174
  headerText: (_column$headerName = column.headerName) != null ? _column$headerName : column.field,
175
175
  // Excel width must stay between 0 and 255 (https://support.microsoft.com/en-us/office/change-the-column-width-and-row-height-72f5e3cc-994d-43e8-ae58-9774a0905f46)
176
176
  // From the example of column width behavior (https://docs.microsoft.com/en-US/office/troubleshoot/excel/determine-column-widths#example-of-column-width-behavior)
177
- // a value of 10 corresponds to 75px. This is an approximation, because column width depends on the the font-size
177
+ // a value of 10 corresponds to 75px. This is an approximation, because column width depends on the font-size
178
178
  width: Math.min(255, column.width ? column.width / 7.5 : 8.43),
179
179
  style: _extends({}, type && (defaultColumnsStyles == null ? void 0 : defaultColumnsStyles[type]), columnsStyles == null ? void 0 : columnsStyles[field])
180
180
  };
@@ -46,25 +46,13 @@ var groupingFieldIndexComparator = function groupingFieldIndexComparator(v1, v2,
46
46
  return 1;
47
47
  };
48
48
  var getLeafProperties = function getLeafProperties(leafColDef) {
49
- var _leafColDef$headerNam, _leafColDef$filterOpe;
49
+ var _leafColDef$headerNam;
50
50
  return {
51
51
  headerName: (_leafColDef$headerNam = leafColDef.headerName) != null ? _leafColDef$headerNam : leafColDef.field,
52
52
  sortable: leafColDef.sortable,
53
53
  filterable: leafColDef.filterable,
54
54
  valueOptions: isSingleSelectColDef(leafColDef) ? leafColDef.valueOptions : undefined,
55
- filterOperators: (_leafColDef$filterOpe = leafColDef.filterOperators) == null ? void 0 : _leafColDef$filterOpe.map(function (operator) {
56
- return _extends({}, operator, {
57
- getApplyFilterFn: function getApplyFilterFn(filterItem, column) {
58
- var originalFn = operator.getApplyFilterFn(filterItem, column);
59
- if (!originalFn) {
60
- return null;
61
- }
62
- return function (params) {
63
- return originalFn(params);
64
- };
65
- }
66
- });
67
- }),
55
+ filterOperators: leafColDef.filterOperators,
68
56
  sortComparator: function sortComparator(v1, v2, cellParams1, cellParams2) {
69
57
  // We only want to sort the leaves
70
58
  if (cellParams1.rowNode.type === 'leaf' && cellParams2.rowNode.type === 'leaf') {
@@ -75,7 +63,6 @@ var getLeafProperties = function getLeafProperties(leafColDef) {
75
63
  };
76
64
  };
77
65
  var getGroupingCriteriaProperties = function getGroupingCriteriaProperties(groupedByColDef, applyHeaderName) {
78
- var _groupedByColDef$filt;
79
66
  var properties = {
80
67
  sortable: groupedByColDef.sortable,
81
68
  filterable: groupedByColDef.filterable,
@@ -87,19 +74,7 @@ var getGroupingCriteriaProperties = function getGroupingCriteriaProperties(group
87
74
  }
88
75
  return groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2);
89
76
  },
90
- filterOperators: (_groupedByColDef$filt = groupedByColDef.filterOperators) == null ? void 0 : _groupedByColDef$filt.map(function (operator) {
91
- return _extends({}, operator, {
92
- getApplyFilterFn: function getApplyFilterFn(filterItem, column) {
93
- var originalFn = operator.getApplyFilterFn(filterItem, column);
94
- if (!originalFn) {
95
- return null;
96
- }
97
- return function (params) {
98
- return originalFn(params);
99
- };
100
- }
101
- });
102
- })
77
+ filterOperators: groupedByColDef.filterOperators
103
78
  };
104
79
  if (applyHeaderName) {
105
80
  var _groupedByColDef$head;
@@ -38,23 +38,25 @@ var shouldApplyFilterItemOnGroup = function shouldApplyFilterItemOnGroup(columnF
38
38
  * - It is passing the filter
39
39
  */
40
40
  export var filterRowTreeFromGroupingColumns = function filterRowTreeFromGroupingColumns(params) {
41
- var rowTree = params.rowTree,
41
+ var apiRef = params.apiRef,
42
+ rowTree = params.rowTree,
42
43
  isRowMatchingFilters = params.isRowMatchingFilters,
43
44
  filterModel = params.filterModel;
44
45
  var filteredRowsLookup = {};
45
46
  var filteredDescendantCountLookup = {};
46
47
  var filterCache = {};
47
48
  var filterTreeNode = function filterTreeNode(node, areAncestorsExpanded, ancestorsResults) {
48
- var isPassingFiltering = false;
49
49
  var filterResults = {
50
50
  passingFilterItems: null,
51
51
  passingQuickFilterValues: null
52
52
  };
53
+ var isPassingFiltering = false;
53
54
  if (isRowMatchingFilters && node.type !== 'footer') {
54
55
  var shouldApplyItem = node.type === 'group' && node.isAutoGenerated ? function (columnField) {
55
56
  return shouldApplyFilterItemOnGroup(columnField, node);
56
57
  } : undefined;
57
- filterResults = isRowMatchingFilters(node.id, shouldApplyItem);
58
+ var row = apiRef.current.getRow(node.id);
59
+ isRowMatchingFilters(row, shouldApplyItem, filterResults);
58
60
  } else {
59
61
  isPassingFiltering = true;
60
62
  }
package/legacy/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-premium v6.9.0
2
+ * @mui/x-data-grid-premium v6.9.2
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export var getReleaseInfo = function getReleaseInfo() {
3
- var releaseInfo = "MTY4NzM4MTIwMDAwMA==";
3
+ var releaseInfo = "MTY4ODU5MDgwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat
@@ -740,7 +740,10 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
740
740
  * Select the pageSize dynamically using the component UI.
741
741
  * @default [25, 50, 100]
742
742
  */
743
- pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
743
+ pageSizeOptions: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
744
+ label: PropTypes.string.isRequired,
745
+ value: PropTypes.number.isRequired
746
+ })]).isRequired),
744
747
  /**
745
748
  * If `true`, pagination is enabled.
746
749
  * @default false
@@ -62,7 +62,7 @@ export const useDataGridPremiumComponent = (inputApiRef, props) => {
62
62
  useGridRowPinning(privateApiRef, props);
63
63
  useGridColumns(privateApiRef, props);
64
64
  useGridRows(privateApiRef, props);
65
- useGridParamsApi(privateApiRef);
65
+ useGridParamsApi(privateApiRef, props);
66
66
  useGridDetailPanel(privateApiRef, props);
67
67
  useGridColumnSpanning(privateApiRef);
68
68
  useGridColumnGrouping(privateApiRef, props);
@@ -1,5 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
+ import { tagInternalFilter } from '@mui/x-data-grid-pro/internals';
3
4
  import { gridAggregationLookupSelector } from './gridAggregationSelectors';
4
5
  import { GridFooterCell } from '../../../components/GridFooterCell';
5
6
  import { GridAggregationHeader } from '../../../components/GridAggregationHeader';
@@ -82,19 +83,35 @@ const getWrappedFilterOperators = ({
82
83
  value: filterOperators,
83
84
  getCellAggregationResult
84
85
  }) => filterOperators.map(operator => {
85
- return _extends({}, operator, {
86
- getApplyFilterFn: (filterItem, column) => {
87
- const originalFn = operator.getApplyFilterFn(filterItem, column);
88
- if (!originalFn) {
89
- return null;
86
+ const baseGetApplyFilterFn = operator.getApplyFilterFn;
87
+ const baseGetApplyFilterFnV7 = operator.getApplyFilterFnV7;
88
+ const getApplyFilterFn = tagInternalFilter((filterItem, colDef) => {
89
+ const filterFn = baseGetApplyFilterFn(filterItem, colDef);
90
+ if (!filterFn) {
91
+ return null;
92
+ }
93
+ return params => {
94
+ if (getCellAggregationResult(params.id, params.field) != null) {
95
+ return true;
90
96
  }
91
- return params => {
92
- if (getCellAggregationResult(params.id, params.field) != null) {
93
- return true;
94
- }
95
- return originalFn(params);
96
- };
97
+ return filterFn(params);
98
+ };
99
+ });
100
+ const getApplyFilterFnV7 = baseGetApplyFilterFnV7 === undefined ? undefined : tagInternalFilter((filterItem, colDef) => {
101
+ const filterFn = baseGetApplyFilterFnV7(filterItem, colDef);
102
+ if (!filterFn) {
103
+ return null;
97
104
  }
105
+ return (value, row, column, api) => {
106
+ if (getCellAggregationResult(row.id, column.field) != null) {
107
+ return true;
108
+ }
109
+ return filterFn(value, row, column, api);
110
+ };
111
+ });
112
+ return _extends({}, operator, {
113
+ getApplyFilterFn,
114
+ getApplyFilterFnV7
98
115
  });
99
116
  });
100
117
 
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { useEventCallback } from '@mui/material/utils';
3
+ import { ownerDocument, useEventCallback } from '@mui/material/utils';
4
4
  import { isNavigationKey, serializeCellValue, useGridRegisterPipeProcessor, useGridVisibleRows } from '@mui/x-data-grid-pro/internals';
5
5
  import { useGridApiEventHandler, useGridApiMethod, GRID_ACTIONS_COLUMN_TYPE, GRID_CHECKBOX_SELECTION_COL_DEF, GRID_DETAIL_PANEL_TOGGLE_FIELD, gridRowsDataRowIdToIdLookupSelector, gridClasses, gridFocusCellSelector } from '@mui/x-data-grid-pro';
6
6
  import { gridCellSelectionStateSelector } from './gridCellSelectionSelector';
@@ -10,10 +10,15 @@ export const cellSelectionStateInitializer = (state, props) => _extends({}, stat
10
10
  function isKeyboardEvent(event) {
11
11
  return !!event.key;
12
12
  }
13
+ const AUTO_SCROLL_SENSITIVITY = 50; // The distance from the edge to start scrolling
14
+ const AUTO_SCROLL_SPEED = 20; // The speed to scroll once the mouse enters the sensitivity area
15
+
13
16
  export const useGridCellSelection = (apiRef, props) => {
14
17
  const visibleRows = useGridVisibleRows(apiRef, props);
15
18
  const cellWithVirtualFocus = React.useRef();
16
19
  const lastMouseDownCell = React.useRef();
20
+ const mousePosition = React.useRef(null);
21
+ const autoScrollRAF = React.useRef();
17
22
  const ignoreValueFormatterProp = props.unstable_ignoreValueFormatterDuringExport;
18
23
  const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp?.clipboardExport : ignoreValueFormatterProp) || false;
19
24
  const clipboardCopyCellDelimiter = props.clipboardCopyCellDelimiter;
@@ -110,6 +115,13 @@ export const useGridCellSelection = (apiRef, props) => {
110
115
  }
111
116
  return params.rowNode.type !== 'pinnedRow';
112
117
  }, [apiRef]);
118
+ const handleMouseUp = useEventCallback(() => {
119
+ lastMouseDownCell.current = null;
120
+ apiRef.current.rootElementRef?.current?.classList.remove(gridClasses['root--disableUserSelection']);
121
+
122
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
123
+ stopAutoScroll();
124
+ });
113
125
  const handleCellMouseDown = React.useCallback((params, event) => {
114
126
  // Skip if the click comes from the right-button or, only on macOS, Ctrl is pressed
115
127
  // Fix for https://github.com/mui/mui-x/pull/6567#issuecomment-1329155578
@@ -126,17 +138,81 @@ export const useGridCellSelection = (apiRef, props) => {
126
138
  field: params.field
127
139
  };
128
140
  apiRef.current.rootElementRef?.current?.classList.add(gridClasses['root--disableUserSelection']);
129
- }, [apiRef, hasClickedValidCellForRangeSelection]);
130
- const handleCellMouseUp = React.useCallback(() => {
131
- lastMouseDownCell.current = null;
132
- apiRef.current.rootElementRef?.current?.classList.remove(gridClasses['root--disableUserSelection']);
133
- }, [apiRef]);
141
+ const document = ownerDocument(apiRef.current.rootElementRef?.current);
142
+ document.addEventListener('mouseup', handleMouseUp, {
143
+ once: true
144
+ });
145
+ }, [apiRef, handleMouseUp, hasClickedValidCellForRangeSelection]);
146
+ const stopAutoScroll = React.useCallback(() => {
147
+ if (autoScrollRAF.current) {
148
+ cancelAnimationFrame(autoScrollRAF.current);
149
+ autoScrollRAF.current = null;
150
+ }
151
+ }, []);
134
152
  const handleCellFocusIn = React.useCallback(params => {
135
153
  cellWithVirtualFocus.current = {
136
154
  id: params.id,
137
155
  field: params.field
138
156
  };
139
157
  }, []);
158
+ const startAutoScroll = React.useCallback(() => {
159
+ if (autoScrollRAF.current) {
160
+ return;
161
+ }
162
+ if (!apiRef.current.virtualScrollerRef?.current) {
163
+ return;
164
+ }
165
+ const virtualScrollerRect = apiRef.current.virtualScrollerRef?.current?.getBoundingClientRect();
166
+ if (!virtualScrollerRect) {
167
+ return;
168
+ }
169
+ function autoScroll() {
170
+ if (!mousePosition.current || !apiRef.current.virtualScrollerRef?.current) {
171
+ return;
172
+ }
173
+ const {
174
+ x: mouseX,
175
+ y: mouseY
176
+ } = mousePosition.current;
177
+ const {
178
+ height,
179
+ width
180
+ } = virtualScrollerRect;
181
+ let deltaX = 0;
182
+ let deltaY = 0;
183
+ let factor = 0;
184
+ const dimensions = apiRef.current.getRootDimensions();
185
+ if (mouseY <= AUTO_SCROLL_SENSITIVITY && dimensions?.hasScrollY) {
186
+ // When scrolling up, the multiplier increases going closer to the top edge
187
+ factor = (AUTO_SCROLL_SENSITIVITY - mouseY) / -AUTO_SCROLL_SENSITIVITY;
188
+ deltaY = AUTO_SCROLL_SPEED;
189
+ } else if (mouseY >= height - AUTO_SCROLL_SENSITIVITY && dimensions?.hasScrollY) {
190
+ // When scrolling down, the multiplier increases going closer to the bottom edge
191
+ factor = (mouseY - (height - AUTO_SCROLL_SENSITIVITY)) / AUTO_SCROLL_SENSITIVITY;
192
+ deltaY = AUTO_SCROLL_SPEED;
193
+ } else if (mouseX <= AUTO_SCROLL_SENSITIVITY && dimensions?.hasScrollX) {
194
+ // When scrolling left, the multiplier increases going closer to the left edge
195
+ factor = (AUTO_SCROLL_SENSITIVITY - mouseX) / -AUTO_SCROLL_SENSITIVITY;
196
+ deltaX = AUTO_SCROLL_SPEED;
197
+ } else if (mouseX >= width - AUTO_SCROLL_SENSITIVITY && dimensions?.hasScrollX) {
198
+ // When scrolling right, the multiplier increases going closer to the right edge
199
+ factor = (mouseX - (width - AUTO_SCROLL_SENSITIVITY)) / AUTO_SCROLL_SENSITIVITY;
200
+ deltaX = AUTO_SCROLL_SPEED;
201
+ }
202
+ if (deltaX !== 0 || deltaY !== 0) {
203
+ const {
204
+ scrollLeft,
205
+ scrollTop
206
+ } = apiRef.current.virtualScrollerRef.current;
207
+ apiRef.current.scroll({
208
+ top: scrollTop + deltaY * factor,
209
+ left: scrollLeft + deltaX * factor
210
+ });
211
+ }
212
+ autoScrollRAF.current = requestAnimationFrame(autoScroll);
213
+ }
214
+ autoScroll();
215
+ }, [apiRef]);
140
216
  const handleCellMouseOver = React.useCallback((params, event) => {
141
217
  if (!lastMouseDownCell.current) {
142
218
  return;
@@ -149,7 +225,33 @@ export const useGridCellSelection = (apiRef, props) => {
149
225
  id,
150
226
  field
151
227
  }, event.ctrlKey || event.metaKey);
152
- }, [apiRef]);
228
+ const virtualScrollerRect = apiRef.current.virtualScrollerRef?.current?.getBoundingClientRect();
229
+ if (!virtualScrollerRect) {
230
+ return;
231
+ }
232
+ const {
233
+ height,
234
+ width,
235
+ x,
236
+ y
237
+ } = virtualScrollerRect;
238
+ const mouseX = event.clientX - x;
239
+ const mouseY = event.clientY - y;
240
+ mousePosition.current = {
241
+ x: mouseX,
242
+ y: mouseY
243
+ };
244
+ const hasEnteredVerticalSensitivityArea = mouseY <= AUTO_SCROLL_SENSITIVITY || mouseY >= height - AUTO_SCROLL_SENSITIVITY;
245
+ const hasEnteredHorizontalSensitivityArea = mouseX <= AUTO_SCROLL_SENSITIVITY || mouseX >= width - AUTO_SCROLL_SENSITIVITY;
246
+ const hasEnteredSensitivityArea = hasEnteredVerticalSensitivityArea || hasEnteredHorizontalSensitivityArea;
247
+ if (hasEnteredSensitivityArea) {
248
+ // Mouse has entered the sensitity area for the first time
249
+ startAutoScroll();
250
+ } else {
251
+ // Mouse has left the sensitivity area while auto scroll is on
252
+ stopAutoScroll();
253
+ }
254
+ }, [apiRef, startAutoScroll, stopAutoScroll]);
153
255
  const handleCellClick = useEventCallback((params, event) => {
154
256
  const {
155
257
  id,
@@ -220,6 +322,10 @@ export const useGridCellSelection = (apiRef, props) => {
220
322
  id: visibleRows.rows[endRowIndex].id,
221
323
  field: visibleColumns[endColumnIndex].field
222
324
  };
325
+ apiRef.current.scrollToIndexes({
326
+ rowIndex: endRowIndex,
327
+ colIndex: endColumnIndex
328
+ });
223
329
  const {
224
330
  id,
225
331
  field
@@ -233,13 +339,20 @@ export const useGridCellSelection = (apiRef, props) => {
233
339
  useGridApiEventHandler(apiRef, 'cellFocusIn', runIfCellSelectionIsEnabled(handleCellFocusIn));
234
340
  useGridApiEventHandler(apiRef, 'cellKeyDown', runIfCellSelectionIsEnabled(handleCellKeyDown));
235
341
  useGridApiEventHandler(apiRef, 'cellMouseDown', runIfCellSelectionIsEnabled(handleCellMouseDown));
236
- useGridApiEventHandler(apiRef, 'cellMouseUp', runIfCellSelectionIsEnabled(handleCellMouseUp));
237
342
  useGridApiEventHandler(apiRef, 'cellMouseOver', runIfCellSelectionIsEnabled(handleCellMouseOver));
238
343
  React.useEffect(() => {
239
344
  if (props.unstable_cellSelectionModel) {
240
345
  apiRef.current.unstable_setCellSelectionModel(props.unstable_cellSelectionModel);
241
346
  }
242
347
  }, [apiRef, props.unstable_cellSelectionModel]);
348
+ React.useEffect(() => {
349
+ const rootRef = apiRef.current.rootElementRef?.current;
350
+ return () => {
351
+ stopAutoScroll();
352
+ const document = ownerDocument(rootRef);
353
+ document.removeEventListener('mouseup', handleMouseUp);
354
+ };
355
+ }, [apiRef, handleMouseUp, stopAutoScroll]);
243
356
  const checkIfCellIsSelected = React.useCallback((isSelected, {
244
357
  id,
245
358
  field
@@ -102,7 +102,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
102
102
  {
103
103
  // Excel does not do any timezone conversion, so we create a date using UTC instead of local timezone
104
104
  // Solution from: https://github.com/exceljs/exceljs/issues/486#issuecomment-432557582
105
- // About Date.UTC(): https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
105
+ // About Date.UTC(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
106
106
  const value = api.getCellParams(id, column.field).value;
107
107
  // value may be `undefined` in auto-generated grouping rows
108
108
  if (!value) {
@@ -149,7 +149,7 @@ export const serializeColumn = (column, columnsStyles) => {
149
149
  headerText: column.headerName ?? column.field,
150
150
  // Excel width must stay between 0 and 255 (https://support.microsoft.com/en-us/office/change-the-column-width-and-row-height-72f5e3cc-994d-43e8-ae58-9774a0905f46)
151
151
  // From the example of column width behavior (https://docs.microsoft.com/en-US/office/troubleshoot/excel/determine-column-widths#example-of-column-width-behavior)
152
- // a value of 10 corresponds to 75px. This is an approximation, because column width depends on the the font-size
152
+ // a value of 10 corresponds to 75px. This is an approximation, because column width depends on the font-size
153
153
  width: Math.min(255, column.width ? column.width / 7.5 : 8.43),
154
154
  style: _extends({}, type && defaultColumnsStyles?.[type], columnsStyles?.[field])
155
155
  };
@@ -48,17 +48,7 @@ const getLeafProperties = leafColDef => ({
48
48
  sortable: leafColDef.sortable,
49
49
  filterable: leafColDef.filterable,
50
50
  valueOptions: isSingleSelectColDef(leafColDef) ? leafColDef.valueOptions : undefined,
51
- filterOperators: leafColDef.filterOperators?.map(operator => _extends({}, operator, {
52
- getApplyFilterFn: (filterItem, column) => {
53
- const originalFn = operator.getApplyFilterFn(filterItem, column);
54
- if (!originalFn) {
55
- return null;
56
- }
57
- return params => {
58
- return originalFn(params);
59
- };
60
- }
61
- })),
51
+ filterOperators: leafColDef.filterOperators,
62
52
  sortComparator: (v1, v2, cellParams1, cellParams2) => {
63
53
  // We only want to sort the leaves
64
54
  if (cellParams1.rowNode.type === 'leaf' && cellParams2.rowNode.type === 'leaf') {
@@ -79,17 +69,7 @@ const getGroupingCriteriaProperties = (groupedByColDef, applyHeaderName) => {
79
69
  }
80
70
  return groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2);
81
71
  },
82
- filterOperators: groupedByColDef.filterOperators?.map(operator => _extends({}, operator, {
83
- getApplyFilterFn: (filterItem, column) => {
84
- const originalFn = operator.getApplyFilterFn(filterItem, column);
85
- if (!originalFn) {
86
- return null;
87
- }
88
- return params => {
89
- return originalFn(params);
90
- };
91
- }
92
- }))
72
+ filterOperators: groupedByColDef.filterOperators
93
73
  };
94
74
  if (applyHeaderName) {
95
75
  properties.headerName = groupedByColDef.headerName ?? groupedByColDef.field;