@mui/x-data-grid 5.16.0 → 5.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/CHANGELOG.md +138 -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/GridCell.js +9 -1
  6. package/components/cell/GridEditBooleanCell.js +2 -1
  7. package/components/cell/GridEditDateCell.js +2 -1
  8. package/components/cell/GridEditInputCell.js +2 -1
  9. package/components/cell/GridEditSingleSelectCell.js +2 -1
  10. package/components/cell/GridSkeletonCell.d.ts +12 -0
  11. package/components/cell/GridSkeletonCell.js +60 -0
  12. package/components/cell/index.d.ts +1 -0
  13. package/components/cell/index.js +2 -1
  14. package/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  15. package/components/containers/GridRootStyles.js +2 -0
  16. package/components/panel/GridColumnsPanel.d.ts +6 -1
  17. package/components/panel/GridColumnsPanel.js +38 -6
  18. package/constants/defaultGridSlotsComponents.js +2 -1
  19. package/constants/gridClasses.d.ts +8 -0
  20. package/constants/gridClasses.js +1 -1
  21. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +5 -1
  22. package/hooks/features/editRows/useGridCellEditing.new.js +8 -2
  23. package/hooks/features/editRows/useGridRowEditing.new.js +8 -2
  24. package/hooks/features/filter/gridFilterUtils.d.ts +1 -1
  25. package/hooks/features/filter/gridFilterUtils.js +55 -54
  26. package/hooks/features/filter/useGridFilter.js +1 -1
  27. package/hooks/features/focus/useGridFocus.js +13 -3
  28. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  29. package/hooks/features/rows/useGridParamsApi.js +1 -1
  30. package/hooks/features/rows/useGridRows.js +65 -8
  31. package/hooks/features/rows/useGridRowsMeta.js +36 -16
  32. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -1
  33. package/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  34. package/index.js +1 -1
  35. package/internals/index.d.ts +1 -1
  36. package/internals/index.js +1 -1
  37. package/legacy/components/GridRow.js +135 -83
  38. package/legacy/components/cell/GridBooleanCell.js +2 -1
  39. package/legacy/components/cell/GridCell.js +11 -1
  40. package/legacy/components/cell/GridEditBooleanCell.js +2 -1
  41. package/legacy/components/cell/GridEditDateCell.js +2 -1
  42. package/legacy/components/cell/GridEditInputCell.js +2 -1
  43. package/legacy/components/cell/GridEditSingleSelectCell.js +2 -1
  44. package/legacy/components/cell/GridSkeletonCell.js +57 -0
  45. package/legacy/components/cell/index.js +2 -1
  46. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  47. package/legacy/components/containers/GridRootStyles.js +3 -3
  48. package/legacy/components/panel/GridColumnsPanel.js +41 -6
  49. package/legacy/constants/defaultGridSlotsComponents.js +2 -1
  50. package/legacy/constants/gridClasses.js +1 -1
  51. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +11 -5
  52. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +8 -2
  53. package/legacy/hooks/features/filter/gridFilterUtils.js +61 -56
  54. package/legacy/hooks/features/filter/useGridFilter.js +1 -1
  55. package/legacy/hooks/features/focus/useGridFocus.js +13 -3
  56. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  57. package/legacy/hooks/features/rows/useGridParamsApi.js +1 -1
  58. package/legacy/hooks/features/rows/useGridRows.js +73 -8
  59. package/legacy/hooks/features/rows/useGridRowsMeta.js +45 -18
  60. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +31 -13
  61. package/legacy/index.js +1 -1
  62. package/legacy/internals/index.js +1 -1
  63. package/legacy/models/events/gridEvents.js +2 -0
  64. package/legacy/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  65. package/legacy/models/params/index.js +2 -1
  66. package/legacy/utils/utils.js +25 -0
  67. package/models/api/gridParamsApi.d.ts +1 -1
  68. package/models/api/gridRowApi.d.ts +6 -0
  69. package/models/api/gridRowsMetaApi.d.ts +6 -1
  70. package/models/events/gridEventLookup.d.ts +7 -1
  71. package/models/events/gridEvents.d.ts +3 -1
  72. package/models/events/gridEvents.js +2 -0
  73. package/models/gridSlotsComponent.d.ts +5 -0
  74. package/models/params/gridCellParams.d.ts +7 -2
  75. package/models/params/gridRenderedRowsIntervalChangeParams.d.ts +10 -0
  76. package/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  77. package/models/params/index.d.ts +1 -0
  78. package/models/params/index.js +2 -1
  79. package/modern/components/GridRow.js +129 -82
  80. package/modern/components/cell/GridBooleanCell.js +2 -1
  81. package/modern/components/cell/GridCell.js +9 -1
  82. package/modern/components/cell/GridEditBooleanCell.js +2 -1
  83. package/modern/components/cell/GridEditDateCell.js +2 -1
  84. package/modern/components/cell/GridEditInputCell.js +2 -1
  85. package/modern/components/cell/GridEditSingleSelectCell.js +2 -1
  86. package/modern/components/cell/GridSkeletonCell.js +60 -0
  87. package/modern/components/cell/index.js +2 -1
  88. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  89. package/modern/components/containers/GridRootStyles.js +2 -0
  90. package/modern/components/panel/GridColumnsPanel.js +38 -6
  91. package/modern/constants/defaultGridSlotsComponents.js +2 -1
  92. package/modern/constants/gridClasses.js +1 -1
  93. package/modern/hooks/features/editRows/useGridCellEditing.new.js +8 -2
  94. package/modern/hooks/features/editRows/useGridRowEditing.new.js +8 -2
  95. package/modern/hooks/features/filter/gridFilterUtils.js +54 -53
  96. package/modern/hooks/features/filter/useGridFilter.js +1 -1
  97. package/modern/hooks/features/focus/useGridFocus.js +13 -3
  98. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  99. package/modern/hooks/features/rows/useGridParamsApi.js +1 -1
  100. package/modern/hooks/features/rows/useGridRows.js +65 -8
  101. package/modern/hooks/features/rows/useGridRowsMeta.js +36 -16
  102. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  103. package/modern/index.js +1 -1
  104. package/modern/internals/index.js +1 -1
  105. package/modern/models/events/gridEvents.js +2 -0
  106. package/modern/models/params/gridRenderedRowsIntervalChangeParams.js +1 -0
  107. package/modern/models/params/index.js +2 -1
  108. package/modern/utils/utils.js +23 -0
  109. package/node/components/GridRow.js +131 -75
  110. package/node/components/cell/GridBooleanCell.js +2 -1
  111. package/node/components/cell/GridCell.js +9 -1
  112. package/node/components/cell/GridEditBooleanCell.js +2 -1
  113. package/node/components/cell/GridEditDateCell.js +2 -1
  114. package/node/components/cell/GridEditInputCell.js +2 -1
  115. package/node/components/cell/GridEditSingleSelectCell.js +2 -1
  116. package/node/components/cell/GridSkeletonCell.js +81 -0
  117. package/node/components/cell/index.js +13 -0
  118. package/node/components/columnSelection/GridCellCheckboxRenderer.js +2 -1
  119. package/node/components/containers/GridRootStyles.js +2 -0
  120. package/node/components/panel/GridColumnsPanel.js +36 -5
  121. package/node/constants/defaultGridSlotsComponents.js +1 -0
  122. package/node/constants/gridClasses.js +1 -1
  123. package/node/hooks/features/editRows/useGridCellEditing.new.js +9 -2
  124. package/node/hooks/features/editRows/useGridRowEditing.new.js +9 -2
  125. package/node/hooks/features/filter/gridFilterUtils.js +55 -55
  126. package/node/hooks/features/filter/useGridFilter.js +1 -1
  127. package/node/hooks/features/focus/useGridFocus.js +13 -3
  128. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -0
  129. package/node/hooks/features/rows/useGridParamsApi.js +1 -1
  130. package/node/hooks/features/rows/useGridRows.js +60 -7
  131. package/node/hooks/features/rows/useGridRowsMeta.js +35 -15
  132. package/node/hooks/features/virtualization/useGridVirtualScroller.js +17 -5
  133. package/node/index.js +1 -1
  134. package/node/internals/index.js +6 -0
  135. package/node/models/events/gridEvents.js +2 -0
  136. package/node/models/params/gridRenderedRowsIntervalChangeParams.js +5 -0
  137. package/node/models/params/index.js +13 -0
  138. package/node/utils/utils.js +27 -0
  139. package/package.json +1 -1
  140. package/utils/utils.d.ts +2 -0
  141. package/utils/utils.js +23 -0
