@mui/x-data-grid 7.17.0 → 7.18.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 (85) hide show
  1. package/CHANGELOG.md +98 -5
  2. package/DataGrid/DataGrid.js +11 -1
  3. package/DataGrid/useDataGridComponent.js +3 -0
  4. package/DataGrid/useDataGridProps.js +2 -1
  5. package/components/GridRow.js +1 -0
  6. package/components/cell/GridCell.js +30 -5
  7. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +0 -1
  8. package/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
  9. package/hooks/features/columnResize/useGridColumnResize.js +6 -6
  10. package/hooks/features/dimensions/gridDimensionsApi.d.ts +4 -0
  11. package/hooks/features/dimensions/useGridDimensions.d.ts +1 -1
  12. package/hooks/features/dimensions/useGridDimensions.js +4 -1
  13. package/hooks/features/editing/useGridCellEditing.js +2 -18
  14. package/hooks/features/editing/useGridRowEditing.js +6 -1
  15. package/hooks/features/editing/utils.d.ts +2 -0
  16. package/hooks/features/editing/utils.js +15 -0
  17. package/hooks/features/export/useGridPrintExport.js +2 -1
  18. package/hooks/features/focus/useGridFocus.js +2 -1
  19. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +10 -46
  20. package/hooks/features/keyboardNavigation/utils.d.ts +17 -0
  21. package/hooks/features/keyboardNavigation/utils.js +58 -0
  22. package/hooks/features/rows/gridRowSpanningSelectors.d.ts +4 -0
  23. package/hooks/features/rows/gridRowSpanningSelectors.js +5 -0
  24. package/hooks/features/rows/gridRowSpanningUtils.d.ts +10 -0
  25. package/hooks/features/rows/gridRowSpanningUtils.js +42 -0
  26. package/hooks/features/rows/useGridRowSpanning.d.ts +27 -0
  27. package/hooks/features/rows/useGridRowSpanning.js +257 -0
  28. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -1
  29. package/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
  30. package/hooks/utils/useGridApiEventHandler.js +0 -1
  31. package/index.js +1 -1
  32. package/internals/index.d.ts +1 -0
  33. package/internals/index.js +1 -0
  34. package/models/colDef/gridColDef.d.ts +4 -0
  35. package/models/gridStateCommunity.d.ts +2 -0
  36. package/models/props/DataGridProps.d.ts +10 -0
  37. package/modern/DataGrid/DataGrid.js +11 -1
  38. package/modern/DataGrid/useDataGridComponent.js +3 -0
  39. package/modern/DataGrid/useDataGridProps.js +2 -1
  40. package/modern/components/GridRow.js +1 -0
  41. package/modern/components/cell/GridCell.js +30 -5
  42. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
  43. package/modern/hooks/features/columnResize/useGridColumnResize.js +6 -6
  44. package/modern/hooks/features/dimensions/useGridDimensions.js +4 -1
  45. package/modern/hooks/features/editing/useGridCellEditing.js +2 -18
  46. package/modern/hooks/features/editing/useGridRowEditing.js +6 -1
  47. package/modern/hooks/features/editing/utils.js +15 -0
  48. package/modern/hooks/features/export/useGridPrintExport.js +2 -1
  49. package/modern/hooks/features/focus/useGridFocus.js +2 -1
  50. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +10 -46
  51. package/modern/hooks/features/keyboardNavigation/utils.js +58 -0
  52. package/modern/hooks/features/rows/gridRowSpanningSelectors.js +5 -0
  53. package/modern/hooks/features/rows/gridRowSpanningUtils.js +42 -0
  54. package/modern/hooks/features/rows/useGridRowSpanning.js +257 -0
  55. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
  56. package/modern/hooks/utils/useGridApiEventHandler.js +0 -1
  57. package/modern/index.js +1 -1
  58. package/modern/internals/index.js +1 -0
  59. package/modern/utils/domUtils.js +12 -12
  60. package/node/DataGrid/DataGrid.js +11 -1
  61. package/node/DataGrid/useDataGridComponent.js +3 -0
  62. package/node/DataGrid/useDataGridProps.js +2 -1
  63. package/node/components/GridRow.js +1 -0
  64. package/node/components/cell/GridCell.js +30 -5
  65. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
  66. package/node/hooks/features/columnResize/useGridColumnResize.js +6 -6
  67. package/node/hooks/features/dimensions/useGridDimensions.js +4 -1
  68. package/node/hooks/features/editing/useGridCellEditing.js +2 -18
  69. package/node/hooks/features/editing/useGridRowEditing.js +6 -1
  70. package/node/hooks/features/editing/utils.js +22 -0
  71. package/node/hooks/features/export/useGridPrintExport.js +2 -1
  72. package/node/hooks/features/focus/useGridFocus.js +2 -1
  73. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +16 -53
  74. package/node/hooks/features/keyboardNavigation/utils.js +68 -0
  75. package/node/hooks/features/rows/gridRowSpanningSelectors.js +11 -0
  76. package/node/hooks/features/rows/gridRowSpanningUtils.js +52 -0
  77. package/node/hooks/features/rows/useGridRowSpanning.js +267 -0
  78. package/node/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
  79. package/node/hooks/utils/useGridApiEventHandler.js +0 -1
  80. package/node/index.js +1 -1
  81. package/node/internals/index.js +15 -0
  82. package/node/utils/domUtils.js +12 -12
  83. package/package.json +3 -3
  84. package/utils/domUtils.d.ts +4 -4
  85. package/utils/domUtils.js +12 -12
