@mui/x-data-grid 6.7.0 → 6.8.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 (153) hide show
  1. package/CHANGELOG.md +77 -15
  2. package/components/GridColumnHeaders.d.ts +2 -2
  3. package/components/GridColumnHeaders.js +3 -1
  4. package/components/GridRow.d.ts +2 -2
  5. package/components/GridRow.js +23 -69
  6. package/components/cell/GridCell.d.ts +24 -15
  7. package/components/cell/GridCell.js +422 -45
  8. package/components/cell/index.d.ts +2 -1
  9. package/components/cell/index.js +1 -1
  10. package/components/containers/GridRootStyles.js +30 -16
  11. package/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  12. package/components/toolbar/GridToolbar.js +2 -2
  13. package/components/virtualization/GridVirtualScroller.js +4 -9
  14. package/components/virtualization/GridVirtualScrollerContent.js +11 -20
  15. package/constants/defaultGridSlotsComponents.js +6 -2
  16. package/hooks/core/useGridApiInitialization.js +4 -1
  17. package/hooks/core/useGridStateInitialization.js +2 -9
  18. package/hooks/features/clipboard/useGridClipboard.js +1 -4
  19. package/hooks/features/columnHeaders/useGridColumnHeaders.js +9 -3
  20. package/hooks/features/editing/useGridCellEditing.js +5 -3
  21. package/hooks/features/editing/useGridRowEditing.js +14 -6
  22. package/hooks/features/filter/gridFilterUtils.d.ts +4 -1
  23. package/hooks/features/filter/gridFilterUtils.js +19 -13
  24. package/hooks/features/filter/useGridFilter.js +2 -1
  25. package/hooks/features/focus/useGridFocus.js +9 -4
  26. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  27. package/hooks/features/rows/useGridParamsApi.d.ts +2 -0
  28. package/hooks/features/rows/useGridParamsApi.js +7 -15
  29. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +8 -816
  30. package/hooks/features/virtualization/useGridVirtualScroller.js +40 -38
  31. package/hooks/utils/index.d.ts +1 -1
  32. package/hooks/utils/index.js +1 -1
  33. package/hooks/utils/useGridSelector.d.ts +3 -1
  34. package/hooks/utils/useGridSelector.js +37 -6
  35. package/hooks/utils/useLazyRef.d.ts +2 -0
  36. package/hooks/utils/useLazyRef.js +9 -0
  37. package/hooks/utils/useOnMount.d.ts +2 -0
  38. package/hooks/utils/useOnMount.js +7 -0
  39. package/index.js +1 -1
  40. package/legacy/components/GridColumnHeaders.js +3 -1
  41. package/legacy/components/GridRow.js +25 -69
  42. package/legacy/components/cell/GridCell.js +425 -46
  43. package/legacy/components/cell/index.js +1 -1
  44. package/legacy/components/containers/GridRootStyles.js +20 -17
  45. package/legacy/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  46. package/legacy/components/toolbar/GridToolbar.js +2 -2
  47. package/legacy/components/virtualization/GridVirtualScroller.js +4 -7
  48. package/legacy/components/virtualization/GridVirtualScrollerContent.js +10 -17
  49. package/legacy/constants/defaultGridSlotsComponents.js +6 -2
  50. package/legacy/hooks/core/useGridApiInitialization.js +4 -1
  51. package/legacy/hooks/core/useGridStateInitialization.js +2 -7
  52. package/legacy/hooks/features/clipboard/useGridClipboard.js +1 -4
  53. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +9 -3
  54. package/legacy/hooks/features/editing/useGridCellEditing.js +5 -3
  55. package/legacy/hooks/features/editing/useGridRowEditing.js +15 -7
  56. package/legacy/hooks/features/filter/gridFilterUtils.js +23 -19
  57. package/legacy/hooks/features/filter/useGridFilter.js +2 -1
  58. package/legacy/hooks/features/focus/useGridFocus.js +9 -4
  59. package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  60. package/legacy/hooks/features/rows/useGridParamsApi.js +23 -15
  61. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +38 -34
  62. package/legacy/hooks/utils/index.js +1 -1
  63. package/legacy/hooks/utils/useGridSelector.js +43 -5
  64. package/legacy/hooks/utils/useLazyRef.js +9 -0
  65. package/legacy/hooks/utils/useOnMount.js +7 -0
  66. package/legacy/index.js +1 -1
  67. package/legacy/locales/elGR.js +70 -79
  68. package/legacy/utils/Store.js +34 -0
  69. package/legacy/utils/doesSupportPreventScroll.js +13 -0
  70. package/legacy/utils/fastMemo.js +5 -0
  71. package/legacy/utils/fastObjectShallowCompare.js +32 -0
  72. package/legacy/utils/keyboardUtils.js +4 -2
  73. package/locales/elGR.js +66 -79
  74. package/models/api/gridCoreApi.d.ts +6 -0
  75. package/models/colDef/gridColDef.d.ts +4 -3
  76. package/models/colDef/gridColType.d.ts +3 -1
  77. package/models/events/gridEventLookup.d.ts +3 -3
  78. package/modern/components/GridColumnHeaders.js +3 -1
  79. package/modern/components/GridRow.js +22 -69
  80. package/modern/components/cell/GridCell.js +421 -45
  81. package/modern/components/cell/index.js +1 -1
  82. package/modern/components/containers/GridRootStyles.js +30 -16
  83. package/modern/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  84. package/modern/components/toolbar/GridToolbar.js +2 -2
  85. package/modern/components/virtualization/GridVirtualScroller.js +4 -9
  86. package/modern/components/virtualization/GridVirtualScrollerContent.js +10 -20
  87. package/modern/constants/defaultGridSlotsComponents.js +6 -2
  88. package/modern/hooks/core/useGridApiInitialization.js +4 -1
  89. package/modern/hooks/core/useGridStateInitialization.js +2 -9
  90. package/modern/hooks/features/clipboard/useGridClipboard.js +1 -4
  91. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +9 -3
  92. package/modern/hooks/features/editing/useGridCellEditing.js +5 -3
  93. package/modern/hooks/features/editing/useGridRowEditing.js +14 -6
  94. package/modern/hooks/features/filter/gridFilterUtils.js +17 -12
  95. package/modern/hooks/features/filter/useGridFilter.js +2 -1
  96. package/modern/hooks/features/focus/useGridFocus.js +8 -4
  97. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  98. package/modern/hooks/features/rows/useGridParamsApi.js +7 -15
  99. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +40 -38
  100. package/modern/hooks/utils/index.js +1 -1
  101. package/modern/hooks/utils/useGridSelector.js +37 -6
  102. package/modern/hooks/utils/useLazyRef.js +9 -0
  103. package/modern/hooks/utils/useOnMount.js +7 -0
  104. package/modern/index.js +1 -1
  105. package/modern/locales/elGR.js +66 -79
  106. package/modern/utils/Store.js +24 -0
  107. package/modern/utils/doesSupportPreventScroll.js +13 -0
  108. package/modern/utils/fastMemo.js +5 -0
  109. package/modern/utils/fastObjectShallowCompare.js +32 -0
  110. package/modern/utils/keyboardUtils.js +4 -2
  111. package/node/components/GridColumnHeaders.js +4 -2
  112. package/node/components/GridRow.js +22 -69
  113. package/node/components/cell/GridCell.js +424 -47
  114. package/node/components/cell/index.js +17 -10
  115. package/node/components/containers/GridRootStyles.js +30 -16
  116. package/node/components/menu/columnMenu/GridColumnHeaderMenu.js +1 -1
  117. package/node/components/toolbar/GridToolbar.js +2 -2
  118. package/node/components/virtualization/GridVirtualScroller.js +4 -9
  119. package/node/components/virtualization/GridVirtualScrollerContent.js +10 -20
  120. package/node/constants/defaultGridSlotsComponents.js +4 -1
  121. package/node/hooks/core/useGridApiInitialization.js +4 -1
  122. package/node/hooks/core/useGridStateInitialization.js +2 -9
  123. package/node/hooks/features/clipboard/useGridClipboard.js +1 -4
  124. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +8 -2
  125. package/node/hooks/features/editing/useGridCellEditing.js +5 -3
  126. package/node/hooks/features/editing/useGridRowEditing.js +14 -6
  127. package/node/hooks/features/filter/gridFilterUtils.js +17 -12
  128. package/node/hooks/features/filter/useGridFilter.js +2 -1
  129. package/node/hooks/features/focus/useGridFocus.js +8 -4
  130. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +2 -3
  131. package/node/hooks/features/rows/useGridParamsApi.js +9 -15
  132. package/node/hooks/features/virtualization/useGridVirtualScroller.js +40 -36
  133. package/node/hooks/utils/index.js +14 -10
  134. package/node/hooks/utils/useGridSelector.js +41 -7
  135. package/node/hooks/utils/useLazyRef.js +17 -0
  136. package/node/hooks/utils/useOnMount.js +15 -0
  137. package/node/index.js +1 -1
  138. package/node/locales/elGR.js +66 -79
  139. package/node/utils/Store.js +31 -0
  140. package/node/utils/doesSupportPreventScroll.js +19 -0
  141. package/node/utils/fastMemo.js +13 -0
  142. package/node/utils/fastObjectShallowCompare.js +38 -0
  143. package/node/utils/keyboardUtils.js +4 -2
  144. package/package.json +1 -1
  145. package/utils/Store.d.ts +11 -0
  146. package/utils/Store.js +24 -0
  147. package/utils/doesSupportPreventScroll.d.ts +1 -0
  148. package/utils/doesSupportPreventScroll.js +13 -0
  149. package/utils/fastMemo.d.ts +1 -0
  150. package/utils/fastMemo.js +5 -0
  151. package/utils/fastObjectShallowCompare.d.ts +1 -0
  152. package/utils/fastObjectShallowCompare.js +32 -0
  153. package/utils/keyboardUtils.js +4 -2
