@mui/x-data-grid 5.16.0 → 5.17.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 (116) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/components/GridRow.d.ts +2 -1
  3. package/components/GridRow.js +132 -83
  4. package/components/cell/GridBooleanCell.js +2 -1
  5. package/components/cell/GridEditBooleanCell.js +2 -1
  6. package/components/cell/GridEditDateCell.js +2 -1
  7. package/components/cell/GridEditInputCell.js +2 -1
  8. package/components/cell/GridEditSingleSelectCell.js +2 -1
  9. package/components/cell/GridSkeletonCell.d.ts +12 -0
  10. package/components/cell/GridSkeletonCell.js +60 -0
  11. package/components/cell/index.d.ts +1 -0
  12. package/components/cell/index.js +2 -1
  13. package/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  14. package/components/containers/GridRootStyles.js +2 -0
  15. package/components/panel/GridColumnsPanel.d.ts +6 -1
  16. package/components/panel/GridColumnsPanel.js +38 -6
  17. package/constants/defaultGridSlotsComponents.js +2 -1
  18. package/constants/gridClasses.d.ts +8 -0
  19. package/constants/gridClasses.js +1 -1
  20. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +5 -1
  21. package/hooks/features/filter/gridFilterUtils.d.ts +1 -1
  22. package/hooks/features/filter/gridFilterUtils.js +55 -54
  23. package/hooks/features/filter/useGridFilter.js +1 -1
  24. package/hooks/features/rows/useGridParamsApi.js +1 -1
  25. package/hooks/features/rows/useGridRows.js +65 -8
  26. package/hooks/features/rows/useGridRowsMeta.js +36 -16
  27. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -1
  28. package/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  29. package/index.js +1 -1
  30. package/legacy/components/GridRow.js +135 -83
  31. package/legacy/components/cell/GridBooleanCell.js +2 -1
  32. package/legacy/components/cell/GridEditBooleanCell.js +2 -1
  33. package/legacy/components/cell/GridEditDateCell.js +2 -1
  34. package/legacy/components/cell/GridEditInputCell.js +2 -1
  35. package/legacy/components/cell/GridEditSingleSelectCell.js +2 -1
  36. package/legacy/components/cell/GridSkeletonCell.js +57 -0
  37. package/legacy/components/cell/index.js +2 -1
  38. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  39. package/legacy/components/containers/GridRootStyles.js +3 -3
  40. package/legacy/components/panel/GridColumnsPanel.js +41 -6
  41. package/legacy/constants/defaultGridSlotsComponents.js +2 -1
  42. package/legacy/constants/gridClasses.js +1 -1
  43. package/legacy/hooks/features/filter/gridFilterUtils.js +61 -56
  44. package/legacy/hooks/features/filter/useGridFilter.js +1 -1
  45. package/legacy/hooks/features/rows/useGridParamsApi.js +1 -1
  46. package/legacy/hooks/features/rows/useGridRows.js +73 -8
  47. package/legacy/hooks/features/rows/useGridRowsMeta.js +45 -18
  48. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +31 -13
  49. package/legacy/index.js +1 -1
  50. package/legacy/models/events/gridEvents.js +2 -0
  51. package/legacy/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  52. package/legacy/models/params/index.js +2 -1
  53. package/legacy/utils/utils.js +18 -0
  54. package/models/api/gridParamsApi.d.ts +1 -1
  55. package/models/api/gridRowApi.d.ts +6 -0
  56. package/models/api/gridRowsMetaApi.d.ts +6 -1
  57. package/models/events/gridEventLookup.d.ts +7 -1
  58. package/models/events/gridEvents.d.ts +3 -1
  59. package/models/events/gridEvents.js +2 -0
  60. package/models/gridSlotsComponent.d.ts +5 -0
  61. package/models/params/gridCellParams.d.ts +7 -2
  62. package/models/params/gridRenderedRowsIntervalChangeParams.d.ts +10 -0
  63. package/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  64. package/models/params/index.d.ts +1 -0
  65. package/models/params/index.js +2 -1
  66. package/modern/components/GridRow.js +129 -82
  67. package/modern/components/cell/GridBooleanCell.js +2 -1
  68. package/modern/components/cell/GridEditBooleanCell.js +2 -1
  69. package/modern/components/cell/GridEditDateCell.js +2 -1
  70. package/modern/components/cell/GridEditInputCell.js +2 -1
  71. package/modern/components/cell/GridEditSingleSelectCell.js +2 -1
  72. package/modern/components/cell/GridSkeletonCell.js +60 -0
  73. package/modern/components/cell/index.js +2 -1
  74. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  75. package/modern/components/containers/GridRootStyles.js +2 -0
  76. package/modern/components/panel/GridColumnsPanel.js +38 -6
  77. package/modern/constants/defaultGridSlotsComponents.js +2 -1
  78. package/modern/constants/gridClasses.js +1 -1
  79. package/modern/hooks/features/filter/gridFilterUtils.js +54 -53
  80. package/modern/hooks/features/filter/useGridFilter.js +1 -1
  81. package/modern/hooks/features/rows/useGridParamsApi.js +1 -1
  82. package/modern/hooks/features/rows/useGridRows.js +65 -8
  83. package/modern/hooks/features/rows/useGridRowsMeta.js +36 -16
  84. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  85. package/modern/index.js +1 -1
  86. package/modern/models/events/gridEvents.js +2 -0
  87. package/modern/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  88. package/modern/models/params/index.js +2 -1
  89. package/modern/utils/utils.js +16 -0
  90. package/node/components/GridRow.js +131 -75
  91. package/node/components/cell/GridBooleanCell.js +2 -1
  92. package/node/components/cell/GridEditBooleanCell.js +2 -1
  93. package/node/components/cell/GridEditDateCell.js +2 -1
  94. package/node/components/cell/GridEditInputCell.js +2 -1
  95. package/node/components/cell/GridEditSingleSelectCell.js +2 -1
  96. package/node/components/cell/GridSkeletonCell.js +81 -0
  97. package/node/components/cell/index.js +13 -0
  98. package/node/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  99. package/node/components/containers/GridRootStyles.js +2 -0
  100. package/node/components/panel/GridColumnsPanel.js +36 -5
  101. package/node/constants/defaultGridSlotsComponents.js +1 -0
  102. package/node/constants/gridClasses.js +1 -1
  103. package/node/hooks/features/filter/gridFilterUtils.js +55 -55
  104. package/node/hooks/features/filter/useGridFilter.js +1 -1
  105. package/node/hooks/features/rows/useGridParamsApi.js +1 -1
  106. package/node/hooks/features/rows/useGridRows.js +60 -7
  107. package/node/hooks/features/rows/useGridRowsMeta.js +35 -15
  108. package/node/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  109. package/node/index.js +1 -1
  110. package/node/models/events/gridEvents.js +2 -0
  111. package/node/models/params/gridRenderedRowsIntervalChangeParams.js +5 -0
  112. package/node/models/params/index.js +13 -0
  113. package/node/utils/utils.js +18 -0
  114. package/package.json +1 -1
  115. package/utils/utils.d.ts +1 -0
  116. package/utils/utils.js +16 -0
