@mui/x-data-grid-premium 7.0.0-beta.6 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +311 -12
  2. package/DataGridPremium/DataGridPremium.js +26 -18
  3. package/README.md +1 -1
  4. package/esm/DataGridPremium/DataGridPremium.js +26 -18
  5. package/esm/components/GridAggregationHeader.js +1 -2
  6. package/esm/components/GridColumnMenuAggregationItem.js +2 -3
  7. package/esm/components/GridColumnMenuRowGroupItem.js +1 -2
  8. package/esm/components/GridColumnMenuRowUngroupItem.js +1 -2
  9. package/esm/components/GridExcelExportMenuItem.js +1 -1
  10. package/esm/components/GridGroupingColumnLeafCell.js +1 -2
  11. package/esm/components/GridGroupingCriteriaCell.js +2 -3
  12. package/esm/hooks/features/aggregation/gridAggregationUtils.js +4 -4
  13. package/esm/hooks/features/aggregation/useGridAggregation.js +1 -2
  14. package/esm/hooks/features/aggregation/useGridAggregationPreProcessors.js +1 -2
  15. package/esm/hooks/features/aggregation/wrapColumnWithAggregation.js +5 -9
  16. package/esm/hooks/features/cellSelection/useGridCellSelection.js +25 -34
  17. package/esm/hooks/features/clipboard/useGridClipboardImport.js +21 -8
  18. package/esm/hooks/features/export/serializer/excelSerializer.js +9 -22
  19. package/esm/hooks/features/export/useGridExcelExport.js +9 -11
  20. package/esm/hooks/features/rowGrouping/createGroupingColDef.js +23 -32
  21. package/esm/hooks/features/rowGrouping/gridRowGroupingUtils.js +4 -7
  22. package/esm/hooks/features/rowGrouping/useGridRowGrouping.js +5 -9
  23. package/esm/hooks/utils/useKeepGroupedColumnsHidden.js +7 -9
  24. package/esm/utils/releaseInfo.js +1 -1
  25. package/hooks/features/aggregation/wrapColumnWithAggregation.d.ts +1 -1
  26. package/hooks/features/cellSelection/useGridCellSelection.d.ts +1 -1
  27. package/hooks/features/cellSelection/useGridCellSelection.js +12 -12
  28. package/hooks/features/clipboard/useGridClipboardImport.d.ts +1 -1
  29. package/hooks/features/clipboard/useGridClipboardImport.js +18 -3
  30. package/hooks/features/rowGrouping/createGroupingColDef.js +3 -2
  31. package/index.js +1 -1
  32. package/models/dataGridPremiumProps.d.ts +12 -2
  33. package/models/gridApiPremium.d.ts +2 -2
  34. package/modern/DataGridPremium/DataGridPremium.js +26 -18
  35. package/modern/hooks/features/cellSelection/useGridCellSelection.js +14 -14
  36. package/modern/hooks/features/clipboard/useGridClipboardImport.js +19 -4
  37. package/modern/hooks/features/rowGrouping/createGroupingColDef.js +3 -2
  38. package/modern/index.js +1 -1
  39. package/modern/utils/releaseInfo.js +1 -1
  40. package/package.json +7 -7
  41. package/utils/releaseInfo.js +1 -1