@@ -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,15 @@ 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);
24
+ var _props$style;
32
25
  const rootProps = useGridRootProps();
33
- const ownerState = _extends({}, rootProps, {
34
- overflowedContent: !rootProps.autoHeight && (style == null ? void 0 : style.minHeight) === 'auto'
35
- });
36
- const classes = useUtilityClasses(ownerState);
26
+ const overflowedContent = !rootProps.autoHeight && ((_props$style = props.style) == null ? void 0 : _props$style.minHeight) === 'auto';
27
+ const classes = useUtilityClasses(rootProps, overflowedContent);
37
28
  return /*#__PURE__*/_jsx(VirtualScrollerContentRoot, _extends({
38
- ref: ref,
39
- className: clsx(classes.root, className),
40
- ownerState: ownerState,
41
- style: style
42
- }, other));
29
+ ref: ref
30
+ }, props, {
31
+ ownerState: rootProps,
32
+ className: clsx(classes.root, props.className)
33
+ }));
43
34
  });
44
35
  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 {
@@ -54,10 +54,7 @@ export const useGridClipboard = (apiRef, props) => {
54
54
  const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.clipboardExport : ignoreValueFormatterProp) || false;
55
55
  const clipboardCopyCellDelimiter = props.clipboardCopyCellDelimiter;
56
56
  const handleCopy = React.useCallback(event => {
57
- const isModifierKeyPressed = event.ctrlKey || event.metaKey;
58
- // event.code === 'KeyC' is not enough as event.code assume a QWERTY keyboard layout which would
59
- // be wrong with a Dvorak keyboard (as if pressing J).
60
- if (String.fromCharCode(event.keyCode) !== 'C' || !isModifierKeyPressed) {
57
+ if (!((event.ctrlKey || event.metaKey) && event.key === 'c')) {
61
58
  return;
62
59
  }
63
60
 
@@ -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]);
@@ -130,7 +136,7 @@ export const useGridColumnHeaders = props => {
130
136
  if (nextRenderContext && canUpdateInnerPosition) {
131
137
  updateInnerPosition(nextRenderContext);
132
138
  }
133
- }, [updateInnerPosition]);
139
+ }, [updateInnerPosition, setRenderContext]);
134
140
  const handleColumnResizeStart = React.useCallback(params => setResizeCol(params.field), []);
