@mui/x-data-grid 6.9.1 → 6.10.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 (100) hide show
  1. package/CHANGELOG.md +287 -107
  2. package/DataGrid/DataGrid.js +5 -1
  3. package/README.md +1 -1
  4. package/components/GridPagination.js +16 -3
  5. package/components/cell/GridEditDateCell.js +1 -1
  6. package/components/cell/GridEditInputCell.js +3 -3
  7. package/components/toolbar/GridToolbarQuickFilter.d.ts +1 -1
  8. package/components/toolbar/GridToolbarQuickFilter.js +12 -9
  9. package/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
  10. package/hooks/core/useGridApiInitialization.d.ts +1 -0
  11. package/hooks/core/useGridApiInitialization.js +59 -36
  12. package/hooks/features/columns/gridColumnsUtils.js +2 -1
  13. package/hooks/features/dimensions/useGridDimensions.js +3 -3
  14. package/hooks/features/editing/useGridEditing.js +2 -1
  15. package/hooks/features/export/serializers/csvSerializer.d.ts +9 -6
  16. package/hooks/features/export/serializers/csvSerializer.js +78 -15
  17. package/hooks/features/export/useGridCsvExport.js +4 -3
  18. package/hooks/features/filter/gridFilterUtils.js +6 -5
  19. package/hooks/features/filter/useGridFilter.js +14 -2
  20. package/hooks/features/rows/gridRowsUtils.js +1 -1
  21. package/hooks/features/rows/useGridParamsApi.js +4 -4
  22. package/hooks/utils/useGridApiMethod.js +7 -23
  23. package/index.js +1 -1
  24. package/internals/index.d.ts +1 -0
  25. package/internals/index.js +1 -0
  26. package/joy/joySlots.js +17 -5
  27. package/legacy/DataGrid/DataGrid.js +5 -1
  28. package/legacy/components/GridPagination.js +16 -3
  29. package/legacy/components/cell/GridEditDateCell.js +1 -1
  30. package/legacy/components/cell/GridEditInputCell.js +3 -3
  31. package/legacy/components/toolbar/GridToolbarQuickFilter.js +12 -12
  32. package/legacy/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
  33. package/legacy/hooks/core/useGridApiInitialization.js +62 -39
  34. package/legacy/hooks/features/columns/gridColumnsUtils.js +4 -1
  35. package/legacy/hooks/features/dimensions/useGridDimensions.js +3 -3
  36. package/legacy/hooks/features/editing/useGridEditing.js +2 -1
  37. package/legacy/hooks/features/export/serializers/csvSerializer.js +84 -11
  38. package/legacy/hooks/features/export/useGridCsvExport.js +4 -3
  39. package/legacy/hooks/features/filter/gridFilterUtils.js +6 -5
  40. package/legacy/hooks/features/filter/useGridFilter.js +12 -2
  41. package/legacy/hooks/features/rows/gridRowsUtils.js +1 -1
  42. package/legacy/hooks/features/rows/useGridParamsApi.js +4 -4
  43. package/legacy/hooks/utils/useGridApiMethod.js +7 -25
  44. package/legacy/index.js +1 -1
  45. package/legacy/internals/index.js +1 -0
  46. package/legacy/joy/joySlots.js +17 -5
  47. package/legacy/locales/esES.js +3 -3
  48. package/legacy/locales/plPL.js +7 -7
  49. package/locales/esES.js +3 -3
  50. package/locales/plPL.js +7 -7
  51. package/models/api/gridEditingApi.d.ts +1 -1
  52. package/models/events/gridEventLookup.d.ts +0 -1
  53. package/models/gridExport.d.ts +8 -1
  54. package/models/gridFilterModel.d.ts +5 -0
  55. package/models/props/DataGridProps.d.ts +4 -1
  56. package/modern/DataGrid/DataGrid.js +5 -1
  57. package/modern/components/GridPagination.js +16 -2
  58. package/modern/components/cell/GridEditDateCell.js +1 -1
  59. package/modern/components/cell/GridEditInputCell.js +3 -3
  60. package/modern/components/toolbar/GridToolbarQuickFilter.js +12 -9
  61. package/modern/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
  62. package/modern/hooks/core/useGridApiInitialization.js +58 -36
  63. package/modern/hooks/features/columns/gridColumnsUtils.js +2 -1
  64. package/modern/hooks/features/dimensions/useGridDimensions.js +3 -3
  65. package/modern/hooks/features/editing/useGridEditing.js +1 -1
  66. package/modern/hooks/features/export/serializers/csvSerializer.js +78 -15
  67. package/modern/hooks/features/export/useGridCsvExport.js +3 -2
  68. package/modern/hooks/features/filter/gridFilterUtils.js +3 -2
  69. package/modern/hooks/features/filter/useGridFilter.js +14 -2
  70. package/modern/hooks/features/rows/gridRowsUtils.js +1 -1
  71. package/modern/hooks/features/rows/useGridParamsApi.js +1 -1
  72. package/modern/hooks/utils/useGridApiMethod.js +7 -23
  73. package/modern/index.js +1 -1
  74. package/modern/internals/index.js +1 -0
  75. package/modern/joy/joySlots.js +17 -4
  76. package/modern/locales/esES.js +3 -3
  77. package/modern/locales/plPL.js +7 -7
  78. package/node/DataGrid/DataGrid.js +5 -1
  79. package/node/components/GridPagination.js +16 -2
  80. package/node/components/cell/GridEditDateCell.js +1 -1
  81. package/node/components/cell/GridEditInputCell.js +3 -3
  82. package/node/components/toolbar/GridToolbarQuickFilter.js +12 -9
  83. package/node/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
  84. package/node/hooks/core/useGridApiInitialization.js +59 -36
  85. package/node/hooks/features/columns/gridColumnsUtils.js +2 -1
  86. package/node/hooks/features/dimensions/useGridDimensions.js +3 -3
  87. package/node/hooks/features/editing/useGridEditing.js +1 -1
  88. package/node/hooks/features/export/serializers/csvSerializer.js +78 -15
  89. package/node/hooks/features/export/useGridCsvExport.js +3 -2
  90. package/node/hooks/features/filter/gridFilterUtils.js +2 -1
  91. package/node/hooks/features/filter/useGridFilter.js +14 -2
  92. package/node/hooks/features/rows/gridRowsUtils.js +1 -1
  93. package/node/hooks/features/rows/useGridParamsApi.js +1 -1
  94. package/node/hooks/utils/useGridApiMethod.js +7 -23
  95. package/node/index.js +1 -1
  96. package/node/internals/index.js +8 -0
  97. package/node/joy/joySlots.js +17 -4
  98. package/node/locales/esES.js +3 -3
  99. package/node/locales/plPL.js +7 -7
  100. package/package.json +1 -1