@@ -7,7 +7,7 @@ import MUISwitch from '@mui/material/Switch';
7
7
  import MUIButton from '@mui/material/Button';
8
8
  import MUITooltip from '@mui/material/Tooltip';
9
9
  import MUIPopper from '@mui/material/Popper';
10
- import { GridArrowDownwardIcon, GridArrowUpwardIcon, GridCell, GridCheckIcon, GridCloseIcon, GridColumnIcon, GridColumnMenu, GridColumnsPanel, GridFilterAltIcon, GridFilterListIcon, GridFilterPanel, GridFooter, GridHeader, GridLoadingOverlay, GridNoRowsOverlay, GridPagination, GridPanel, GridPreferencesPanel, GridRow, GridSaveAltIcon, GridSeparatorIcon, GridTableRowsIcon, GridTripleDotsVerticalIcon, GridViewHeadlineIcon, GridViewStreamIcon, GridMoreVertIcon, GridExpandMoreIcon, GridKeyboardArrowRight, GridAddIcon, GridRemoveIcon, GridDragIcon, GridColumnHeaderFilterIconButton, GridSearchIcon } from '../components';
10
+ import { GridArrowDownwardIcon, GridArrowUpwardIcon, GridCell, GridSkeletonCell, GridCheckIcon, GridCloseIcon, GridColumnIcon, GridColumnMenu, GridColumnsPanel, GridFilterAltIcon, GridFilterListIcon, GridFilterPanel, GridFooter, GridHeader, GridLoadingOverlay, GridNoRowsOverlay, GridPagination, GridPanel, GridPreferencesPanel, GridRow, GridSaveAltIcon, GridSeparatorIcon, GridTableRowsIcon, GridTripleDotsVerticalIcon, GridViewHeadlineIcon, GridViewStreamIcon, GridMoreVertIcon, GridExpandMoreIcon, GridKeyboardArrowRight, GridAddIcon, GridRemoveIcon, GridDragIcon, GridColumnHeaderFilterIconButton, GridSearchIcon } from '../components';
11
11
  import { GridColumnUnsortedIcon } from '../components/columnHeaders/GridColumnUnsortedIcon';
12
12
  import { ErrorOverlay } from '../components/ErrorOverlay';
13
13
  import { GridNoResultsOverlay } from '../components/GridNoResultsOverlay';
