@mui/x-data-grid 6.7.0 → 6.9.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 (205) hide show
  1. package/CHANGELOG.md +145 -5541
  2. package/components/GridColumnHeaders.d.ts +2 -2
  3. package/components/GridColumnHeaders.js +3 -1
  4. package/components/GridPagination.d.ts +2 -2
  5. package/components/GridRow.d.ts +2 -2
  6. package/components/GridRow.js +33 -79
  7. package/components/cell/GridCell.d.ts +24 -15
  8. package/components/cell/GridCell.js +422 -45
  9. package/components/cell/GridEditInputCell.js +9 -9
  10. package/components/cell/index.d.ts +2 -1
  11. package/components/cell/index.js +1 -1
  12. package/components/containers/GridRootStyles.js +30 -16
  13. package/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  14. package/components/panel/GridPanel.d.ts +1 -1
  15. package/components/toolbar/GridToolbar.js +2 -2
  16. package/components/virtualization/GridVirtualScroller.js +4 -9
  17. package/components/virtualization/GridVirtualScrollerContent.js +11 -20
  18. package/constants/defaultGridSlotsComponents.js +6 -2
  19. package/hooks/core/useGridApiInitialization.js +4 -1
  20. package/hooks/core/useGridStateInitialization.js +2 -9
  21. package/hooks/features/clipboard/useGridClipboard.js +1 -4
  22. package/hooks/features/columnGrouping/gridColumnGroupsSelector.js +4 -4
  23. package/hooks/features/columnHeaders/useGridColumnHeaders.js +9 -3
  24. package/hooks/features/columns/gridColumnsSelector.js +7 -7
  25. package/hooks/features/dimensions/useGridDimensions.js +6 -12
  26. package/hooks/features/editing/useGridCellEditing.js +5 -3
  27. package/hooks/features/editing/useGridRowEditing.js +14 -6
  28. package/hooks/features/filter/gridFilterSelector.js +8 -8
  29. package/hooks/features/filter/gridFilterUtils.d.ts +4 -1
  30. package/hooks/features/filter/gridFilterUtils.js +19 -13
  31. package/hooks/features/filter/useGridFilter.js +2 -1
  32. package/hooks/features/focus/useGridFocus.js +9 -4
  33. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  34. package/hooks/features/pagination/gridPaginationSelector.js +4 -4
  35. package/hooks/features/rowSelection/gridRowSelectionSelector.js +3 -3
  36. package/hooks/features/rows/gridRowsSelector.js +3 -3
  37. package/hooks/features/rows/useGridParamsApi.d.ts +2 -0
  38. package/hooks/features/rows/useGridParamsApi.js +7 -15
  39. package/hooks/features/sorting/gridSortingSelector.js +3 -3
  40. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +8 -816
  41. package/hooks/features/virtualization/useGridVirtualScroller.js +40 -38
  42. package/hooks/utils/index.d.ts +1 -1
  43. package/hooks/utils/index.js +1 -1
  44. package/hooks/utils/useGridSelector.d.ts +3 -1
  45. package/hooks/utils/useGridSelector.js +37 -6
  46. package/hooks/utils/useLazyRef.d.ts +2 -0
  47. package/hooks/utils/useLazyRef.js +9 -0
  48. package/hooks/utils/useOnMount.d.ts +2 -0
  49. package/hooks/utils/useOnMount.js +7 -0
  50. package/index.js +1 -1
  51. package/internals/index.d.ts +1 -1
  52. package/internals/index.js +1 -1
  53. package/legacy/components/GridColumnHeaders.js +3 -1
  54. package/legacy/components/GridRow.js +35 -79
  55. package/legacy/components/cell/GridCell.js +425 -46
  56. package/legacy/components/cell/GridEditInputCell.js +9 -9
  57. package/legacy/components/cell/index.js +1 -1
  58. package/legacy/components/containers/GridRootStyles.js +20 -17
  59. package/legacy/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  60. package/legacy/components/toolbar/GridToolbar.js +2 -2
  61. package/legacy/components/virtualization/GridVirtualScroller.js +4 -7
  62. package/legacy/components/virtualization/GridVirtualScrollerContent.js +10 -17
  63. package/legacy/constants/defaultGridSlotsComponents.js +6 -2
  64. package/legacy/hooks/core/useGridApiInitialization.js +4 -1
  65. package/legacy/hooks/core/useGridStateInitialization.js +2 -7
  66. package/legacy/hooks/features/clipboard/useGridClipboard.js +1 -4
  67. package/legacy/hooks/features/columnGrouping/gridColumnGroupsSelector.js +4 -4
  68. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +9 -3
  69. package/legacy/hooks/features/columns/gridColumnsSelector.js +7 -7
  70. package/legacy/hooks/features/dimensions/useGridDimensions.js +6 -12
  71. package/legacy/hooks/features/editing/useGridCellEditing.js +5 -3
  72. package/legacy/hooks/features/editing/useGridRowEditing.js +15 -7
  73. package/legacy/hooks/features/filter/gridFilterSelector.js +8 -8
  74. package/legacy/hooks/features/filter/gridFilterUtils.js +23 -19
  75. package/legacy/hooks/features/filter/useGridFilter.js +2 -1
  76. package/legacy/hooks/features/focus/useGridFocus.js +9 -4
  77. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  78. package/legacy/hooks/features/pagination/gridPaginationSelector.js +4 -4
  79. package/legacy/hooks/features/rowSelection/gridRowSelectionSelector.js +3 -3
  80. package/legacy/hooks/features/rows/gridRowsSelector.js +3 -3
  81. package/legacy/hooks/features/rows/useGridParamsApi.js +23 -15
  82. package/legacy/hooks/features/sorting/gridSortingSelector.js +3 -3
  83. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +38 -34
  84. package/legacy/hooks/utils/index.js +1 -1
  85. package/legacy/hooks/utils/useGridSelector.js +43 -5
  86. package/legacy/hooks/utils/useLazyRef.js +9 -0
  87. package/legacy/hooks/utils/useOnMount.js +7 -0
  88. package/legacy/index.js +1 -1
  89. package/legacy/internals/index.js +1 -1
  90. package/legacy/locales/elGR.js +70 -79
  91. package/legacy/locales/ptBR.js +12 -13
  92. package/legacy/utils/Store.js +34 -0
  93. package/legacy/utils/createSelector.js +74 -6
  94. package/legacy/utils/doesSupportPreventScroll.js +13 -0
  95. package/legacy/utils/fastMemo.js +5 -0
  96. package/legacy/utils/fastObjectShallowCompare.js +32 -0
  97. package/legacy/utils/keyboardUtils.js +4 -2
  98. package/locales/elGR.js +66 -79
  99. package/locales/ptBR.js +12 -13
  100. package/models/api/gridCoreApi.d.ts +6 -0
  101. package/models/colDef/gridColDef.d.ts +4 -3
  102. package/models/colDef/gridColType.d.ts +3 -1
  103. package/models/events/gridEventLookup.d.ts +3 -3
  104. package/modern/components/GridColumnHeaders.js +3 -1
  105. package/modern/components/GridRow.js +32 -79
  106. package/modern/components/cell/GridCell.js +421 -45
  107. package/modern/components/cell/GridEditInputCell.js +9 -9
  108. package/modern/components/cell/index.js +1 -1
  109. package/modern/components/containers/GridRootStyles.js +30 -16
  110. package/modern/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  111. package/modern/components/toolbar/GridToolbar.js +2 -2
  112. package/modern/components/virtualization/GridVirtualScroller.js +4 -9
  113. package/modern/components/virtualization/GridVirtualScrollerContent.js +10 -20
  114. package/modern/constants/defaultGridSlotsComponents.js +6 -2
  115. package/modern/hooks/core/useGridApiInitialization.js +4 -1
  116. package/modern/hooks/core/useGridStateInitialization.js +2 -9
  117. package/modern/hooks/features/clipboard/useGridClipboard.js +1 -4
  118. package/modern/hooks/features/columnGrouping/gridColumnGroupsSelector.js +4 -4
  119. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +9 -3
  120. package/modern/hooks/features/columns/gridColumnsSelector.js +7 -7
  121. package/modern/hooks/features/dimensions/useGridDimensions.js +6 -12
  122. package/modern/hooks/features/editing/useGridCellEditing.js +5 -3
  123. package/modern/hooks/features/editing/useGridRowEditing.js +14 -6
  124. package/modern/hooks/features/filter/gridFilterSelector.js +8 -8
  125. package/modern/hooks/features/filter/gridFilterUtils.js +17 -12
  126. package/modern/hooks/features/filter/useGridFilter.js +2 -1
  127. package/modern/hooks/features/focus/useGridFocus.js +8 -4
  128. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  129. package/modern/hooks/features/pagination/gridPaginationSelector.js +4 -4
  130. package/modern/hooks/features/rowSelection/gridRowSelectionSelector.js +3 -3
  131. package/modern/hooks/features/rows/gridRowsSelector.js +3 -3
  132. package/modern/hooks/features/rows/useGridParamsApi.js +7 -15
  133. package/modern/hooks/features/sorting/gridSortingSelector.js +3 -3
  134. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +40 -38
  135. package/modern/hooks/utils/index.js +1 -1
  136. package/modern/hooks/utils/useGridSelector.js +37 -6
  137. package/modern/hooks/utils/useLazyRef.js +9 -0
  138. package/modern/hooks/utils/useOnMount.js +7 -0
  139. package/modern/index.js +1 -1
  140. package/modern/internals/index.js +1 -1
  141. package/modern/locales/elGR.js +66 -79
  142. package/modern/locales/ptBR.js +12 -13
  143. package/modern/utils/Store.js +24 -0
  144. package/modern/utils/createSelector.js +74 -6
  145. package/modern/utils/doesSupportPreventScroll.js +13 -0
  146. package/modern/utils/fastMemo.js +5 -0
  147. package/modern/utils/fastObjectShallowCompare.js +32 -0
  148. package/modern/utils/keyboardUtils.js +4 -2
  149. package/node/components/GridColumnHeaders.js +4 -2
  150. package/node/components/GridRow.js +32 -79
  151. package/node/components/cell/GridCell.js +424 -47
  152. package/node/components/cell/GridEditInputCell.js +9 -9
  153. package/node/components/cell/index.js +17 -10
  154. package/node/components/containers/GridRootStyles.js +30 -16
  155. package/node/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  156. package/node/components/toolbar/GridToolbar.js +2 -2
  157. package/node/components/virtualization/GridVirtualScroller.js +4 -9
  158. package/node/components/virtualization/GridVirtualScrollerContent.js +10 -20
  159. package/node/constants/defaultGridSlotsComponents.js +4 -1
  160. package/node/hooks/core/useGridApiInitialization.js +4 -1
  161. package/node/hooks/core/useGridStateInitialization.js +2 -9
  162. package/node/hooks/features/clipboard/useGridClipboard.js +1 -4
  163. package/node/hooks/features/columnGrouping/gridColumnGroupsSelector.js +3 -3
  164. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +8 -2
  165. package/node/hooks/features/columns/gridColumnsSelector.js +6 -6
  166. package/node/hooks/features/dimensions/useGridDimensions.js +6 -12
  167. package/node/hooks/features/editing/useGridCellEditing.js +5 -3
  168. package/node/hooks/features/editing/useGridRowEditing.js +14 -6
  169. package/node/hooks/features/filter/gridFilterSelector.js +7 -7
  170. package/node/hooks/features/filter/gridFilterUtils.js +17 -12
  171. package/node/hooks/features/filter/useGridFilter.js +2 -1
  172. package/node/hooks/features/focus/useGridFocus.js +8 -4
  173. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  174. package/node/hooks/features/pagination/gridPaginationSelector.js +3 -3
  175. package/node/hooks/features/rowSelection/gridRowSelectionSelector.js +2 -2
  176. package/node/hooks/features/rows/gridRowsSelector.js +2 -2
  177. package/node/hooks/features/rows/useGridParamsApi.js +9 -15
  178. package/node/hooks/features/sorting/gridSortingSelector.js +2 -2
  179. package/node/hooks/features/virtualization/useGridVirtualScroller.js +40 -36
  180. package/node/hooks/utils/index.js +14 -10
  181. package/node/hooks/utils/useGridSelector.js +41 -7
  182. package/node/hooks/utils/useLazyRef.js +17 -0
  183. package/node/hooks/utils/useOnMount.js +15 -0
  184. package/node/index.js +1 -1
  185. package/node/internals/index.js +7 -0
  186. package/node/locales/elGR.js +66 -79
  187. package/node/locales/ptBR.js +12 -13
  188. package/node/utils/Store.js +31 -0
  189. package/node/utils/createSelector.js +77 -8
  190. package/node/utils/doesSupportPreventScroll.js +19 -0
  191. package/node/utils/fastMemo.js +13 -0
  192. package/node/utils/fastObjectShallowCompare.js +38 -0
  193. package/node/utils/keyboardUtils.js +4 -2
  194. package/package.json +2 -2
  195. package/utils/Store.d.ts +11 -0
  196. package/utils/Store.js +24 -0
  197. package/utils/createSelector.d.ts +1 -0
  198. package/utils/createSelector.js +74 -6
  199. package/utils/doesSupportPreventScroll.d.ts +1 -0
  200. package/utils/doesSupportPreventScroll.js +13 -0
  201. package/utils/fastMemo.d.ts +1 -0
  202. package/utils/fastMemo.js +5 -0
  203. package/utils/fastObjectShallowCompare.d.ts +1 -0
  204. package/utils/fastObjectShallowCompare.js +32 -0
  205. package/utils/keyboardUtils.js +4 -2