@@ -20,13 +20,12 @@ function GridColumnMenuRowGroupItem(props) {
20
20
  const columnsLookup = useGridSelector(apiRef, gridColumnLookupSelector);
21
21
  const rootProps = useGridRootProps();
22
22
  const renderUnGroupingMenuItem = field => {
23
- var _groupedColumn$header;
24
23
  const ungroupColumn = event => {
25
24
  apiRef.current.removeRowGroupingCriteria(field);
26
25
  onClick(event);
27
26
  };
28
27
  const groupedColumn = columnsLookup[field];
29
- const name = (_groupedColumn$header = groupedColumn.headerName) != null ? _groupedColumn$header : field;
28
+ const name = groupedColumn.headerName ?? field;
30
29
  return /*#__PURE__*/_jsxs(MenuItem, {
31
30
  onClick: ungroupColumn,
32
31
  disabled: !groupedColumn.groupable,
@@ -10,7 +10,6 @@ import { useGridRootProps } from '../hooks/utils/useGridRootProps';
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
11
  import { jsxs as _jsxs } from "react/jsx-runtime";
12
12
  function GridColumnMenuRowUngroupItem(props) {
13
- var _columnsLookup$colDef;
14
13
  const {
15
14
  colDef,
16
15
  onClick
@@ -30,7 +29,7 @@ function GridColumnMenuRowUngroupItem(props) {
30
29
  apiRef.current.addRowGroupingCriteria(colDef.field);
31
30
  onClick(event);
32
31
  };
33
- const name = (_columnsLookup$colDef = columnsLookup[colDef.field].headerName) != null ? _columnsLookup$colDef : colDef.field;
32
+ const name = columnsLookup[colDef.field].headerName ?? colDef.field;
34
33
  if (rowGroupingModel.includes(colDef.field)) {
35
34
  return /*#__PURE__*/_jsxs(MenuItem, {
36
35
  onClick: ungroupColumn,
@@ -16,7 +16,7 @@ function GridExcelExportMenuItem(props) {
16
16
  return /*#__PURE__*/_jsx(MenuItem, _extends({
17
17
  onClick: () => {
18
18
  apiRef.current.exportDataAsExcel(options);
19
- hideMenu == null || hideMenu();
19
+ hideMenu?.();
20
20
  }
21
21
  }, other, {
22
22
  children: apiRef.current.getLocaleText('toolbarExportExcel')
@@ -3,7 +3,6 @@ import Box from '@mui/material/Box';
3
3
  import { useGridRootProps } from '../hooks/utils/useGridRootProps';
4
4
  import { jsx as _jsx } from "react/jsx-runtime";
5
5
  function GridGroupingColumnLeafCell(props) {
6
- var _props$formattedValue;
7
6
  const {
8
7
  rowNode
9
8
  } = props;
@@ -12,7 +11,7 @@ function GridGroupingColumnLeafCell(props) {
12
11
  sx: {
13
12
  ml: rootProps.rowGroupingColumnMode === 'multiple' ? 1 : theme => `calc(var(--DataGrid-cellOffsetMultiplier) * ${theme.spacing(rowNode.depth)})`
14
13
  },
15
- children: (_props$formattedValue = props.formattedValue) != null ? _props$formattedValue : props.value
14
+ children: props.formattedValue ?? props.value
16
15
  });
17
16
  }
18
17
  export { GridGroupingColumnLeafCell };
@@ -18,7 +18,6 @@ const useUtilityClasses = ownerState => {
18
18
  return composeClasses(slots, getDataGridUtilityClass, classes);
19
19
  };
20
20
  export function GridGroupingCriteriaCell(props) {
21
- var _filteredDescendantCo, _rootProps$slotProps;
22
21
  const {
23
22
  id,
24
23
  field,
@@ -33,7 +32,7 @@ export function GridGroupingCriteriaCell(props) {
33
32
  };
34
33
  const classes = useUtilityClasses(ownerState);
35
34
  const filteredDescendantCountLookup = useGridSelector(apiRef, gridFilteredDescendantCountLookupSelector);
36
- const filteredDescendantCount = (_filteredDescendantCo = filteredDescendantCountLookup[rowNode.id]) != null ? _filteredDescendantCo : 0;
35
+ const filteredDescendantCount = filteredDescendantCountLookup[rowNode.id] ?? 0;
37
36
  const Icon = rowNode.childrenExpanded ? rootProps.slots.groupingCriteriaCollapseIcon : rootProps.slots.groupingCriteriaExpandIcon;
38
37
  const handleKeyDown = event => {
39
38
  if (event.key === ' ') {
@@ -74,7 +73,7 @@ export function GridGroupingCriteriaCell(props) {
74
73
  onKeyDown: handleKeyDown,
75
74
  tabIndex: -1,
76
75
  "aria-label": rowNode.childrenExpanded ? apiRef.current.getLocaleText('treeDataCollapse') : apiRef.current.getLocaleText('treeDataExpand')
77
- }, (_rootProps$slotProps = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps.baseIconButton, {
76
+ }, rootProps.slotProps?.baseIconButton, {
78
77
  children: /*#__PURE__*/_jsx(Icon, {
79
78
  fontSize: "inherit"
80
79
  })
@@ -143,18 +143,18 @@ export const addFooterRows = ({
143
143
  * Compares two sets of aggregation rules to determine if they are equal or not.
144
144
  */
145
145
  export const areAggregationRulesEqual = (previousValue, newValue) => {
146
- const previousFields = Object.keys(previousValue != null ? previousValue : {});
146
+ const previousFields = Object.keys(previousValue ?? {});
147
147
  const newFields = Object.keys(newValue);
148
148
  if (!isDeepEqual(previousFields, newFields)) {
149
149
  return false;
150
150
  }
151
151
  return newFields.every(field => {
152
- const previousRule = previousValue == null ? void 0 : previousValue[field];
152
+ const previousRule = previousValue?.[field];
153
153
  const newRule = newValue[field];
154
- if ((previousRule == null ? void 0 : previousRule.aggregationFunction) !== (newRule == null ? void 0 : newRule.aggregationFunction)) {
154
+ if (previousRule?.aggregationFunction !== newRule?.aggregationFunction) {
155
155
  return false;
156
156
  }
157
- if ((previousRule == null ? void 0 : previousRule.aggregationFunctionName) !== (newRule == null ? void 0 : newRule.aggregationFunctionName)) {
157
+ if (previousRule?.aggregationFunctionName !== newRule?.aggregationFunctionName) {
158
158
  return false;
159
159
  }
160
160
  return true;
@@ -5,14 +5,13 @@ import { gridAggregationModelSelector } from './gridAggregationSelectors';
5
5
  import { getAggregationRules, mergeStateWithAggregationModel, areAggregationRulesEqual } from './gridAggregationUtils';
6
6
  import { createAggregationLookup } from './createAggregationLookup';
7
7
  export const aggregationStateInitializer = (state, props, apiRef) => {
8
- var _ref, _props$aggregationMod, _props$initialState;
9
8
  apiRef.current.caches.aggregation = {
10
9
  rulesOnLastColumnHydration: {},
11
10
  rulesOnLastRowHydration: {}
12
11
  };
13
12
  return _extends({}, state, {
14
13
  aggregation: {
15
- model: (_ref = (_props$aggregationMod = props.aggregationModel) != null ? _props$aggregationMod : (_props$initialState = props.initialState) == null || (_props$initialState = _props$initialState.aggregation) == null ? void 0 : _props$initialState.model) != null ? _ref : {}
14
+ model: props.aggregationModel ?? props.initialState?.aggregation?.model ?? {}
16
15
  }
17
16
  });
18
17
  };
@@ -85,11 +85,10 @@ export const useGridAggregationPreProcessors = (apiRef, props) => {
85
85
  });
86
86
  }, [apiRef, props.disableAggregation]);
87
87
  const stateRestorePreProcessing = React.useCallback((params, context) => {
88
- var _context$stateToResto;
89
88
  if (props.disableAggregation) {
90
89
  return params;
91
90
  }
92
- const aggregationModel = (_context$stateToResto = context.stateToRestore.aggregation) == null ? void 0 : _context$stateToResto.model;
91
+ const aggregationModel = context.stateToRestore.aggregation?.model;
93
92
  if (aggregationModel != null) {
94
93
  apiRef.current.setState(mergeStateWithAggregationModel(aggregationModel));
95
94
  }
@@ -15,8 +15,7 @@ const getAggregationValueWrappedValueGetter = ({
15
15
  const rowId = apiRef.current.getRowId(row);
16
16
  const cellAggregationResult = getCellAggregationResult(rowId, column.field);
17
17
  if (cellAggregationResult != null) {
18
- var _cellAggregationResul;
19
- return (_cellAggregationResul = cellAggregationResult == null ? void 0 : cellAggregationResult.value) != null ? _cellAggregationResul : null;
18
+ return cellAggregationResult?.value ?? null;
20
19
  }
21
20
  if (valueGetter) {
22
21
  return valueGetter(value, row, column, apiRef);
@@ -40,8 +39,7 @@ const getAggregationValueWrappedValueFormatter = ({
40
39
  if (rowId != null) {
41
40
  const cellAggregationResult = getCellAggregationResult(rowId, column.field);
42
41
  if (cellAggregationResult != null) {
43
- var _aggregationRule$aggr, _aggregationRule$aggr2;
44
- return (_aggregationRule$aggr = (_aggregationRule$aggr2 = aggregationRule.aggregationFunction).valueFormatter) == null ? void 0 : _aggregationRule$aggr.call(_aggregationRule$aggr2, {
42
+ return aggregationRule.aggregationFunction.valueFormatter?.({
45
43
  id: rowId,
46
44
  field: column.field,
47
45
  value,
@@ -64,7 +62,6 @@ const getAggregationValueWrappedRenderCell = ({
64
62
  const wrappedRenderCell = params => {
65
63
  const cellAggregationResult = getCellAggregationResult(params.id, params.field);
66
64
  if (cellAggregationResult != null) {
67
- var _aggregationFunction$;
68
65
  if (!renderCell) {
69
66
  if (cellAggregationResult.position === 'footer') {
70
67
  return /*#__PURE__*/_jsx(GridFooterCell, _extends({}, params));
@@ -72,7 +69,7 @@ const getAggregationValueWrappedRenderCell = ({
72
69
  return params.formattedValue;
73
70
  }
74
71
  const aggregationMeta = {
75
- hasCellUnit: (_aggregationFunction$ = aggregationRule.aggregationFunction.hasCellUnit) != null ? _aggregationFunction$ : true,
72
+ hasCellUnit: aggregationRule.aggregationFunction.hasCellUnit ?? true,
76
73
  aggregationFunctionName: aggregationRule.aggregationFunctionName
77
74
  };
78
75
  return renderCell(_extends({}, params, {
@@ -140,7 +137,6 @@ export const wrapColumnWithAggregationValue = ({
140
137
  aggregationRule
141
138
  }) => {
142
139
  const getCellAggregationResult = (id, field) => {
143
- var _rowNode$parent, _gridAggregationLooku;
144
140
  let cellAggregationPosition = null;
145
141
  const rowNode = apiRef.current.getRowNode(id);
146
142
  if (rowNode.type === 'group') {
@@ -153,8 +149,8 @@ export const wrapColumnWithAggregationValue = ({
153
149
  }
154
150
 
155
151
  // TODO: Add custom root id
156
- const groupId = cellAggregationPosition === 'inline' ? id : (_rowNode$parent = rowNode.parent) != null ? _rowNode$parent : '';
157
- const aggregationResult = (_gridAggregationLooku = gridAggregationLookupSelector(apiRef)) == null || (_gridAggregationLooku = _gridAggregationLooku[groupId]) == null ? void 0 : _gridAggregationLooku[field];
152
+ const groupId = cellAggregationPosition === 'inline' ? id : rowNode.parent ?? '';
153
+ const aggregationResult = gridAggregationLookupSelector(apiRef)?.[groupId]?.[field];
158
154
  if (!aggregationResult || aggregationResult.position !== cellAggregationPosition) {
159
155
  return null;
160
156
  }
@@ -1,15 +1,12 @@
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 { isNavigationKey, serializeCellValue, useGridRegisterPipeProcessor, useGridVisibleRows } from '@mui/x-data-grid-pro/internals';
5
- import { useGridApiEventHandler, useGridApiMethod, GRID_ACTIONS_COLUMN_TYPE, GRID_CHECKBOX_SELECTION_COL_DEF, GRID_DETAIL_PANEL_TOGGLE_FIELD, gridRowsDataRowIdToIdLookupSelector, gridClasses, gridFocusCellSelector, GRID_REORDER_COL_DEF, useGridSelector, gridSortedRowIdsSelector } from '@mui/x-data-grid-pro';
4
+ import { getTotalHeaderHeight, isNavigationKey, serializeCellValue, useGridRegisterPipeProcessor, useGridVisibleRows } from '@mui/x-data-grid-pro/internals';
5
+ import { useGridApiEventHandler, useGridApiMethod, GRID_ACTIONS_COLUMN_TYPE, GRID_CHECKBOX_SELECTION_COL_DEF, GRID_DETAIL_PANEL_TOGGLE_FIELD, gridRowsDataRowIdToIdLookupSelector, gridClasses, gridFocusCellSelector, GRID_REORDER_COL_DEF, useGridSelector, gridSortedRowIdsSelector, gridDimensionsSelector } from '@mui/x-data-grid-pro';
6
6
  import { gridCellSelectionStateSelector } from './gridCellSelectionSelector';
7
- export const cellSelectionStateInitializer = (state, props) => {
8
- var _props$cellSelectionM, _props$initialState;
9
- return _extends({}, state, {
10
- cellSelection: _extends({}, (_props$cellSelectionM = props.cellSelectionModel) != null ? _props$cellSelectionM : (_props$initialState = props.initialState) == null ? void 0 : _props$initialState.cellSelection)
11
- });
12
- };
7
+ export const cellSelectionStateInitializer = (state, props) => _extends({}, state, {
8
+ cellSelection: _extends({}, props.cellSelectionModel ?? props.initialState?.cellSelection)
9
+ });
13
10
  function isKeyboardEvent(event) {
14
11
  return !!event.key;
15
12
  }
@@ -23,8 +20,10 @@ export const useGridCellSelection = (apiRef, props) => {
23
20
  const mousePosition = React.useRef(null);
24
21
  const autoScrollRAF = React.useRef();
25
22
  const sortedRowIds = useGridSelector(apiRef, gridSortedRowIdsSelector);
23
+ const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
24
+ const totalHeaderHeight = getTotalHeaderHeight(apiRef, props.columnHeaderHeight);
26
25
  const ignoreValueFormatterProp = props.ignoreValueFormatterDuringExport;
27
- const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.clipboardExport : ignoreValueFormatterProp) || false;
26
+ const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp?.clipboardExport : ignoreValueFormatterProp) || false;
28
27
  const clipboardCopyCellDelimiter = props.clipboardCopyCellDelimiter;
29
28
  apiRef.current.registerControlState({
30
29
  stateId: 'cellSelection',
@@ -120,15 +119,13 @@ export const useGridCellSelection = (apiRef, props) => {
120
119
  return params.rowNode.type !== 'pinnedRow';
121
120
  }, [apiRef]);
122
121
  const handleMouseUp = useEventCallback(() => {
123
- var _apiRef$current$rootE;
124
122
  lastMouseDownCell.current = null;
125
- (_apiRef$current$rootE = apiRef.current.rootElementRef) == null || (_apiRef$current$rootE = _apiRef$current$rootE.current) == null || _apiRef$current$rootE.classList.remove(gridClasses['root--disableUserSelection']);
123
+ apiRef.current.rootElementRef?.current?.classList.remove(gridClasses['root--disableUserSelection']);
126
124
 
127
125
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
128
126
  stopAutoScroll();
129
127
  });
130
128
  const handleCellMouseDown = React.useCallback((params, event) => {
131
- var _apiRef$current$rootE2, _apiRef$current$rootE3;
132
129
  // Skip if the click comes from the right-button or, only on macOS, Ctrl is pressed
133
130
  // Fix for https://github.com/mui/mui-x/pull/6567#issuecomment-1329155578
134
131
  const isMacOs = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0;
@@ -146,8 +143,8 @@ export const useGridCellSelection = (apiRef, props) => {
146
143
  id: params.id,
147
144
  field: params.field
148
145
  };
149
- (_apiRef$current$rootE2 = apiRef.current.rootElementRef) == null || (_apiRef$current$rootE2 = _apiRef$current$rootE2.current) == null || _apiRef$current$rootE2.classList.add(gridClasses['root--disableUserSelection']);
150
- const document = ownerDocument((_apiRef$current$rootE3 = apiRef.current.rootElementRef) == null ? void 0 : _apiRef$current$rootE3.current);
146
+ apiRef.current.rootElementRef?.current?.classList.add(gridClasses['root--disableUserSelection']);
147
+ const document = ownerDocument(apiRef.current.rootElementRef?.current);
151
148
  document.addEventListener('mouseup', handleMouseUp, {
152
149
  once: true
153
150
  });
@@ -165,20 +162,14 @@ export const useGridCellSelection = (apiRef, props) => {
165
162
  };
166
163
  }, []);
167
164
  const startAutoScroll = React.useCallback(() => {
168
- var _apiRef$current$virtu, _apiRef$current$virtu2;
169
165
  if (autoScrollRAF.current) {
170
166
  return;
171
167
  }
172
- if (!((_apiRef$current$virtu = apiRef.current.virtualScrollerRef) != null && _apiRef$current$virtu.current)) {
173
- return;
174
- }
175
- const virtualScrollerRect = (_apiRef$current$virtu2 = apiRef.current.virtualScrollerRef) == null || (_apiRef$current$virtu2 = _apiRef$current$virtu2.current) == null ? void 0 : _apiRef$current$virtu2.getBoundingClientRect();
176
- if (!virtualScrollerRect) {
168
+ if (!apiRef.current.virtualScrollerRef?.current) {
177
169
  return;
178
170
  }
179
171
  function autoScroll() {
180
- var _apiRef$current$virtu3;
181
- if (!mousePosition.current || !((_apiRef$current$virtu3 = apiRef.current.virtualScrollerRef) != null && _apiRef$current$virtu3.current)) {
172
+ if (!mousePosition.current || !apiRef.current.virtualScrollerRef?.current) {
182
173
  return;
183
174
  }
184
175
  const {
@@ -188,11 +179,10 @@ export const useGridCellSelection = (apiRef, props) => {
188
179
  const {
189
180
  height,
190
181
  width
191
- } = virtualScrollerRect;
182
+ } = dimensions.viewportInnerSize;
192
183
  let deltaX = 0;
193
184
  let deltaY = 0;
194
185
  let factor = 0;
195
- const dimensions = apiRef.current.getRootDimensions();
196
186
  if (mouseY <= AUTO_SCROLL_SENSITIVITY && dimensions.hasScrollY) {
197
187
  // When scrolling up, the multiplier increases going closer to the top edge
198
188
  factor = (AUTO_SCROLL_SENSITIVITY - mouseY) / -AUTO_SCROLL_SENSITIVITY;
@@ -223,9 +213,8 @@ export const useGridCellSelection = (apiRef, props) => {
223
213
  autoScrollRAF.current = requestAnimationFrame(autoScroll);
224
214
  }
225
215
  autoScroll();
226
- }, [apiRef]);
216
+ }, [apiRef, dimensions]);
227
217
  const handleCellMouseOver = React.useCallback((params, event) => {
228
- var _apiRef$current$virtu4;
229
218
  if (!lastMouseDownCell.current) {
230
219
  return;
231
220
  }
@@ -237,18 +226,20 @@ export const useGridCellSelection = (apiRef, props) => {
237
226
  id,
238
227
  field
239
228
  }, event.ctrlKey || event.metaKey);
240
- const virtualScrollerRect = (_apiRef$current$virtu4 = apiRef.current.virtualScrollerRef) == null || (_apiRef$current$virtu4 = _apiRef$current$virtu4.current) == null ? void 0 : _apiRef$current$virtu4.getBoundingClientRect();
229
+ const virtualScrollerRect = apiRef.current.virtualScrollerRef?.current?.getBoundingClientRect();
241
230
  if (!virtualScrollerRect) {
242
231
  return;
243
232
  }
244
233
  const {
245
- height,
246
- width,
247
234
  x,
248
235
  y
249
236
  } = virtualScrollerRect;
237
+ const {
238
+ height,
239
+ width
240
+ } = dimensions.viewportInnerSize;
250
241
  const mouseX = event.clientX - x;
251
- const mouseY = event.clientY - y;
242
+ const mouseY = event.clientY - y - totalHeaderHeight;
252
243
  mousePosition.current = {
253
244
  x: mouseX,
254
245
  y: mouseY
@@ -263,7 +254,7 @@ export const useGridCellSelection = (apiRef, props) => {
263
254
  // Mouse has left the sensitivity area while auto scroll is on
264
255
  stopAutoScroll();
265
256
  }
266
- }, [apiRef, startAutoScroll, stopAutoScroll]);
257
+ }, [apiRef, startAutoScroll, stopAutoScroll, totalHeaderHeight, dimensions]);
267
258
  const handleCellClick = useEventCallback((params, event) => {
268
259
  const {
269
260
  id,
@@ -358,8 +349,7 @@ export const useGridCellSelection = (apiRef, props) => {
358
349
  }
359
350
  }, [apiRef, props.cellSelectionModel]);
360
351
  React.useEffect(() => {
361
- var _apiRef$current$rootE4;
362
- const rootRef = (_apiRef$current$rootE4 = apiRef.current.rootElementRef) == null ? void 0 : _apiRef$current$rootE4.current;
352
+ const rootRef = apiRef.current.rootElementRef?.current;
363
353
  return () => {
364
354
  stopAutoScroll();
365
355
  const document = ownerDocument(rootRef);
@@ -456,7 +446,8 @@ export const useGridCellSelection = (apiRef, props) => {
456
446
  const cellParams = apiRef.current.getCellParams(rowId, field);
457
447
  cellData = serializeCellValue(cellParams, {
458
448
  delimiterCharacter: clipboardCopyCellDelimiter,
459
- ignoreValueFormatter
449
+ ignoreValueFormatter,
450
+ shouldAppendQuotes: true
460
451
  });
461
452
  } else {
462
453
  cellData = '';
@@ -1,10 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { GRID_CHECKBOX_SELECTION_FIELD, gridFocusCellSelector, gridVisibleColumnFieldsSelector, useGridApiOptionHandler, useGridApiEventHandler, gridPaginatedVisibleSortedGridRowIdsSelector, gridExpandedSortedRowIdsSelector } from '@mui/x-data-grid';
4
- import { buildWarning, getRowIdFromRowModel, getActiveElement, useGridRegisterPipeProcessor, getPublicApiRef, isPasteShortcut } from '@mui/x-data-grid/internals';
4
+ import { buildWarning, getRowIdFromRowModel, getActiveElement, useGridRegisterPipeProcessor, getPublicApiRef, isPasteShortcut, useGridLogger } from '@mui/x-data-grid/internals';
5
5
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD, GRID_REORDER_COL_DEF } from '@mui/x-data-grid-pro';
6
6
  import { unstable_debounce as debounce } from '@mui/utils';
7
- const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI X: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, e.g. `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see https://mui.com/x/react-data-grid/editing/#server-side-persistence.'], 'error');
7
+ const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI X: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, for example `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see https://mui.com/x/react-data-grid/editing/#server-side-persistence.'], 'error');
8
8
  const columnFieldsToExcludeFromPaste = [GRID_CHECKBOX_SELECTION_FIELD, GRID_REORDER_COL_DEF.field, GRID_DETAIL_PANEL_TOGGLE_FIELD];
9
9
 
10
10
  // Batches rows that are updated during clipboard paste to reduce `updateRows` calls
@@ -33,9 +33,8 @@ async function getTextFromClipboard(rootEl) {
33
33
  el.style.top = '0';
34
34
  el.style.left = '0';
35
35
  const handlePasteEvent = event => {
36
- var _event$clipboardData;
37
36
  el.removeEventListener('paste', handlePasteEvent);
38
- const text = (_event$clipboardData = event.clipboardData) == null ? void 0 : _event$clipboardData.getData('text/plain');
37
+ const text = event.clipboardData?.getData('text/plain');
39
38
  if (focusedCell instanceof HTMLElement) {
40
39
  focusedCell.focus({
41
40
  preventScroll: true
@@ -236,13 +235,17 @@ function defaultPasteResolver({
236
235
  });
237
236
  }
238
237
  export const useGridClipboardImport = (apiRef, props) => {
239
- var _apiRef$current$rootE;
240
238
  const processRowUpdate = props.processRowUpdate;
241
239
  const onProcessRowUpdateError = props.onProcessRowUpdateError;
242
240
  const getRowId = props.getRowId;
243
241
  const enableClipboardPaste = !props.disableClipboardPaste;
244
- const rootEl = (_apiRef$current$rootE = apiRef.current.rootElementRef) == null ? void 0 : _apiRef$current$rootE.current;
242
+ const rootEl = apiRef.current.rootElementRef?.current;
243
+ const logger = useGridLogger(apiRef, 'useGridClipboardImport');
245
244
  const splitClipboardPastedText = props.splitClipboardPastedText;
245
+ const {
246
+ pagination,
247
+ onBeforeClipboardPasteStart
248
+ } = props;
246
249
  const handlePaste = React.useCallback(async (params, event) => {
247
250
  if (!enableClipboardPaste) {
248
251
  return;
@@ -269,6 +272,16 @@ export const useGridClipboardImport = (apiRef, props) => {
269
272
  if (!pastedData) {
270
273
  return;
271
274
  }
275
+ if (onBeforeClipboardPasteStart) {
276
+ try {
277
+ await onBeforeClipboardPasteStart({
278
+ data: pastedData
279
+ });
280
+ } catch (error) {
281
+ logger.debug('Clipboard paste operation cancelled');
282
+ return;
283
+ }
284
+ }
272
285
  const cellUpdater = new CellValueUpdater({
273
286
  apiRef,
274
287
  processRowUpdate,
@@ -284,10 +297,10 @@ export const useGridClipboardImport = (apiRef, props) => {
284
297
  updateCell: (...args) => {
285
298
  cellUpdater.updateCell(...args);
286
299
  },
287
- pagination: props.pagination
300
+ pagination
288
301
  });
289
302
  cellUpdater.applyUpdates();
290
- }, [apiRef, processRowUpdate, onProcessRowUpdateError, getRowId, enableClipboardPaste, rootEl, splitClipboardPastedText, props.pagination]);
303
+ }, [apiRef, processRowUpdate, onProcessRowUpdateError, getRowId, enableClipboardPaste, rootEl, splitClipboardPastedText, pagination, onBeforeClipboardPasteStart, logger]);
291
304
  const checkIfCanStartEditing = React.useCallback((initialValue, {
292
305
  event
293
306
  }) => {
@@ -2,9 +2,8 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { GRID_DATE_COL_DEF, GRID_DATETIME_COL_DEF } from '@mui/x-data-grid-pro';
3
3
  import { buildWarning, isObject, isSingleSelectColDef } from '@mui/x-data-grid/internals';
4
4
  const getExcelJs = async () => {
5
- var _excelJsModule$defaul;
6
5
  const excelJsModule = await import('exceljs');
7
- return (_excelJsModule$defaul = excelJsModule.default) != null ? _excelJsModule$defaul : excelJsModule;
6
+ return excelJsModule.default ?? excelJsModule;
8
7
  };
9
8
  const warnInvalidFormattedValue = buildWarning(['MUI X: When the value of a field is an object or a `renderCell` is provided, the Excel export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
10
9
  const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
@@ -85,7 +84,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
85
84
  }
86
85
  }
87
86
  if (isObject(formattedValue)) {
88
- row[castColumn.field] = formattedValue == null ? void 0 : formattedValue.label;
87
+ row[castColumn.field] = formattedValue?.label;
89
88
  } else {
90
89
  row[castColumn.field] = formattedValue;
91
90
  }
@@ -138,28 +137,24 @@ const defaultColumnsStyles = {
138
137
  }
139
138
  };
140
139
  export const serializeColumn = (column, columnsStyles) => {
141
- var _column$headerName;
142
140
  const {
143
141
  field,
144
142
  type
145
143
  } = column;
146
144
  return {
147
145
  key: field,
148
- headerText: (_column$headerName = column.headerName) != null ? _column$headerName : column.field,
146
+ headerText: column.headerName ?? column.field,
149
147
  // 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)
150
148
  // From the example of column width behavior (https://docs.microsoft.com/en-US/office/troubleshoot/excel/determine-column-widths#example-of-column-width-behavior)
151
149
  // a value of 10 corresponds to 75px. This is an approximation, because column width depends on the font-size
152
150
  width: Math.min(255, column.width ? column.width / 7.5 : 8.43),
153
- style: _extends({}, type && (defaultColumnsStyles == null ? void 0 : defaultColumnsStyles[type]), columnsStyles == null ? void 0 : columnsStyles[field])
151
+ style: _extends({}, type && defaultColumnsStyles?.[type], columnsStyles?.[field])
154
152
  };
155
153
  };
156
154
  const addColumnGroupingHeaders = (worksheet, columns, columnGroupPaths, columnGroupDetails) => {
157
155
  const maxDepth = Math.max(...columns.map(({
158
156
  key
159
- }) => {
160
- var _columnGroupPaths$key, _columnGroupPaths$key2;
161
- return (_columnGroupPaths$key = (_columnGroupPaths$key2 = columnGroupPaths[key]) == null ? void 0 : _columnGroupPaths$key2.length) != null ? _columnGroupPaths$key : 0;
162
- }));
157
+ }) => columnGroupPaths[key]?.length ?? 0));
163
158
  if (maxDepth === 0) {
164
159
  return;
165
160
  }
@@ -178,10 +173,7 @@ const addColumnGroupingHeaders = (worksheet, columns, columnGroupPaths, columnGr
178
173
  parents: groupingPath.slice(0, rowIndex)
179
174
  });
180
175
  });
181
- const newRow = worksheet.addRow(row.map(group => {
182
- var _group$headerName;
183
- return group.groupId === null ? null : (_group$headerName = group == null ? void 0 : group.headerName) != null ? _group$headerName : group.groupId;
184
- }));
176
+ const newRow = worksheet.addRow(row.map(group => group.groupId === null ? null : group?.headerName ?? group.groupId));
185
177
 
186
178
  // use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
187
179
  const lastRowIndex = newRow.worksheet.rowCount;
@@ -226,10 +218,9 @@ export async function getDataForValueOptionsSheet(columns, valueOptionsSheetName
226
218
  key: column.field
227
219
  }));
228
220
  return candidateColumns.reduce((acc, column) => {
229
- var _column$headerName2;
230
221
  const singleSelectColumn = column;
231
222
  const formattedValueOptions = getFormattedValueOptions(singleSelectColumn, {}, singleSelectColumn.valueOptions, api);
232
- const header = (_column$headerName2 = column.headerName) != null ? _column$headerName2 : column.field;
223
+ const header = column.headerName ?? column.field;
233
224
  const values = [header, ...formattedValueOptions];
234
225
  const letter = worksheet.getColumn(column.field).letter;
235
226
  const address = `${valueOptionsSheetName}!$${letter}$2:$${letter}$${values.length}`;
@@ -305,10 +296,7 @@ export async function buildExcel(options, api) {
305
296
  addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, api.getAllGroupDetails());
306
297
  }
307
298
  if (includeHeaders) {
308
- worksheet.addRow(columns.map(column => {
309
- var _column$headerName3;
310
- return (_column$headerName3 = column.headerName) != null ? _column$headerName3 : column.field;
311
- }));
299
+ worksheet.addRow(columns.map(column => column.headerName ?? column.field));
312
300
  }
313
301
  const valueOptionsData = await getDataForValueOptionsSheet(columns, valueOptionsSheetName, api);
314
302
  createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
@@ -327,7 +315,6 @@ export async function buildExcel(options, api) {
327
315
  export function setupExcelExportWebWorker(workerOptions = {}) {
328
316
  // eslint-disable-next-line no-restricted-globals
329
317
  addEventListener('message', async event => {
330
- var _options$includeHeade;
331
318
  const {
332
319
  serializedColumns,
333
320
  serializedRows,
@@ -354,7 +341,7 @@ export function setupExcelExportWebWorker(workerOptions = {}) {
354
341
  if (options.includeColumnGroupsHeaders) {
355
342
  addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, columnGroupDetails);
356
343
  }
357
- const includeHeaders = (_options$includeHeade = options.includeHeaders) != null ? _options$includeHeade : true;
344
+ const includeHeaders = options.includeHeaders ?? true;
358
345
  if (includeHeaders) {
359
346
  worksheet.addRow(serializedColumns.map(column => column.headerText));
360
347
  }
@@ -17,9 +17,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
17
17
  export const useGridExcelExport = (apiRef, props) => {
18
18
  const logger = useGridLogger(apiRef, 'useGridExcelExport');
19
19
  const getDataAsExcel = React.useCallback((options = {}) => {
20
- var _options$getRowsToExp, _options$includeHeade, _options$includeColum;
21
20
  logger.debug(`Get data as excel`);
22
- const getRowsToExport = (_options$getRowsToExp = options.getRowsToExport) != null ? _options$getRowsToExp : defaultGetRowsToExport;
21
+ const getRowsToExport = options.getRowsToExport ?? defaultGetRowsToExport;
23
22
  const exportedRowIds = getRowsToExport({
24
23
  apiRef
25
24
  });
@@ -30,12 +29,12 @@ export const useGridExcelExport = (apiRef, props) => {
30
29
  return buildExcel({
31
30
  columns: exportedColumns,
32
31
  rowIds: exportedRowIds,
33
- includeHeaders: (_options$includeHeade = options.includeHeaders) != null ? _options$includeHeade : true,
34
- includeColumnGroupsHeaders: (_options$includeColum = options.includeColumnGroupsHeaders) != null ? _options$includeColum : true,
35
- valueOptionsSheetName: (options == null ? void 0 : options.valueOptionsSheetName) || 'Options',
36
- columnsStyles: options == null ? void 0 : options.columnsStyles,
37
- exceljsPreProcess: options == null ? void 0 : options.exceljsPreProcess,
38
- exceljsPostProcess: options == null ? void 0 : options.exceljsPostProcess
32
+ includeHeaders: options.includeHeaders ?? true,
33
+ includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
34
+ valueOptionsSheetName: options?.valueOptionsSheetName || 'Options',
35
+ columnsStyles: options?.columnsStyles,
36
+ exceljsPreProcess: options?.exceljsPreProcess,
37
+ exceljsPostProcess: options?.exceljsPostProcess
39
38
  }, apiRef.current);
40
39
  }, [logger, apiRef]);
41
40
  const exportDataAsExcel = React.useCallback(async (options = {}) => {
@@ -51,7 +50,7 @@ export const useGridExcelExport = (apiRef, props) => {
51
50
  const blob = new Blob([buffer], {
52
51
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
53
52
  });
54
- exportAs(blob, 'xlsx', options == null ? void 0 : options.fileName);
53
+ exportAs(blob, 'xlsx', options?.fileName);
55
54
  };
56
55
  if (!workerFn) {
57
56
  apiRef.current.publishEvent('excelExportStateChange', 'pending');
@@ -114,8 +113,7 @@ export const useGridExcelExport = (apiRef, props) => {
114
113
  * PRE-PROCESSING
115
114
  */
116
115
  const addExportMenuButtons = React.useCallback((initialValue, options) => {
117
- var _options$excelOptions;
118
- if ((_options$excelOptions = options.excelOptions) != null && _options$excelOptions.disableToolbarButton) {
116
+ if (options.excelOptions?.disableToolbarButton) {
119
117
  return initialValue;
120
118
  }
121
119
  return [...initialValue, {