@mui/x-data-grid 7.13.0 → 7.14.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 (56) hide show
  1. package/CHANGELOG.md +82 -2
  2. package/components/cell/GridCell.js +11 -12
  3. package/components/cell/GridEditSingleSelectCell.js +2 -3
  4. package/components/menu/columnMenu/GridColumnMenuContainer.js +2 -2
  5. package/components/panel/GridPanel.js +1 -2
  6. package/components/panel/filterPanel/GridFilterForm.js +9 -4
  7. package/components/toolbar/GridToolbarDensitySelector.js +2 -2
  8. package/components/toolbar/GridToolbarExportContainer.js +2 -2
  9. package/components/toolbar/GridToolbarQuickFilter.js +5 -3
  10. package/hooks/features/rows/useGridParamsApi.js +2 -1
  11. package/hooks/utils/useGridSelector.d.ts +4 -1
  12. package/hooks/utils/useGridSelector.js +38 -0
  13. package/index.js +1 -1
  14. package/internals/index.d.ts +2 -1
  15. package/internals/index.js +2 -1
  16. package/locales/csCZ.js +4 -5
  17. package/locales/heIL.js +4 -5
  18. package/models/gridDataSource.d.ts +6 -6
  19. package/models/params/gridCellParams.d.ts +4 -0
  20. package/modern/components/cell/GridCell.js +11 -12
  21. package/modern/components/cell/GridEditSingleSelectCell.js +2 -3
  22. package/modern/components/menu/columnMenu/GridColumnMenuContainer.js +2 -2
  23. package/modern/components/panel/GridPanel.js +1 -2
  24. package/modern/components/panel/filterPanel/GridFilterForm.js +9 -4
  25. package/modern/components/toolbar/GridToolbarDensitySelector.js +2 -2
  26. package/modern/components/toolbar/GridToolbarExportContainer.js +2 -2
  27. package/modern/components/toolbar/GridToolbarQuickFilter.js +5 -3
  28. package/modern/hooks/features/rows/useGridParamsApi.js +2 -1
  29. package/modern/hooks/utils/useGridSelector.js +38 -0
  30. package/modern/index.js +1 -1
  31. package/modern/internals/index.js +2 -1
  32. package/modern/locales/csCZ.js +4 -5
  33. package/modern/locales/heIL.js +4 -5
  34. package/modern/utils/createSelector.js +116 -0
  35. package/modern/utils/keyboardUtils.js +1 -11
  36. package/node/components/cell/GridCell.js +11 -12
  37. package/node/components/cell/GridEditSingleSelectCell.js +2 -3
  38. package/node/components/menu/columnMenu/GridColumnMenuContainer.js +1 -1
  39. package/node/components/panel/GridPanel.js +1 -2
  40. package/node/components/panel/filterPanel/GridFilterForm.js +9 -4
  41. package/node/components/toolbar/GridToolbarDensitySelector.js +1 -1
  42. package/node/components/toolbar/GridToolbarExportContainer.js +1 -1
  43. package/node/components/toolbar/GridToolbarQuickFilter.js +5 -3
  44. package/node/hooks/features/rows/useGridParamsApi.js +2 -1
  45. package/node/hooks/utils/useGridSelector.js +41 -2
  46. package/node/index.js +1 -1
  47. package/node/internals/index.js +22 -0
  48. package/node/locales/csCZ.js +4 -5
  49. package/node/locales/heIL.js +4 -5
  50. package/node/utils/createSelector.js +119 -2
  51. package/node/utils/keyboardUtils.js +2 -15
  52. package/package.json +4 -4
  53. package/utils/createSelector.d.ts +19 -0
  54. package/utils/createSelector.js +116 -0
  55. package/utils/keyboardUtils.d.ts +1 -9
  56. package/utils/keyboardUtils.js +1 -11