@@ -1,5 +1,8 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["sort"];
2
4
  import * as React from 'react';
5
+ import PropTypes from 'prop-types';
3
6
  import { unstable_composeClasses as composeClasses } from '@mui/material';
4
7
  import IconButton from '@mui/material/IconButton';
5
8
  import { switchClasses } from '@mui/material/Switch';
@@ -54,7 +57,9 @@ const GridColumnsPanelRowRoot = styled('div', {
54
57
  const GridIconButtonRoot = styled(IconButton)({
55
58
  justifyContent: 'flex-end'
56
59
  });
57
- export function GridColumnsPanel(props) {
60
+ const collator = new Intl.Collator();
61
+
62
+ function GridColumnsPanel(props) {
58
63
  var _rootProps$components, _rootProps$components3, _rootProps$components4;
59
64
 
60
65
  const apiRef = useGridApiContext();
@@ -68,6 +73,24 @@ export function GridColumnsPanel(props) {
68
73
  };
69
74
  const classes = useUtilityClasses(ownerState);
70
75
 
76
+ const {
77
+ sort
78
+ } = props,
79
+ other = _objectWithoutPropertiesLoose(props, _excluded);
80
+
81
+ const sortedColumns = React.useMemo(() => {
82
+ switch (sort) {
83
+ case 'asc':
84
+ return [...columns].sort((a, b) => collator.compare(a.headerName || a.field, b.headerName || b.field));
85
+
86
+ case 'desc':
87
+ return [...columns].sort((a, b) => -collator.compare(a.headerName || a.field, b.headerName || b.field));
88
+
89
+ default:
90
+ return columns;
91
+ }
92
+ }, [columns, sort]);
93
+
71
94
  const toggleColumn = event => {
72
95
  const {
73
96
  name: field
@@ -101,16 +124,16 @@ export function GridColumnsPanel(props) {
101
124
  }, []);
102
125
  const currentColumns = React.useMemo(() => {
103
126
  if (!searchValue) {
104
- return columns;
127
+ return sortedColumns;
105
128
  }
106
129
 
107
130
  const searchValueToCheck = searchValue.toLowerCase();
108
- return columns.filter(column => (column.headerName || column.field).toLowerCase().indexOf(searchValueToCheck) > -1);
109
- }, [columns, searchValue]);
131
+ return sortedColumns.filter(column => (column.headerName || column.field).toLowerCase().indexOf(searchValueToCheck) > -1);
132
+ }, [sortedColumns, searchValue]);
110
133
  React.useEffect(() => {
111
134
  searchInputRef.current.focus();
112
135
  }, []);
113
- return /*#__PURE__*/_jsxs(GridPanelWrapper, _extends({}, props, {
136
+ return /*#__PURE__*/_jsxs(GridPanelWrapper, _extends({}, other, {
114
137
  children: [/*#__PURE__*/_jsx(GridPanelHeader, {
115
138
  children: /*#__PURE__*/_jsx(rootProps.components.BaseTextField, _extends({
116
139
  label: apiRef.current.getLocaleText('columnsPanelTextFieldLabel'),
@@ -161,4 +184,13 @@ export function GridColumnsPanel(props) {
161
184
  }))]
162
185
  })]
163
186
  }));
164
- }
187
+ }
188
+
189
+ process.env.NODE_ENV !== "production" ? GridColumnsPanel.propTypes = {
190
+ // ----------------------------- Warning --------------------------------
191
+ // | These PropTypes are generated from the TypeScript type definitions |
192
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
193
+ // ----------------------------------------------------------------------
194
+ sort: PropTypes.oneOf(['asc', 'desc'])
195
+ } : void 0;
196
+ export { GridColumnsPanel };
@@ -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;
@@ -11,6 +11,7 @@ import { gridEditRowsStateSelector } from './gridEditRowsSelector';
11
11
  import { isPrintableKey } from '../../../utils/keyboardUtils';
12
12
  import { buildWarning } from '../../../utils/warning';
13
13
  import { gridRowsIdToIdLookupSelector } from '../rows/gridRowsSelector';
14
+ import { deepClone } from '../../../utils/utils';
14
15
  import { GridCellEditStartReasons, GridCellEditStopReasons } from '../../../models/params/gridEditCellParams';
15
16
  const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, e.g. `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see http://mui.com/components/data-grid/editing/#persistence.'], 'error');
16
17
  export const useGridCellEditing = (apiRef, props) => {
@@ -319,7 +320,11 @@ export const useGridCellEditing = (apiRef, props) => {
319
320
  if (error || isProcessingProps) {
320
321
  // Attempt to change cell mode to "view" was not successful
321
322
  // Update previous mode to allow another attempt
322
- prevCellModesModel.current[id][field].mode = GridCellModes.Edit;
323
+ prevCellModesModel.current[id][field].mode = GridCellModes.Edit; // Revert the mode in the cellModesModel prop back to "edit"
324
+
325
+ updateFieldInCellModesModel(id, field, {
326
+ mode: GridCellModes.Edit
327
+ });
323
328
  return;
324
329
  }
325
330
 
@@ -437,7 +442,8 @@ export const useGridCellEditing = (apiRef, props) => {
437
442
  const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopCellEditMode may change it later
438
443
 
439
444
  const copyOfPrevCellModes = prevCellModesModel.current;
440
- prevCellModesModel.current = cellModesModel;
445
+ prevCellModesModel.current = deepClone(cellModesModel); // Do a deep-clone because the attributes might be changed later
446
+
441
447
  Object.entries(cellModesModel).forEach(([id, fields]) => {
442
448
  Object.entries(fields).forEach(([field, params]) => {
443
449
  var _copyOfPrevCellModes$, _copyOfPrevCellModes$2, _idToIdLookup$id;
@@ -12,6 +12,7 @@ import { isPrintableKey } from '../../../utils/keyboardUtils';
12
12
  import { gridColumnFieldsSelector } from '../columns/gridColumnsSelector';
13
13
  import { buildWarning } from '../../../utils/warning';
14
14
  import { gridRowsIdToIdLookupSelector } from '../rows/gridRowsSelector';
15
+ import { deepClone } from '../../../utils/utils';
15
16
  import { GridRowEditStopReasons, GridRowEditStartReasons } from '../../../models/params/gridRowParams';
16
17
  const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, e.g. `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see http://mui.com/components/data-grid/editing/#persistence.'], 'error');
17
18
  export const useGridRowEditing = (apiRef, props) => {
@@ -403,7 +404,11 @@ export const useGridRowEditing = (apiRef, props) => {
403
404
  const hasSomeFieldWithError = Object.values(editingState[id]).some(fieldProps => fieldProps.error);
404
405
 
405
406
  if (hasSomeFieldWithError) {
406
- prevRowModesModel.current[id].mode = GridRowModes.Edit;
407
+ prevRowModesModel.current[id].mode = GridRowModes.Edit; // Revert the mode in the rowModesModel prop back to "edit"
408
+
409
+ updateRowInRowModesModel(id, {
410
+ mode: GridRowModes.Edit
411
+ });
407
412
  return;
408
413
  }
409
414
 
@@ -586,7 +591,8 @@ export const useGridRowEditing = (apiRef, props) => {
586
591
  const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef); // Update the ref here because updateStateToStopRowEditMode may change it later
587
592
 
588
593
  const copyOfPrevRowModesModel = prevRowModesModel.current;
589
- prevRowModesModel.current = rowModesModel;
594
+ prevRowModesModel.current = deepClone(rowModesModel); // Do a deep-clone because the attributes might be changed later
595
+
590
596
  Object.entries(rowModesModel).forEach(([id, params]) => {
591
597
  var _copyOfPrevRowModesMo, _idToIdLookup$id;
592
598
 
@@ -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;
@@ -131,8 +131,18 @@ export const useGridFocus = (apiRef, props) => {
131
131
  }
132
132
 
133
133
  rowIndexToFocus = clamp(rowIndexToFocus, 0, currentPage.rows.length - 1);
134
- columnIndexToFocus = clamp(columnIndexToFocus, 0, visibleColumns.length - 1);
135
134
  const rowToFocus = currentPage.rows[rowIndexToFocus];
135
+ const colSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowToFocus.id, columnIndexToFocus);
136
+
137
+ if (colSpanInfo && colSpanInfo.spannedByColSpan) {
138
+ if (direction === 'left' || direction === 'below') {
139
+ columnIndexToFocus = colSpanInfo.leftVisibleCellIndex;
140
+ } else if (direction === 'right') {
141
+ columnIndexToFocus = colSpanInfo.rightVisibleCellIndex;
142
+ }
143
+ }
144
+
145
+ columnIndexToFocus = clamp(columnIndexToFocus, 0, visibleColumns.length - 1);
136
146
  const columnToFocus = visibleColumns[columnIndexToFocus];
137
147
  apiRef.current.setCellFocus(rowToFocus.id, columnToFocus.field);
138
148
  }, [apiRef, props.pagination, props.paginationMode]);
@@ -168,7 +178,7 @@ export const useGridFocus = (apiRef, props) => {
168
178
  }
169
179
  }));
170
180
  }, [logger, apiRef]);