@@ -101,8 +101,8 @@ export function useGridParamsApi(apiRef, props) {
101
101
  return colDef.valueGetter(getBaseCellParams(id, field));
102
102
  }, [apiRef, getBaseCellParams]);
103
103
  const getRowValue = React.useCallback((row, colDef) => {
104
- var _ref;
105
- const id = (_ref = getRowId ? getRowId(row) : row.id) != null ? _ref : row[GRID_ID_AUTOGENERATED];
104
+ var _getRowId;
105
+ const id = GRID_ID_AUTOGENERATED in row ? row[GRID_ID_AUTOGENERATED] : (_getRowId = getRowId == null ? void 0 : getRowId(row)) != null ? _getRowId : row.id;
106
106
  const field = colDef.field;
107
107
  if (!colDef || !colDef.valueGetter) {
108
108
  return row[field];
@@ -110,12 +110,12 @@ export function useGridParamsApi(apiRef, props) {
110
110
  return colDef.valueGetter(getBaseCellParams(id, field));
111
111
  }, [getBaseCellParams, getRowId]);
112
112
  const getRowFormattedValue = React.useCallback((row, colDef) => {
113
- var _ref2;
113
+ var _ref;
114
114
  const value = getRowValue(row, colDef);
115
115
  if (!colDef || !colDef.valueFormatter) {
116
116
  return value;
117
117
  }
118
- const id = (_ref2 = getRowId ? getRowId(row) : row.id) != null ? _ref2 : row[GRID_ID_AUTOGENERATED];
118
+ const id = (_ref = getRowId ? getRowId(row) : row.id) != null ? _ref : row[GRID_ID_AUTOGENERATED];
119
119
  const field = colDef.field;
120
120
  return colDef.valueFormatter({
121
121
  id,
@@ -1,27 +1,11 @@
1
1
  import * as React from 'react';
2
2
  export function useGridApiMethod(privateApiRef, apiMethods, visibility) {
3
- const apiMethodsRef = React.useRef(apiMethods);
4
- const [apiMethodsNames] = React.useState(Object.keys(apiMethods));
5
- const installMethods = React.useCallback(() => {
6
- if (!privateApiRef.current) {
7
- return;
8
- }
9
- apiMethodsNames.forEach(methodName => {
10
- if (!privateApiRef.current.hasOwnProperty(methodName)) {
11
- privateApiRef.current.register(visibility, {
12
- [methodName]: (...args) => {
13
- const fn = apiMethodsRef.current[methodName];
14
- return fn(...args);
15
- }
16
- });
17
- }
18
- });
19
- }, [apiMethodsNames, privateApiRef, visibility]);
3
+ const isFirstRender = React.useRef(true);
20
4
  React.useEffect(() => {
21
- apiMethodsRef.current = apiMethods;
22
- }, [apiMethods]);
23
- React.useEffect(() => {
24
- installMethods();
25
- }, [installMethods]);
26
- installMethods();
5
+ isFirstRender.current = false;
6
+ privateApiRef.current.register(visibility, apiMethods);
7
+ }, [privateApiRef, visibility, apiMethods]);
8
+ if (isFirstRender.current) {
9
+ privateApiRef.current.register(visibility, apiMethods);
10
+ }
27
11
  }
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.9.1
2
+ * @mui/x-data-grid v6.10.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -11,6 +11,7 @@ export type { GridPipeProcessor } from '../hooks/core/pipeProcessing';
11
11
  export { useGridRegisterStrategyProcessor, GRID_DEFAULT_STRATEGY, } from '../hooks/core/strategyProcessing';
12
12
  export type { GridStrategyProcessor } from '../hooks/core/strategyProcessing';
13
13
  export { useGridInitialization } from '../hooks/core/useGridInitialization';
14
+ export { unwrapPrivateAPI } from '../hooks/core/useGridApiInitialization';
14
15
  export { useGridClipboard } from '../hooks/features/clipboard/useGridClipboard';
15
16
  export { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';
16
17
  export { unstable_gridHeaderFilteringEditFieldSelector, unstable_gridHeaderFilteringMenuSelector, } from '../hooks/features/headerFiltering/gridHeaderFilteringSelectors';
@@ -8,6 +8,7 @@ export { getGridFilter } from '../components/panel/filterPanel/GridFilterPanel';
8
8
  export { useGridRegisterPipeProcessor } from '../hooks/core/pipeProcessing';
9
9
  export { useGridRegisterStrategyProcessor, GRID_DEFAULT_STRATEGY } from '../hooks/core/strategyProcessing';
10
10
  export { useGridInitialization } from '../hooks/core/useGridInitialization';
11
+ export { unwrapPrivateAPI } from '../hooks/core/useGridApiInitialization';
11
12
  export { useGridClipboard } from '../hooks/features/clipboard/useGridClipboard';
12
13
  export { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';
13
14
  export { unstable_gridHeaderFilteringEditFieldSelector, unstable_gridHeaderFilteringMenuSelector } from '../hooks/features/headerFiltering/gridHeaderFilteringSelectors';
package/joy/joySlots.js CHANGED
@@ -291,7 +291,6 @@ const getLabelDisplayedRowsTo = ({
291
291
  return pageSize === -1 ? rowCount : Math.min(rowCount, (page + 1) * pageSize);
292
292
  };
293
293
  const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
294
- var _rootProps$pageSizeOp;
295
294
  const apiRef = useGridApiContext();
296
295
  const rootProps = useGridRootProps();
297
296
  const paginationModel = gridPaginationModelSelector(apiRef);
@@ -306,7 +305,20 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
306
305
  }, [apiRef]);
307
306
  const page = paginationModel.page <= lastPage ? paginationModel.page : lastPage;
308
307
  const pageSize = paginationModel.pageSize;
309
- const pageSizeOptions = (_rootProps$pageSizeOp = rootProps.pageSizeOptions) != null && _rootProps$pageSizeOp.includes(pageSize) ? rootProps.pageSizeOptions : [];
308
+ const isPageSizeIncludedInPageSizeOptions = () => {
309
+ for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
310
+ const option = rootProps.pageSizeOptions[i];
311
+ if (typeof option === 'number') {
312
+ if (option === pageSize) {
313
+ return true;
314
+ }
315
+ } else if (option.value === pageSize) {
316
+ return true;
317
+ }
318
+ }
319
+ return false;
320
+ };
321
+ const pageSizeOptions = isPageSizeIncludedInPageSizeOptions() ? rootProps.pageSizeOptions : [];
310
322
  const handleChangeRowsPerPage = (event, newValue) => {
311
323
  const newPageSize = Number(newValue);
312
324
  apiRef.current.setPageSize(newPageSize);
@@ -330,9 +342,9 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
330
342
  value: pageSize,
331
343
  children: pageSizeOptions.map(option => {
332
344
  return /*#__PURE__*/_jsx(Option, {
333
- value: option,
334
- children: option
335
- }, option);
345
+ value: typeof option !== 'number' && option.value ? option.value : option,
346
+ children: typeof option !== 'number' && option.label ? option.label : `${option}`
347
+ }, typeof option !== 'number' && option.label ? option.label : `${option}`);
336
348
  })
337
349
  })]