@@ -52,6 +52,7 @@ export const DATA_GRID_DEFAULT_SLOTS_COMPONENTS = _extends({}, DEFAULT_GRID_ICON
52
52
  BaseTooltip: MUITooltip,
53
53
  BasePopper: MUIPopper,
54
54
  Cell: GridCell,
55
+ SkeletonCell: GridSkeletonCell,
55
56
  ColumnHeaderFilterIconButton: GridColumnHeaderFilterIconButton,
56
57
  ColumnMenu: GridColumnMenu,
57
58
  ErrorOverlay,
@@ -67,6 +67,10 @@ export interface GridClasses {
67
67
  * Styles applied to the cell checkbox element.
68
68
  */
69
69
  cellCheckbox: string;
70
+ /**
71
+ * Styles applied to the skeleton cell element.
72
+ */
73
+ cellSkeleton: string;
70
74
  /**
71
75
  * Styles applied to the selection checkbox element.
72
76
  */
@@ -391,6 +395,10 @@ export interface GridClasses {
391
395
  * Styles applied to the row if it has dynamic row height.
392
396
  */
393
397
  'row--dynamicHeight': string;
398
+ /**
399
+ * Styles applied to the row if its detail panel is open.
400
+ */
401
+ 'row--detailPanelExpanded': string;
394
402
  /**
395
403
  * Styles applied to the row element.
396
404
  */
@@ -2,4 +2,4 @@ import { generateUtilityClasses, generateUtilityClass } from '@mui/material';
2
2
  export function getDataGridUtilityClass(slot) {
3
3
  return generateUtilityClass('MuiDataGrid', slot);
4
4
  }
5
- export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell', 'cellContent', 'cellCheckbox', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnGroupHeader', 'columnHeader--filledGroup', 'columnHeader--emptyGroup', 'columnHeader--showColumnBorder', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLinkOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
5
+ export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell', 'cellContent', 'cellCheckbox', 'cellSkeleton', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnGroupHeader', 'columnHeader--filledGroup', 'columnHeader--emptyGroup', 'columnHeader--showColumnBorder', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLinkOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'row--detailPanelExpanded', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
@@ -3,7 +3,7 @@ import { GridCellIndexCoordinates, GridScrollParams, GridColDef } from '../../..
3
3
  import { GridInitialStateCommunity } from '../../../models/gridStateCommunity';
4
4
  import { GridExportStateParams, GridRestoreStatePreProcessingContext, GridRestoreStatePreProcessingValue } from '../../features/statePersistence/gridStatePersistenceInterface';
5
5
  import { GridHydrateColumnsValue } from '../../features/columns/gridColumnsInterfaces';
6
- import { GridRowEntry } from '../../../models/gridRows';
6
+ import { GridRowEntry, GridRowId } from '../../../models/gridRows';
7
7
  import { GridHydrateRowsValue } from '../../features/rows/gridRowsState';
8
8
  import { GridPreferencePanelsValue } from '../../features/preferencesPanel';
9
9
  export declare type GridPipeProcessorGroup = keyof GridPipeProcessingLookup;
@@ -45,6 +45,10 @@ export interface GridPipeProcessingLookup {
45
45
  value: Partial<GridScrollParams>;
46
46
  context: Partial<GridCellIndexCoordinates>;
47
47
  };
48
+ rowClassName: {
49
+ value: string[];
50
+ context: GridRowId;
51
+ };
48
52
  }
49
53
  export declare type GridPipeProcessor<P extends GridPipeProcessorGroup> = (value: GridPipeProcessingLookup[P]['value'], context: GridPipeProcessingLookup[P] extends {
50
54
  context: any;
@@ -29,5 +29,5 @@ export declare const buildAggregatedFilterItemsApplier: (filterModel: GridFilter
29
29
  */
30
30
  export declare const buildAggregatedQuickFilterApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => GridFilterItemApplierNotAggregated | null;
31
31
  export declare const buildAggregatedFilterApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => GridAggregatedFilterItemApplier;
32
- export declare const passFilterLogic: (allFilterItemResults: (null | GridFilterItemResult)[], allQuickFilterResults: (null | GridQuickFilterValueResult)[], filterModel: GridFilterModel) => boolean;
32
+ export declare const passFilterLogic: (allFilterItemResults: (null | GridFilterItemResult)[], allQuickFilterResults: (null | GridQuickFilterValueResult)[], filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => boolean;
33
33
  export {};
@@ -69,74 +69,74 @@ export const sanitizeFilterModel = (model, disableMultipleColumnsFiltering, apiR
69
69
  export const mergeStateWithFilterModel = (filterModel, disableMultipleColumnsFiltering, apiRef) => filteringState => _extends({}, filteringState, {
70
70
  filterModel: sanitizeFilterModel(filterModel, disableMultipleColumnsFiltering, apiRef)
71
71
  });
72
- /**
73
- * Generates a method to easily check if a row is matching the current filter model.
74
- * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
75
- * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
76
- * @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
77
- */
78
72
 
79
- export const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
80
- const {
81
- items
82
- } = filterModel;
83
-
84
- const getFilterCallbackFromItem = filterItem => {
85
- if (!filterItem.columnField || !filterItem.operatorValue) {
86
- return null;
87
- }
73
+ const getFilterCallbackFromItem = (filterItem, apiRef) => {
74
+ if (!filterItem.columnField || !filterItem.operatorValue) {
75
+ return null;
76
+ }
88
77
 
89
- const column = apiRef.current.getColumn(filterItem.columnField);
78
+ const column = apiRef.current.getColumn(filterItem.columnField);
90
79
 
91
- if (!column) {
92
- return null;
93
- }
80
+ if (!column) {
81
+ return null;
82
+ }
94
83
 
95
- let parsedValue;
84
+ let parsedValue;
96
85
 
97
- if (column.valueParser) {
98
- var _filterItem$value;
86
+ if (column.valueParser) {
87
+ var _filterItem$value;
99
88
 
100
- const parser = column.valueParser;
101
- parsedValue = Array.isArray(filterItem.value) ? (_filterItem$value = filterItem.value) == null ? void 0 : _filterItem$value.map(x => parser(x)) : parser(filterItem.value);
102
- } else {
103
- parsedValue = filterItem.value;
104
- }
89
+ const parser = column.valueParser;
90
+ parsedValue = Array.isArray(filterItem.value) ? (_filterItem$value = filterItem.value) == null ? void 0 : _filterItem$value.map(x => parser(x)) : parser(filterItem.value);
91
+ } else {
92
+ parsedValue = filterItem.value;
93
+ }
105
94
 
106
- const newFilterItem = _extends({}, filterItem, {
107
- value: parsedValue
108
- });
95
+ const newFilterItem = _extends({}, filterItem, {
96
+ value: parsedValue
97
+ });
109
98
 
110
- const filterOperators = column.filterOperators;
99
+ const filterOperators = column.filterOperators;
111
100
 
112
- if (!(filterOperators != null && filterOperators.length)) {
113
- throw new Error(`MUI: No filter operators found for column '${column.field}'.`);
114
- }
101
+ if (!(filterOperators != null && filterOperators.length)) {
102
+ throw new Error(`MUI: No filter operators found for column '${column.field}'.`);
103
+ }
115
104
 
116
- const filterOperator = filterOperators.find(operator => operator.value === newFilterItem.operatorValue);
105
+ const filterOperator = filterOperators.find(operator => operator.value === newFilterItem.operatorValue);
117
106
 
118
- if (!filterOperator) {
119
- throw new Error(`MUI: No filter operator found for column '${column.field}' and operator value '${newFilterItem.operatorValue}'.`);
120
- }
107
+ if (!filterOperator) {
108
+ throw new Error(`MUI: No filter operator found for column '${column.field}' and operator value '${newFilterItem.operatorValue}'.`);
109
+ }
121
110
 
122
- const applyFilterOnRow = filterOperator.getApplyFilterFn(newFilterItem, column);
111
+ const applyFilterOnRow = filterOperator.getApplyFilterFn(newFilterItem, column);
123
112
 
124
- if (typeof applyFilterOnRow !== 'function') {
125
- return null;
126
- }
113
+ if (typeof applyFilterOnRow !== 'function') {
114
+ return null;
115
+ }
127
116
 
128
- const fn = rowId => {
129
- const cellParams = apiRef.current.getCellParams(rowId, newFilterItem.columnField);
130
- return applyFilterOnRow(cellParams);
131
- };
117
+ const fn = rowId => {
118
+ const cellParams = apiRef.current.getCellParams(rowId, newFilterItem.columnField);
119
+ return applyFilterOnRow(cellParams);
120
+ };
132
121
 
133
- return {
134
- fn,
135
- item: newFilterItem
136
- };
122
+ return {
123
+ fn,
124
+ item: newFilterItem
137
125
  };
126
+ };
127
+ /**
128
+ * Generates a method to easily check if a row is matching the current filter model.
129
+ * @param {GridFilterModel} filterModel The model with which we want to filter the rows.
130
+ * @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
131
+ * @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
132
+ */
138
133
 
139
- const appliers = items.map(getFilterCallbackFromItem).filter(callback => !!callback);
134
+
135
+ export const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
136
+ const {
137
+ items
138
+ } = filterModel;
139
+ const appliers = items.map(item => getFilterCallbackFromItem(item, apiRef)).filter(callback => !!callback);
140
140
 
141
141
  if (appliers.length === 0) {
142
142
  return null;
@@ -219,9 +219,10 @@ export const buildAggregatedFilterApplier = (filterModel, apiRef) => {
219
219
  passingQuickFilterValues: isRowMatchingQuickFilter && isRowMatchingQuickFilter(rowId, shouldApplyFilter)
220
220
  });
221
221
  };
222
- export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel) => {
222
+ export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel, apiRef) => {
223
223
  var _filterModel$quickFil, _filterModel$linkOper;
224
224
 
225
+ const cleanedFilterItems = filterModel.items.filter(item => getFilterCallbackFromItem(item, apiRef) !== null);
225
226
  const cleanedAllFilterItemResults = allFilterItemResults.filter(result => result != null);
226
227
  const cleanedAllQuickFilterResults = allQuickFilterResults.filter(result => result != null); // Defaultize operators
227
228
 
@@ -235,13 +236,13 @@ export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, fil
235
236
  };
236
237
 
237
238
  if (linkOperator === GridLinkOperator.And) {
238
- const passesAllFilters = filterModel.items.every(filterItemPredicate);
239
+ const passesAllFilters = cleanedFilterItems.every(filterItemPredicate);
239
240
 
240
241
  if (!passesAllFilters) {
241
242
  return false;
242
243
  }
243
244
  } else {
244
- const passesSomeFilters = filterModel.items.some(filterItemPredicate);
245
+ const passesSomeFilters = cleanedFilterItems.some(filterItemPredicate);
245
246
 
246
247
  if (!passesSomeFilters) {
247
248
  return false;
@@ -271,7 +271,7 @@ export const useGridFilter = (apiRef, props) => {
271
271
  passingFilterItems,
272
272
  passingQuickFilterValues
273
273
  } = params.isRowMatchingFilters(rowId);
274
- isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel);
274
+ isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel, apiRef);
275
275
  }
276
276
 
277
277
  filteredRowsLookup[rowId] = isRowPassing;
@@ -105,7 +105,7 @@ export function useGridParamsApi(apiRef) {
105
105
  formattedValue: value
106
106
  };
107
107
 
108
- if (colDef.valueFormatter) {
108
+ if (colDef && colDef.valueFormatter) {
109
109
  params.formattedValue = colDef.valueFormatter({
110
110
  id,
111
111
  field: params.field,
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
4
4
  import { useGridLogger } from '../../utils/useGridLogger';
5
- import { gridRowCountSelector, gridRowsLookupSelector, gridRowTreeSelector, gridRowIdsSelector, gridRowGroupingNameSelector } from './gridRowsSelector';
5
+ import { gridRowCountSelector, gridRowsLookupSelector, gridRowTreeSelector, gridRowIdsSelector, gridRowGroupingNameSelector, gridRowsIdToIdLookupSelector } from './gridRowsSelector';
6
6
  import { GridSignature, useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
7
7
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
8
8
  import { gridSortedRowIdsSelector } from '../sorting/gridSortingSelector';
@@ -104,14 +104,14 @@ export const useGridRows = (apiRef, props) => {
104
104
  } // we remove duplicate updates. A server can batch updates, and send several updates for the same row in one fn call.
105
105
 
106
106
 
107
- const uniqUpdates = new Map();
107
+ const uniqueUpdates = new Map();
108
108
  updates.forEach(update => {
109
109
  const id = getRowIdFromRowModel(update, props.getRowId, 'A row was provided without id when calling updateRows():');
110
110
 
111
- if (uniqUpdates.has(id)) {
112
- uniqUpdates.set(id, _extends({}, uniqUpdates.get(id), update));
111
+ if (uniqueUpdates.has(id)) {
112
+ uniqueUpdates.set(id, _extends({}, uniqueUpdates.get(id), update));
113
113
  } else {
114
- uniqUpdates.set(id, update);
114
+ uniqueUpdates.set(id, update);
115
115
  }
116
116
  });
117
117
  const deletedRowIds = [];
@@ -123,7 +123,7 @@ export const useGridRows = (apiRef, props) => {
123
123
  idToIdLookup: _extends({}, prevCache.idToIdLookup),
124
124
  ids: [...prevCache.ids]
125
125
  };
126
- uniqUpdates.forEach((partialRow, id) => {
126
+ uniqueUpdates.forEach((partialRow, id) => {
127
127
  // eslint-disable-next-line no-underscore-dangle
128
128
  if (partialRow._action === 'delete') {
129
129
  delete newCache.idRowsLookup[id];
@@ -241,8 +241,64 @@ export const useGridRows = (apiRef, props) => {
241
241
  ids: updatedRows
242
242
  })
243
243
  }));
244
- apiRef.current.applySorting();
244
+ apiRef.current.publishEvent('rowsSet');
245
245
  }, [apiRef, logger]);
246
+ const replaceRows = React.useCallback((firstRowToRender, newRows) => {
247
+ if (props.signature === GridSignature.DataGrid && newRows.length > 1) {
248
+ throw new Error(["MUI: You can't replace rows using `apiRef.current.unstable_replaceRows` on the DataGrid.", 'You need to upgrade to DataGridPro or DataGridPremium component to unlock this feature.'].join('\n'));
249
+ }
250
+
251
+ if (newRows.length === 0) {
252
+ return;
253
+ }
254
+
255
+ const allRows = gridRowIdsSelector(apiRef);
256
+ const updatedRows = [...allRows];
257
+ const idRowsLookup = gridRowsLookupSelector(apiRef);
258
+ const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef);
259
+ const tree = gridRowTreeSelector(apiRef);
260
+
261
+ const updatedIdRowsLookup = _extends({}, idRowsLookup);
262
+
263
+ const updatedIdToIdLookup = _extends({}, idToIdLookup);
264
+
265
+ const updatedTree = _extends({}, tree);
266
+
267
+ const newRowEntries = newRows.map(newRowModel => {
268
+ const rowId = getRowIdFromRowModel(newRowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
269
+ return {
270
+ id: rowId,
271
+ model: newRowModel
272
+ };
273
+ });
274
+ newRowEntries.forEach((row, index) => {
275
+ const [replacedRowId] = updatedRows.splice(firstRowToRender + index, 1, row.id);
276
+ delete updatedIdRowsLookup[replacedRowId];
277
+ delete updatedIdToIdLookup[replacedRowId];
278
+ delete updatedTree[replacedRowId];
279
+ });
280
+ newRowEntries.forEach(row => {
281
+ const rowTreeNodeConfig = {
282
+ id: row.id,
283
+ parent: null,
284
+ depth: 0,
285
+ groupingKey: null,
286
+ groupingField: null
287
+ };
288
+ updatedIdRowsLookup[row.id] = row.model;
289
+ updatedIdToIdLookup[row.id] = row.id;
290
+ updatedTree[row.id] = rowTreeNodeConfig;
291
+ });
292
+ apiRef.current.setState(state => _extends({}, state, {
293
+ rows: _extends({}, state.rows, {
294
+ idRowsLookup: updatedIdRowsLookup,
295
+ idToIdLookup: updatedIdToIdLookup,
296
+ tree: updatedTree,
297
+ ids: updatedRows
298
+ })
299
+ }));
300
+ apiRef.current.publishEvent('rowsSet');
301
+ }, [apiRef, props.signature, props.getRowId]);
246
302
  const rowApi = {
247
303
  getRow,
248
304
  getRowModels,
@@ -254,7 +310,8 @@ export const useGridRows = (apiRef, props) => {
254
310
  setRowChildrenExpansion,
255
311
  getRowNode,
256
312
  getRowIndexRelativeToVisibleRows,
257
- getRowGroupChildren
313
+ getRowGroupChildren,
314
+ unstable_replaceRows: replaceRows
258
315
  };
259
316
  /**
260
317
  * EVENTS
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { debounce } from '@mui/material/utils';
3
+ import { debounce, capitalize } from '@mui/material/utils';
4
4
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
5
5
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
6
6
  import { useGridSelector } from '../../utils/useGridSelector';
@@ -47,7 +47,7 @@ export const useGridRowsMeta = (apiRef, props) => {
47
47
  if (!rowsHeightLookup.current[row.id]) {
48
48
  rowsHeightLookup.current[row.id] = {
49
49
  sizes: {
50
- base: rowHeightFromDensity
50
+ baseCenter: rowHeightFromDensity
51
51
  },
52
52
  isResized: false,
53
53
  autoHeight: false,
@@ -62,7 +62,7 @@ export const useGridRowsMeta = (apiRef, props) => {
62
62
  sizes
63
63
  } = rowsHeightLookup.current[row.id];
64
64
  let baseRowHeight = rowHeightFromDensity;
65
- const existingBaseRowHeight = sizes.base;
65
+ const existingBaseRowHeight = sizes.baseCenter;
66
66
 
67
67
  if (isResized) {
68
68
  // Do not recalculate resized row height and use the value from the lookup
@@ -93,12 +93,19 @@ export const useGridRowsMeta = (apiRef, props) => {
93
93
  }
94
94
  } else {
95
95
  rowsHeightLookup.current[row.id].needsFirstMeasurement = false;
96
- } // We use an object to make simple to check if a height is already added or not
96
+ }
97
97
 
98
+ const existingBaseSizes = Object.entries(sizes).reduce((acc, [key, size]) => {
99
+ if (/^base[A-Z]/.test(key)) {
100
+ acc[key] = size;
101
+ }
98
102
 
99
- const initialHeights = {
100
- base: baseRowHeight
101
- };
103
+ return acc;
104
+ }, {}); // We use an object to make simple to check if a height is already added or not
105
+
106
+ const initialHeights = _extends({}, existingBaseSizes, {
107
+ baseCenter: baseRowHeight
108
+ });
102
109
 
103
110
  if (getRowSpacing) {
104
111
  var _spacing$top, _spacing$bottom;
@@ -121,9 +128,17 @@ export const useGridRowsMeta = (apiRef, props) => {
121
128
  const positions = [];
122
129
  const currentPageTotalHeight = currentPage.rows.reduce((acc, row) => {
123
130
  positions.push(acc);
131
+ let maximumBaseSize = 0;
132
+ let otherSizes = 0;
124
133
  const processedSizes = calculateRowProcessedSizes(row);
125
- const finalRowHeight = Object.values(processedSizes).reduce((acc2, value) => acc2 + value, 0);
126
- return acc + finalRowHeight;
134
+ Object.entries(processedSizes).forEach(([size, value]) => {
135
+ if (/^base[A-Z]/.test(size)) {
136
+ maximumBaseSize = value > maximumBaseSize ? value : maximumBaseSize;
137
+ } else {
138
+ otherSizes += value;
139
+ }
140
+ });
141
+ return acc + maximumBaseSize + otherSizes;
127
142
  }, 0);
128
143
  pinnedRows == null ? void 0 : (_pinnedRows$top = pinnedRows.top) == null ? void 0 : _pinnedRows$top.forEach(row => {
129
144
  calculateRowProcessedSizes(row);
@@ -149,7 +164,7 @@ export const useGridRowsMeta = (apiRef, props) => {
149
164
  }, [apiRef, currentPage.rows, rowHeightFromDensity, getRowHeightProp, getRowSpacing, getEstimatedRowHeight, pinnedRows]);
150
165
  const getRowHeight = React.useCallback(rowId => {
151
166
  const height = rowsHeightLookup.current[rowId];
152
- return height ? height.sizes.base : rowHeightFromDensity;
167
+ return height ? height.sizes.baseCenter : rowHeightFromDensity;
153
168
  }, [rowHeightFromDensity]);
154
169
 
155
170
  const getRowInternalSizes = rowId => {
@@ -159,21 +174,21 @@ export const useGridRowsMeta = (apiRef, props) => {
159
174
  };
160
175
 
161
176
  const setRowHeight = React.useCallback((id, height) => {
162
- rowsHeightLookup.current[id].sizes.base = height;
177
+ rowsHeightLookup.current[id].sizes.baseCenter = height;
163
178
  rowsHeightLookup.current[id].isResized = true;
164
179
  rowsHeightLookup.current[id].needsFirstMeasurement = false;
165
180
  hydrateRowsMeta();
166
181
  }, [hydrateRowsMeta]);
167
182
  const debouncedHydrateRowsMeta = React.useMemo(() => debounce(hydrateRowsMeta), [hydrateRowsMeta]);
168
- const storeMeasuredRowHeight = React.useCallback((id, height) => {
183
+ const storeMeasuredRowHeight = React.useCallback((id, height, position) => {
169
184
  if (!rowsHeightLookup.current[id] || !rowsHeightLookup.current[id].autoHeight) {
170
185
  return;
171
186
  } // Only trigger hydration if the value is different, otherwise we trigger a loop
172
187
 
173
188
 
174
- const needsHydration = rowsHeightLookup.current[id].sizes.base !== height;
189
+ const needsHydration = rowsHeightLookup.current[id].sizes[`base${capitalize(position)}`] !== height;
175
190
  rowsHeightLookup.current[id].needsFirstMeasurement = false;
176
- rowsHeightLookup.current[id].sizes.base = height;
191
+ rowsHeightLookup.current[id].sizes[`base${capitalize(position)}`] = height;
177
192
 
178
193
  if (needsHydration) {
179
194
  debouncedHydrateRowsMeta();
@@ -191,7 +206,11 @@ export const useGridRowsMeta = (apiRef, props) => {
191
206
  if (hasRowWithAutoHeight.current && index > lastMeasuredRowIndex.current) {
192
207
  lastMeasuredRowIndex.current = index;
193
208
  }
194
- }, []); // The effect is used to build the rows meta data - currentPageTotalHeight and positions.
209
+ }, []);
210
+ const resetRowHeights = React.useCallback(() => {
211
+ rowsHeightLookup.current = {};
212
+ hydrateRowsMeta();
213
+ }, [hydrateRowsMeta]); // The effect is used to build the rows meta data - currentPageTotalHeight and positions.
195
214
  // Because of variable row height this is needed for the virtualization
196
215
 
197
216
  React.useEffect(() => {
@@ -205,7 +224,8 @@ export const useGridRowsMeta = (apiRef, props) => {
205
224
  unstable_getRowHeight: getRowHeight,
206
225
  unstable_getRowInternalSizes: getRowInternalSizes,
207
226
  unstable_setRowHeight: setRowHeight,
208
- unstable_storeRowHeightMeasurement: storeMeasuredRowHeight
227
+ unstable_storeRowHeightMeasurement: storeMeasuredRowHeight,
228
+ resetRowHeights
209
229
  };
210
230
  useGridApiMethod(apiRef, rowsMetaApi, 'GridRowsMetaApi');
211
231
  };
@@ -25,10 +25,10 @@ export declare const useGridVirtualScroller: (props: UseGridVirtualScrollerProps
25
25
  updateRenderZonePosition: (nextRenderContext: GridRenderContext) => void;
26
26
  getRows: (params?: {
27
27
  renderContext: GridRenderContext | null;
28
+ position?: string | undefined;
28
29
  minFirstColumn?: number | undefined;
29
30
  maxLastColumn?: number | undefined;
30
31
  availableSpace?: number | null | undefined;
31
- ignoreAutoHeight?: boolean | undefined;
32
32
  rows?: GridRowEntry<import("../../../models").GridValidRowModel>[] | undefined;
33
33
  rowIndexOffset?: number | undefined;
34
34
  }) => JSX.Element[] | null;
@@ -215,8 +215,19 @@ export const useGridVirtualScroller = props => {
215
215
  }, [renderContext, updateRenderZonePosition]);
216
216
  const updateRenderContext = React.useCallback(nextRenderContext => {
217
217
  setRenderContext(nextRenderContext);
218
+ const [firstRowToRender, lastRowToRender] = getRenderableIndexes({
219
+ firstIndex: nextRenderContext.firstRowIndex,
220
+ lastIndex: nextRenderContext.lastRowIndex,
221
+ minFirstIndex: 0,
222
+ maxLastIndex: currentPage.rows.length,
223
+ buffer: rootProps.rowBuffer
224
+ });
225
+ apiRef.current.publishEvent('renderedRowsIntervalChange', {
226
+ firstRowToRender,
227
+ lastRowToRender
228
+ });
218
229
  prevRenderContext.current = nextRenderContext;
219
- }, [setRenderContext, prevRenderContext]);
230
+ }, [apiRef, setRenderContext, prevRenderContext, currentPage.rows.length, rootProps.rowBuffer]);
220
231
  React.useEffect(() => {
221
232
  if (containerWidth == null) {
222
233
  return;
@@ -287,8 +298,8 @@ export const useGridVirtualScroller = props => {
287
298
  minFirstColumn = renderZoneMinColumnIndex,
288
299
  maxLastColumn = renderZoneMaxColumnIndex,
289
300
  availableSpace = containerWidth,
290
- ignoreAutoHeight,
291
- rowIndexOffset = 0
301
+ rowIndexOffset = 0,
302
+ position = 'center'
292
303
  } = params;
293
304
 
294
305
  if (!nextRenderContext || availableSpace == null) {
@@ -358,7 +369,7 @@ export const useGridVirtualScroller = props => {
358
369
  model
359
370
  } = renderedRows[i];
360
371
  const lastVisibleRowIndex = firstRowToRender + i === currentPage.rows.length - 1;
361
- const baseRowHeight = !apiRef.current.unstable_rowHasAutoHeight(id) || ignoreAutoHeight ? apiRef.current.unstable_getRowHeight(id) : 'auto';
372
+ const baseRowHeight = !apiRef.current.unstable_rowHasAutoHeight(id) ? apiRef.current.unstable_getRowHeight(id) : 'auto';
362
373
  let isSelected;
363
374
 
364
375
  if (selectedRowsLookup[id] == null) {
@@ -384,7 +395,8 @@ export const useGridVirtualScroller = props => {
384
395
  selected: isSelected,
385
396
  index: rowIndexOffset + ((currentPage == null ? void 0 : (_currentPage$range5 = currentPage.range) == null ? void 0 : _currentPage$range5.firstRowIndex) || 0) + firstRowToRender + i,
386
397
  containerWidth: availableSpace,
387
- isLastVisible: lastVisibleRowIndex
398
+ isLastVisible: lastVisibleRowIndex,
399
+ position: position
388
400
  }, typeof getRowProps === 'function' ? getRowProps(id, model) : {}, (_rootProps$components = rootProps.componentsProps) == null ? void 0 : _rootProps$components.row), id));
389
401
  }
390
402
 
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.16.0
1
+ /** @license MUI v5.17.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.