171
- const handleCellMouseUp = React.useCallback(params => {
181
+ const handleCellMouseDown = React.useCallback(params => {
172
182
  lastClickedCell.current = params;
173
183
  }, []);
174
184
  const handleDocumentClick = React.useCallback(event => {
@@ -251,7 +261,7 @@ export const useGridFocus = (apiRef, props) => {
251
261
  }, [apiRef, handleDocumentClick]);
252
262
  useGridApiEventHandler(apiRef, 'columnHeaderBlur', handleBlur);
253
263
  useGridApiEventHandler(apiRef, 'cellDoubleClick', handleCellDoubleClick);
254
- useGridApiEventHandler(apiRef, 'cellMouseUp', handleCellMouseUp);
264
+ useGridApiEventHandler(apiRef, 'cellMouseDown', handleCellMouseDown);
255
265
  useGridApiEventHandler(apiRef, 'cellKeyDown', handleCellKeyDown);
256
266
  useGridApiEventHandler(apiRef, 'cellModeChange', handleCellModeChange);
257
267
  useGridApiEventHandler(apiRef, 'columnHeaderFocus', handleColumnHeaderFocus);
@@ -34,6 +34,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
34
34
  * @param {number} colIndex Index of the column to focus
35
35
  * @param {number} rowIndex index of the row to focus
36
36
  * @param {string} closestColumnToUse Which closest column cell to use when the cell is spanned by `colSpan`.
37
+ * TODO replace with apiRef.current.unstable_moveFocusToRelativeCell()
37
38
  */
38
39
 
39
40
  const goToCell = React.useCallback((colIndex, rowId, closestColumnToUse = 'left') => {
@@ -90,6 +91,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
90
91
  case 'ArrowDown':
91
92
  case 'Enter':
92
93
  {
94
+ // TODO v6: Remove Enter case because `cellNavigationKeyDown` is not fired by the new editing API
93
95
  // "Enter" is only triggered by the row / cell editing feature
94
96
  if (rowIndexBefore < lastRowIndexInPage) {
95
97
  goToCell(colIndexBefore, getRowIdFromIndex(rowIndexBefore + 1));
@@ -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