338
350
  }), /*#__PURE__*/_jsx(JoyTypography, {
@@ -183,6 +183,7 @@ DataGridRaw.propTypes = {
183
183
  value: PropTypes.any
184
184
  })).isRequired,
185
185
  logicOperator: PropTypes.oneOf(['and', 'or']),
186
+ quickFilterExcludeHiddenColumns: PropTypes.bool,
186
187
  quickFilterLogicOperator: PropTypes.oneOf(['and', 'or']),
187
188
  quickFilterValues: PropTypes.array
188
189
  }),
@@ -515,7 +516,10 @@ DataGridRaw.propTypes = {
515
516
  * Select the pageSize dynamically using the component UI.
516
517
  * @default [25, 50, 100]
517
518
  */
518
- pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
519
+ pageSizeOptions: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
520
+ label: PropTypes.string.isRequired,
521
+ value: PropTypes.number.isRequired
522
+ })]).isRequired),
519
523
  pagination: function pagination(props) {
520
524
  if (props.pagination === false) {
521
525
  return new Error(['MUI: `<DataGrid pagination={false} />` is not a valid prop.', 'Infinite scrolling is not available in the MIT version.', '', 'You need to upgrade to DataGridPro or DataGridPremium component to disable the pagination.'].join('\n'));
@@ -23,7 +23,6 @@ var GridPaginationRoot = styled(TablePagination)(function (_ref) {
23
23
  })), _ref2;
24
24
  });