135
141
  const handleColumnResizeStop = React.useCallback(() => setResizeCol(''), []);
136
142
  const handleColumnReorderStart = React.useCallback(params => setDragCol(params.field), []);
@@ -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);
@@ -114,7 +115,13 @@ export const useGridRowEditing = (apiRef, props) => {
114
115
  } else if (event.key === 'Enter') {
115
116
  reason = GridRowEditStopReasons.enterKeyDown;
116
117
  } else if (event.key === 'Tab') {
117
- const columnFields = gridColumnFieldsSelector(apiRef).filter(field => apiRef.current.isCellEditable(apiRef.current.getCellParams(params.id, field)));
118
+ const columnFields = gridColumnFieldsSelector(apiRef).filter(field => {
119
+ const column = apiRef.current.getColumn(field);
120
+ if (column.type === GRID_ACTIONS_COLUMN_TYPE) {
121
+ return true;
122
+ }
123
+ return apiRef.current.isCellEditable(apiRef.current.getCellParams(params.id, field));
124
+ });
118
125
  if (event.shiftKey) {
119
126
  if (params.field === columnFields[0]) {
120
127
  // Exit if user pressed Shift+Tab on the first field
@@ -135,8 +142,7 @@ export const useGridRowEditing = (apiRef, props) => {
135
142
  }
136
143
  }
137
144
  if (reason) {
138
- const rowParams = apiRef.current.getRowParams(params.id);
139
- const newParams = _extends({}, rowParams, {
145
+ const newParams = _extends({}, apiRef.current.getRowParams(params.id), {
140
146
  reason,
141
147
  field: params.field
142
148
  });
@@ -178,7 +184,8 @@ export const useGridRowEditing = (apiRef, props) => {
178
184
  id,
179
185
  field,
180
186
  reason,
181
- key
187
+ key,
188
+ columns
182
189
  } = params;
183
190
  const startRowEditModeParams = {
184
191
  id,
@@ -190,7 +197,8 @@ export const useGridRowEditing = (apiRef, props) => {
190
197
  // The sequence of events makes the key pressed by the end-users update the textbox directly.
191
198
  startRowEditModeParams.deleteValue = !!field;
192
199
  } else {
193
- startRowEditModeParams.initialValue = key;
200
+ const colDef = columns.find(col => col.field === field);
201
+ startRowEditModeParams.initialValue = colDef.valueParser ? colDef.valueParser(key) : key;
194
202
  }
195
203
  } else if (reason === GridRowEditStartReasons.deleteKeyDown) {
196
204
  startRowEditModeParams.deleteValue = !!field;
@@ -29,5 +29,8 @@ 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, apiRef: React.MutableRefObject<GridApiCommunity>) => boolean;
32
+ type FilterCache = {
33
+ cleanedFilterItems?: GridFilterItem[];
34
+ };
35
+ export declare const passFilterLogic: (allFilterItemResults: (null | GridFilterItemResult)[], allQuickFilterResults: (null | GridQuickFilterValueResult)[], filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>, cache: FilterCache) => boolean;
33
36
  export {};
@@ -183,22 +183,26 @@ export const buildAggregatedFilterApplier = (filterModel, apiRef) => {
183
183
  passingQuickFilterValues: isRowMatchingQuickFilter && isRowMatchingQuickFilter(rowId, shouldApplyFilter)
184
184
  });
185
185
  };
186
- export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel, apiRef) => {
187
- var _filterModel$quickFil, _filterModel$logicOpe;
188
- const cleanedFilterItems = filterModel.items.filter(item => getFilterCallbackFromItem(item, apiRef) !== null);
189
- const cleanedAllFilterItemResults = allFilterItemResults.filter(result => result != null);
190
- const cleanedAllQuickFilterResults = allQuickFilterResults.filter(result => result != null);
191
-
192
- // Defaultize operators
193
- const quickFilterLogicOperator = (_filterModel$quickFil = filterModel.quickFilterLogicOperator) != null ? _filterModel$quickFil : getDefaultGridFilterModel().quickFilterLogicOperator;
194
- const logicOperator = (_filterModel$logicOpe = filterModel.logicOperator) != null ? _filterModel$logicOpe : getDefaultGridFilterModel().logicOperator;
186
+ const isNotNull = result => result != null;
187
+ const filterModelItems = (cache, apiRef, items) => {
188
+ if (!cache.cleanedFilterItems) {
189
+ cache.cleanedFilterItems = items.filter(item => getFilterCallbackFromItem(item, apiRef) !== null);
190
+ }
191
+ return cache.cleanedFilterItems;
192
+ };
193
+ export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel, apiRef, cache) => {
194
+ const cleanedFilterItems = filterModelItems(cache, apiRef, filterModel.items);
195
+ const cleanedFilterItemResults = allFilterItemResults.filter(isNotNull);
196
+ const cleanedQuickFilterResults = allQuickFilterResults.filter(isNotNull);
195
197
 
196
198
  // get result for filter items model
197
- if (cleanedAllFilterItemResults.length > 0) {
199
+ if (cleanedFilterItemResults.length > 0) {
200
+ var _filterModel$logicOpe;
198
201
  // Return true if the item pass with one of the rows
199
202
  const filterItemPredicate = item => {
200
- return cleanedAllFilterItemResults.some(filterItemResult => filterItemResult[item.id]);
203
+ return cleanedFilterItemResults.some(filterItemResult => filterItemResult[item.id]);
201
204
  };
205
+ const logicOperator = (_filterModel$logicOpe = filterModel.logicOperator) != null ? _filterModel$logicOpe : getDefaultGridFilterModel().logicOperator;
202
206
  if (logicOperator === GridLogicOperator.And) {
203
207
  const passesAllFilters = cleanedFilterItems.every(filterItemPredicate);
204
208
  if (!passesAllFilters) {
@@ -213,11 +217,13 @@ export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, fil
213
217
  }
214
218
 
215
219
  // get result for quick filter model
216
- if (cleanedAllQuickFilterResults.length > 0 && filterModel.quickFilterValues != null) {
220
+ if (cleanedQuickFilterResults.length > 0 && filterModel.quickFilterValues != null) {
221
+ var _filterModel$quickFil;
217
222
  // Return true if the item pass with one of the rows
218
223
  const quickFilterValuePredicate = value => {
219
- return cleanedAllQuickFilterResults.some(quickFilterValueResult => quickFilterValueResult[value]);
224
+ return cleanedQuickFilterResults.some(quickFilterValueResult => quickFilterValueResult[value]);
220
225
  };
226
+ const quickFilterLogicOperator = (_filterModel$quickFil = filterModel.quickFilterLogicOperator) != null ? _filterModel$quickFil : getDefaultGridFilterModel().quickFilterLogicOperator;
221
227
  if (quickFilterLogicOperator === GridLogicOperator.And) {
222
228
  const passesAllQuickFilterValues = filterModel.quickFilterValues.every(quickFilterValuePredicate);
223
229
  if (!passesAllQuickFilterValues) {
@@ -261,6 +261,7 @@ export const useGridFilter = (apiRef, props) => {
261
261
  const tree = gridRowTreeSelector(apiRef);
262
262
  const rowIds = tree[GRID_ROOT_GROUP_ID].children;
263
263
  const filteredRowsLookup = {};
264
+ const filterCache = {};
264
265
  for (let i = 0; i < rowIds.length; i += 1) {
265
266
  const rowId = rowIds[i];
266
267
  let isRowPassing;
@@ -271,7 +272,7 @@ export const useGridFilter = (apiRef, props) => {
271
272
  passingFilterItems,
272
273
  passingQuickFilterValues
273
274
  } = params.isRowMatchingFilters(rowId);
274
- isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel, apiRef);
275
+ isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel, apiRef, filterCache);
275
276
  }
276
277
  filteredRowsLookup[rowId] = isRowPassing;
277
278
  }
@@ -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,18 @@ 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
+ var _event$relatedTarget;
256
+ if ((_event$relatedTarget = event.relatedTarget) != null && _event$relatedTarget.className.includes(gridClasses.columnHeader)) {
257
+ return;
258
+ }
254
259
  logger.debug(`Clearing focus`);
255
260
  apiRef.current.setState(state => _extends({}, state, {
256
261
  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)) {
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity';
3
+ export declare class MissingRowIdError extends Error {
4
+ }
3
5
  /**
4
6
  * @requires useGridColumns (method)
5
7
  * @requires useGridRows (method)
@@ -2,11 +2,7 @@ import * as React from 'react';
2
2
  import { getGridCellElement, getGridColumnHeaderElement, getGridRowElement } from '../../../utils/domUtils';
3
3
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
4
4
  import { gridFocusCellSelector, gridTabIndexCellSelector } from '../focus/gridFocusStateSelector';
5
- let warnedOnceMissingColumn = false;
6
- function warnMissingColumn(field) {
7
- console.warn([`MUI: You are calling getValue('${field}') but the column \`${field}\` is not defined.`, `Instead, you can access the data from \`params.row.${field}\`.`].join('\n'));
8
- warnedOnceMissingColumn = true;
9
- }
5
+ export class MissingRowIdError extends Error {}
10
6
 
11
7
  /**
12
8
  * @requires useGridColumns (method)
@@ -24,7 +20,7 @@ export function useGridParamsApi(apiRef) {
24
20
  const getRowParams = React.useCallback(id => {
25
21
  const row = apiRef.current.getRow(id);
26
22
  if (!row) {
27
- throw new Error(`No row with id #${id} found`);
23
+ throw new MissingRowIdError(`No row with id #${id} found`);
28
24
  }
29
25
  const params = {
30
26
  id,
@@ -37,7 +33,7 @@ export function useGridParamsApi(apiRef) {
37
33
  const row = apiRef.current.getRow(id);
38
34
  const rowNode = apiRef.current.getRowNode(id);
39
35
  if (!row || !rowNode) {
40
- throw new Error(`No row with id #${id} found`);
36
+ throw new MissingRowIdError(`No row with id #${id} found`);
41
37
  }
42
38
  const cellFocus = gridFocusCellSelector(apiRef);
43
39
  const cellTabIndex = gridTabIndexCellSelector(apiRef);
@@ -61,7 +57,7 @@ export function useGridParamsApi(apiRef) {
61
57
  const row = apiRef.current.getRow(id);
62
58
  const rowNode = apiRef.current.getRowNode(id);
63
59
  if (!row || !rowNode) {
64
- throw new Error(`No row with id #${id} found`);
60
+ throw new MissingRowIdError(`No row with id #${id} found`);
65
61
  }
66
62
  const cellFocus = gridFocusCellSelector(apiRef);
67
63
  const cellTabIndex = gridTabIndexCellSelector(apiRef);
@@ -75,7 +71,8 @@ export function useGridParamsApi(apiRef) {
75
71
  hasFocus: cellFocus !== null && cellFocus.field === field && cellFocus.id === id,
76
72
  tabIndex: cellTabIndex && cellTabIndex.field === field && cellTabIndex.id === id ? 0 : -1,
77
73
  value,
78
- formattedValue: value
74
+ formattedValue: value,
75
+ isEditable: false
79
76
  };
80
77
  if (colDef && colDef.valueFormatter) {
81
78
  params.formattedValue = colDef.valueFormatter({
@@ -90,15 +87,10 @@ export function useGridParamsApi(apiRef) {
90
87
  }, [apiRef]);
91
88
  const getCellValue = React.useCallback((id, field) => {
92
89
  const colDef = apiRef.current.getColumn(field);
93
- if (process.env.NODE_ENV !== 'production') {
94
- if (!colDef && !warnedOnceMissingColumn) {
95
- warnMissingColumn(field);
96
- }
97
- }
98
90
  if (!colDef || !colDef.valueGetter) {
99
91
  const rowModel = apiRef.current.getRow(id);
100
92
  if (!rowModel) {
101
- throw new Error(`No row with id #${id} found`);
93
+ throw new MissingRowIdError(`No row with id #${id} found`);
102
94
  }
103
95
  return rowModel[field];
104
96
  }