@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
@@ -3,58 +3,79 @@ import { Store } from '../../utils/Store';
3
3
  import { useGridApiMethod } from '../utils/useGridApiMethod';
4
4
  import { GridSignature } from '../utils/useGridApiEventHandler';
5
5
  import { EventManager } from '../../utils/EventManager';
6
+ const SYMBOL_API_PRIVATE = Symbol('mui.api_private');
6
7
  const isSyntheticEvent = event => {
7
8
  return event.isPropagationStopped !== undefined;
8
9
  };
10
+ export function unwrapPrivateAPI(publicApi) {
11
+ return publicApi[SYMBOL_API_PRIVATE];
12
+ }
9
13
  let globalId = 0;
10
- const wrapPublicApi = publicApi => {
11
- const privateOnlyApi = {};
12
- privateOnlyApi.getPublicApi = () => publicApi;
13
- privateOnlyApi.register = (visibility, methods) => {
14
+ function createPrivateAPI(publicApiRef) {
15
+ const existingPrivateApi = publicApiRef.current?.[SYMBOL_API_PRIVATE];
16
+ if (existingPrivateApi) {
17
+ return existingPrivateApi;
18
+ }
19
+ const state = {};
20
+ const privateApi = {
21
+ state,
22
+ store: Store.create(state),
23
+ instanceId: {
24
+ id: globalId
25
+ }
26
+ };
27
+ globalId += 1;
28
+ privateApi.getPublicApi = () => publicApiRef.current;
29
+ privateApi.register = (visibility, methods) => {
14
30
  Object.keys(methods).forEach(methodName => {
15
- if (visibility === 'public') {
16
- publicApi[methodName] = methods[methodName];
31
+ const method = methods[methodName];
32
+ const currentPrivateMethod = privateApi[methodName];
33
+ if (currentPrivateMethod?.spying === true) {
34
+ currentPrivateMethod.target = method;
17
35
  } else {
18
- privateOnlyApi[methodName] = methods[methodName];
36
+ privateApi[methodName] = method;
37
+ }
38
+ if (visibility === 'public') {
39
+ const publicApi = publicApiRef.current;
40
+ const currentPublicMethod = publicApi[methodName];
41
+ if (currentPublicMethod?.spying === true) {
42
+ currentPublicMethod.target = method;
43
+ } else {
44
+ publicApi[methodName] = method;
45
+ }
19
46
  }
20
47
  });
21
48
  };
22
- const handler = {
23
- get: (obj, prop) => {
24
- if (prop in obj) {
25
- return obj[prop];
26
- }
27
- return privateOnlyApi[prop];
49
+ privateApi.register('private', {
50
+ caches: {},
51
+ eventManager: new EventManager()
52
+ });
53
+ return privateApi;
54
+ }
55
+ function createPublicAPI(privateApiRef) {
56
+ const publicApi = {
57
+ get state() {
58
+ return privateApiRef.current.state;
28
59
  },
29
- set: (obj, prop, value) => {
30
- obj[prop] = value;
31
- return true;
32
- }
60
+ get store() {
61
+ return privateApiRef.current.store;
62
+ },
63
+ get instanceId() {
64
+ return privateApiRef.current.instanceId;
65
+ },
66
+ [SYMBOL_API_PRIVATE]: privateApiRef.current
33
67
  };
34
- return new Proxy(publicApi, handler);
35
- };
68
+ return publicApi;
69
+ }
36
70
  export function useGridApiInitialization(inputApiRef, props) {
37
71
  const publicApiRef = React.useRef();
38
- if (!publicApiRef.current) {
39
- const state = {};
40
- publicApiRef.current = {
41
- state,
42
- store: Store.create(state),
43
- instanceId: {
44
- id: globalId
45
- }
46
- };
47
- globalId += 1;
48
- }
49
72
  const privateApiRef = React.useRef();
50
73
  if (!privateApiRef.current) {
51
- privateApiRef.current = wrapPublicApi(publicApiRef.current);
52
- privateApiRef.current.register('private', {
53
- caches: {},
54
- eventManager: new EventManager()
55
- });
74
+ privateApiRef.current = createPrivateAPI(publicApiRef);
75
+ }
76
+ if (!publicApiRef.current) {
77
+ publicApiRef.current = createPublicAPI(privateApiRef);
56
78
  }
57
- React.useImperativeHandle(inputApiRef, () => publicApiRef.current, [publicApiRef]);
58
79
  const publishEvent = React.useCallback((...args) => {
59
80
  const [name, params, event = {}] = args;
60
81
  event.defaultMuiPrevented = false;
@@ -77,6 +98,7 @@ export function useGridApiInitialization(inputApiRef, props) {
77
98
  subscribeEvent,
78
99
  publishEvent
79
100
  }, 'public');
101
+ React.useImperativeHandle(inputApiRef, () => publicApiRef.current, [publicApiRef]);
80
102
  React.useEffect(() => {
81
103
  const api = privateApiRef.current;
82
104
  return () => {
@@ -15,6 +15,7 @@ export function computeFlexColumnsWidth({
15
15
  totalFlexUnits,
16
16
  flexColumns
17
17
  }) {
18
+ const uniqueFlexColumns = new Set(flexColumns.map(col => col.field));
18
19
  const flexColumnsLookup = {
19
20
  all: {},
20
21
  frozenFields: [],
@@ -30,7 +31,7 @@ export function computeFlexColumnsWidth({
30
31
  // Step 5 of https://drafts.csswg.org/css-flexbox-1/#resolve-flexible-lengths
31
32
  function loopOverFlexItems() {
32
33
  // 5a: If all the flex items on the line are frozen, free space has been distributed.
33
- if (flexColumnsLookup.frozenFields.length === flexColumns.length) {
34
+ if (flexColumnsLookup.frozenFields.length === uniqueFlexColumns.size) {
34
35
  return;
35
36
  }
36
37
  const violationsLookup = {
@@ -72,7 +72,7 @@ export function useGridDimensions(apiRef, props) {
72
72
  let hasScrollY;
73
73
  if (props.autoHeight) {
74
74
  hasScrollY = false;
75
- hasScrollX = columnsTotalWidth > rootDimensionsRef.current.width;
75
+ hasScrollX = Math.round(columnsTotalWidth) > Math.round(rootDimensionsRef.current.width);
76
76
  viewportOuterSize = {
77
77
  width: rootDimensionsRef.current.width,
78
78
  height: rowsMeta.currentPageTotalHeight + (hasScrollX ? scrollBarSize : 0)
@@ -84,11 +84,11 @@ export function useGridDimensions(apiRef, props) {
84
84
  };
85
85
  const scrollInformation = hasScroll({
86
86
  content: {
87
- width: columnsTotalWidth,
87
+ width: Math.round(columnsTotalWidth),
88
88
  height: rowsMeta.currentPageTotalHeight
89
89
  },
90
90
  container: {
91
- width: viewportOuterSize.width,
91
+ width: Math.round(viewportOuterSize.width),
92
92
  height: viewportOuterSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom
93
93
  },
94
94
  scrollBarSize
@@ -107,7 +107,7 @@ export const useGridEditing = (apiRef, props) => {
107
107
  }, [apiRef, props.editMode]);
108
108
  const getEditCellMeta = React.useCallback((id, field) => {
109
109
  const editingState = gridEditRowsStateSelector(apiRef.current.state);
110
- return editingState[id][field];
110
+ return editingState[id]?.[field] ?? null;
111
111
  }, [apiRef]);
112
112
  const editingSharedApi = {
113
113
  isCellEditable,
@@ -35,43 +35,106 @@ export const serializeCellValue = (cellParams, options) => {
35
35
  return sanitizeCellValue(value, delimiterCharacter);
36
36
  };
37
37
  const 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.']);
38
+ class CSVRow {
39
+ constructor(options) {
40
+ this.options = void 0;
41
+ this.rowString = '';
42
+ this.isEmpty = true;
43
+ this.options = options;
44
+ }
45
+ addValue(value) {
46
+ if (!this.isEmpty) {
47
+ this.rowString += this.options.delimiterCharacter;
48
+ }
49
+ if (value === null || value === undefined) {
50
+ this.rowString += '';
51
+ } else if (typeof this.options.sanitizeCellValue === 'function') {
52
+ this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
53
+ } else {
54
+ this.rowString += value;
55
+ }
56
+ this.isEmpty = false;
57
+ }
58
+ getRowString() {
59
+ return this.rowString;
60
+ }
61
+ }
38
62
  const serializeRow = ({
39
63
  id,
40
64
  columns,
41
65
  getCellParams,
42
66
  delimiterCharacter,
43
67
  ignoreValueFormatter
44
- }) => columns.map(column => {
45
- const cellParams = getCellParams(id, column.field);
46
- if (process.env.NODE_ENV !== 'production') {
47
- if (String(cellParams.formattedValue) === '[object Object]') {
48
- objectFormattedValueWarning();
68
+ }) => {
69
+ const row = new CSVRow({
70
+ delimiterCharacter
71
+ });
72
+ columns.forEach(column => {
73
+ const cellParams = getCellParams(id, column.field);
74
+ if (process.env.NODE_ENV !== 'production') {
75
+ if (String(cellParams.formattedValue) === '[object Object]') {
76
+ objectFormattedValueWarning();
77
+ }
49
78
  }
50
- }
51
- return serializeCellValue(cellParams, {
52
- delimiterCharacter,
53
- ignoreValueFormatter
79
+ row.addValue(serializeCellValue(cellParams, {
80
+ delimiterCharacter,
81
+ ignoreValueFormatter
82
+ }));
54
83
  });
55
- });
84
+ return row.getRowString();
85
+ };
56
86
  export function buildCSV(options) {
57
87
  const {
58
88
  columns,
59
89
  rowIds,
60
- getCellParams,
61
90
  delimiterCharacter,
62
91
  includeHeaders,
63
- ignoreValueFormatter
92
+ includeColumnGroupsHeaders,
93
+ ignoreValueFormatter,
94
+ apiRef
64
95
  } = options;
65
96
  const CSVBody = rowIds.reduce((acc, id) => `${acc}${serializeRow({
66
97
  id,
67
98
  columns,
68
- getCellParams,
99
+ getCellParams: apiRef.current.getCellParams,
69
100
  delimiterCharacter,
70
101
  ignoreValueFormatter
71
- }).join(delimiterCharacter)}\r\n`, '').trim();
102
+ })}\r\n`, '').trim();
72
103
  if (!includeHeaders) {
73
104
  return CSVBody;
74
105
  }
75
- const CSVHead = `${columns.filter(column => column.field !== GRID_CHECKBOX_SELECTION_COL_DEF.field).map(column => sanitizeCellValue(column.headerName || column.field, delimiterCharacter)).join(delimiterCharacter)}\r\n`;
106
+ const filteredColumns = columns.filter(column => column.field !== GRID_CHECKBOX_SELECTION_COL_DEF.field);
107
+ const headerRows = [];
108
+ if (includeColumnGroupsHeaders) {
109
+ const columnGroupLookup = apiRef.current.unstable_getAllGroupDetails();
110
+ let maxColumnGroupsDepth = 0;
111
+ const columnGroupPathsLookup = filteredColumns.reduce((acc, column) => {
112
+ const columnGroupPath = apiRef.current.unstable_getColumnGroupPath(column.field);
113
+ acc[column.field] = columnGroupPath;
114
+ maxColumnGroupsDepth = Math.max(maxColumnGroupsDepth, columnGroupPath.length);
115
+ return acc;
116
+ }, {});
117
+ for (let i = 0; i < maxColumnGroupsDepth; i += 1) {
118
+ const headerGroupRow = new CSVRow({
119
+ delimiterCharacter,
120
+ sanitizeCellValue
121
+ });
122
+ headerRows.push(headerGroupRow);
123
+ filteredColumns.forEach(column => {
124
+ const columnGroupId = (columnGroupPathsLookup[column.field] || [])[i];
125
+ const columnGroup = columnGroupLookup[columnGroupId];
126
+ headerGroupRow.addValue(columnGroup ? columnGroup.headerName || columnGroup.groupId : '');
127
+ });
128
+ }
129
+ }
130
+ const mainHeaderRow = new CSVRow({
131
+ delimiterCharacter,
132
+ sanitizeCellValue
133
+ });
134
+ filteredColumns.forEach(column => {
135
+ mainHeaderRow.addValue(column.headerName || column.field);
136
+ });
137
+ headerRows.push(mainHeaderRow);
138
+ const CSVHead = `${headerRows.map(row => row.getRowString()).join('\r\n')}\r\n`;
76
139
  return `${CSVHead}${CSVBody}`.trim();
77
140
  }
@@ -31,10 +31,11 @@ export const useGridCsvExport = (apiRef, props) => {
31
31
  return buildCSV({
32
32
  columns: exportedColumns,
33
33
  rowIds: exportedRowIds,
34
- getCellParams: apiRef.current.getCellParams,
35
34
  delimiterCharacter: options.delimiter || ',',
36
35
  includeHeaders: options.includeHeaders ?? true,
37
- ignoreValueFormatter
36
+ includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
37
+ ignoreValueFormatter,
38
+ apiRef
38
39
  });
39
40
  }, [logger, apiRef, ignoreValueFormatter]);
40
41
  const exportDataAsCsv = React.useCallback(options => {
@@ -3,7 +3,7 @@ import { GridLogicOperator } from '../../../models';
3
3
  import { GLOBAL_API_REF, isInternalFilter } from '../../../colDef/utils';
4
4
  import { getDefaultGridFilterModel } from './gridFilterState';
5
5
  import { buildWarning } from '../../../utils/warning';
6
- import { gridColumnFieldsSelector, gridColumnLookupSelector } from '../columns';
6
+ import { gridColumnFieldsSelector, gridColumnLookupSelector, gridVisibleColumnFieldsSelector } from '../columns';
7
7
  /**
8
8
  * Adds default values to the optional fields of a filter items.
9
9
  * @param {GridFilterItem} item The raw filter item.
@@ -157,7 +157,8 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
157
157
  if (quickFilterValues.length === 0) {
158
158
  return null;
159
159
  }
160
- const columnFields = gridColumnFieldsSelector(apiRef);
160
+ const quickFilterExcludeHiddenColumns = filterModel.quickFilterExcludeHiddenColumns ?? false;
161
+ const columnFields = quickFilterExcludeHiddenColumns ? gridVisibleColumnFieldsSelector(apiRef) : gridColumnFieldsSelector(apiRef);
161
162
  const appliersPerField = [];
162
163
  columnFields.forEach(field => {
163
164
  const column = apiRef.current.getColumn(field);
@@ -20,6 +20,7 @@ export const filterStateInitializer = (state, props, apiRef) => {
20
20
  return _extends({}, state, {
21
21
  filter: {
22
22
  filterModel: sanitizeFilterModel(filterModel, props.disableMultipleColumnsFiltering, apiRef),
23
+ filteredRowsLookup: {},
23
24
  filteredDescendantCountLookup: {}
24
25
  },
25
26
  visibleRowsLookup: {}
@@ -252,6 +253,9 @@ export const useGridFilter = (apiRef, props) => {
252
253
  }, [props.slots.filterPanel, props.slotProps?.filterPanel]);
253
254
  const dataRowIdToIdLookup = apiRef.current.state.rows.dataRowIdToModelLookup;
254
255
  const rows = React.useMemo(() => Object.values(dataRowIdToIdLookup), [dataRowIdToIdLookup]);
256
+ const {
257
+ getRowId
258
+ } = props;
255
259
  const flatFilteringMethod = React.useCallback(params => {
256
260
  if (props.filterMode !== 'client' || !params.isRowMatchingFilters) {
257
261
  return {
@@ -271,9 +275,10 @@ export const useGridFilter = (apiRef, props) => {
271
275
  };
272
276
  for (let i = 0; i < rows.length; i += 1) {
273
277
  const row = rows[i];
278
+ const id = getRowId ? getRowId(row) : row.id;
274
279
  isRowMatchingFilters(row, undefined, result);
275
280
  const isRowPassing = passFilterLogic([result.passingFilterItems], [result.passingQuickFilterValues], params.filterModel, apiRef, filterCache);
276
- filteredRowsLookup[row.id] = isRowPassing;
281
+ filteredRowsLookup[id] = isRowPassing;
277
282
  }
278
283
  const footerId = 'auto-generated-group-footer-root';
279
284
  const footer = dataRowIdToModelLookup[footerId];
@@ -284,7 +289,7 @@ export const useGridFilter = (apiRef, props) => {
284
289
  filteredRowsLookup,
285
290
  filteredDescendantCountLookup: {}
286
291
  };
287
- }, [apiRef, props.filterMode, rows]);
292
+ }, [apiRef, rows, props.filterMode, getRowId]);
288
293
  useGridRegisterPipeProcessor(apiRef, 'columnMenu', addColumnMenuItem);
289
294
  useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
290
295
  useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
@@ -326,6 +331,13 @@ export const useGridFilter = (apiRef, props) => {
326
331
  useGridApiEventHandler(apiRef, 'columnsChange', handleColumnsChange);
327
332
  useGridApiEventHandler(apiRef, 'activeStrategyProcessorChange', handleStrategyProcessorChange);
328
333
  useGridApiEventHandler(apiRef, 'rowExpansionChange', updateVisibleRowsLookupState);
334
+ useGridApiEventHandler(apiRef, 'columnVisibilityModelChange', () => {
335
+ const filterModel = gridFilterModelSelector(apiRef);
336
+ if (filterModel.quickFilterValues && filterModel.quickFilterExcludeHiddenColumns) {
337
+ // re-apply filters because the quick filter results may have changed
338
+ apiRef.current.unstable_applyFilters();
339
+ }
340
+ });
329
341
 
330
342
  /**
331
343
  * 1ST RENDER
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { gridPinnedRowsSelector } from './gridRowsSelector';
3
3
  import { gridDensityFactorSelector } from '../density/densitySelector';
4
4
  export const GRID_ROOT_GROUP_ID = `auto-generated-group-node-root`;
5
- export const GRID_ID_AUTOGENERATED = Symbol('mui-autogenerated-id');
5
+ export const GRID_ID_AUTOGENERATED = Symbol('mui.id_autogenerated');
6
6
  export const buildRootGroup = () => ({
7
7
  type: 'group',
8
8
  id: GRID_ROOT_GROUP_ID,
@@ -101,7 +101,7 @@ 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
- const id = (getRowId ? getRowId(row) : row.id) ?? row[GRID_ID_AUTOGENERATED];
104
+ const id = GRID_ID_AUTOGENERATED in row ? row[GRID_ID_AUTOGENERATED] : getRowId?.(row) ?? row.id;
105
105
  const field = colDef.field;
106
106
  if (!colDef || !colDef.valueGetter) {
107
107
  return row[field];
@@ -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/modern/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
@@ -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';
@@ -299,7 +299,20 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
299
299
  }, [apiRef]);
300
300
  const page = paginationModel.page <= lastPage ? paginationModel.page : lastPage;
301
301
  const pageSize = paginationModel.pageSize;
302
- const pageSizeOptions = rootProps.pageSizeOptions?.includes(pageSize) ? rootProps.pageSizeOptions : [];
302
+ const isPageSizeIncludedInPageSizeOptions = () => {
303
+ for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
304
+ const option = rootProps.pageSizeOptions[i];
305
+ if (typeof option === 'number') {
306
+ if (option === pageSize) {
307
+ return true;
308
+ }
309
+ } else if (option.value === pageSize) {
310
+ return true;
311
+ }
312
+ }
313
+ return false;
314
+ };
315
+ const pageSizeOptions = isPageSizeIncludedInPageSizeOptions() ? rootProps.pageSizeOptions : [];
303
316
  const handleChangeRowsPerPage = (event, newValue) => {
304
317
  const newPageSize = Number(newValue);
305
318
  apiRef.current.setPageSize(newPageSize);
@@ -323,9 +336,9 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
323
336
  value: pageSize,
324
337
  children: pageSizeOptions.map(option => {
325
338
  return /*#__PURE__*/_jsx(Option, {
326
- value: option,
327
- children: option
328
- }, option);
339
+ value: typeof option !== 'number' && option.value ? option.value : option,
340
+ children: typeof option !== 'number' && option.label ? option.label : `${option}`
341
+ }, typeof option !== 'number' && option.label ? option.label : `${option}`);
329
342
  })
330
343
  })]
331
344
  }), /*#__PURE__*/_jsx(JoyTypography, {
@@ -8,8 +8,8 @@ const esESGrid = {
8
8
  toolbarDensity: 'Densidad',
9
9
  toolbarDensityLabel: 'Densidad',
10
10
  toolbarDensityCompact: 'Compacta',
11
- toolbarDensityStandard: 'Standard',
12
- toolbarDensityComfortable: 'Comoda',
11
+ toolbarDensityStandard: 'Estándar',
12
+ toolbarDensityComfortable: 'Cómoda',
13
13
  // Columns selector toolbar button text
14
14
  toolbarColumns: 'Columnas',
15
15
  toolbarColumnsLabel: 'Seleccionar columnas',
@@ -37,7 +37,7 @@ const esESGrid = {
37
37
  columnsPanelHideAllButton: 'Ocultar todo',
38
38
  // Filter panel text
39
39
  filterPanelAddFilter: 'Agregar filtro',
40
- // filterPanelRemoveAll: 'Remove all',
40
+ filterPanelRemoveAll: 'Remover todos',
41
41
  filterPanelDeleteIconLabel: 'Borrar',
42
42
  filterPanelLogicOperator: 'Operador lógico',
43
43
  filterPanelOperator: 'Operadores',
@@ -37,7 +37,7 @@ const plPLGrid = {
37
37
  columnsPanelHideAllButton: 'Ukryj wszystko',
38
38
  // Filter panel text
39
39
  filterPanelAddFilter: 'Dodaj filtr',
40
- // filterPanelRemoveAll: 'Remove all',
40
+ filterPanelRemoveAll: 'Usuń wszystkie',
41
41
  filterPanelDeleteIconLabel: 'Usuń',
42
42
  filterPanelLogicOperator: 'Operator logiczny',
43
43
  filterPanelOperator: 'Operator',
@@ -68,12 +68,12 @@ const plPLGrid = {
68
68
  // 'filterOperator<=': '<=',
69
69
 
70
70
  // Header filter operators text
71
- // headerFilterOperatorContains: 'Contains',
72
- // headerFilterOperatorEquals: 'Equals',
73
- // headerFilterOperatorStartsWith: 'Starts with',
74
- // headerFilterOperatorEndsWith: 'Ends with',
71
+ headerFilterOperatorContains: 'Zawiera',
72
+ headerFilterOperatorEquals: 'Równa się',
73
+ headerFilterOperatorStartsWith: 'Zaczyna się od',
74
+ headerFilterOperatorEndsWith: 'Kończy się na',
75
75
  // headerFilterOperatorIs: 'Is',
76
- // headerFilterOperatorNot: 'Is not',
76
+ headerFilterOperatorNot: 'Niepuste',
77
77
  // headerFilterOperatorAfter: 'Is after',
78
78
  // headerFilterOperatorOnOrAfter: 'Is on or after',
79
79
  // headerFilterOperatorBefore: 'Is before',
@@ -95,7 +95,7 @@ const plPLGrid = {
95
95
  // Column menu text
96
96
  columnMenuLabel: 'Menu',
97
97
  columnMenuShowColumns: 'Pokaż wszystkie kolumny',
98
- // columnMenuManageColumns: 'Manage columns',
98
+ columnMenuManageColumns: 'Zarządzaj kolumnami',
99
99
  columnMenuFilter: 'Filtr',
100
100
  columnMenuHideColumn: 'Ukryj',
101
101
  columnMenuUnsort: 'Anuluj sortowanie',
@@ -190,6 +190,7 @@ DataGridRaw.propTypes = {
190
190
  value: _propTypes.default.any
191
191
  })).isRequired,
192
192
  logicOperator: _propTypes.default.oneOf(['and', 'or']),
193
+ quickFilterExcludeHiddenColumns: _propTypes.default.bool,
193
194
  quickFilterLogicOperator: _propTypes.default.oneOf(['and', 'or']),
194
195
  quickFilterValues: _propTypes.default.array
195
196
  }),
@@ -522,7 +523,10 @@ DataGridRaw.propTypes = {
522
523
  * Select the pageSize dynamically using the component UI.
523
524
  * @default [25, 50, 100]
524
525
  */
525
- pageSizeOptions: _propTypes.default.arrayOf(_propTypes.default.number),
526
+ pageSizeOptions: _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.shape({
527
+ label: _propTypes.default.string.isRequired,
528
+ value: _propTypes.default.number.isRequired
529
+ })]).isRequired),
526
530
  pagination: props => {
527
531
  if (props.pagination === false) {
528
532
  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'));
@@ -47,21 +47,35 @@ const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(pro
47
47
  const handlePageChange = React.useCallback((_, page) => {
48
48
  apiRef.current.setPage(page);
49
49
  }, [apiRef]);
50
+ const isPageSizeIncludedInPageSizeOptions = pageSize => {
51
+ for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
52
+ const option = rootProps.pageSizeOptions[i];
53
+ if (typeof option === 'number') {
54
+ if (option === pageSize) {
55
+ return true;
56
+ }
57
+ } else if (option.value === pageSize) {
58
+ return true;
59
+ }
60
+ }
61
+ return false;
62
+ };
50
63
  if (process.env.NODE_ENV !== 'production') {
51
64
  // eslint-disable-next-line react-hooks/rules-of-hooks
52
65
  const warnedOnceMissingInPageSizeOptions = React.useRef(false);
53
66
  const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
54
- if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !rootProps.pageSizeOptions.includes(pageSize)) {
67
+ if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
55
68
  console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\``, `Add it to show the pagination select.`].join('\n'));
56
69
  warnedOnceMissingInPageSizeOptions.current = true;
57
70
  }
58
71
  }
72
+ const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
59
73
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridPaginationRoot, (0, _extends2.default)({
60
74
  ref: ref,
61
75
  component: "div",
62
76
  count: rowCount,
63
77
  page: paginationModel.page <= lastPage ? paginationModel.page : lastPage,
64
- rowsPerPageOptions: rootProps.pageSizeOptions?.includes(paginationModel.pageSize) ? rootProps.pageSizeOptions : [],
78
+ rowsPerPageOptions: pageSizeOptions,
65
79
  rowsPerPage: paginationModel.pageSize,
66
80
  onPageChange: handlePageChange,
67
81
  onRowsPerPageChange: handlePageSizeChange
@@ -121,7 +121,7 @@ function GridEditDateCell(props) {
121
121
  const meta = apiRef.current.unstable_getEditCellMeta(id, field);
122
122
  const handleInputRef = el => {
123
123
  inputRef.current = el;
124
- if (meta.unstable_updateValueOnRender && !hasUpdatedEditValueOnMount.current) {
124
+ if (meta?.unstable_updateValueOnRender && !hasUpdatedEditValueOnMount.current) {
125
125
  const inputValue = inputRef.current.value;
126
126
  const parsedDate = parseValueToDate(inputValue);
127
127
  setValueState({
@@ -77,12 +77,12 @@ const GridEditInputCell = /*#__PURE__*/React.forwardRef((props, ref) => {
77
77
  unstable_skipValueParser: true
78
78
  }, event);
79
79
  }, [apiRef, debounceMs, field, id, onValueChange]);
80
- const meta = apiRef.current.unstable_getEditCellMeta ? apiRef.current.unstable_getEditCellMeta(id, field) : {};
80
+ const meta = apiRef.current.unstable_getEditCellMeta(id, field);
81
81
  React.useEffect(() => {
82
- if (meta.changeReason !== 'debouncedSetEditCellValue') {
82
+ if (meta?.changeReason !== 'debouncedSetEditCellValue') {
83
83
  setValueState(value);
84
84
  }
85
- }, [meta.changeReason, value]);
85
+ }, [meta, value]);
86
86
  (0, _utils.unstable_useEnhancedEffect)(() => {
87
87
  if (hasFocus) {
88
88
  inputRef.current.focus();