25
25
  export var GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(props, ref) {
26
- var _rootProps$pageSizeOp;
27
26
  var apiRef = useGridApiContext();
28
27
  var rootProps = useGridRootProps();
29
28
  var paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
@@ -42,22 +41,36 @@ export var GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginatio
42
41
  var handlePageChange = React.useCallback(function (_, page) {
43
42
  apiRef.current.setPage(page);
44
43
  }, [apiRef]);
44
+ var isPageSizeIncludedInPageSizeOptions = function isPageSizeIncludedInPageSizeOptions(pageSize) {
45
+ for (var i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
46
+ var option = rootProps.pageSizeOptions[i];
47
+ if (typeof option === 'number') {
48
+ if (option === pageSize) {
49
+ return true;
50
+ }
51
+ } else if (option.value === pageSize) {
52
+ return true;
53
+ }
54
+ }
55
+ return false;
56
+ };
45
57
  if (process.env.NODE_ENV !== 'production') {
46
58
  var _rootProps$pagination, _rootProps$pagination2;
47
59
  // eslint-disable-next-line react-hooks/rules-of-hooks
48
60
  var warnedOnceMissingInPageSizeOptions = React.useRef(false);
49
61
  var pageSize = (_rootProps$pagination = (_rootProps$pagination2 = rootProps.paginationModel) == null ? void 0 : _rootProps$pagination2.pageSize) != null ? _rootProps$pagination : paginationModel.pageSize;
50
- if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !rootProps.pageSizeOptions.includes(pageSize)) {
62
+ if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
51
63
  console.warn(["MUI: The page size `".concat(paginationModel.pageSize, "` is not preset in the `pageSizeOptions`"), "Add it to show the pagination select."].join('\n'));
52
64
  warnedOnceMissingInPageSizeOptions.current = true;
53
65
  }
54
66
  }