package/CHANGELOG.md CHANGED
@@ -3,6 +3,99 @@
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.18.0
7
+
8
+ _Sep 20, 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
+ - 💫 Support [Row spanning](https://mui.com/x/react-data-grid/row-spanning/) on the Data Grid that automatically merges the consecutive cells in a column based on the cell value
13
+
14
+ <img width="600" src="https://github.com/user-attachments/assets/d32ec936-d238-4c92-9e1a-af6788d74cdf" alt="data grid row spanning" />
15
+
16
+ - ⏰ Support `date-fns` v4 (#14673) @LukasTy
17
+ - 🎉 Add option for Pickers to change the order of displayed years (#11780) @thomasmoon
18
+ - 🐞 Bugfixes
19
+ - 📚 Documentation improvements
20
+
21
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@7.18.0`
26
+
27
+ - [DataGrid] Add default reset value in row edit mode (#14050) @michelengelen
28
+ - [DataGrid] Add `columnGroupHeaderHeight` prop for sizing column group headers (#14637) @KenanYusuf
29
+ - [DataGrid] Fix `document` reference when the grid is rendered in a popup window (#14649) @arminmeh
30
+ - [DataGrid] Remove `minFirstColumn` from `GetHeadersParams` interface (#14450) @k-rajat19
31
+ - [DataGrid] Row spanning (#14124) @MBilalShafi
32
+
33
+ #### `@mui/x-data-grid-pro@7.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
34
+
35
+ Same changes as in `@mui/x-data-grid@7.18.0`, plus:
36
+
37
+ - [DataGridPro] Fix `onRowsScrollEnd` being triggered instantly when bottom pinned row is present (#14602) @arminmeh
38
+ - [DataGridPro] Fix header filters rendering issue for `isEmpty` and `isNotEmpty` filter operators (#14493) @k-rajat19
39
+ - [DataGridPro] Fix pinned columns in RTL mode (#14586) @KenanYusuf
40
+
41
+ #### `@mui/x-data-grid-premium@7.18.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
42
+
43
+ Same changes as in `@mui/x-data-grid-pro@7.18.0`.
44
+
45
+ ### Date and Time Pickers
46
+
47
+ #### `@mui/x-date-pickers@7.18.0`
48
+
49
+ - [pickers] Add option to change the order of displayed years (#11780) @thomasmoon
50
+ - [pickers] Support `date-fns` v4 (#14673) @LukasTy
51
+
52
+ #### `@mui/x-date-pickers-pro@7.18.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
53
+
54
+ Same changes as in `@mui/x-date-pickers@7.18.0`.
55
+
56
+ ### Charts
57
+
58
+ #### `@mui/x-charts@7.18.0`
59
+
60
+ - [charts] Add a `PolarProvider` to manage polar axes (#14642) @alexfauquette
61
+ - [charts] Fix `LineChart` animation being stuck with initial drawing area value (#14553) @JCQuintas
62
+ - [charts] Fix legend slot typing (#14657) @alexfauquette
63
+ - [charts] Pass the axis index to extremum getter (#14641) @alexfauquette
64
+ - [charts] Provide hooks to create custom tooltip (#14377) @alexfauquette
65
+
66
+ #### `@mui/x-charts-pro@7.0.0-beta.1` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
67
+
68
+ Same changes as in `@mui/x-charts@7.18.0`.
69
+
70
+ ### Tree View
71
+
72
+ #### `@mui/x-tree-view@7.18.0`
73
+
74
+ - [TreeView] Add `"use client"` directive to every public component and hook (#14579) @flaviendelangle
75
+
76
+ ### Docs
77
+
78
+ - [docs] Add `groupingValueGetter` callout in column definition docs (#14599) @michelengelen
79
+ - [docs] Clean v6 => v7 migration guide (#14652) @flaviendelangle
80
+ - [docs] Copy `vale-action.yml` from main repo @oliviertassinari
81
+ - [docs] Edit the Pickers Getting started doc (#14555) @samuelsycamore
82
+ - [docs] Fix TypeScript capitalization @oliviertassinari
83
+ - [docs] Fix Vale error @oliviertassinari
84
+ - [docs] Make the migration guide diff a bit easier to read @oliviertassinari
85
+ - [docs] Report Vale at warning level (#14660) @oliviertassinari
86
+ - [docs] Warn about the `valueGetter` and `valueFormatter` signature change (#14613) @cherniavskii
87
+ - [docs] Polish code formatting (#14603) @oliviertassinari
88
+ - [test] Spy on `observe` method to avoid flaky wait for a callback (#14640) @arminmeh
89
+
90
+ ### Core
91
+
92
+ - [core] Fix 301 link to Next.js and git diff @oliviertassinari
93
+ - [core] Fix failing CI on `master` (#14644) @cherniavskii
94
+ - [core] Fix `package.json` repository rule @oliviertassinari
95
+ - [core] MUI X repository moved to a new location @oliviertassinari
96
+ - [docs-infra] Strengthen CSP (#14581) @oliviertassinari
97
+ - [license] Finish renaming of LicensingModel (#14615) @oliviertassinari
98
+
6
99
  ## 7.17.0
7
100
 
8
101
  _Sep 13, 2024_
@@ -75,7 +168,7 @@ Same changes as in `@mui/x-charts@7.17.0`.
75
168
  ### Docs
76
169
 
77
170
  - [docs] Add missing callout on "Imperative API" tree view sections (#14503) @flaviendelangle
78
- - [docs] Fix broken redirection to MUI X v5 @oliviertassinari
171
+ - [docs] Fix broken redirection to MUI X v5 @oliviertassinari
79
172
  - [docs] Fix multiple `console.error` messages on `charts` docs (#14554) @JCQuintas
80
173
  - [docs] Fixed typo in Row Grouping recipes (#14549) @Miodini
81
174
  - [docs] Match title with blog posts @oliviertassinari
@@ -195,7 +288,7 @@ We'd like to offer a big thanks to the 8 contributors who made this release poss
195
288
 
196
289
  - 💫 Support Material UI v6 (`@mui/material@6`) peer dependency (#14142) @cherniavskii
197
290
 
198
- You can now use MUI X components with either v5 or v6 of `@mui/material` package 🎉
291
+ You can now use MUI X components with either v5 or v6 of `@mui/material` package 🎉
199
292
 
200
293
  - 🐞 Bugfixes
201
294
 
@@ -240,7 +333,7 @@ Same changes as in `@mui/x-charts@7.15.0`, plus:
240
333
 
241
334
  - [docs] Fix sentence case `h2` @oliviertassinari
242
335
  - [docs] Clarify contribution guide references @oliviertassinari
243
- - [docs] Fix Stack Overflow issue canned response @oliviertassinari
336
+ - [docs] Fix Stack Overflow issue canned response @oliviertassinari
244
337
  - [docs] Fix outdated link to support page @oliviertassinari
245
338
  - [docs] Fix use of Material UI @oliviertassinari
246
339
  - [docs] Update deprecated props in docs (#14295) @JCQuintas
@@ -498,7 +591,7 @@ The [Pro plan](https://mui.com/x/introduction/licensing/#pro-plan) is receiving
498
591
 
499
592
  As always, every feature released as part of the MIT plan will remain free and MIT licensed forever.
500
593
 
501
- This expansion of the Pro plan comes with some adjustments to our pricing strategy. Learn more about those in the [Upcoming changes to MUI X pricing in 2024](https://mui.com/blog/mui-x-sep-2024-price-update/) blog post.
594
+ This expansion of the Pro plan comes with some adjustments to our pricing strategy. Learn more about those in the [Upcoming changes to MUI X pricing in 2024](https://mui.com/blog/mui-x-sep-2024-price-update/) blog post.
502
595
 
503
596
  ### Highlights
504
597
 
@@ -563,7 +656,7 @@ Same changes as in `@mui/x-date-pickers@7.12.0`.
563
656
  #### `@mui/x-charts@7.12.0`
564
657
 
565
658
  - [charts] Fix incorrect `axisId` prop being allowed in xAxis/yAxis config. Use `id` instead. (#13986) @JCQuintas
566
- - [charts] Use vendor to have Common JS bundle working out of the box (#13608) @alexfauquette
659
+ - [charts] Use vendor to have CommonJS bundle working out of the box (#13608) @alexfauquette
567
660
  - [charts] Divide the `SeriesProvider` to use in filtering (#14026) @JCQuintas
568
661
 
569
662
  ### Tree View
@@ -118,6 +118,11 @@ DataGridRaw.propTypes = {
118
118
  * @default 150
119
119
  */
120
120
  columnBufferPx: PropTypes.number,
121
+ /**
122
+ * Sets the height in pixels of the column group headers in the Data Grid.
123
+ * Inherits the `columnHeaderHeight` value if not set.
124
+ */
125
+ columnGroupHeaderHeight: PropTypes.number,
121
126
  columnGroupingModel: PropTypes.arrayOf(PropTypes.object),
122
127
  /**
123
128
  * Sets the height in pixel of the column headers in the Data Grid.
@@ -743,5 +748,10 @@ DataGridRaw.propTypes = {
743
748
  /**
744
749
  * The system prop that allows defining system overrides as well as additional CSS styles.
745
750
  */
746
- sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
751
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
752
+ /**
753
+ * If `true`, the Data Grid will auto span the cells over the rows having the same value.
754
+ * @default false
755
+ */
756
+ unstable_rowSpanning: PropTypes.bool
747
757
  };
@@ -27,6 +27,7 @@ import { useGridColumnSpanning } from "../hooks/features/columns/useGridColumnSp
27
27
  import { useGridColumnGrouping, columnGroupsStateInitializer } from "../hooks/features/columnGrouping/useGridColumnGrouping.js";
28
28
  import { useGridVirtualization, virtualizationStateInitializer } from "../hooks/features/virtualization/index.js";
29
29
  import { columnResizeStateInitializer, useGridColumnResize } from "../hooks/features/columnResize/useGridColumnResize.js";
30
+ import { rowSpanningStateInitializer, useGridRowSpanning } from "../hooks/features/rows/useGridRowSpanning.js";
30
31
  export const useDataGridComponent = (inputApiRef, props) => {
31
32
  const apiRef = useGridInitialization(inputApiRef, props);
32
33
 
@@ -48,6 +49,7 @@ export const useDataGridComponent = (inputApiRef, props) => {
48
49
  useGridInitializeState(sortingStateInitializer, apiRef, props);
49
50
  useGridInitializeState(preferencePanelStateInitializer, apiRef, props);
50
51
  useGridInitializeState(filterStateInitializer, apiRef, props);
52
+ useGridInitializeState(rowSpanningStateInitializer, apiRef, props);
51
53
  useGridInitializeState(densityStateInitializer, apiRef, props);
52
54
  useGridInitializeState(columnResizeStateInitializer, apiRef, props);
53
55
  useGridInitializeState(paginationStateInitializer, apiRef, props);
@@ -59,6 +61,7 @@ export const useDataGridComponent = (inputApiRef, props) => {
59
61
  useGridRowSelection(apiRef, props);
60
62
  useGridColumns(apiRef, props);
61
63
  useGridRows(apiRef, props);
64
+ useGridRowSpanning(apiRef, props);
62
65
  useGridParamsApi(apiRef);
63
66
  useGridColumnSpanning(apiRef);
64
67
  useGridColumnGrouping(apiRef, props);
@@ -73,7 +73,8 @@ export const DATA_GRID_PROPS_DEFAULT_VALUES = {
73
73
  showColumnVerticalBorder: false,
74
74
  sortingMode: 'client',
75
75
  sortingOrder: ['asc', 'desc', null],
76
- throttleRowsMs: 0
76
+ throttleRowsMs: 0,
77
+ unstable_rowSpanning: false
77
78
  };
78
79
  const defaultSlots = DATA_GRID_DEFAULT_SLOTS_COMPONENTS;
79
80
  export const useDataGridProps = inProps => {
@@ -338,6 +338,7 @@ process.env.NODE_ENV !== "production" ? GridRow.propTypes = {
338
338
  height: PropTypes.number.isRequired,
339
339
  width: PropTypes.number.isRequired
340
340
  }).isRequired,
341
+ groupHeaderHeight: PropTypes.number.isRequired,
341
342
  hasScrollX: PropTypes.bool.isRequired,
342
343
  hasScrollY: PropTypes.bool.isRequired,
343
344
  headerFilterHeight: PropTypes.number.isRequired,
@@ -7,6 +7,7 @@ import PropTypes from 'prop-types';
7
7
  import clsx from 'clsx';
8
8
  import { unstable_useForkRef as useForkRef, unstable_composeClasses as composeClasses, unstable_ownerDocument as ownerDocument, unstable_capitalize as capitalize } from '@mui/utils';
9
9
  import { fastMemo } from '@mui/x-internals/fastMemo';
10
+ import { useRtl } from '@mui/system/RtlProvider';
10
11
  import { doesSupportPreventScroll } from "../../utils/doesSupportPreventScroll.js";
11
12
  import { getDataGridUtilityClass, gridClasses } from "../../constants/gridClasses.js";
12
13
  import { GridCellModes } from "../../models/index.js";
@@ -17,6 +18,7 @@ import { gridFocusCellSelector } from "../../hooks/features/focus/gridFocusState
17
18
  import { MissingRowIdError } from "../../hooks/features/rows/useGridParamsApi.js";
18
19
  import { shouldCellShowLeftBorder, shouldCellShowRightBorder } from "../../utils/cellBorderUtils.js";
19
20
  import { GridPinnedColumnPosition } from "../../hooks/features/columns/gridColumnsInterfaces.js";
21
+ import { gridRowSpanningHiddenCellsSelector, gridRowSpanningSpannedCellsSelector } from "../../hooks/features/rows/gridRowSpanningSelectors.js";
20
22
  import { jsx as _jsx } from "react/jsx-runtime";
21
23
  export let PinnedPosition = /*#__PURE__*/function (PinnedPosition) {
22
24
  PinnedPosition[PinnedPosition["NONE"] = 0] = "NONE";
@@ -106,6 +108,7 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
106
108
  other = _objectWithoutPropertiesLoose(props, _excluded);
107
109
  const apiRef = useGridApiContext();
108
110
  const rootProps = useGridRootProps();
111
+ const isRtl = useRtl();
109
112
  const field = column.field;
110
113
  const cellParams = useGridSelector(apiRef, () => {
111
114
  // This is required because `.getCellParams` tries to get the `state.rows.tree` entry
@@ -126,6 +129,8 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
126
129
  id: rowId,
127
130
  field
128
131
  }));
132
+ const hiddenCells = useGridSelector(apiRef, gridRowSpanningHiddenCellsSelector);
133
+ const spannedCells = useGridSelector(apiRef, gridRowSpanningSpannedCellsSelector);
129
134
  const {
130
135
  cellMode,
131
136
  hasFocus,
@@ -198,6 +203,8 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
198
203
  propHandler(event);
199
204
  }
200
205
  }, [apiRef, field, rowId]);
206
+ const isCellRowSpanned = hiddenCells[rowId]?.[field] ?? false;
207
+ const rowSpan = spannedCells[rowId]?.[field] ?? 1;
201
208
  const style = React.useMemo(() => {
202
209
  if (isNotVisible) {
203
210
  return {
@@ -210,14 +217,21 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
210
217
  const cellStyle = _extends({
211
218
  '--width': `${width}px`
212
219
  }, styleProp);
213
- if (pinnedPosition === PinnedPosition.LEFT) {
214
- cellStyle.left = pinnedOffset;
220
+ const isLeftPinned = pinnedPosition === PinnedPosition.LEFT;
221
+ const isRightPinned = pinnedPosition === PinnedPosition.RIGHT;
222
+ if (isLeftPinned || isRightPinned) {
223
+ let side = isLeftPinned ? 'left' : 'right';
224
+ if (isRtl) {
225
+ side = isLeftPinned ? 'right' : 'left';
226
+ }
227
+ cellStyle[side] = pinnedOffset;
215
228
  }
216
- if (pinnedPosition === PinnedPosition.RIGHT) {
217
- cellStyle.right = pinnedOffset;
229
+ if (rowSpan > 1) {
230
+ cellStyle.height = `calc(var(--height) * ${rowSpan})`;
231
+ cellStyle.zIndex = 5;
218
232
  }
219
233
  return cellStyle;
220
- }, [width, isNotVisible, styleProp, pinnedOffset, pinnedPosition]);
234
+ }, [width, isNotVisible, styleProp, pinnedOffset, pinnedPosition, isRtl, rowSpan]);
221
235
  React.useEffect(() => {
222
236
  if (!hasFocus || cellMode === GridCellModes.Edit) {
223
237
  return;
@@ -237,6 +251,16 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
237
251
  }
238
252
  }
239
253
  }, [hasFocus, cellMode, apiRef]);
254
+ if (isCellRowSpanned) {
255
+ return /*#__PURE__*/_jsx("div", {
256
+ "data-colindex": colIndex,
257
+ role: "presentation",
258
+ style: _extends({}, style, {
259
+ minWidth: 'var(--width)',
260
+ maxWidth: 'var(--width)'
261
+ })
262
+ });
263
+ }
240
264
  if (cellParams === EMPTY_CELL_PARAMS) {
241
265
  return null;
242
266
  }
@@ -297,6 +321,7 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
297
321
  "data-colindex": colIndex,
298
322
  "aria-colindex": colIndex + 1,
299
323
  "aria-colspan": colSpan,
324
+ "aria-rowspan": rowSpan,
300
325
  style: style,
301
326
  title: title,
302
327
  tabIndex: tabIndex,
@@ -25,7 +25,6 @@ export interface UseGridColumnHeadersProps {
25
25
  export interface GetHeadersParams {
26
26
  position?: GridPinnedColumnPosition;
27
27
  renderContext?: GridColumnsRenderContext;
28
- minFirstColumn?: number;
29
28
  maxLastColumn?: number;
30
29
  }
31
30
  type OwnerState = DataGridProcessedProps;
@@ -53,7 +53,7 @@ export const useGridColumnHeaders = props => {
53
53
  const renderContext = useGridSelector(apiRef, gridRenderContextColumnsSelector);
54
54
  const pinnedColumns = useGridSelector(apiRef, gridVisiblePinnedColumnDefinitionsSelector);
55
55
  const columnsLookup = useGridSelector(apiRef, gridColumnLookupSelector);
56
- const offsetLeft = computeOffsetLeft(columnPositions, renderContext, isRtl, pinnedColumns.left.length);
56
+ const offsetLeft = computeOffsetLeft(columnPositions, renderContext, pinnedColumns.left.length);
57
57
  const gridHasFiller = dimensions.columnsTotalWidth < dimensions.viewportOuterSize.width;
58
58
  React.useEffect(() => {
59
59
  apiRef.current.columnHeadersContainerRef.current.scrollLeft = 0;
@@ -83,7 +83,6 @@ export const useGridColumnHeaders = props => {
83
83
  const getColumnsToRender = params => {
84
84
  const {
85
85
  renderContext: currentContext = renderContext,
86
- // TODO: `minFirstColumn` is not used anymore, could be refactored out.
87
86
  maxLastColumn = visibleColumns.length
88
87
  } = params || {};
89
88
  const firstColumnToRender = currentContext.firstColumnIndex;
@@ -123,16 +122,22 @@ export const useGridColumnHeaders = props => {
123
122
  computedWidth
124
123
  }) => {
125
124
  let style;
126
- if (pinnedPosition === 'left' || pinnedPosition === 'right') {
125
+ const isLeftPinned = pinnedPosition === GridPinnedColumnPosition.LEFT;
126
+ const isRightPinned = pinnedPosition === GridPinnedColumnPosition.RIGHT;
127
+ if (isLeftPinned || isRightPinned) {
127
128
  const pinnedOffset = getPinnedCellOffset(pinnedPosition, computedWidth, columnIndex, columnPositions, dimensions);
129
+ let side = isLeftPinned ? 'left' : 'right';
130
+ if (isRtl) {
131
+ side = isLeftPinned ? 'right' : 'left';
132
+ }
128
133
  if (pinnedPosition === 'left') {
129
134
  style = {
130
- left: pinnedOffset
135
+ [side]: pinnedOffset
131
136
  };
132
137
  }
133
138
  if (pinnedPosition === 'right') {
134
139
  style = {
135
- right: pinnedOffset
140
+ [side]: pinnedOffset
136
141
  };
137
142
  }
138
143
  }
@@ -191,18 +196,15 @@ export const useGridColumnHeaders = props => {
191
196
  children: [leftRenderContext && getColumnHeaders({
192
197
  position: GridPinnedColumnPosition.LEFT,
193
198
  renderContext: leftRenderContext,
194
- minFirstColumn: leftRenderContext.firstColumnIndex,
195
199
  maxLastColumn: leftRenderContext.lastColumnIndex
196
200
  }, {
197
201
  disableReorder: true
198
202
  }), getColumnHeaders({
199
203
  renderContext,
200
- minFirstColumn: pinnedColumns.left.length,
201
204
  maxLastColumn: visibleColumns.length - pinnedColumns.right.length
202
205
  }), rightRenderContext && getColumnHeaders({
203
206
  position: GridPinnedColumnPosition.RIGHT,
204
207
  renderContext: rightRenderContext,
205
- minFirstColumn: rightRenderContext.firstColumnIndex,
206
208
  maxLastColumn: rightRenderContext.lastColumnIndex
207
209
  }, {
208
210
  disableReorder: true,
@@ -282,7 +284,7 @@ export const useGridColumnHeaders = props => {
282
284
  depth: depth,
283
285
  isLastColumn: headerInfo.colIndex === visibleColumns.length - headerInfo.fields.length,
284
286
  maxDepth: headerGroupingMaxDepth,
285
- height: dimensions.headerHeight,
287
+ height: dimensions.groupHeaderHeight,
286
288
  hasFocus: hasFocus,
287
289
  tabIndex: tabIndex,
288
290
  pinnedPosition: pinnedPosition,
@@ -309,7 +311,6 @@ export const useGridColumnHeaders = props => {
309
311
  params: {
310
312
  position: GridPinnedColumnPosition.LEFT,
311
313
  renderContext: leftRenderContext,
312
- minFirstColumn: leftRenderContext.firstColumnIndex,
313
314
  maxLastColumn: leftRenderContext.lastColumnIndex
314
315
  }
315
316
  }), getColumnGroupHeaders({
@@ -322,7 +323,6 @@ export const useGridColumnHeaders = props => {
322
323
  params: {
323
324
  position: GridPinnedColumnPosition.RIGHT,
324
325
  renderContext: rightRenderContext,
325
- minFirstColumn: rightRenderContext.firstColumnIndex,
326
326
  maxLastColumn: rightRenderContext.lastColumnIndex
327
327
  }
328
328
  })]
@@ -302,13 +302,13 @@ export const useGridColumnResize = (apiRef, props) => {
302
302
  }
303
303
  refs.groupHeaderElements = findGroupHeaderElementsFromField(apiRef.current.columnHeadersContainerRef?.current, colDef.field);
304
304
  refs.cellElements = findGridCellElementsFromCol(refs.columnHeaderElement, apiRef.current);
305
- refs.fillerLeft = findGridElement(apiRef.current, 'filler--pinnedLeft');
306
- refs.fillerRight = findGridElement(apiRef.current, 'filler--pinnedRight');
305
+ refs.fillerLeft = findGridElement(apiRef.current, isRtl ? 'filler--pinnedRight' : 'filler--pinnedLeft');
306
+ refs.fillerRight = findGridElement(apiRef.current, isRtl ? 'filler--pinnedLeft' : 'filler--pinnedRight');
307
307
  const pinnedPosition = apiRef.current.unstable_applyPipeProcessors('isColumnPinned', false, refs.colDef.field);
308
- refs.leftPinnedCellsAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedCellsAfterCol(apiRef.current, refs.columnHeaderElement);
309
- refs.rightPinnedCellsBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedCellsBeforeCol(apiRef.current, refs.columnHeaderElement);
310
- refs.leftPinnedHeadersAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedHeadersAfterCol(apiRef.current, refs.columnHeaderElement);
311
- refs.rightPinnedHeadersBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedHeadersBeforeCol(apiRef.current, refs.columnHeaderElement);
308
+ refs.leftPinnedCellsAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedCellsAfterCol(apiRef.current, refs.columnHeaderElement, isRtl);
309
+ refs.rightPinnedCellsBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedCellsBeforeCol(apiRef.current, refs.columnHeaderElement, isRtl);
310
+ refs.leftPinnedHeadersAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedHeadersAfterCol(apiRef.current, refs.columnHeaderElement, isRtl);
311
+ refs.rightPinnedHeadersBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedHeadersBeforeCol(apiRef.current, refs.columnHeaderElement, isRtl);
312
312
  resizeDirection.current = getResizeDirection(separator, isRtl);
313
313
  initialOffsetToSeparator.current = computeOffsetToSeparator(xStart, refs.columnHeaderElement.getBoundingClientRect(), resizeDirection.current);
314
314
  };
@@ -61,6 +61,10 @@ export interface GridDimensions {
61
61
  * Height of one column header.
62
62
  */
63
63
  headerHeight: number;
64
+ /**
65
+ * Height of one column group header.
66
+ */
67
+ groupHeaderHeight: number;
64
68
  /**
65
69
  * Height of header filters.
66
70
  */
@@ -3,7 +3,7 @@ import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity';
3
3
  import { DataGridProcessedProps } from '../../../models/props/DataGridProps';
4
4
  import { GridDimensions } from './gridDimensionsApi';
5
5
  import { GridStateInitializer } from '../../utils/useGridInitializeState';
6
- type RootProps = Pick<DataGridProcessedProps, 'onResize' | 'scrollbarSize' | 'pagination' | 'paginationMode' | 'autoHeight' | 'getRowHeight' | 'rowHeight' | 'resizeThrottleMs' | 'columnHeaderHeight' | 'headerFilterHeight'>;
6
+ type RootProps = Pick<DataGridProcessedProps, 'onResize' | 'scrollbarSize' | 'pagination' | 'paginationMode' | 'autoHeight' | 'getRowHeight' | 'rowHeight' | 'resizeThrottleMs' | 'columnHeaderHeight' | 'columnGroupHeaderHeight' | 'headerFilterHeight'>;
7
7
  export type GridDimensionsState = GridDimensions;
8
8
  export declare const dimensionsStateInitializer: GridStateInitializer<RootProps>;
9
9
  export declare function useGridDimensions(apiRef: React.MutableRefObject<GridPrivateApiCommunity>, props: RootProps): void;
@@ -29,6 +29,7 @@ const EMPTY_DIMENSIONS = {
29
29
  hasScrollY: false,
30
30
  scrollbarSize: 0,
31
31
  headerHeight: 0,
32
+ groupHeaderHeight: 0,
32
33
  headerFilterHeight: 0,
33
34
  rowWidth: 0,
34
35
  rowHeight: 0,
@@ -55,6 +56,7 @@ export function useGridDimensions(apiRef, props) {
55
56
  const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
56
57
  const rowHeight = Math.floor(props.rowHeight * densityFactor);
57
58
  const headerHeight = Math.floor(props.columnHeaderHeight * densityFactor);
59
+ const groupHeaderHeight = Math.floor((props.columnGroupHeaderHeight ?? props.columnHeaderHeight) * densityFactor);
58
60
  const headerFilterHeight = Math.floor((props.headerFilterHeight ?? props.columnHeaderHeight) * densityFactor);
59
61
  const columnsTotalWidth = roundToDecimalPlaces(gridColumnsTotalWidthSelector(apiRef), 6);
60
62
  const headersTotalHeight = getTotalHeaderHeight(apiRef, props);
@@ -175,6 +177,7 @@ export function useGridDimensions(apiRef, props) {
175
177
  hasScrollY,
176
178
  scrollbarSize,
177
179
  headerHeight,
180
+ groupHeaderHeight,
178
181
  headerFilterHeight,
179
182
  rowWidth,
180
183
  rowHeight,
@@ -191,7 +194,7 @@ export function useGridDimensions(apiRef, props) {
191
194
  apiRef.current.publishEvent('viewportInnerSizeChange', newDimensions.viewportInnerSize);
192
195
  }
193
196
  apiRef.current.updateRenderContext?.();
194
- }, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, rowHeight, headerHeight, headerFilterHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
197
+ }, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, rowHeight, headerHeight, groupHeaderHeight, headerFilterHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
195
198
  const apiPublic = {
196
199
  resize,
197
200
  getRootDimensions
@@ -14,6 +14,7 @@ import { isPrintableKey, isPasteShortcut } from "../../../utils/keyboardUtils.js
14
14
  import { gridRowsDataRowIdToIdLookupSelector } from "../rows/gridRowsSelector.js";
15
15
  import { deepClone } from "../../../utils/utils.js";
16
16
  import { GridCellEditStartReasons, GridCellEditStopReasons } from "../../../models/params/gridEditCellParams.js";
17
+ import { getDefaultCellValue } from "./utils.js";
17
18
  export const useGridCellEditing = (apiRef, props) => {
18
19
  const [cellModesModel, setCellModesModel] = React.useState({});
19
20
  const cellModesModelRef = React.useRef(cellModesModel);
@@ -249,24 +250,7 @@ export const useGridCellEditing = (apiRef, props) => {
249
250
  } = params;
250
251
  let newValue = apiRef.current.getCellValue(id, field);
251
252
  if (deleteValue) {
252
- const fieldType = apiRef.current.getColumn(field).type;
253
- switch (fieldType) {
254
- case 'boolean':
255
- newValue = false;
256
- break;
257
- case 'date':
258
- case 'dateTime':
259
- case 'number':
260
- newValue = undefined;
261
- break;
262
- case 'singleSelect':
263
- newValue = null;
264
- break;
265
- case 'string':
266
- default:
267
- newValue = '';
268
- break;
269
- }
253
+ newValue = getDefaultCellValue(apiRef.current.getColumn(field));
270
254
  } else if (initialValue) {
271
255
  newValue = initialValue;
272
256
  }
@@ -16,6 +16,7 @@ import { gridRowsDataRowIdToIdLookupSelector } from "../rows/gridRowsSelector.js
16
16
  import { deepClone } from "../../../utils/utils.js";
17
17
  import { GridRowEditStopReasons, GridRowEditStartReasons } from "../../../models/params/gridRowParams.js";
18
18
  import { GRID_ACTIONS_COLUMN_TYPE } from "../../../colDef/index.js";
19
+ import { getDefaultCellValue } from "./utils.js";
19
20
  export const useGridRowEditing = (apiRef, props) => {
20
21
  const [rowModesModel, setRowModesModel] = React.useState({});
21
22
  const rowModesModelRef = React.useRef(rowModesModel);
@@ -319,7 +320,11 @@ export const useGridRowEditing = (apiRef, props) => {
319
320
  }
320
321
  let newValue = apiRef.current.getCellValue(id, field);
321
322
  if (fieldToFocus === field && (deleteValue || initialValue)) {
322
- newValue = deleteValue ? '' : initialValue;
323
+ if (deleteValue) {
324
+ newValue = getDefaultCellValue(apiRef.current.getColumn(field));
325
+ } else if (initialValue) {
326
+ newValue = initialValue;
327
+ }
323
328
  }
324
329
  acc[field] = {
325
330
  value: newValue,
@@ -0,0 +1,2 @@
1
+ import { GridColDef } from '../../../models/colDef/gridColDef';
2
+ export declare const getDefaultCellValue: (colDef: GridColDef) => false | "" | null | undefined;
@@ -0,0 +1,15 @@
1
+ export const getDefaultCellValue = colDef => {
2
+ switch (colDef.type) {
3
+ case 'boolean':
4
+ return false;
5
+ case 'date':
6
+ case 'dateTime':
7
+ case 'number':
8
+ return undefined;
9
+ case 'singleSelect':
10
+ return null;
11
+ case 'string':
12
+ default:
13
+ return '';
14
+ }
15
+ };
@@ -38,6 +38,7 @@ function buildPrintWindow(title) {
38
38
  * @requires useGridParamsApi (method)
39
39
  */
40
40
  export const useGridPrintExport = (apiRef, props) => {
41
+ const hasRootReference = apiRef.current.rootElementRef.current !== null;
41
42
  const logger = useGridLogger(apiRef, 'useGridPrintExport');
42
43
  const doc = React.useRef(null);
43
44
  const previousGridState = React.useRef(null);
@@ -46,7 +47,7 @@ export const useGridPrintExport = (apiRef, props) => {
46
47
  const previousVirtualizationState = React.useRef();
47
48
  React.useEffect(() => {
48
49
  doc.current = ownerDocument(apiRef.current.rootElementRef.current);
49
- }, [apiRef]);
50
+ }, [apiRef, hasRootReference]);
50
51
 
51
52
  // Returns a promise because updateColumns triggers state update and
52
53
  // the new state needs to be in place before the grid can be sized correctly
@@ -34,6 +34,7 @@ export const focusStateInitializer = state => _extends({}, state, {
34
34
  export const useGridFocus = (apiRef, props) => {
35
35
  const logger = useGridLogger(apiRef, 'useGridFocus');
36
36
  const lastClickedCell = React.useRef(null);
37
+ const hasRootReference = apiRef.current.rootElementRef.current !== null;
37
38
  const publishCellFocusOut = React.useCallback((cell, event) => {
38
39
  if (cell) {
39
40
  // The row might have been deleted
@@ -380,7 +381,7 @@ export const useGridFocus = (apiRef, props) => {
380
381
  return () => {
381
382
  doc.removeEventListener('mouseup', handleDocumentClick);
382
383
  };
383
- }, [apiRef, handleDocumentClick]);
384
+ }, [apiRef, hasRootReference, handleDocumentClick]);
384
385
  useGridApiEventHandler(apiRef, 'columnHeaderBlur', handleBlur);
385
386
  useGridApiEventHandler(apiRef, 'cellDoubleClick', handleCellDoubleClick);
386
387
  useGridApiEventHandler(apiRef, 'cellMouseDown', handleCellMouseDown);