package/CHANGELOG.md CHANGED
@@ -3,6 +3,86 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 7.14.0
7
+
8
+ _Aug 23, 2024_
9
+
10
+ We'd like to offer a big thanks to the 14 contributors who made this release possible. Here are some highlights ✨:
11
+
12
+ - 💫 Allow [filtering the axis on zoom](https://mui.com/x/react-charts/zoom-and-pan/#zoom-filtering), making the axis adapt by removing values outside the view.
13
+
14
+ <img width="600" src="https://github.com/user-attachments/assets/e65bbd00-d2a8-4136-81cd-3598f1373c16" alt="filtering the axis on zoom" />
15
+
16
+ - 📊 Improve bar chart performances
17
+ - 🌍 Improve Czech (cs-CZ) and Hebrew (he-IL) locales on the Data Grid
18
+ - 🌍 Improve Chinese (zh-HK), Hebrew (he-IL), and Vietnamese (vi-VN) locales on the Date and Time Pickers
19
+ - 🐞 Bugfixes
20
+
21
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@7.14.0`
26
+
27
+ - [DataGrid] Use readonly array result for `getTreeDataPath` (#11743) @pcorpet
28
+ - [DataGrid] Use `event.key` for `Tab` and `Escape` keys (#14170) @k-rajat19
29
+ - [DataGrid] Introduce selectors with arguments (#14236) @MBilalShafi
30
+ - [DataGrid] include `api` in `gridCellParams` interface (#14201) @k-rajat19
31
+ - [l10n] Improve Czech (cs-CZ) locale (#14135) @chirimiri22
32
+ - [l10n] Improve Hebrew (he-IL) locale (#14287) @rotembarsela
33
+
34
+ #### `@mui/x-data-grid-pro@7.14.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
35
+
36
+ Same changes as in `@mui/x-data-grid@7.14.0`.
37
+
38
+ #### `@mui/x-data-grid-premium@7.14.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
39
+
40
+ Same changes as in `@mui/x-data-grid-pro@7.14.0`, plus:
41
+
42
+ - [DataGridPremium] Fix clipboard paste not working for a single cell on non-first page (#14261) @arminmeh
43
+ - [DataGridPremium] Fix `onCellSelectionModelChange` not triggered when additional cell range is selected (#14199) @arminmeh
44
+
45
+ ### Date and Time Pickers
46
+
47
+ #### `@mui/x-date-pickers@7.14.0`
48
+
49
+ - [l10n] Improve Chinese (zh-HK) locale (#13289) @yeeharn
50
+ - [l10n] Improve Hebrew (he-IL) locale (#14287) @rotembarsela
51
+ - [l10n] Improve Vietnamese (vi-VN) locale (#14238) @locnbk2002
52
+ - [TimePicker] Handle `Space` and `Enter` on the `TimeClock` component @arthurbalduini
53
+
54
+ #### `@mui/x-date-pickers-pro@7.14.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
55
+
56
+ Same changes as in `@mui/x-date-pickers@7.14.0`.
57
+
58
+ ### Charts
59
+
60
+ #### `@mui/x-charts@7.14.0`
61
+
62
+ - [charts] Fix grid overflow with zooming (#14280) @alexfauquette
63
+ - [charts] Improve bar chart performances (#14278) @alexfauquette
64
+ - [charts] Test pointer events (#14042) @alexfauquette
65
+ - [charts] Use `isPointInside` function for both graphs and axis (#14222) @JCQuintas
66
+
67
+ #### `@mui/x-charts-pro@7.0.0-alpha.2` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
68
+
69
+ Same changes as in `@mui/x-charts@7.14.0`, plus:
70
+
71
+ - [charts-pro] Zoom axis filtering (#14121) @JCQuintas
72
+
73
+ ### Docs
74
+
75
+ - [docs] Consistent use of UTC and timezones (#14250) @oliviertassinari
76
+ - [docs] Fix missing leading slashes in URLs (#14249) @oliviertassinari
77
+ - [docs] Dash usage revision on pickers pages (#14260) @arthurbalduini
78
+
79
+ ### Core
80
+
81
+ - [core] Follow JSDocs convention @oliviertassinari
82
+ - [core] Prepare for material v6 (#14143) @LukasTy
83
+ - [code-infra] Set up `eslint-plugin-testing-library` (#14232) @LukasTy
84
+ - [infra] Updated mui-x roadmap links with new project URL (#14271) @michelengelen
85
+
6
86
  ## 7.13.0
7
87
 
8
88
  _Aug 16, 2024_
@@ -58,7 +138,7 @@ Same changes as in `@mui/x-date-pickers@7.13.0`.
58
138
  - [charts] Rename `CartesianContextProvider` to `CartesianProvider` (#14102) @JCQuintas
59
139
  - [charts] Support axis with the same value for all data points (#14191) @alexfauquette
60
140
 
61
- #### `@mui/x-date-charts-pro@7.0.0-alpha.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
141
+ #### `@mui/x-charts-pro@7.0.0-alpha.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
62
142
 
63
143
  Same changes as in `@mui/x-charts@7.13.0`.
64
144
 
@@ -132,7 +212,7 @@ Same changes as in `@mui/x-date-pickers@7.12.1`.
132
212
  - [charts] Fix charts vendor publish config (#14073) @JCQuintas
133
213
  - [charts] Move `plugins` to `PluginProvider` (#14056) @JCQuintas
134
214
 
135
- #### `@mui/x-date-charts-pro@7.0.0-alpha.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
215
+ #### `@mui/x-charts-pro@7.0.0-alpha.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
136
216
 
137
217
  Same changes as in `@mui/x-charts@7.12.1`, plus:
138
218
 
@@ -107,13 +107,12 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
107
107
  const apiRef = useGridApiContext();
108
108
  const rootProps = useGridRootProps();
109
109
  const field = column.field;
110
- const cellParamsWithAPI = useGridSelector(apiRef, () => {
110
+ const cellParams = useGridSelector(apiRef, () => {
111
111
  // This is required because `.getCellParams` tries to get the `state.rows.tree` entry
112
112
  // associated with `rowId`/`fieldId`, but this selector runs after the state has been
113
113
  // updated, while `rowId`/`fieldId` reference an entry in the old state.
114
114
  try {
115
- const cellParams = apiRef.current.getCellParams(rowId, field);
116
- const result = cellParams;
115
+ const result = apiRef.current.getCellParams(rowId, field);
117
116
  result.api = apiRef.current;
118
117
  return result;
119
118
  } catch (e) {
@@ -132,9 +131,9 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
132
131
  hasFocus,
133
132
  isEditable = false,
134
133
  value
135
- } = cellParamsWithAPI;
134
+ } = cellParams;
136
135
  const canManageOwnFocus = column.type === 'actions' && column.getActions?.(apiRef.current.getRowParams(rowId)).some(action => !action.props.disabled);
137
- const tabIndex = (cellMode === 'view' || !isEditable) && !canManageOwnFocus ? cellParamsWithAPI.tabIndex : -1;
136
+ const tabIndex = (cellMode === 'view' || !isEditable) && !canManageOwnFocus ? cellParams.tabIndex : -1;
138
137
  const {
139
138
  classes: rootClasses,
140
139
  getCellClassName
@@ -147,15 +146,15 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
147
146
  }).filter(Boolean).join(' '));
148
147
  const classNames = [pipesClassName];
149
148
  if (column.cellClassName) {
150
- classNames.push(typeof column.cellClassName === 'function' ? column.cellClassName(cellParamsWithAPI) : column.cellClassName);
149
+ classNames.push(typeof column.cellClassName === 'function' ? column.cellClassName(cellParams) : column.cellClassName);
151
150
  }
152
151
  if (column.display === 'flex') {
153
152
  classNames.push(gridClasses['cell--flex']);
154
153
  }
155
154
  if (getCellClassName) {
156
- classNames.push(getCellClassName(cellParamsWithAPI));
155
+ classNames.push(getCellClassName(cellParams));
157
156
  }
158
- const valueToRender = cellParamsWithAPI.formattedValue ?? value;
157
+ const valueToRender = cellParams.formattedValue ?? value;
159
158
  const cellRef = React.useRef(null);
160
159
  const handleRef = useForkRef(ref, cellRef);
161
160
  const focusElementRef = React.useRef(null);
@@ -238,7 +237,7 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
238
237
  }
239
238
  }
240
239
  }, [hasFocus, cellMode, apiRef]);
241
- if (cellParamsWithAPI === EMPTY_CELL_PARAMS) {
240
+ if (cellParams === EMPTY_CELL_PARAMS) {
242
241
  return null;
243
242
  }
244
243
  let handleFocus = other.onFocus;
@@ -260,15 +259,15 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
260
259
  let children;
261
260
  let title;
262
261
  if (editCellState === null && column.renderCell) {
263
- children = column.renderCell(cellParamsWithAPI);
262
+ children = column.renderCell(cellParams);
264
263
  }
265
264
  if (editCellState !== null && column.renderEditCell) {
266
265
  const updatedRow = apiRef.current.getRowWithUpdatedValues(rowId, column.field);
267
266
 
268
267
  // eslint-disable-next-line @typescript-eslint/naming-convention
269
268
  const editCellStateRest = _objectWithoutPropertiesLoose(editCellState, _excluded2);
270
- const formattedValue = column.valueFormatter ? column.valueFormatter(editCellState.value, updatedRow, column, apiRef) : cellParamsWithAPI.formattedValue;
271
- const params = _extends({}, cellParamsWithAPI, {
269
+ const formattedValue = column.valueFormatter ? column.valueFormatter(editCellState.value, updatedRow, column, apiRef) : cellParams.formattedValue;
270
+ const params = _extends({}, cellParams, {
272
271
  row: updatedRow,
273
272
  formattedValue
274
273
  }, editCellStateRest);
@@ -6,7 +6,6 @@ import * as React from 'react';
6
6
  import PropTypes from 'prop-types';
7
7
  import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
8
8
  import { GridCellEditStopReasons } from '../../models/params/gridEditCellParams';
9
- import { isEscapeKey } from '../../utils/keyboardUtils';
10
9
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
11
10
  import { GridEditModes } from '../../models/gridEditRowModel';
12
11
  import { getValueFromValueOptions, getValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
@@ -80,10 +79,10 @@ function GridEditSingleSelectCell(props) {
80
79
  setOpen(false);
81
80
  return;
82
81
  }
83
- if (reason === 'backdropClick' || isEscapeKey(event.key)) {
82
+ if (reason === 'backdropClick' || event.key === 'Escape') {
84
83
  const params = apiRef.current.getCellParams(id, field);
85
84
  apiRef.current.publishEvent('cellEditStop', _extends({}, params, {
86
- reason: isEscapeKey(event.key) ? GridCellEditStopReasons.escapeKeyDown : GridCellEditStopReasons.cellFocusOut
85
+ reason: event.key === 'Escape' ? GridCellEditStopReasons.escapeKeyDown : GridCellEditStopReasons.cellFocusOut
87
86
  }));
88
87
  }
89
88
  };
@@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
6
6
  import * as React from 'react';
7
7
  import MenuList from '@mui/material/MenuList';
8
8
  import { styled } from '@mui/material/styles';
9
- import { isHideMenuKey, isTabKey } from '../../../utils/keyboardUtils';
9
+ import { isHideMenuKey } from '../../../utils/keyboardUtils';
10
10
  import { gridClasses } from '../../../constants/gridClasses';
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
12
  const StyledMenuList = styled(MenuList)(() => ({
@@ -23,7 +23,7 @@ const GridColumnMenuContainer = /*#__PURE__*/React.forwardRef(function GridColum
23
23
  } = props,
24
24
  other = _objectWithoutPropertiesLoose(props, _excluded);
25
25
  const handleListKeyDown = React.useCallback(event => {
26
- if (isTabKey(event.key)) {
26
+ if (event.key === 'Tab') {
27
27
  event.preventDefault();
28
28
  }
29
29
  if (isHideMenuKey(event.key)) {
@@ -10,7 +10,6 @@ import ClickAwayListener from '@mui/material/ClickAwayListener';
10
10
  import Paper from '@mui/material/Paper';
11
11
  import Popper from '@mui/material/Popper';
12
12
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
13
- import { isEscapeKey } from '../../utils/keyboardUtils';
14
13
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
15
14
  import { jsx as _jsx } from "react/jsx-runtime";
16
15
  export const gridPanelClasses = generateUtilityClasses('MuiDataGrid', ['panel', 'paper']);
@@ -51,7 +50,7 @@ const GridPanel = /*#__PURE__*/React.forwardRef((props, ref) => {
51
50
  apiRef.current.hidePreferences();
52
51
  }, [apiRef]);
53
52
  const handleKeyDown = React.useCallback(event => {
54
- if (isEscapeKey(event.key)) {
53
+ if (event.key === 'Escape') {
55
54
  apiRef.current.hidePreferences();
56
55
  }
57
56
  }, [apiRef]);
@@ -281,10 +281,15 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
281
281
  variant: "standard",
282
282
  as: rootProps.slots.baseFormControl
283
283
  }, baseFormControlProps, logicOperatorInputProps, {
284
- sx: _extends({
285
- display: hasLogicOperatorColumn ? 'flex' : 'none',
286
- visibility: showMultiFilterOperators ? 'visible' : 'hidden'
287
- }, baseFormControlProps.sx || {}, logicOperatorInputProps.sx || {}),
284
+ sx: [hasLogicOperatorColumn ? {
285
+ display: 'flex'
286
+ } : {
287
+ display: 'none'
288
+ }, showMultiFilterOperators ? {
289
+ visibility: 'visible'
290
+ } : {
291
+ visibility: 'hidden'
292
+ }, baseFormControlProps.sx, logicOperatorInputProps.sx],
288
293
  className: clsx(classes.logicOperatorInput, baseFormControlProps.className, logicOperatorInputProps.className),
289
294
  ownerState: rootProps,
290
295
  children: /*#__PURE__*/_jsx(rootProps.slots.baseSelect, _extends({
@@ -6,7 +6,7 @@ import MenuList from '@mui/material/MenuList';
6
6
  import MenuItem from '@mui/material/MenuItem';
7
7
  import ListItemIcon from '@mui/material/ListItemIcon';
8
8
  import { gridDensitySelector } from '../../hooks/features/density/densitySelector';
9
- import { isHideMenuKey, isTabKey } from '../../utils/keyboardUtils';
9
+ import { isHideMenuKey } from '../../utils/keyboardUtils';
10
10
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
11
11
  import { useGridSelector } from '../../hooks/utils/useGridSelector';
12
12
  import { GridMenu } from '../menu/GridMenu';
@@ -62,7 +62,7 @@ const GridToolbarDensitySelector = /*#__PURE__*/React.forwardRef(function GridTo
62
62
  setOpen(false);
63
63
  };
64
64
  const handleListKeyDown = event => {
65
- if (isTabKey(event.key)) {
65
+ if (event.key === 'Tab') {
66
66
  event.preventDefault();
67
67
  }
68
68
  if (isHideMenuKey(event.key)) {
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { unstable_useId as useId, unstable_useForkRef as useForkRef } from '@mui/utils';
5
5
  import MenuList from '@mui/material/MenuList';
6
- import { isHideMenuKey, isTabKey } from '../../utils/keyboardUtils';
6
+ import { isHideMenuKey } from '../../utils/keyboardUtils';
7
7
  import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
8
8
  import { GridMenu } from '../menu/GridMenu';
9
9
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
@@ -29,7 +29,7 @@ const GridToolbarExportContainer = /*#__PURE__*/React.forwardRef(function GridTo
29
29
  };
30
30
  const handleMenuClose = () => setOpen(false);
31
31
  const handleListKeyDown = event => {
32
- if (isTabKey(event.key)) {
32
+ if (event.key === 'Tab') {
33
33
  event.preventDefault();
34
34
  }
35
35
  if (isHideMenuKey(event.key)) {
@@ -105,9 +105,11 @@ function GridToolbarQuickFilter(props) {
105
105
  endAdornment: /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
106
106
  "aria-label": apiRef.current.getLocaleText('toolbarQuickFilterDeleteIconLabel'),
107
107
  size: "small",
108
- sx: {
109
- visibility: searchValue ? 'visible' : 'hidden'
110
- },
108
+ sx: [searchValue ? {
109
+ visibility: 'visible'
110
+ } : {
111
+ visibility: 'hidden'
112
+ }],
111
113
  onClick: handleSearchReset
112
114
  }, rootProps.slotProps?.baseIconButton, {
113
115
  children: /*#__PURE__*/_jsx(rootProps.slots.quickFilterClearIcon, {
@@ -51,7 +51,8 @@ export function useGridParamsApi(apiRef) {
51
51
  tabIndex: cellTabIndex && cellTabIndex.field === field && cellTabIndex.id === id ? 0 : -1,
52
52
  value,
53
53
  formattedValue: value,
54
- isEditable: false
54
+ isEditable: false,
55
+ api: {}
55
56
  };
56
57
  if (colDef && colDef.valueFormatter) {
57
58
  params.formattedValue = colDef.valueFormatter(value, row, colDef, apiRef);
@@ -1,6 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare';
3
3
  import type { GridApiCommon } from '../../models/api/gridApiCommon';
4
- import { OutputSelector } from '../../utils/createSelector';
4
+ import { OutputSelector, OutputSelectorV8 } from '../../utils/createSelector';
5
+ type Selector<Api extends GridApiCommon, Args, T> = ((state: Api['state']) => T) | OutputSelectorV8<Api['state'], Args, T>;
5
6
  export declare const objectShallowCompare: typeof fastObjectShallowCompare;
6
7
  export declare const useGridSelector: <Api extends GridApiCommon, T>(apiRef: React.MutableRefObject<Api>, selector: ((state: Api["state"]) => T) | OutputSelector<Api["state"], T>, equals?: (a: T, b: T) => boolean) => T;
8
+ export declare const useGridSelectorV8: <Api extends GridApiCommon, Args, T>(apiRef: React.MutableRefObject<Api>, selector: Selector<Api, Args, T>, args?: Args, equals?: (a: T, b: T) => boolean) => T;
9
+ export {};
@@ -6,12 +6,21 @@ import { warnOnce } from '../../internals/utils/warning';
6
6
  function isOutputSelector(selector) {
7
7
  return selector.acceptsApiRef;
8
8
  }
9
+ // TODO v8: Remove this function
9
10
  function applySelector(apiRef, selector) {
10
11
  if (isOutputSelector(selector)) {
11
12
  return selector(apiRef);
12
13
  }
13
14
  return selector(apiRef.current.state);
14
15
  }
16
+
17
+ // TODO v8: Rename this function to `applySelector`
18
+ function applySelectorV8(apiRef, selector, args, instanceId) {
19
+ if (isOutputSelector(selector)) {
20
+ return selector(apiRef, args);
21
+ }
22
+ return selector(apiRef.current.state, instanceId);
23
+ }
15
24
  const defaultCompare = Object.is;
16
25
  export const objectShallowCompare = fastObjectShallowCompare;
17
26
  const createRefs = () => ({
@@ -19,6 +28,8 @@ const createRefs = () => ({
19
28
  equals: null,
20
29
  selector: null
21
30
  });
31
+
32
+ // TODO v8: Remove this function
22
33
  export const useGridSelector = (apiRef, selector, equals = defaultCompare) => {
23
34
  if (process.env.NODE_ENV !== 'production') {
24
35
  if (!apiRef.current.state) {
@@ -43,4 +54,31 @@ export const useGridSelector = (apiRef, selector, equals = defaultCompare) => {
43
54
  });
44
55
  });
45
56
  return state;
57
+ };
58
+
59
+ // TODO v8: Rename this function to `useGridSelector`
60
+ export const useGridSelectorV8 = (apiRef, selector, args = undefined, equals = defaultCompare) => {
61
+ if (process.env.NODE_ENV !== 'production') {
62
+ if (!apiRef.current.state) {
63
+ warnOnce(['MUI X: `useGridSelector` has been called before the initialization of the state.', 'This hook can only be used inside the context of the grid.']);
64
+ }
65
+ }
66
+ const refs = useLazyRef(createRefs);
67
+ const didInit = refs.current.selector !== null;
68
+ const [state, setState] = React.useState(
69
+ // We don't use an initialization function to avoid allocations
70
+ didInit ? null : applySelectorV8(apiRef, selector, args, apiRef.current.instanceId));
71
+ refs.current.state = state;
72
+ refs.current.equals = equals;
73
+ refs.current.selector = selector;
74
+ useOnMount(() => {
75
+ return apiRef.current.store.subscribe(() => {
76
+ const newState = applySelectorV8(apiRef, refs.current.selector, args, apiRef.current.instanceId);
77
+ if (!refs.current.equals(refs.current.state, newState)) {
78
+ refs.current.state = newState;
79
+ setState(newState);
80
+ }
81
+ });
82
+ });
83
+ return state;
46
84
  };
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.13.0
2
+ * @mui/x-data-grid v7.14.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -72,7 +72,8 @@ export type * from '../models/props/DataGridProps';
72
72
  export type * from '../models/gridDataSource';
73
73
  export { getColumnsToExport, defaultGetRowsToExport } from '../hooks/features/export/utils';
74
74
  export * from '../utils/createControllablePromise';
75
- export { createSelector, createSelectorMemoized } from '../utils/createSelector';
75
+ export { createSelector, createSelectorV8, createSelectorMemoized, createSelectorMemoizedV8, } from '../utils/createSelector';
76
+ export { useGridSelectorV8 } from '../hooks/utils/useGridSelector';
76
77
  export { gridRowGroupsToFetchSelector } from '../hooks/features/rows/gridRowsSelector';
77
78
  export { findParentElementFromClassName, getActiveElement, isEventTargetInPortal, } from '../utils/domUtils';
78
79
  export { isNavigationKey, isPasteShortcut } from '../utils/keyboardUtils';
@@ -57,7 +57,8 @@ export { useGridVisibleRows, getVisibleRows } from '../hooks/utils/useGridVisibl
57
57
  export { useGridInitializeState } from '../hooks/utils/useGridInitializeState';
58
58
  export { getColumnsToExport, defaultGetRowsToExport } from '../hooks/features/export/utils';
59
59
  export * from '../utils/createControllablePromise';
60
- export { createSelector, createSelectorMemoized } from '../utils/createSelector';
60
+ export { createSelector, createSelectorV8, createSelectorMemoized, createSelectorMemoizedV8 } from '../utils/createSelector';
61
+ export { useGridSelectorV8 } from '../hooks/utils/useGridSelector';
61
62
  export { gridRowGroupsToFetchSelector } from '../hooks/features/rows/gridRowsSelector';
62
63
  export { findParentElementFromClassName, getActiveElement, isEventTargetInPortal } from '../utils/domUtils';
63
64
  export { isNavigationKey, isPasteShortcut } from '../utils/keyboardUtils';
package/locales/csCZ.js CHANGED
@@ -38,11 +38,10 @@ const csCZGrid = {
38
38
  toolbarExportPrint: 'Vytisknout',
39
39
  toolbarExportExcel: 'Stáhnout jako Excel',
40
40
  // Columns management text
41
- // columnsManagementSearchTitle: 'Search',
42
- // columnsManagementNoColumns: 'No columns',
43
- // columnsManagementShowHideAllText: 'Show/Hide All',
44
- // columnsManagementReset: 'Reset',
45
-
41
+ columnsManagementSearchTitle: 'Hledat sloupce',
42
+ columnsManagementNoColumns: 'Žádné sloupce',
43
+ columnsManagementShowHideAllText: 'Zobrazit/skrýt vše',
44
+ columnsManagementReset: 'Resetovat',
46
45
  // Filter panel text
47
46
  filterPanelAddFilter: 'Přidat filtr',
48
47
  filterPanelRemoveAll: 'Odstranit vše',
package/locales/heIL.js CHANGED
@@ -30,11 +30,10 @@ const heILGrid = {
30
30
  toolbarExportPrint: 'הדפסה',
31
31
  toolbarExportExcel: 'ייצוא ל- Excel',
32
32
  // Columns management text
33
- // columnsManagementSearchTitle: 'Search',
34
- // columnsManagementNoColumns: 'No columns',
35
- // columnsManagementShowHideAllText: 'Show/Hide All',
36
- // columnsManagementReset: 'Reset',
37
-
33
+ columnsManagementSearchTitle: 'חיפוש',
34
+ columnsManagementNoColumns: 'אין עמודות',
35
+ columnsManagementShowHideAllText: 'הצג/הסתר הכל',
36
+ columnsManagementReset: 'אתחול',
38
37
  // Filter panel text
39
38
  filterPanelAddFilter: 'הוסף מסנן',
40
39
  filterPanelRemoveAll: 'מחק הכל',
@@ -43,19 +43,19 @@ export interface GridGetRowsResponse {
43
43
  }
44
44
  export interface GridDataSource {
45
45
  /**
46
- * This method will be called when the grid needs to fetch some rows
46
+ * This method will be called when the grid needs to fetch some rows.
47
47
  * @param {GridGetRowsParams} params The parameters required to fetch the rows
48
48
  * @returns {Promise<GridGetRowsResponse>} A promise that resolves to the data of type [GridGetRowsResponse]
49
49
  */
50
50
  getRows(params: GridGetRowsParams): Promise<GridGetRowsResponse>;
51
51
  /**
52
- * This method will be called when the user updates a row [Not yet implemented]
52
+ * This method will be called when the user updates a row [Not yet implemented].
53
53
  * @param {GridRowModel} updatedRow The updated row
54
54
  * @returns {Promise<any>} If resolved (synced on the backend), the grid will update the row and mutate the cache
55
55
  */
56
56
  updateRow?(updatedRow: GridRowModel): Promise<any>;
57
57
  /**
58
- * Used to group rows by their parent group. Replaces `getTreeDataPath` used in client side tree-data .
58
+ * Used to group rows by their parent group. Replaces `getTreeDataPath` used in client side tree-data.
59
59
  * @param {GridRowModel} row The row to get the group key of
60
60
  * @returns {string} The group key for the row
61
61
  */
@@ -70,19 +70,19 @@ export interface GridDataSource {
70
70
  }
71
71
  export interface GridDataSourceCache {
72
72
  /**
73
- * Set the cache entry for the given key
73
+ * Set the cache entry for the given key.
74
74
  * @param {GridGetRowsParams} key The key of type `GridGetRowsParams`
75
75
  * @param {GridGetRowsResponse} value The value to be stored in the cache
76
76
  */
77
77
  set: (key: GridGetRowsParams, value: GridGetRowsResponse) => void;
78
78
  /**
79
- * Get the cache entry for the given key
79
+ * Get the cache entry for the given key.
80
80
  * @param {GridGetRowsParams} key The key of type `GridGetRowsParams`
81
81
  * @returns {GridGetRowsResponse} The value stored in the cache
82
82
  */
83
83
  get: (key: GridGetRowsParams) => GridGetRowsResponse | undefined;
84
84
  /**
85
- * Clear the cache
85
+ * Clear the cache.
86
86
  */
87
87
  clear: () => void;
88
88
  }
@@ -53,6 +53,10 @@ export interface GridCellParams<R extends GridValidRowModel = any, V = unknown,
53
53
  * the tabIndex value.
54
54
  */
55
55
  tabIndex: 0 | -1;
56
+ /**
57
+ * GridApi that let you manipulate the grid.
58
+ */
59
+ api: GridApiCommunity;
56
60
  }
57
61
  export interface FocusElement {
58
62
  focus(): void;
@@ -107,13 +107,12 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
107
107
  const apiRef = useGridApiContext();
108
108
  const rootProps = useGridRootProps();
109
109
  const field = column.field;
110
- const cellParamsWithAPI = useGridSelector(apiRef, () => {
110
+ const cellParams = useGridSelector(apiRef, () => {
111
111
  // This is required because `.getCellParams` tries to get the `state.rows.tree` entry
112
112
  // associated with `rowId`/`fieldId`, but this selector runs after the state has been
113
113
  // updated, while `rowId`/`fieldId` reference an entry in the old state.
114
114
  try {
115
- const cellParams = apiRef.current.getCellParams(rowId, field);
116
- const result = cellParams;
115
+ const result = apiRef.current.getCellParams(rowId, field);
117
116
  result.api = apiRef.current;
118
117
  return result;
119
118
  } catch (e) {
@@ -132,9 +131,9 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
132
131
  hasFocus,
133
132
  isEditable = false,
134
133
  value
135
- } = cellParamsWithAPI;
134
+ } = cellParams;
136
135
  const canManageOwnFocus = column.type === 'actions' && column.getActions?.(apiRef.current.getRowParams(rowId)).some(action => !action.props.disabled);
137
- const tabIndex = (cellMode === 'view' || !isEditable) && !canManageOwnFocus ? cellParamsWithAPI.tabIndex : -1;
136
+ const tabIndex = (cellMode === 'view' || !isEditable) && !canManageOwnFocus ? cellParams.tabIndex : -1;
138
137
  const {
139
138
  classes: rootClasses,
140
139
  getCellClassName
@@ -147,15 +146,15 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
147
146
  }).filter(Boolean).join(' '));
148
147
  const classNames = [pipesClassName];
149
148
  if (column.cellClassName) {
150
- classNames.push(typeof column.cellClassName === 'function' ? column.cellClassName(cellParamsWithAPI) : column.cellClassName);
149
+ classNames.push(typeof column.cellClassName === 'function' ? column.cellClassName(cellParams) : column.cellClassName);
151
150
  }
152
151
  if (column.display === 'flex') {
153
152
  classNames.push(gridClasses['cell--flex']);
154
153
  }
155
154
  if (getCellClassName) {
156
- classNames.push(getCellClassName(cellParamsWithAPI));
155
+ classNames.push(getCellClassName(cellParams));
157
156
  }
158
- const valueToRender = cellParamsWithAPI.formattedValue ?? value;
157
+ const valueToRender = cellParams.formattedValue ?? value;
159
158
  const cellRef = React.useRef(null);
160
159
  const handleRef = useForkRef(ref, cellRef);
161
160
  const focusElementRef = React.useRef(null);
@@ -238,7 +237,7 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
238
237
  }
239
238
  }
240
239
  }, [hasFocus, cellMode, apiRef]);
241
- if (cellParamsWithAPI === EMPTY_CELL_PARAMS) {
240
+ if (cellParams === EMPTY_CELL_PARAMS) {
242
241
  return null;
243
242
  }
244
243
  let handleFocus = other.onFocus;
@@ -260,15 +259,15 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
260
259
  let children;
261
260
  let title;
262
261
  if (editCellState === null && column.renderCell) {
263
- children = column.renderCell(cellParamsWithAPI);
262
+ children = column.renderCell(cellParams);
264
263
  }
265
264
  if (editCellState !== null && column.renderEditCell) {
266
265
  const updatedRow = apiRef.current.getRowWithUpdatedValues(rowId, column.field);
267
266
 
268
267
  // eslint-disable-next-line @typescript-eslint/naming-convention
269
268
  const editCellStateRest = _objectWithoutPropertiesLoose(editCellState, _excluded2);
270
- const formattedValue = column.valueFormatter ? column.valueFormatter(editCellState.value, updatedRow, column, apiRef) : cellParamsWithAPI.formattedValue;
271
- const params = _extends({}, cellParamsWithAPI, {
269
+ const formattedValue = column.valueFormatter ? column.valueFormatter(editCellState.value, updatedRow, column, apiRef) : cellParams.formattedValue;
270
+ const params = _extends({}, cellParams, {
272
271
  row: updatedRow,
273
272
  formattedValue
274
273
  }, editCellStateRest);
@@ -6,7 +6,6 @@ import * as React from 'react';
6
6
  import PropTypes from 'prop-types';
7
7
  import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
8
8
  import { GridCellEditStopReasons } from '../../models/params/gridEditCellParams';
9
- import { isEscapeKey } from '../../utils/keyboardUtils';
10
9
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
11
10
  import { GridEditModes } from '../../models/gridEditRowModel';
12
11
  import { getValueFromValueOptions, getValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
@@ -80,10 +79,10 @@ function GridEditSingleSelectCell(props) {
80
79
  setOpen(false);
81
80
  return;
82
81
  }
83
- if (reason === 'backdropClick' || isEscapeKey(event.key)) {
82
+ if (reason === 'backdropClick' || event.key === 'Escape') {
84
83
  const params = apiRef.current.getCellParams(id, field);
85
84
  apiRef.current.publishEvent('cellEditStop', _extends({}, params, {
86
- reason: isEscapeKey(event.key) ? GridCellEditStopReasons.escapeKeyDown : GridCellEditStopReasons.cellFocusOut
85
+ reason: event.key === 'Escape' ? GridCellEditStopReasons.escapeKeyDown : GridCellEditStopReasons.cellFocusOut
87
86
  }));
88
87
  }
89
88
  };
@@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
6
6
  import * as React from 'react';
7
7
  import MenuList from '@mui/material/MenuList';
8
8
  import { styled } from '@mui/material/styles';
9
- import { isHideMenuKey, isTabKey } from '../../../utils/keyboardUtils';
9
+ import { isHideMenuKey } from '../../../utils/keyboardUtils';
10
10
  import { gridClasses } from '../../../constants/gridClasses';
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
12
  const StyledMenuList = styled(MenuList)(() => ({
@@ -23,7 +23,7 @@ const GridColumnMenuContainer = /*#__PURE__*/React.forwardRef(function GridColum
23
23
  } = props,
24
24
  other = _objectWithoutPropertiesLoose(props, _excluded);
25
25
  const handleListKeyDown = React.useCallback(event => {
26
- if (isTabKey(event.key)) {
26
+ if (event.key === 'Tab') {
27
27
  event.preventDefault();
28
28
  }
29
29
  if (isHideMenuKey(event.key)) {