67
+ var pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
55
68
  return /*#__PURE__*/_jsx(GridPaginationRoot, _extends({
56
69
  ref: ref,
57
70
  component: "div",
58
71
  count: rowCount,
59
72
  page: paginationModel.page <= lastPage ? paginationModel.page : lastPage,
60
- rowsPerPageOptions: (_rootProps$pageSizeOp = rootProps.pageSizeOptions) != null && _rootProps$pageSizeOp.includes(paginationModel.pageSize) ? rootProps.pageSizeOptions : [],
73
+ rowsPerPageOptions: pageSizeOptions,
61
74
  rowsPerPage: paginationModel.pageSize,
62
75
  onPageChange: handlePageChange,
63
76
  onRowsPerPageChange: handlePageSizeChange
@@ -151,7 +151,7 @@ function GridEditDateCell(props) {
151
151
  var meta = apiRef.current.unstable_getEditCellMeta(id, field);
152
152
  var handleInputRef = function handleInputRef(el) {
153
153
  inputRef.current = el;
154
- if (meta.unstable_updateValueOnRender && !hasUpdatedEditValueOnMount.current) {
154
+ if (meta != null && meta.unstable_updateValueOnRender && !hasUpdatedEditValueOnMount.current) {
155
155
  var inputValue = inputRef.current.value;
156
156
  var parsedDate = parseValueToDate(inputValue);
157
157
  setValueState({
@@ -100,12 +100,12 @@ var GridEditInputCell = /*#__PURE__*/React.forwardRef(function (props, ref) {
100
100
  return _ref2.apply(this, arguments);
101
101
  };
102
102
  }(), [apiRef, debounceMs, field, id, onValueChange]);
103
- var meta = apiRef.current.unstable_getEditCellMeta ? apiRef.current.unstable_getEditCellMeta(id, field) : {};
103
+ var meta = apiRef.current.unstable_getEditCellMeta(id, field);
104
104
  React.useEffect(function () {
105
- if (meta.changeReason !== 'debouncedSetEditCellValue') {
105
+ if ((meta == null ? void 0 : meta.changeReason) !== 'debouncedSetEditCellValue') {
106
106
  setValueState(value);
107
107
  }
108
- }, [meta.changeReason, value]);
108
+ }, [meta, value]);
109
109
  useEnhancedEffect(function () {
110
110
  if (hasFocus) {
111
111
  inputRef.current.focus();
@@ -68,23 +68,22 @@ function GridToolbarQuickFilter(props) {
68
68
  _React$useState2 = _slicedToArray(_React$useState, 2),
69
69
  searchValue = _React$useState2[0],
70
70
  setSearchValue = _React$useState2[1];
71
- var _React$useState3 = React.useState(quickFilterValues),
72
- _React$useState4 = _slicedToArray(_React$useState3, 2),
73
- prevQuickFilterValues = _React$useState4[0],
74
- setPrevQuickFilterValues = _React$useState4[1];
71
+ var prevQuickFilterValuesRef = React.useRef(quickFilterValues);
75
72
  React.useEffect(function () {
76
- if (!isDeepEqual(prevQuickFilterValues, quickFilterValues)) {
73
+ if (!isDeepEqual(prevQuickFilterValuesRef.current, quickFilterValues)) {
77
74
  // The model of quick filter value has been updated
78
- setPrevQuickFilterValues(quickFilterValues);
75
+ prevQuickFilterValuesRef.current = quickFilterValues;
79
76
 
80
77
  // Update the input value if needed to match the new model
81
78
  setSearchValue(function (prevSearchValue) {
82
79
  return isDeepEqual(quickFilterParser(prevSearchValue), quickFilterValues) ? prevSearchValue : quickFilterFormatter(quickFilterValues != null ? quickFilterValues : []);
83
80
  });
84
81
  }
85
- }, [prevQuickFilterValues, quickFilterValues, quickFilterFormatter, quickFilterParser]);
82
+ }, [quickFilterValues, quickFilterFormatter, quickFilterParser]);
86
83
  var updateSearchValue = React.useCallback(function (newSearchValue) {
87
- apiRef.current.setQuickFilterValues(quickFilterParser(newSearchValue));
84
+ var newQuickFilterValues = quickFilterParser(newSearchValue);
85
+ prevQuickFilterValuesRef.current = newQuickFilterValues;
86
+ apiRef.current.setQuickFilterValues(newQuickFilterValues);
88
87
  }, [apiRef, quickFilterParser]);
89
88
  var debouncedUpdateSearchValue = React.useMemo(function () {
90
89
  return debounce(updateSearchValue, debounceMs);
@@ -106,8 +105,9 @@ function GridToolbarQuickFilter(props) {
106
105
  onChange: handleSearchValueChange,
107
106
  placeholder: apiRef.current.getLocaleText('toolbarQuickFilterPlaceholder'),
108
107
  "aria-label": apiRef.current.getLocaleText('toolbarQuickFilterLabel'),
109
- type: "search",
110
- InputProps: {
108
+ type: "search"
109
+ }, other, {
110
+ InputProps: _extends({
111
111
  startAdornment: /*#__PURE__*/_jsx(rootProps.slots.quickFilterIcon, {
112
112
  fontSize: "small"
113
113
  }),
@@ -123,8 +123,8 @@ function GridToolbarQuickFilter(props) {
123
123
  fontSize: "small"
124
124
  })
125
125
  }))
126
- }
127
- }, other, (_rootProps$slotProps2 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps2.baseTextField));
126
+ }, other.InputProps)
127
+ }, (_rootProps$slotProps2 = rootProps.slotProps) == null ? void 0 : _rootProps$slotProps2.baseTextField));
128
128
  }
129
129
  process.env.NODE_ENV !== "production" ? GridToolbarQuickFilter.propTypes = {
130
130
  // ----------------------------- Warning --------------------------------
@@ -34,13 +34,16 @@ import { useGridApiMethod } from '../../utils/useGridApiMethod';
34
34
  */
35
35
  export var useGridPipeProcessing = function useGridPipeProcessing(apiRef) {
36
36
  var processorsCache = React.useRef({});
37
+ var isRunning = React.useRef(false);
37
38
  var runAppliers = React.useCallback(function (groupCache) {
38
- if (!groupCache) {
39
+ if (isRunning.current || !groupCache) {
39
40
  return;
40
41
  }
42
+ isRunning.current = true;
41
43
  Object.values(groupCache.appliers).forEach(function (callback) {
42
44
  callback();
43
45
  });
46
+ isRunning.current = false;
44
47
  }, []);
45
48
  var registerPipeProcessor = React.useCallback(function (group, id, processor) {
46
49
  if (!processorsCache.current[group]) {
@@ -1,64 +1,84 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
1
2
  import * as React from 'react';
2
3
  import { Store } from '../../utils/Store';
3
4
  import { useGridApiMethod } from '../utils/useGridApiMethod';
4
5
  import { GridSignature } from '../utils/useGridApiEventHandler';
5
6
  import { EventManager } from '../../utils/EventManager';
7
+ var SYMBOL_API_PRIVATE = Symbol('mui.api_private');
6
8
  var isSyntheticEvent = function isSyntheticEvent(event) {
7
9
  return event.isPropagationStopped !== undefined;
8
10
  };
11
+ export function unwrapPrivateAPI(publicApi) {
12
+ return publicApi[SYMBOL_API_PRIVATE];
13
+ }
9
14
  var globalId = 0;
10
- var wrapPublicApi = function wrapPublicApi(publicApi) {
11
- var privateOnlyApi = {};
12
- privateOnlyApi.getPublicApi = function () {
13
- return publicApi;
15
+ function createPrivateAPI(publicApiRef) {
16
+ var _publicApiRef$current;
17
+ var existingPrivateApi = (_publicApiRef$current = publicApiRef.current) == null ? void 0 : _publicApiRef$current[SYMBOL_API_PRIVATE];
18
+ if (existingPrivateApi) {
19
+ return existingPrivateApi;
20
+ }
21
+ var state = {};
22
+ var privateApi = {
23
+ state: state,
24
+ store: Store.create(state),
25
+ instanceId: {
26
+ id: globalId
27
+ }
28
+ };
29
+ globalId += 1;
30
+ privateApi.getPublicApi = function () {
31
+ return publicApiRef.current;
14
32
  };
15
- privateOnlyApi.register = function (visibility, methods) {
33
+ privateApi.register = function (visibility, methods) {
16
34
  Object.keys(methods).forEach(function (methodName) {
17
- if (visibility === 'public') {
18
- publicApi[methodName] = methods[methodName];
35
+ var method = methods[methodName];
36
+ var currentPrivateMethod = privateApi[methodName];
37
+ if ((currentPrivateMethod == null ? void 0 : currentPrivateMethod.spying) === true) {
38
+ currentPrivateMethod.target = method;
19
39
  } else {
20
- privateOnlyApi[methodName] = methods[methodName];
40
+ privateApi[methodName] = method;
41
+ }
42
+ if (visibility === 'public') {
43
+ var publicApi = publicApiRef.current;
44
+ var currentPublicMethod = publicApi[methodName];
45
+ if ((currentPublicMethod == null ? void 0 : currentPublicMethod.spying) === true) {
46
+ currentPublicMethod.target = method;
47
+ } else {
48
+ publicApi[methodName] = method;
49
+ }
21
50
  }
22
51
  });
23
52
  };
24
- var handler = {
25
- get: function get(obj, prop) {
26
- if (prop in obj) {
27
- return obj[prop];
28
- }
29
- return privateOnlyApi[prop];
53
+ privateApi.register('private', {
54
+ caches: {},
55
+ eventManager: new EventManager()
56
+ });
57
+ return privateApi;
58
+ }
59
+ function createPublicAPI(privateApiRef) {
60
+ var publicApi = _defineProperty({
61
+ get state() {
62
+ return privateApiRef.current.state;
63
+ },
64
+ get store() {
65
+ return privateApiRef.current.store;
30
66
  },
31
- set: function set(obj, prop, value) {
32
- obj[prop] = value;
33
- return true;
67
+ get instanceId() {
68
+ return privateApiRef.current.instanceId;
34
69
  }
35
- };
36
- return new Proxy(publicApi, handler);
37
- };
70
+ }, SYMBOL_API_PRIVATE, privateApiRef.current);
71
+ return publicApi;
72
+ }
38
73
  export function useGridApiInitialization(inputApiRef, props) {
39
74
  var publicApiRef = React.useRef();
40
- if (!publicApiRef.current) {
41
- var state = {};
42
- publicApiRef.current = {
43
- state: state,
44
- store: Store.create(state),
45
- instanceId: {
46
- id: globalId
47
- }
48
- };
49
- globalId += 1;
50
- }
51
75
  var privateApiRef = React.useRef();
52
76
  if (!privateApiRef.current) {
53
- privateApiRef.current = wrapPublicApi(publicApiRef.current);
54
- privateApiRef.current.register('private', {
55
- caches: {},
56
- eventManager: new EventManager()
57
- });
77
+ privateApiRef.current = createPrivateAPI(publicApiRef);
78
+ }
79
+ if (!publicApiRef.current) {
80
+ publicApiRef.current = createPublicAPI(privateApiRef);
58
81
  }
59
- React.useImperativeHandle(inputApiRef, function () {
60
- return publicApiRef.current;
61
- }, [publicApiRef]);
62
82
  var publishEvent = React.useCallback(function () {
63
83
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
64
84
  args[_key] = arguments[_key];
@@ -87,6 +107,9 @@ export function useGridApiInitialization(inputApiRef, props) {
87
107
  subscribeEvent: subscribeEvent,
88
108
  publishEvent: publishEvent
89
109
  }, 'public');
110
+ React.useImperativeHandle(inputApiRef, function () {
111
+ return publicApiRef.current;
112
+ }, [publicApiRef]);
90
113
  React.useEffect(function () {
91
114
  var api = privateApiRef.current;
92
115
  return function () {
@@ -17,6 +17,9 @@ export function computeFlexColumnsWidth(_ref) {
17
17
  var initialFreeSpace = _ref.initialFreeSpace,
18
18
  totalFlexUnits = _ref.totalFlexUnits,
19
19
  flexColumns = _ref.flexColumns;
20
+ var uniqueFlexColumns = new Set(flexColumns.map(function (col) {
21
+ return col.field;
22
+ }));
20
23
  var flexColumnsLookup = {
21
24
  all: {},
22
25
  frozenFields: [],
@@ -32,7 +35,7 @@ export function computeFlexColumnsWidth(_ref) {
32
35
  // Step 5 of https://drafts.csswg.org/css-flexbox-1/#resolve-flexible-lengths
33
36
  function loopOverFlexItems() {
34
37
  // 5a: If all the flex items on the line are frozen, free space has been distributed.
35
- if (flexColumnsLookup.frozenFields.length === flexColumns.length) {
38
+ if (flexColumnsLookup.frozenFields.length === uniqueFlexColumns.size) {
36
39
  return;
37
40
  }
38
41
  var violationsLookup = {
@@ -73,7 +73,7 @@ export function useGridDimensions(apiRef, props) {
73
73
  var hasScrollY;
74
74
  if (props.autoHeight) {
75
75
  hasScrollY = false;
76
- hasScrollX = columnsTotalWidth > rootDimensionsRef.current.width;
76
+ hasScrollX = Math.round(columnsTotalWidth) > Math.round(rootDimensionsRef.current.width);
77
77
  viewportOuterSize = {
78
78
  width: rootDimensionsRef.current.width,
79
79
  height: rowsMeta.currentPageTotalHeight + (hasScrollX ? scrollBarSize : 0)
@@ -85,11 +85,11 @@ export function useGridDimensions(apiRef, props) {
85
85
  };
86
86
  var scrollInformation = hasScroll({
87
87
  content: {
88
- width: columnsTotalWidth,
88
+ width: Math.round(columnsTotalWidth),
89
89
  height: rowsMeta.currentPageTotalHeight
90
90
  },
91
91
  container: {
92
- width: viewportOuterSize.width,
92
+ width: Math.round(viewportOuterSize.width),
93
93
  height: viewportOuterSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom
94
94
  },
95
95
  scrollBarSize: scrollBarSize
@@ -127,8 +127,9 @@ export var useGridEditing = function useGridEditing(apiRef, props) {
127
127
  return props.editMode === GridEditModes.Cell ? apiRef.current.getRowWithUpdatedValuesFromCellEditing(id, field) : apiRef.current.getRowWithUpdatedValuesFromRowEditing(id);
128
128
  }, [apiRef, props.editMode]);
129
129
  var getEditCellMeta = React.useCallback(function (id, field) {
130
+ var _editingState$id$fiel, _editingState$id;
130
131
  var editingState = gridEditRowsStateSelector(apiRef.current.state);
131
- return editingState[id][field];
132
+ return (_editingState$id$fiel = (_editingState$id = editingState[id]) == null ? void 0 : _editingState$id[field]) != null ? _editingState$id$fiel : null;
132
133
  }, [apiRef]);
133
134
  var editingSharedApi = {
134
135
  isCellEditable: isCellEditable,
@@ -1,3 +1,5 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
1
3
  import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../../colDef';
2
4
  import { buildWarning } from '../../../../utils/warning';
3
5
  function sanitizeCellValue(value, delimiterCharacter) {
@@ -37,48 +39,119 @@ export var serializeCellValue = function serializeCellValue(cellParams, options)
37
39
  return sanitizeCellValue(value, delimiterCharacter);
38
40
  };
39
41
  var objectFormattedValueWarning = buildWarning(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
42
+ var CSVRow = /*#__PURE__*/function () {
43
+ function CSVRow(options) {
44
+ _classCallCheck(this, CSVRow);
45
+ this.options = void 0;
46
+ this.rowString = '';
47
+ this.isEmpty = true;
48
+ this.options = options;
49
+ }
50
+ _createClass(CSVRow, [{
51
+ key: "addValue",
52
+ value: function addValue(value) {
53
+ if (!this.isEmpty) {
54
+ this.rowString += this.options.delimiterCharacter;
55
+ }
56
+ if (value === null || value === undefined) {
57
+ this.rowString += '';
58
+ } else if (typeof this.options.sanitizeCellValue === 'function') {
59
+ this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
60
+ } else {
61
+ this.rowString += value;
62
+ }
63
+ this.isEmpty = false;
64
+ }
65
+ }, {
66
+ key: "getRowString",
67
+ value: function getRowString() {
68
+ return this.rowString;
69
+ }
70
+ }]);
71
+ return CSVRow;
72
+ }();
40
73
  var serializeRow = function serializeRow(_ref) {
41
74
  var id = _ref.id,
42
75
  columns = _ref.columns,
43
76
  getCellParams = _ref.getCellParams,
44
77
  delimiterCharacter = _ref.delimiterCharacter,
45
78
  ignoreValueFormatter = _ref.ignoreValueFormatter;
46
- return columns.map(function (column) {
79
+ var row = new CSVRow({
80
+ delimiterCharacter: delimiterCharacter
81
+ });
82
+ columns.forEach(function (column) {
47
83
  var cellParams = getCellParams(id, column.field);
48
84
  if (process.env.NODE_ENV !== 'production') {
49
85
  if (String(cellParams.formattedValue) === '[object Object]') {
50
86
  objectFormattedValueWarning();
51
87
  }
52
88
  }
53
- return serializeCellValue(cellParams, {
89
+ row.addValue(serializeCellValue(cellParams, {
54
90
  delimiterCharacter: delimiterCharacter,
55
91
  ignoreValueFormatter: ignoreValueFormatter
56
- });
92
+ }));
57
93
  });
94
+ return row.getRowString();
58
95
  };
59
96
  export function buildCSV(options) {
60
97
  var columns = options.columns,
61
98
  rowIds = options.rowIds,
62
- getCellParams = options.getCellParams,
63
99
  delimiterCharacter = options.delimiterCharacter,
64
100
  includeHeaders = options.includeHeaders,
65
- ignoreValueFormatter = options.ignoreValueFormatter;
101
+ includeColumnGroupsHeaders = options.includeColumnGroupsHeaders,
102
+ ignoreValueFormatter = options.ignoreValueFormatter,
103
+ apiRef = options.apiRef;
66
104
  var CSVBody = rowIds.reduce(function (acc, id) {
67
105
  return "".concat(acc).concat(serializeRow({
68
106
  id: id,
69
107
  columns: columns,
70
- getCellParams: getCellParams,
108
+ getCellParams: apiRef.current.getCellParams,
71
109
  delimiterCharacter: delimiterCharacter,
72
110
  ignoreValueFormatter: ignoreValueFormatter
73
- }).join(delimiterCharacter), "\r\n");
111
+ }), "\r\n");
74
112
  }, '').trim();
75
113
  if (!includeHeaders) {
76
114
  return CSVBody;
77
115
  }
78
- var CSVHead = "".concat(columns.filter(function (column) {
116
+ var filteredColumns = columns.filter(function (column) {
79
117
  return column.field !== GRID_CHECKBOX_SELECTION_COL_DEF.field;
80
- }).map(function (column) {
81
- return sanitizeCellValue(column.headerName || column.field, delimiterCharacter);
82
- }).join(delimiterCharacter), "\r\n");
118
+ });
119
+ var headerRows = [];
120
+ if (includeColumnGroupsHeaders) {
121
+ var columnGroupLookup = apiRef.current.unstable_getAllGroupDetails();
122
+ var maxColumnGroupsDepth = 0;
123
+ var columnGroupPathsLookup = filteredColumns.reduce(function (acc, column) {
124
+ var columnGroupPath = apiRef.current.unstable_getColumnGroupPath(column.field);
125
+ acc[column.field] = columnGroupPath;
126
+ maxColumnGroupsDepth = Math.max(maxColumnGroupsDepth, columnGroupPath.length);
127
+ return acc;
128
+ }, {});
129
+ var _loop = function _loop(i) {
130
+ var headerGroupRow = new CSVRow({
131
+ delimiterCharacter: delimiterCharacter,
132
+ sanitizeCellValue: sanitizeCellValue
133
+ });
134
+ headerRows.push(headerGroupRow);
135
+ filteredColumns.forEach(function (column) {
136
+ var columnGroupId = (columnGroupPathsLookup[column.field] || [])[i];
137
+ var columnGroup = columnGroupLookup[columnGroupId];
138
+ headerGroupRow.addValue(columnGroup ? columnGroup.headerName || columnGroup.groupId : '');
139
+ });
140
+ };
141
+ for (var i = 0; i < maxColumnGroupsDepth; i += 1) {
142
+ _loop(i);
143
+ }
144
+ }
145
+ var mainHeaderRow = new CSVRow({
146
+ delimiterCharacter: delimiterCharacter,
147
+ sanitizeCellValue: sanitizeCellValue
148
+ });
149
+ filteredColumns.forEach(function (column) {
150
+ mainHeaderRow.addValue(column.headerName || column.field);
151
+ });
152
+ headerRows.push(mainHeaderRow);
153
+ var CSVHead = "".concat(headerRows.map(function (row) {
154
+ return row.getRowString();
155
+ }).join('\r\n'), "\r\n");
83
156
  return "".concat(CSVHead).concat(CSVBody).trim();
84
157
  }
@@ -21,7 +21,7 @@ export var useGridCsvExport = function useGridCsvExport(apiRef, props) {
21
21
  var ignoreValueFormatterProp = props.unstable_ignoreValueFormatterDuringExport;
22
22
  var ignoreValueFormatter = (_typeof(ignoreValueFormatterProp) === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.csvExport : ignoreValueFormatterProp) || false;
23
23
  var getDataAsCsv = React.useCallback(function () {
24
- var _options$getRowsToExp, _options$includeHeade;
24
+ var _options$getRowsToExp, _options$includeHeade, _options$includeColum;
25
25
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
26
26
  logger.debug("Get data as CSV");
27
27
  var exportedColumns = getColumnsToExport({
@@ -35,10 +35,11 @@ export var useGridCsvExport = function useGridCsvExport(apiRef, props) {
35
35
  return buildCSV({
36
36
  columns: exportedColumns,
37
37
  rowIds: exportedRowIds,
38
- getCellParams: apiRef.current.getCellParams,
39
38
  delimiterCharacter: options.delimiter || ',',
40
39
  includeHeaders: (_options$includeHeade = options.includeHeaders) != null ? _options$includeHeade : true,
41
- ignoreValueFormatter: ignoreValueFormatter
40
+ includeColumnGroupsHeaders: (_options$includeColum = options.includeColumnGroupsHeaders) != null ? _options$includeColum : true,
41
+ ignoreValueFormatter: ignoreValueFormatter,
42
+ apiRef: apiRef
42
43
  });
43
44
  }, [logger, apiRef, ignoreValueFormatter]);
44
45
  var exportDataAsCsv = React.useCallback(function (options) {