@@ -24,7 +24,7 @@ function GridColumnHeaderMenu({
24
24
  apiRef.current.hideColumnMenu();
25
25
  }
26
26
  }, [apiRef, target]);
27
- if (!target) {
27
+ if (!target || !colDef) {
28
28
  return null;
29
29
  }
30
30
  return /*#__PURE__*/_jsx(GridMenu, {
@@ -14,8 +14,8 @@ import { GridToolbarQuickFilter } from './GridToolbarQuickFilter';
14
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
15
  import { jsxs as _jsxs } from "react/jsx-runtime";
16
16
  const GridToolbar = /*#__PURE__*/React.forwardRef(function GridToolbar(props, ref) {
17
- // TODO v6: think about where export option should be passed.
18
- // from componentProps={{ toolbarExport: { ...exportOption} }} seems to be more appropriate
17
+ // TODO v7: think about where export option should be passed.
18
+ // from slotProps={{ toolbarExport: { ...exportOption } }} seems to be more appropriate
19
19
  const {
20
20
  csvOptions,
21
21
  printOptions,
@@ -1,6 +1,4 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["className"];
4
2
  import * as React from 'react';
5
3
  import clsx from 'clsx';
6
4
  import { styled } from '@mui/system';
@@ -31,16 +29,13 @@ const VirtualScrollerRoot = styled('div', {
31
29
  }
32
30
  });
33
31
  const GridVirtualScroller = /*#__PURE__*/React.forwardRef(function GridVirtualScroller(props, ref) {
34
- const {
35
- className
36
- } = props,
37
- other = _objectWithoutPropertiesLoose(props, _excluded);
38
32
  const rootProps = useGridRootProps();
39
33
  const classes = useUtilityClasses(rootProps);
40
34
  return /*#__PURE__*/_jsx(VirtualScrollerRoot, _extends({
41
- ref: ref,
42
- className: clsx(classes.root, className),
35
+ ref: ref
36
+ }, props, {
37
+ className: clsx(classes.root, props.className),
43
38
  ownerState: rootProps
44
- }, other));
39
+ }));
45
40
  });
46
41
  export { GridVirtualScroller };
@@ -1,6 +1,4 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["className", "style"];
4
2
  import * as React from 'react';
5
3
  import clsx from 'clsx';
6
4
  import { styled } from '@mui/system';
@@ -8,11 +6,10 @@ import { unstable_composeClasses as composeClasses } from '@mui/utils';
8
6
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
9
7
  import { getDataGridUtilityClass } from '../../constants/gridClasses';
10
8
  import { jsx as _jsx } from "react/jsx-runtime";
11
- const useUtilityClasses = ownerState => {
9
+ const useUtilityClasses = (props, overflowedContent) => {
12
10
  const {
13
- classes,
14
- overflowedContent
15
- } = ownerState;
11
+ classes
12
+ } = props;
16
13
  const slots = {
17
14
  root: ['virtualScrollerContent', overflowedContent && 'virtualScrollerContent--overflowed']
18
15
  };
@@ -24,21 +21,14 @@ const VirtualScrollerContentRoot = styled('div', {
24
21
  overridesResolver: (props, styles) => styles.virtualScrollerContent
25
22
  })({});
26
23
  const GridVirtualScrollerContent = /*#__PURE__*/React.forwardRef(function GridVirtualScrollerContent(props, ref) {
27
- const {
28
- className,
29
- style
30
- } = props,
31
- other = _objectWithoutPropertiesLoose(props, _excluded);
32
24
  const rootProps = useGridRootProps();
33
- const ownerState = _extends({}, rootProps, {
34
- overflowedContent: !rootProps.autoHeight && style?.minHeight === 'auto'
35
- });
36
- const classes = useUtilityClasses(ownerState);
25
+ const overflowedContent = !rootProps.autoHeight && props.style?.minHeight === 'auto';
26
+ const classes = useUtilityClasses(rootProps, overflowedContent);
37
27
  return /*#__PURE__*/_jsx(VirtualScrollerContentRoot, _extends({
38
- ref: ref,
39
- className: clsx(classes.root, className),
40
- ownerState: ownerState,
41
- style: style
42
- }, other));
28
+ ref: ref
29
+ }, props, {
30
+ ownerState: rootProps,
31
+ className: clsx(classes.root, props.className)
32
+ }));
43
33
  });
44
34
  export { GridVirtualScrollerContent };
@@ -1,11 +1,15 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import { GridCell, GridSkeletonCell, GridColumnsPanel, GridFilterPanel, GridFooter, GridLoadingOverlay, GridNoRowsOverlay, GridPagination, GridPanel, GridPreferencesPanel, GridRow, GridColumnHeaderFilterIconButton } from '../components';
2
+ import { GridSkeletonCell, GridColumnsPanel, GridFilterPanel, GridFooter, GridLoadingOverlay, GridNoRowsOverlay, GridPagination, GridPanel, GridPreferencesPanel, GridRow, GridColumnHeaderFilterIconButton } from '../components';
3
+ import { GridCellV7 } from '../components/cell/GridCell';
3
4
  import { GridColumnHeaders } from '../components/GridColumnHeaders';
4
5
  import { GridColumnMenu } from '../components/menu/columnMenu/GridColumnMenu';
5
6
  import { GridNoResultsOverlay } from '../components/GridNoResultsOverlay';
6
7
  import materialSlots from '../material';
8
+
9
+ // TODO: camelCase these key. It's a private helper now.
10
+ // Remove then need to call `uncapitalizeObjectKeys`.
7
11
  export const DATA_GRID_DEFAULT_SLOTS_COMPONENTS = _extends({}, materialSlots, {
8
- Cell: GridCell,
12
+ Cell: GridCellV7,
9
13
  SkeletonCell: GridSkeletonCell,
10
14
  ColumnHeaderFilterIconButton: GridColumnHeaderFilterIconButton,
11
15
  ColumnMenu: GridColumnMenu,
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { Store } from '../../utils/Store';
2
3
  import { useGridApiMethod } from '../utils/useGridApiMethod';
3
4
  import { GridSignature } from '../utils/useGridApiEventHandler';
4
5
  import { EventManager } from '../../utils/EventManager';
@@ -35,8 +36,10 @@ const wrapPublicApi = publicApi => {
35
36
  export function useGridApiInitialization(inputApiRef, props) {
36
37
  const publicApiRef = React.useRef();
37
38
  if (!publicApiRef.current) {
39
+ const state = {};
38
40
  publicApiRef.current = {
39
- state: {},
41
+ state,
42
+ store: Store.create(state),
40
43
  instanceId: {
41
44
  id: globalId
42
45
  }
@@ -1,6 +1,4 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["stateId"];
4
2
  import * as React from 'react';
5
3
  import { GridSignature } from '../utils/useGridApiEventHandler';
6
4
  import { useGridApiMethod } from '../utils';
@@ -9,13 +7,7 @@ export const useGridStateInitialization = (apiRef, props) => {
9
7
  const controlStateMapRef = React.useRef({});
10
8
  const [, rawForceUpdate] = React.useState();
11
9
  const registerControlState = React.useCallback(controlStateItem => {
12
- const {
13
- stateId
14
- } = controlStateItem,
15
- others = _objectWithoutPropertiesLoose(controlStateItem, _excluded);
16
- controlStateMapRef.current[stateId] = _extends({}, others, {
17
- stateId
18
- });
10
+ controlStateMapRef.current[controlStateItem.stateId] = controlStateItem;
19
11
  }, []);
20
12
  const setState = React.useCallback((state, reason) => {
21
13
  let newState;
@@ -60,6 +52,7 @@ export const useGridStateInitialization = (apiRef, props) => {
60
52
  if (apiRef.current.publishEvent) {
61
53
  apiRef.current.publishEvent('stateChange', newState);
62
54
  }
55
+ apiRef.current.store.update(newState);
63
56
  }
64
57
  if (updatedControlStateIds.length === 1) {
65
58
  const {
@@ -53,10 +53,7 @@ export const useGridClipboard = (apiRef, props) => {
53
53
  const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp?.clipboardExport : ignoreValueFormatterProp) || false;
54
54
  const clipboardCopyCellDelimiter = props.clipboardCopyCellDelimiter;
55
55
  const handleCopy = React.useCallback(event => {
56
- const isModifierKeyPressed = event.ctrlKey || event.metaKey;
57
- // event.code === 'KeyC' is not enough as event.code assume a QWERTY keyboard layout which would
58
- // be wrong with a Dvorak keyboard (as if pressing J).
59
- if (String.fromCharCode(event.keyCode) !== 'C' || !isModifierKeyPressed) {
56
+ if (!((event.ctrlKey || event.metaKey) && event.key === 'c')) {
60
57
  return;
61
58
  }
62
59
 
@@ -1,10 +1,10 @@
1
- import { createSelector } from '../../../utils/createSelector';
1
+ import { createSelector, createSelectorMemoized } from '../../../utils/createSelector';
2
2
  /**
3
3
  * @category ColumnGrouping
4
4
  * @ignore - do not document.
5
5
  */
6
6
  export const gridColumnGroupingSelector = state => state.columnGrouping;
7
- export const gridColumnGroupsUnwrappedModelSelector = createSelector(gridColumnGroupingSelector, columnGrouping => columnGrouping?.unwrappedGroupingModel ?? {});
8
- export const gridColumnGroupsLookupSelector = createSelector(gridColumnGroupingSelector, columnGrouping => columnGrouping?.lookup ?? {});
9
- export const gridColumnGroupsHeaderStructureSelector = createSelector(gridColumnGroupingSelector, columnGrouping => columnGrouping?.headerStructure ?? []);
7
+ export const gridColumnGroupsUnwrappedModelSelector = createSelectorMemoized(gridColumnGroupingSelector, columnGrouping => columnGrouping?.unwrappedGroupingModel ?? {});
8
+ export const gridColumnGroupsLookupSelector = createSelectorMemoized(gridColumnGroupingSelector, columnGrouping => columnGrouping?.lookup ?? {});
9
+ export const gridColumnGroupsHeaderStructureSelector = createSelectorMemoized(gridColumnGroupingSelector, columnGrouping => columnGrouping?.headerStructure ?? []);
10
10
  export const gridColumnGroupsHeaderMaxDepthSelector = createSelector(gridColumnGroupingSelector, columnGrouping => columnGrouping?.maxDepth ?? 0);
@@ -10,7 +10,7 @@ import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
10
10
  import { GridColumnHeaderItem } from '../../../components/columnHeaders/GridColumnHeaderItem';
11
11
  import { getFirstColumnIndexToRender, getTotalHeaderHeight } from '../columns/gridColumnsUtils';
12
12
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
13
- import { getRenderableIndexes } from '../virtualization/useGridVirtualScroller';
13
+ import { areRenderContextsEqual, getRenderableIndexes } from '../virtualization/useGridVirtualScroller';
14
14
  import { GridColumnGroupHeader } from '../../../components/columnHeaders/GridColumnGroupHeader';
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
16
16
  const GridColumnHeaderRow = styled('div', {
@@ -49,12 +49,18 @@ export const useGridColumnHeaders = props => {
49
49
  const rootProps = useGridRootProps();
50
50
  const innerRef = React.useRef(null);
51
51
  const handleInnerRef = useForkRef(innerRefProp, innerRef);
52
- const [renderContext, setRenderContext] = React.useState(null);
52
+ const [renderContext, setRenderContextRaw] = React.useState(null);
53
53
  const prevRenderContext = React.useRef(renderContext);
54
54
  const prevScrollLeft = React.useRef(0);
55
55
  const currentPage = useGridVisibleRows(apiRef, rootProps);
56
56
  const totalHeaderHeight = getTotalHeaderHeight(apiRef, rootProps.columnHeaderHeight);
57
57
  const headerHeight = Math.floor(rootProps.columnHeaderHeight * densityFactor);
58
+ const setRenderContext = React.useCallback(nextRenderContext => {
59
+ if (renderContext && nextRenderContext && areRenderContextsEqual(renderContext, nextRenderContext)) {
60
+ return;
61
+ }
62
+ setRenderContextRaw(nextRenderContext);
63
+ }, [renderContext]);
58
64
  React.useEffect(() => {
59
65
  apiRef.current.columnHeadersContainerElementRef.current.scrollLeft = 0;
60
66
  }, [apiRef]);
@@ -129,7 +135,7 @@ export const useGridColumnHeaders = props => {
129
135
  if (nextRenderContext && canUpdateInnerPosition) {
130
136
  updateInnerPosition(nextRenderContext);
131
137
  }
132
- }, [updateInnerPosition]);
138
+ }, [updateInnerPosition, setRenderContext]);
133
139
  const handleColumnResizeStart = React.useCallback(params => setResizeCol(params.field), []);
134
140
  const handleColumnResizeStop = React.useCallback(() => setResizeCol(''), []);
135
141
  const handleColumnReorderStart = React.useCallback(params => setDragCol(params.field), []);
@@ -1,4 +1,4 @@
1
- import { createSelector } from '../../../utils/createSelector';
1
+ import { createSelector, createSelectorMemoized } from '../../../utils/createSelector';
2
2
  /**
3
3
  * Get the columns state
4
4
  * @category Columns
@@ -21,7 +21,7 @@ export const gridColumnLookupSelector = createSelector(gridColumnsStateSelector,
21
21
  * Get an array of column definitions in the order rendered on screen..
22
22
  * @category Columns
23
23
  */
24
- export const gridColumnDefinitionsSelector = createSelector(gridColumnFieldsSelector, gridColumnLookupSelector, (allFields, lookup) => allFields.map(field => lookup[field]));
24
+ export const gridColumnDefinitionsSelector = createSelectorMemoized(gridColumnFieldsSelector, gridColumnLookupSelector, (allFields, lookup) => allFields.map(field => lookup[field]));
25
25
 
26
26
  /**
27
27
  * Get the column visibility model, containing the visibility status of each column.
@@ -34,19 +34,19 @@ export const gridColumnVisibilityModelSelector = createSelector(gridColumnsState
34
34
  * Get the visible columns as a lookup (an object containing the field for keys and the definition for values).
35
35
  * @category Visible Columns
36
36
  */
37
- export const gridVisibleColumnDefinitionsSelector = createSelector(gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, (columns, columnVisibilityModel) => columns.filter(column => columnVisibilityModel[column.field] !== false));
37
+ export const gridVisibleColumnDefinitionsSelector = createSelectorMemoized(gridColumnDefinitionsSelector, gridColumnVisibilityModelSelector, (columns, columnVisibilityModel) => columns.filter(column => columnVisibilityModel[column.field] !== false));
38
38
 
39
39
  /**
40
40
  * Get the field of each visible column.
41
41
  * @category Visible Columns
42
42
  */
43
- export const gridVisibleColumnFieldsSelector = createSelector(gridVisibleColumnDefinitionsSelector, visibleColumns => visibleColumns.map(column => column.field));
43
+ export const gridVisibleColumnFieldsSelector = createSelectorMemoized(gridVisibleColumnDefinitionsSelector, visibleColumns => visibleColumns.map(column => column.field));
44
44
 
45
45
  /**
46
46
  * Get the left position in pixel of each visible columns relative to the left of the first column.
47
47
  * @category Visible Columns
48
48
  */
49
- export const gridColumnPositionsSelector = createSelector(gridVisibleColumnDefinitionsSelector, visibleColumns => {
49
+ export const gridColumnPositionsSelector = createSelectorMemoized(gridVisibleColumnDefinitionsSelector, visibleColumns => {
50
50
  const positions = [];
51
51
  let currentPosition = 0;
52
52
  for (let i = 0; i < visibleColumns.length; i += 1) {
@@ -72,13 +72,13 @@ export const gridColumnsTotalWidthSelector = createSelector(gridVisibleColumnDef
72
72
  * Get the filterable columns as an array.
73
73
  * @category Columns
74
74
  */
75
- export const gridFilterableColumnDefinitionsSelector = createSelector(gridColumnDefinitionsSelector, columns => columns.filter(col => col.filterable));
75
+ export const gridFilterableColumnDefinitionsSelector = createSelectorMemoized(gridColumnDefinitionsSelector, columns => columns.filter(col => col.filterable));
76
76
 
77
77
  /**
78
78
  * Get the filterable columns as a lookup (an object containing the field for keys and the definition for values).
79
79
  * @category Columns
80
80
  */
81
- export const gridFilterableColumnLookupSelector = createSelector(gridColumnDefinitionsSelector, columns => columns.reduce((acc, col) => {
81
+ export const gridFilterableColumnLookupSelector = createSelectorMemoized(gridColumnDefinitionsSelector, columns => columns.reduce((acc, col) => {
82
82
  if (col.filterable) {
83
83
  acc[col.field] = col;
84
84
  }
@@ -153,22 +153,16 @@ export function useGridDimensions(apiRef, props) {
153
153
  if (!mainEl) {
154
154
  return;
155
155
  }
156
- const height = mainEl.clientHeight || 0;
157
- const width = mainEl.clientWidth || 0;
158
156
  const win = ownerWindow(mainEl);
159
157
  const computedStyle = win.getComputedStyle(mainEl);
160
- const paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
161
- const paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
162
- const paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
163
- const paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
164
- const newHeight = height - paddingTop - paddingBottom;
165
- const newWidth = width - paddingLeft - paddingRight;
166
- const hasHeightChanged = newHeight !== previousSize.current?.height;
167
- const hasWidthChanged = newWidth !== previousSize.current?.width;
158
+ const height = parseFloat(computedStyle.height) || 0;
159
+ const width = parseFloat(computedStyle.width) || 0;
160
+ const hasHeightChanged = height !== previousSize.current?.height;
161
+ const hasWidthChanged = width !== previousSize.current?.width;
168
162
  if (!previousSize.current || hasHeightChanged || hasWidthChanged) {
169
163
  const size = {
170
- width: newWidth,
171
- height: newHeight
164
+ width,
165
+ height
172
166
  };
173
167
  apiRef.current.publishEvent('resize', size);
174
168
  previousSize.current = size;
@@ -14,7 +14,7 @@ import { buildWarning } from '../../../utils/warning';
14
14
  import { gridRowsDataRowIdToIdLookupSelector } from '../rows/gridRowsSelector';
15
15
  import { deepClone } from '../../../utils/utils';
16
16
  import { GridCellEditStartReasons, GridCellEditStopReasons } from '../../../models/params/gridEditCellParams';
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
+ 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/#server-side-persistence.'], 'error');
18
18
  export const useGridCellEditing = (apiRef, props) => {
19
19
  const [cellModesModel, setCellModesModel] = React.useState({});
20
20
  const cellModesModelRef = React.useRef(cellModesModel);
@@ -122,7 +122,8 @@ export const useGridCellEditing = (apiRef, props) => {
122
122
  id,
123
123
  field,
124
124
  reason,
125
- key
125
+ key,
126
+ colDef
126
127
  } = params;
127
128
  const startCellEditModeParams = {
128
129
  id,
@@ -134,7 +135,8 @@ export const useGridCellEditing = (apiRef, props) => {
134
135
  // The sequence of events makes the key pressed by the end-users update the textbox directly.
135
136
  startCellEditModeParams.deleteValue = true;
136
137
  } else {
137
- startCellEditModeParams.initialValue = key;
138
+ const initialValue = colDef.valueParser ? colDef.valueParser(key) : key;
139
+ startCellEditModeParams.initialValue = initialValue;
138
140
  }
139
141
  } else if (reason === GridCellEditStartReasons.deleteKeyDown) {
140
142
  startCellEditModeParams.deleteValue = true;
@@ -15,7 +15,8 @@ import { buildWarning } from '../../../utils/warning';
15
15
  import { gridRowsDataRowIdToIdLookupSelector } from '../rows/gridRowsSelector';
16
16
  import { deepClone } from '../../../utils/utils';
17
17
  import { GridRowEditStopReasons, GridRowEditStartReasons } from '../../../models/params/gridRowParams';
18
- 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');
18
+ import { GRID_ACTIONS_COLUMN_TYPE } from '../../../colDef';
19
+ 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/#server-side-persistence.'], 'error');
19
20
  export const useGridRowEditing = (apiRef, props) => {
20
21
  const [rowModesModel, setRowModesModel] = React.useState({});
21
22
  const rowModesModelRef = React.useRef(rowModesModel);
@@ -113,7 +114,13 @@ export const useGridRowEditing = (apiRef, props) => {
113
114
  } else if (event.key === 'Enter') {
114
115
  reason = GridRowEditStopReasons.enterKeyDown;
115
116
  } else if (event.key === 'Tab') {
116
- const columnFields = gridColumnFieldsSelector(apiRef).filter(field => apiRef.current.isCellEditable(apiRef.current.getCellParams(params.id, field)));
117
+ const columnFields = gridColumnFieldsSelector(apiRef).filter(field => {
118
+ const column = apiRef.current.getColumn(field);
119
+ if (column.type === GRID_ACTIONS_COLUMN_TYPE) {
120
+ return true;
121
+ }
122
+ return apiRef.current.isCellEditable(apiRef.current.getCellParams(params.id, field));
123
+ });
117
124
  if (event.shiftKey) {
118
125
  if (params.field === columnFields[0]) {
119
126
  // Exit if user pressed Shift+Tab on the first field
@@ -134,8 +141,7 @@ export const useGridRowEditing = (apiRef, props) => {
134
141
  }
135
142
  }
136
143
  if (reason) {
137
- const rowParams = apiRef.current.getRowParams(params.id);
138
- const newParams = _extends({}, rowParams, {
144
+ const newParams = _extends({}, apiRef.current.getRowParams(params.id), {
139
145
  reason,
140
146
  field: params.field
141
147
  });
@@ -177,7 +183,8 @@ export const useGridRowEditing = (apiRef, props) => {
177
183
  id,
178
184
  field,
179
185
  reason,
180
- key
186
+ key,
187
+ columns
181
188
  } = params;
182
189
  const startRowEditModeParams = {
183
190
  id,
@@ -189,7 +196,8 @@ export const useGridRowEditing = (apiRef, props) => {
189
196
  // The sequence of events makes the key pressed by the end-users update the textbox directly.
190
197
  startRowEditModeParams.deleteValue = !!field;
191
198
  } else {
192
- startRowEditModeParams.initialValue = key;
199
+ const colDef = columns.find(col => col.field === field);
200
+ startRowEditModeParams.initialValue = colDef.valueParser ? colDef.valueParser(key) : key;
193
201
  }
194
202
  } else if (reason === GridRowEditStartReasons.deleteKeyDown) {
195
203
  startRowEditModeParams.deleteValue = !!field;
@@ -1,4 +1,4 @@
1
- import { createSelector } from '../../../utils/createSelector';
1
+ import { createSelector, createSelectorMemoized } from '../../../utils/createSelector';
2
2
  import { gridSortedRowEntriesSelector } from '../sorting/gridSortingSelector';
3
3
  import { gridColumnLookupSelector } from '../columns/gridColumnsSelector';
4
4
  import { gridRowMaximumTreeDepthSelector, gridRowTreeSelector } from '../rows/gridRowsSelector';
@@ -43,34 +43,34 @@ export const gridFilteredDescendantCountLookupSelector = createSelector(gridFilt
43
43
  * Does not contain the collapsed children.
44
44
  * @category Filtering
45
45
  */
46
- export const gridExpandedSortedRowEntriesSelector = createSelector(gridVisibleRowsLookupSelector, gridSortedRowEntriesSelector, (visibleRowsLookup, sortedRows) => sortedRows.filter(row => visibleRowsLookup[row.id] !== false));
46
+ export const gridExpandedSortedRowEntriesSelector = createSelectorMemoized(gridVisibleRowsLookupSelector, gridSortedRowEntriesSelector, (visibleRowsLookup, sortedRows) => sortedRows.filter(row => visibleRowsLookup[row.id] !== false));
47
47
 
48
48
  /**
49
49
  * Get the id of the rows accessible after the filtering process.
50
50
  * Does not contain the collapsed children.
51
51
  * @category Filtering
52
52
  */
53
- export const gridExpandedSortedRowIdsSelector = createSelector(gridExpandedSortedRowEntriesSelector, visibleSortedRowEntries => visibleSortedRowEntries.map(row => row.id));
53
+ export const gridExpandedSortedRowIdsSelector = createSelectorMemoized(gridExpandedSortedRowEntriesSelector, visibleSortedRowEntries => visibleSortedRowEntries.map(row => row.id));
54
54
 
55
55
  /**
56
56
  * Get the id and the model of the rows accessible after the filtering process.
57
57
  * Contains the collapsed children.
58
58
  * @category Filtering
59
59
  */
60
- export const gridFilteredSortedRowEntriesSelector = createSelector(gridFilteredRowsLookupSelector, gridSortedRowEntriesSelector, (filteredRowsLookup, sortedRows) => sortedRows.filter(row => filteredRowsLookup[row.id] !== false));
60
+ export const gridFilteredSortedRowEntriesSelector = createSelectorMemoized(gridFilteredRowsLookupSelector, gridSortedRowEntriesSelector, (filteredRowsLookup, sortedRows) => sortedRows.filter(row => filteredRowsLookup[row.id] !== false));
61
61
 
62
62
  /**
63
63
  * Get the id of the rows accessible after the filtering process.
64
64
  * Contains the collapsed children.
65
65
  * @category Filtering
66
66
  */
67
- export const gridFilteredSortedRowIdsSelector = createSelector(gridFilteredSortedRowEntriesSelector, filteredSortedRowEntries => filteredSortedRowEntries.map(row => row.id));
67
+ export const gridFilteredSortedRowIdsSelector = createSelectorMemoized(gridFilteredSortedRowEntriesSelector, filteredSortedRowEntries => filteredSortedRowEntries.map(row => row.id));
68
68
 
69
69
  /**
70
70
  * Get the id and the model of the top level rows accessible after the filtering process.
71
71
  * @category Filtering
72
72
  */
73
- export const gridFilteredSortedTopLevelRowEntriesSelector = createSelector(gridExpandedSortedRowEntriesSelector, gridRowTreeSelector, gridRowMaximumTreeDepthSelector, (visibleSortedRows, rowTree, rowTreeDepth) => {
73
+ export const gridFilteredSortedTopLevelRowEntriesSelector = createSelectorMemoized(gridExpandedSortedRowEntriesSelector, gridRowTreeSelector, gridRowMaximumTreeDepthSelector, (visibleSortedRows, rowTree, rowTreeDepth) => {
74
74
  if (rowTreeDepth < 2) {
75
75
  return visibleSortedRows;
76
76
  }
@@ -93,7 +93,7 @@ export const gridFilteredTopLevelRowCountSelector = createSelector(gridFilteredS
93
93
  * @category Filtering
94
94
  * @ignore - do not document.
95
95
  */
96
- export const gridFilterActiveItemsSelector = createSelector(gridFilterModelSelector, gridColumnLookupSelector, (filterModel, columnLookup) => filterModel.items?.filter(item => {
96
+ export const gridFilterActiveItemsSelector = createSelectorMemoized(gridFilterModelSelector, gridColumnLookupSelector, (filterModel, columnLookup) => filterModel.items?.filter(item => {
97
97
  if (!item.field) {
98
98
  return false;
99
99
  }
@@ -111,7 +111,7 @@ export const gridFilterActiveItemsSelector = createSelector(gridFilterModelSelec
111
111
  * @category Filtering
112
112
  * @ignore - do not document.
113
113
  */
114
- export const gridFilterActiveItemsLookupSelector = createSelector(gridFilterActiveItemsSelector, activeFilters => {
114
+ export const gridFilterActiveItemsLookupSelector = createSelectorMemoized(gridFilterActiveItemsSelector, activeFilters => {
115
115
  const result = activeFilters.reduce((res, filterItem) => {
116
116
  if (!res[filterItem.field]) {
117
117
  res[filterItem.field] = [filterItem];
@@ -181,21 +181,25 @@ export const buildAggregatedFilterApplier = (filterModel, apiRef) => {
181
181
  passingQuickFilterValues: isRowMatchingQuickFilter && isRowMatchingQuickFilter(rowId, shouldApplyFilter)
182
182
  });
183
183
  };
184
- export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel, apiRef) => {
185
- const cleanedFilterItems = filterModel.items.filter(item => getFilterCallbackFromItem(item, apiRef) !== null);
186
- const cleanedAllFilterItemResults = allFilterItemResults.filter(result => result != null);
187
- const cleanedAllQuickFilterResults = allQuickFilterResults.filter(result => result != null);
188
-
189
- // Defaultize operators
190
- const quickFilterLogicOperator = filterModel.quickFilterLogicOperator ?? getDefaultGridFilterModel().quickFilterLogicOperator;
191
- const logicOperator = filterModel.logicOperator ?? getDefaultGridFilterModel().logicOperator;
184
+ const isNotNull = result => result != null;
185
+ const filterModelItems = (cache, apiRef, items) => {
186
+ if (!cache.cleanedFilterItems) {
187
+ cache.cleanedFilterItems = items.filter(item => getFilterCallbackFromItem(item, apiRef) !== null);
188
+ }
189
+ return cache.cleanedFilterItems;
190
+ };
191
+ export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel, apiRef, cache) => {
192
+ const cleanedFilterItems = filterModelItems(cache, apiRef, filterModel.items);
193
+ const cleanedFilterItemResults = allFilterItemResults.filter(isNotNull);
194
+ const cleanedQuickFilterResults = allQuickFilterResults.filter(isNotNull);
192
195
 
193
196
  // get result for filter items model
194
- if (cleanedAllFilterItemResults.length > 0) {
197
+ if (cleanedFilterItemResults.length > 0) {
195
198
  // Return true if the item pass with one of the rows
196
199
  const filterItemPredicate = item => {
197
- return cleanedAllFilterItemResults.some(filterItemResult => filterItemResult[item.id]);
200
+ return cleanedFilterItemResults.some(filterItemResult => filterItemResult[item.id]);
198
201
  };
202
+ const logicOperator = filterModel.logicOperator ?? getDefaultGridFilterModel().logicOperator;
199
203
  if (logicOperator === GridLogicOperator.And) {
200
204
  const passesAllFilters = cleanedFilterItems.every(filterItemPredicate);
201
205
  if (!passesAllFilters) {
@@ -210,11 +214,12 @@ export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, fil
210
214
  }
211
215
 
212
216
  // get result for quick filter model
213
- if (cleanedAllQuickFilterResults.length > 0 && filterModel.quickFilterValues != null) {
217
+ if (cleanedQuickFilterResults.length > 0 && filterModel.quickFilterValues != null) {
214
218
  // Return true if the item pass with one of the rows
215
219
  const quickFilterValuePredicate = value => {
216
- return cleanedAllQuickFilterResults.some(quickFilterValueResult => quickFilterValueResult[value]);
220
+ return cleanedQuickFilterResults.some(quickFilterValueResult => quickFilterValueResult[value]);
217
221
  };
222
+ const quickFilterLogicOperator = filterModel.quickFilterLogicOperator ?? getDefaultGridFilterModel().quickFilterLogicOperator;
218
223
  if (quickFilterLogicOperator === GridLogicOperator.And) {
219
224
  const passesAllQuickFilterValues = filterModel.quickFilterValues.every(quickFilterValuePredicate);
220
225
  if (!passesAllQuickFilterValues) {
@@ -255,6 +255,7 @@ export const useGridFilter = (apiRef, props) => {
255
255
  const tree = gridRowTreeSelector(apiRef);
256
256
  const rowIds = tree[GRID_ROOT_GROUP_ID].children;
257
257
  const filteredRowsLookup = {};
258
+ const filterCache = {};
258
259
  for (let i = 0; i < rowIds.length; i += 1) {
259
260
  const rowId = rowIds[i];
260
261
  let isRowPassing;
@@ -265,7 +266,7 @@ export const useGridFilter = (apiRef, props) => {
265
266
  passingFilterItems,
266
267
  passingQuickFilterValues
267
268
  } = params.isRowMatchingFilters(rowId);
268
- isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel, apiRef);
269
+ isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel, apiRef, filterCache);
269
270
  }
270
271
  filteredRowsLookup[rowId] = isRowPassing;
271
272
  }
@@ -1,6 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { unstable_ownerDocument as ownerDocument } from '@mui/utils';
4
+ import { gridClasses } from '../../../constants/gridClasses';
4
5
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
5
6
  import { useGridLogger } from '../../utils/useGridLogger';
6
7
  import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
@@ -236,7 +237,6 @@ export const useGridFocus = (apiRef, props) => {
236
237
  }
237
238
  apiRef.current.setColumnHeaderFocus(field, event);
238
239
  }, [apiRef]);
239
- const focussedColumnGroup = unstable_gridFocusColumnGroupHeaderSelector(apiRef);
240
240
  const handleColumnGroupHeaderFocus = React.useCallback(({
241
241
  fields,
242
242
  depth
@@ -244,13 +244,17 @@ export const useGridFocus = (apiRef, props) => {
244
244
  if (event.target !== event.currentTarget) {
245
245
  return;
246
246
  }
247
- if (focussedColumnGroup !== null && focussedColumnGroup.depth === depth && fields.includes(focussedColumnGroup.field)) {
247
+ const focusedColumnGroup = unstable_gridFocusColumnGroupHeaderSelector(apiRef);
248
+ if (focusedColumnGroup !== null && focusedColumnGroup.depth === depth && fields.includes(focusedColumnGroup.field)) {
248
249
  // This group cell has already been focused
249
250
  return;
250
251
  }
251
252
  apiRef.current.setColumnGroupHeaderFocus(fields[0], depth, event);
252
- }, [apiRef, focussedColumnGroup]);
253
- const handleBlur = React.useCallback(() => {
253
+ }, [apiRef]);
254
+ const handleBlur = React.useCallback((_, event) => {
255
+ if (event.relatedTarget?.className.includes(gridClasses.columnHeader)) {
256
+ return;
257
+ }
254
258
  logger.debug(`Clearing focus`);
255
259
  apiRef.current.setState(state => _extends({}, state, {
256
260
  focus: {
@@ -13,7 +13,6 @@ import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../../../constants/gridDetailPan
13
13
  import { gridPinnedRowsSelector } from '../rows/gridRowsSelector';
14
14
  import { unstable_gridFocusColumnGroupHeaderSelector } from '../focus';
15
15
  import { gridColumnGroupsHeaderMaxDepthSelector } from '../columnGrouping/gridColumnGroupsSelector';
16
- import { useGridSelector } from '../../utils/useGridSelector';
17
16
  import { unstable_gridHeaderFilteringEditFieldSelector, unstable_gridHeaderFilteringMenuSelector } from '../headerFiltering/gridHeaderFilteringSelectors';
18
17
  import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
19
18
  function enrichPageRowsWithPinnedRows(apiRef, rows) {
@@ -322,12 +321,12 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
322
321
  event.preventDefault();
323
322
  }
324
323
  }, [apiRef, currentPageRows.length, goToHeaderFilter, theme.direction, goToHeader, goToCell, getRowIdFromIndex]);
325
- const focusedColumnGroup = useGridSelector(apiRef, unstable_gridFocusColumnGroupHeaderSelector);
326
324
  const handleColumnGroupHeaderKeyDown = React.useCallback((params, event) => {
327
325
  const dimensions = apiRef.current.getRootDimensions();
328
326
  if (!dimensions) {
329
327
  return;
330
328
  }
329
+ const focusedColumnGroup = unstable_gridFocusColumnGroupHeaderSelector(apiRef);
331
330
  if (focusedColumnGroup === null) {
332
331
  return;
333
332
  }
@@ -411,7 +410,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
411
410
  if (shouldPreventDefault) {
412
411
  event.preventDefault();
413
412
  }
414
- }, [apiRef, focusedColumnGroup, currentPageRows.length, goToHeader, goToGroupHeader, goToCell, getRowIdFromIndex]);
413
+ }, [apiRef, currentPageRows.length, goToHeader, goToGroupHeader, goToCell, getRowIdFromIndex]);
415
414
  const handleCellKeyDown = React.useCallback((params, event) => {
416
415
  // Ignore portal
417
416
  if (!event.currentTarget.contains(event.target)) {