@mui/x-data-grid 7.24.1 → 7.26.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 (188) hide show
  1. package/CHANGELOG.md +148 -0
  2. package/DataGrid/DataGrid.js +1 -7
  3. package/DataGrid/useDataGridComponent.js +2 -2
  4. package/components/GridRow.d.ts +0 -1
  5. package/components/GridRow.js +32 -20
  6. package/components/GridScrollArea.d.ts +5 -2
  7. package/components/GridScrollArea.js +32 -25
  8. package/components/GridSkeletonLoadingOverlay.js +2 -1
  9. package/components/cell/GridCell.d.ts +9 -6
  10. package/components/cell/GridCell.js +29 -52
  11. package/components/containers/GridRoot.js +11 -9
  12. package/components/containers/GridRootStyles.js +138 -40
  13. package/components/toolbar/GridToolbarColumnsButton.js +5 -4
  14. package/components/toolbar/GridToolbarDensitySelector.js +2 -2
  15. package/components/toolbar/GridToolbarExportContainer.js +2 -2
  16. package/components/toolbar/GridToolbarFilterButton.js +4 -3
  17. package/components/virtualization/GridMainContainer.d.ts +10 -0
  18. package/components/virtualization/GridMainContainer.js +10 -2
  19. package/components/virtualization/GridVirtualScrollbar.d.ts +4 -0
  20. package/components/virtualization/GridVirtualScrollbar.js +5 -5
  21. package/components/virtualization/GridVirtualScroller.js +36 -16
  22. package/components/virtualization/GridVirtualScrollerContent.js +11 -2
  23. package/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.d.ts +1 -1
  24. package/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +6 -4
  25. package/hooks/core/useGridStateInitialization.js +3 -2
  26. package/hooks/features/columnHeaders/useGridColumnHeaders.js +10 -14
  27. package/hooks/features/columnResize/useGridColumnResize.js +2 -1
  28. package/hooks/features/columns/gridColumnsSelector.d.ts +0 -5
  29. package/hooks/features/columns/gridColumnsSelector.js +0 -12
  30. package/hooks/features/columns/useGridColumns.js +7 -3
  31. package/hooks/features/dimensions/gridDimensionsSelectors.d.ts +16 -0
  32. package/hooks/features/dimensions/gridDimensionsSelectors.js +26 -1
  33. package/hooks/features/dimensions/index.d.ts +1 -1
  34. package/hooks/features/dimensions/index.js +1 -2
  35. package/hooks/features/dimensions/useGridDimensions.js +102 -77
  36. package/hooks/features/editing/gridEditingSelectors.d.ts +10 -0
  37. package/hooks/features/editing/gridEditingSelectors.js +12 -1
  38. package/hooks/features/editing/index.d.ts +1 -1
  39. package/hooks/features/editing/index.js +1 -1
  40. package/hooks/features/editing/useGridCellEditing.js +3 -3
  41. package/hooks/features/editing/useGridRowEditing.js +8 -9
  42. package/hooks/features/filter/gridFilterState.d.ts +5 -0
  43. package/hooks/features/filter/gridFilterState.js +5 -0
  44. package/hooks/features/filter/useGridFilter.js +6 -13
  45. package/hooks/features/focus/useGridFocus.js +3 -2
  46. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +24 -16
  47. package/hooks/features/keyboardNavigation/utils.d.ts +1 -2
  48. package/hooks/features/keyboardNavigation/utils.js +0 -5
  49. package/hooks/features/listView/useGridListView.js +2 -1
  50. package/hooks/features/pagination/useGridPagination.js +1 -1
  51. package/hooks/features/rowSelection/useGridRowSelection.js +4 -4
  52. package/hooks/features/rowSelection/utils.js +1 -1
  53. package/hooks/features/rows/gridRowsMetaState.d.ts +8 -0
  54. package/hooks/features/rows/gridRowsUtils.d.ts +0 -4
  55. package/hooks/features/rows/gridRowsUtils.js +0 -16
  56. package/hooks/features/rows/useGridParamsApi.d.ts +1 -1
  57. package/hooks/features/rows/useGridParamsApi.js +33 -14
  58. package/hooks/features/rows/useGridRowSpanning.js +94 -91
  59. package/hooks/features/rows/useGridRows.js +7 -8
  60. package/hooks/features/rows/useGridRowsMeta.js +36 -19
  61. package/hooks/features/sorting/gridSortingSelector.js +10 -9
  62. package/hooks/features/virtualization/gridFocusedVirtualCellSelector.js +2 -2
  63. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +15 -1
  64. package/hooks/features/virtualization/useGridVirtualScroller.js +74 -72
  65. package/hooks/utils/useGridSelector.d.ts +8 -1
  66. package/hooks/utils/useGridSelector.js +42 -8
  67. package/hooks/utils/useIsSSR.d.ts +1 -0
  68. package/hooks/utils/useIsSSR.js +5 -0
  69. package/index.js +1 -1
  70. package/internals/index.d.ts +2 -1
  71. package/internals/index.js +2 -1
  72. package/models/api/gridApiCommon.d.ts +2 -2
  73. package/models/api/gridParamsApi.d.ts +29 -2
  74. package/models/api/gridStateApi.d.ts +1 -0
  75. package/models/api/index.d.ts +1 -1
  76. package/models/api/index.js +0 -1
  77. package/models/events/gridEventLookup.d.ts +6 -0
  78. package/modern/DataGrid/DataGrid.js +1 -7
  79. package/modern/DataGrid/useDataGridComponent.js +2 -2
  80. package/modern/components/GridRow.js +32 -20
  81. package/modern/components/GridScrollArea.js +32 -25
  82. package/modern/components/GridSkeletonLoadingOverlay.js +2 -1
  83. package/modern/components/cell/GridCell.js +29 -52
  84. package/modern/components/containers/GridRoot.js +11 -9
  85. package/modern/components/containers/GridRootStyles.js +138 -40
  86. package/modern/components/toolbar/GridToolbarColumnsButton.js +5 -4
  87. package/modern/components/toolbar/GridToolbarDensitySelector.js +2 -2
  88. package/modern/components/toolbar/GridToolbarExportContainer.js +2 -2
  89. package/modern/components/toolbar/GridToolbarFilterButton.js +4 -3
  90. package/modern/components/virtualization/GridMainContainer.js +10 -2
  91. package/modern/components/virtualization/GridVirtualScrollbar.js +5 -5
  92. package/modern/components/virtualization/GridVirtualScroller.js +36 -16
  93. package/modern/components/virtualization/GridVirtualScrollerContent.js +11 -2
  94. package/modern/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +6 -4
  95. package/modern/hooks/core/useGridStateInitialization.js +3 -2
  96. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +10 -14
  97. package/modern/hooks/features/columnResize/useGridColumnResize.js +2 -1
  98. package/modern/hooks/features/columns/gridColumnsSelector.js +0 -12
  99. package/modern/hooks/features/columns/useGridColumns.js +7 -3
  100. package/modern/hooks/features/dimensions/gridDimensionsSelectors.js +26 -1
  101. package/modern/hooks/features/dimensions/index.js +1 -2
  102. package/modern/hooks/features/dimensions/useGridDimensions.js +102 -77
  103. package/modern/hooks/features/editing/gridEditingSelectors.js +12 -1
  104. package/modern/hooks/features/editing/index.js +1 -1
  105. package/modern/hooks/features/editing/useGridCellEditing.js +3 -3
  106. package/modern/hooks/features/editing/useGridRowEditing.js +8 -9
  107. package/modern/hooks/features/filter/gridFilterState.js +5 -0
  108. package/modern/hooks/features/filter/useGridFilter.js +6 -13
  109. package/modern/hooks/features/focus/useGridFocus.js +3 -2
  110. package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +24 -16
  111. package/modern/hooks/features/keyboardNavigation/utils.js +0 -5
  112. package/modern/hooks/features/listView/useGridListView.js +2 -1
  113. package/modern/hooks/features/pagination/useGridPagination.js +1 -1
  114. package/modern/hooks/features/rowSelection/useGridRowSelection.js +4 -4
  115. package/modern/hooks/features/rowSelection/utils.js +1 -1
  116. package/modern/hooks/features/rows/gridRowsUtils.js +0 -16
  117. package/modern/hooks/features/rows/useGridParamsApi.js +33 -14
  118. package/modern/hooks/features/rows/useGridRowSpanning.js +94 -91
  119. package/modern/hooks/features/rows/useGridRows.js +7 -8
  120. package/modern/hooks/features/rows/useGridRowsMeta.js +36 -19
  121. package/modern/hooks/features/sorting/gridSortingSelector.js +10 -9
  122. package/modern/hooks/features/virtualization/gridFocusedVirtualCellSelector.js +2 -2
  123. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +74 -72
  124. package/modern/hooks/utils/useGridSelector.js +42 -8
  125. package/modern/hooks/utils/useIsSSR.js +5 -0
  126. package/modern/index.js +1 -1
  127. package/modern/internals/index.js +2 -1
  128. package/modern/models/api/index.js +0 -1
  129. package/modern/utils/roundToDecimalPlaces.js +3 -0
  130. package/modern/utils/utils.js +6 -1
  131. package/node/DataGrid/DataGrid.js +1 -7
  132. package/node/DataGrid/useDataGridComponent.js +2 -2
  133. package/node/components/GridRow.js +28 -17
  134. package/node/components/GridScrollArea.js +31 -24
  135. package/node/components/GridSkeletonLoadingOverlay.js +2 -1
  136. package/node/components/cell/GridCell.js +27 -50
  137. package/node/components/containers/GridRoot.js +10 -8
  138. package/node/components/containers/GridRootStyles.js +138 -40
  139. package/node/components/toolbar/GridToolbarColumnsButton.js +5 -4
  140. package/node/components/toolbar/GridToolbarDensitySelector.js +2 -2
  141. package/node/components/toolbar/GridToolbarExportContainer.js +2 -2
  142. package/node/components/toolbar/GridToolbarFilterButton.js +4 -3
  143. package/node/components/virtualization/GridMainContainer.js +10 -2
  144. package/node/components/virtualization/GridVirtualScrollbar.js +5 -5
  145. package/node/components/virtualization/GridVirtualScroller.js +36 -16
  146. package/node/components/virtualization/GridVirtualScrollerContent.js +11 -2
  147. package/node/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +6 -4
  148. package/node/hooks/core/useGridStateInitialization.js +3 -2
  149. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +10 -14
  150. package/node/hooks/features/columnResize/useGridColumnResize.js +2 -1
  151. package/node/hooks/features/columns/gridColumnsSelector.js +1 -13
  152. package/node/hooks/features/columns/useGridColumns.js +7 -3
  153. package/node/hooks/features/dimensions/gridDimensionsSelectors.js +38 -2
  154. package/node/hooks/features/dimensions/index.js +13 -11
  155. package/node/hooks/features/dimensions/useGridDimensions.js +99 -74
  156. package/node/hooks/features/editing/gridEditingSelectors.js +12 -2
  157. package/node/hooks/features/editing/index.js +7 -11
  158. package/node/hooks/features/editing/useGridCellEditing.js +2 -2
  159. package/node/hooks/features/editing/useGridRowEditing.js +6 -7
  160. package/node/hooks/features/filter/gridFilterState.js +6 -1
  161. package/node/hooks/features/filter/useGridFilter.js +5 -12
  162. package/node/hooks/features/focus/useGridFocus.js +3 -2
  163. package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +24 -15
  164. package/node/hooks/features/keyboardNavigation/utils.js +0 -6
  165. package/node/hooks/features/listView/useGridListView.js +2 -1
  166. package/node/hooks/features/pagination/useGridPagination.js +1 -1
  167. package/node/hooks/features/rowSelection/useGridRowSelection.js +3 -3
  168. package/node/hooks/features/rowSelection/utils.js +1 -1
  169. package/node/hooks/features/rows/gridRowsUtils.js +0 -17
  170. package/node/hooks/features/rows/useGridParamsApi.js +33 -14
  171. package/node/hooks/features/rows/useGridRowSpanning.js +92 -89
  172. package/node/hooks/features/rows/useGridRows.js +7 -8
  173. package/node/hooks/features/rows/useGridRowsMeta.js +36 -19
  174. package/node/hooks/features/sorting/gridSortingSelector.js +10 -9
  175. package/node/hooks/features/virtualization/gridFocusedVirtualCellSelector.js +2 -2
  176. package/node/hooks/features/virtualization/useGridVirtualScroller.js +73 -71
  177. package/node/hooks/utils/useGridSelector.js +42 -8
  178. package/node/hooks/utils/useIsSSR.js +12 -0
  179. package/node/index.js +1 -1
  180. package/node/internals/index.js +20 -7
  181. package/node/models/api/index.js +0 -11
  182. package/node/utils/roundToDecimalPlaces.js +9 -0
  183. package/node/utils/utils.js +8 -1
  184. package/package.json +3 -2
  185. package/utils/roundToDecimalPlaces.d.ts +1 -0
  186. package/utils/roundToDecimalPlaces.js +3 -0
  187. package/utils/utils.d.ts +1 -0
  188. package/utils/utils.js +6 -1
@@ -7,7 +7,7 @@ import { useGridRootProps } from "../../utils/useGridRootProps.js";
7
7
  import { useGridPrivateApiContext } from "../../utils/useGridPrivateApiContext.js";
8
8
  import { useGridApiEventHandler } from "../../utils/useGridApiEventHandler.js";
9
9
  import { GridColumnHeaderItem } from "../../../components/columnHeaders/GridColumnHeaderItem.js";
10
- import { gridDimensionsSelector } from "../dimensions/index.js";
10
+ import { gridColumnsTotalWidthSelector, gridGroupHeaderHeightSelector, gridHasFillerSelector, gridHeaderHeightSelector, gridVerticalScrollbarWidthSelector } from "../dimensions/gridDimensionsSelectors.js";
11
11
  import { gridRenderContextColumnsSelector } from "../virtualization/index.js";
12
12
  import { computeOffsetLeft } from "../virtualization/useGridVirtualScroller.js";
13
13
  import { GridColumnGroupHeader } from "../../../components/columnHeaders/GridColumnGroupHeader.js";
@@ -46,19 +46,17 @@ export const useGridColumnHeaders = props => {
46
46
  const [resizeCol, setResizeCol] = React.useState('');
47
47
  const apiRef = useGridPrivateApiContext();
48
48
  const rootProps = useGridRootProps();
49
- const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
50
49
  const columnGroupsModel = useGridSelector(apiRef, gridColumnGroupsUnwrappedModelSelector);
51
50
  const columnPositions = useGridSelector(apiRef, gridColumnPositionsSelector);
52
51
  const renderContext = useGridSelector(apiRef, gridRenderContextColumnsSelector);
53
52
  const pinnedColumns = useGridSelector(apiRef, gridVisiblePinnedColumnDefinitionsSelector);
54
53
  const columnsLookup = useGridSelector(apiRef, gridColumnLookupSelector);
55
54
  const offsetLeft = computeOffsetLeft(columnPositions, renderContext, pinnedColumns.left.length);
56
- const gridHasFiller = dimensions.columnsTotalWidth < dimensions.viewportOuterSize.width;
57
- React.useEffect(() => {
58
- if (apiRef.current.columnHeadersContainerRef.current) {
59
- apiRef.current.columnHeadersContainerRef.current.scrollLeft = 0;
60
- }
61
- }, [apiRef]);
55
+ const columnsTotalWidth = useGridSelector(apiRef, gridColumnsTotalWidthSelector);
56
+ const gridHasFiller = useGridSelector(apiRef, gridHasFillerSelector);
57
+ const headerHeight = useGridSelector(apiRef, gridHeaderHeightSelector);
58
+ const groupHeaderHeight = useGridSelector(apiRef, gridGroupHeaderHeightSelector);
59
+ const scrollbarWidth = useGridSelector(apiRef, gridVerticalScrollbarWidthSelector);
62
60
  const handleColumnResizeStart = React.useCallback(params => setResizeCol(params.field), []);
63
61
  const handleColumnResizeStop = React.useCallback(() => setResizeCol(''), []);
64
62
  const handleColumnReorderStart = React.useCallback(params => setDragCol(params.field), []);
@@ -130,8 +128,7 @@ export const useGridColumnHeaders = props => {
130
128
  const hasFocus = columnHeaderFocus !== null && columnHeaderFocus.field === colDef.field;
131
129
  const open = columnMenuState.open && columnMenuState.field === colDef.field;
132
130
  const pinnedPosition = params?.position;
133
- const scrollbarWidth = dimensions.hasScrollY ? dimensions.scrollbarSize : 0;
134
- const pinnedOffset = getPinnedCellOffset(pinnedPosition, colDef.computedWidth, columnIndex, columnPositions, dimensions.columnsTotalWidth, scrollbarWidth);
131
+ const pinnedOffset = getPinnedCellOffset(pinnedPosition, colDef.computedWidth, columnIndex, columnPositions, columnsTotalWidth, scrollbarWidth);
135
132
  const siblingWithBorderingSeparator = pinnedPosition === PinnedColumnPosition.RIGHT ? renderedColumns[i - 1] : renderedColumns[i + 1];
136
133
  const isSiblingFocused = siblingWithBorderingSeparator ? columnHeaderFocus !== null && columnHeaderFocus.field === siblingWithBorderingSeparator.field : false;
137
134
  const isLastUnpinned = columnIndex + 1 === columnPositions.length - pinnedColumns.right.length;
@@ -142,7 +139,7 @@ export const useGridColumnHeaders = props => {
142
139
  columns.push(/*#__PURE__*/_jsx(GridColumnHeaderItem, _extends({}, sortColumnLookup[colDef.field], {
143
140
  columnMenuOpen: open,
144
141
  filterItemsCounter: filterColumnLookup[colDef.field] && filterColumnLookup[colDef.field].length,
145
- headerHeight: dimensions.headerHeight,
142
+ headerHeight: headerHeight,
146
143
  isDragging: colDef.field === dragCol,
147
144
  colDef: colDef,
148
145
  colIndex: columnIndex,
@@ -234,8 +231,7 @@ export const useGridColumnHeaders = props => {
234
231
  tabIndex
235
232
  };
236
233
  const pinnedPosition = params.position;
237
- const scrollbarWidth = dimensions.hasScrollY ? dimensions.scrollbarSize : 0;
238
- const pinnedOffset = getPinnedCellOffset(pinnedPosition, headerInfo.width, columnIndex, columnPositions, dimensions.columnsTotalWidth, scrollbarWidth);
234
+ const pinnedOffset = getPinnedCellOffset(pinnedPosition, headerInfo.width, columnIndex, columnPositions, columnsTotalWidth, scrollbarWidth);
239
235
  columnIndex += columnFields.length;
240
236
  let indexInSection = index;
241
237
  if (pinnedPosition === PinnedColumnPosition.LEFT) {
@@ -250,7 +246,7 @@ export const useGridColumnHeaders = props => {
250
246
  depth: depth,
251
247
  isLastColumn: index === visibleColumnGroupHeader.length - 1,
252
248
  maxDepth: headerGroupingMaxDepth,
253
- height: dimensions.groupHeaderHeight,
249
+ height: groupHeaderHeight,
254
250
  hasFocus: hasFocus,
255
251
  tabIndex: tabIndex,
256
252
  pinnedPosition: pinnedPosition,
@@ -500,7 +500,8 @@ export const useGridColumnResize = (apiRef, props) => {
500
500
  if (options.expand) {
501
501
  const visibleColumns = state.orderedFields.map(field => state.lookup[field]).filter(c => state.columnVisibilityModel[c.field] !== false);
502
502
  const totalWidth = visibleColumns.reduce((total, column) => total + (widthByField[column.field] ?? column.computedWidth ?? column.width), 0);
503
- const availableWidth = apiRef.current.getRootDimensions().viewportInnerSize.width;
503
+ const dimensions = apiRef.current.getRootDimensions();
504
+ const availableWidth = dimensions.viewportInnerSize.width;
504
505
  const remainingWidth = availableWidth - totalWidth;
505
506
  if (remainingWidth > 0) {
506
507
  const widthPerColumn = remainingWidth / (newColumns.length || 1);
@@ -107,18 +107,6 @@ export const gridColumnPositionsSelector = createSelectorMemoized(gridVisibleCol
107
107
  return positions;
108
108
  });
109
109
 
110
- /**
111
- * Get the summed width of all the visible columns.
112
- * @category Visible Columns
113
- */
114
- export const gridColumnsTotalWidthSelector = createSelector(gridVisibleColumnDefinitionsSelector, gridColumnPositionsSelector, (visibleColumns, positions) => {
115
- const colCount = visibleColumns.length;
116
- if (colCount === 0) {
117
- return 0;
118
- }
119
- return positions[colCount - 1] + visibleColumns[colCount - 1].computedWidth;
120
- });
121
-
122
110
  /**
123
111
  * Get the filterable columns as an array.
124
112
  * @category Columns
@@ -242,9 +242,13 @@ export function useGridColumns(apiRef, props) {
242
242
  */
243
243
 
244
244
  const prevInnerWidth = React.useRef(null);
245
- const handleGridSizeChange = viewportInnerSize => {
246
- if (prevInnerWidth.current !== viewportInnerSize.width) {
247
- prevInnerWidth.current = viewportInnerSize.width;
245
+ const handleGridSizeChange = size => {
246
+ if (prevInnerWidth.current !== size.width) {
247
+ prevInnerWidth.current = size.width;
248
+ const hasFlexColumns = gridVisibleColumnDefinitionsSelector(apiRef).some(col => col.flex && col.flex > 0);
249
+ if (!hasFlexColumns) {
250
+ return;
251
+ }
248
252
  setGridColumnsState(hydrateColumnsWidth(gridColumnsStateSelector(apiRef.current.state), apiRef.current.getRootDimensions()));
249
253
  }
250
254
  };
@@ -1 +1,26 @@
1
- export const gridDimensionsSelector = state => state.dimensions;
1
+ import { createSelector } from "../../../utils/createSelector.js";
2
+ export const gridDimensionsSelector = state => state.dimensions;
3
+
4
+ /**
5
+ * Get the summed width of all the visible columns.
6
+ * @category Visible Columns
7
+ */
8
+ export const gridColumnsTotalWidthSelector = createSelector(gridDimensionsSelector, dimensions => dimensions.columnsTotalWidth);
9
+ export const gridRowHeightSelector = state => state.dimensions.rowHeight;
10
+ export const gridContentHeightSelector = state => state.dimensions.contentSize.height;
11
+ export const gridHasScrollXSelector = state => state.dimensions.hasScrollX;
12
+ export const gridHasScrollYSelector = state => state.dimensions.hasScrollY;
13
+ export const gridHasFillerSelector = state => state.dimensions.columnsTotalWidth < state.dimensions.viewportOuterSize.width;
14
+ export const gridHeaderHeightSelector = state => state.dimensions.headerHeight;
15
+ export const gridGroupHeaderHeightSelector = state => state.dimensions.groupHeaderHeight;
16
+ export const gridHeaderFilterHeightSelector = state => state.dimensions.headerFilterHeight;
17
+ export const gridVerticalScrollbarWidthSelector = state => state.dimensions.hasScrollY ? state.dimensions.scrollbarSize : 0;
18
+ export const gridHorizontalScrollbarHeightSelector = state => state.dimensions.hasScrollX ? state.dimensions.scrollbarSize : 0;
19
+ export const gridHasBottomFillerSelector = state => {
20
+ const height = state.dimensions.hasScrollX ? state.dimensions.scrollbarSize : 0;
21
+ const needsLastRowBorder = state.dimensions.viewportOuterSize.height - state.dimensions.minimumSize.height > 0;
22
+ if (height === 0 && !needsLastRowBorder) {
23
+ return false;
24
+ }
25
+ return true;
26
+ };
@@ -1,2 +1 @@
1
- export * from "./gridDimensionsSelectors.js";
2
- export {};
1
+ export { gridDimensionsSelector, gridColumnsTotalWidthSelector } from "./gridDimensionsSelectors.js";
@@ -2,20 +2,23 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { unstable_ownerDocument as ownerDocument, unstable_useEnhancedEffect as useEnhancedEffect, unstable_useEventCallback as useEventCallback, unstable_ownerWindow as ownerWindow } from '@mui/utils';
4
4
  import { throttle } from '@mui/x-internals/throttle';
5
- import { useGridApiEventHandler, useGridApiOptionHandler } from "../../utils/useGridApiEventHandler.js";
5
+ import { useGridApiOptionHandler } from "../../utils/useGridApiEventHandler.js";
6
6
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
7
+ import { createSelector } from "../../../utils/createSelector.js";
7
8
  import { useGridLogger } from "../../utils/useGridLogger.js";
8
- import { gridColumnsTotalWidthSelector, gridVisiblePinnedColumnDefinitionsSelector } from "../columns/index.js";
9
+ import { gridColumnPositionsSelector, gridVisibleColumnDefinitionsSelector, gridVisiblePinnedColumnDefinitionsSelector } from "../columns/index.js";
9
10
  import { gridDimensionsSelector } from "./gridDimensionsSelectors.js";
10
11
  import { gridDensityFactorSelector } from "../density/index.js";
11
12
  import { gridRenderContextSelector } from "../virtualization/index.js";
12
13
  import { useGridSelector } from "../../utils/index.js";
13
14
  import { getVisibleRows } from "../../utils/useGridVisibleRows.js";
14
15
  import { gridRowsMetaSelector } from "../rows/gridRowsMetaSelector.js";
15
- import { calculatePinnedRowsHeight, getValidRowHeight, rowHeightWarning } from "../rows/gridRowsUtils.js";
16
+ import { getValidRowHeight, rowHeightWarning } from "../rows/gridRowsUtils.js";
16
17
  import { getTotalHeaderHeight } from "../columns/gridColumnsUtils.js";
17
18
  import { DATA_GRID_PROPS_DEFAULT_VALUES } from "../../../constants/dataGridPropsDefaultValues.js";
19
+ import { roundToDecimalPlaces } from "../../../utils/roundToDecimalPlaces.js";
18
20
  import { isJSDOM } from "../../../utils/isJSDOM.js";
21
+ import { isDeepEqual } from "../../../utils/utils.js";
19
22
  const EMPTY_SIZE = {
20
23
  width: 0,
21
24
  height: 0
@@ -42,39 +45,47 @@ const EMPTY_DIMENSIONS = {
42
45
  topContainerHeight: 0,
43
46
  bottomContainerHeight: 0
44
47
  };
45
- export const dimensionsStateInitializer = state => {
48
+ export const dimensionsStateInitializer = (state, props, apiRef) => {
46
49
  const dimensions = EMPTY_DIMENSIONS;
50
+ const density = gridDensityFactorSelector(apiRef);
47
51
  return _extends({}, state, {
48
- dimensions
52
+ dimensions: _extends({}, dimensions, getStaticDimensions(props, apiRef, density, gridVisiblePinnedColumnDefinitionsSelector(apiRef)))
49
53
  });
50
54
  };
55
+ const columnsTotalWidthSelector = createSelector(gridVisibleColumnDefinitionsSelector, gridColumnPositionsSelector, (visibleColumns, positions) => {
56
+ const colCount = visibleColumns.length;
57
+ if (colCount === 0) {
58
+ return 0;
59
+ }
60
+ return roundToDecimalPlaces(positions[colCount - 1] + visibleColumns[colCount - 1].computedWidth, 1);
61
+ });
51
62
  export function useGridDimensions(apiRef, props) {
52
63
  const logger = useGridLogger(apiRef, 'useResizeContainer');
53
64
  const errorShown = React.useRef(false);
54
65
  const rootDimensionsRef = React.useRef(EMPTY_SIZE);
55
- const dimensionsState = useGridSelector(apiRef, gridDimensionsSelector);
56
- const rowsMeta = useGridSelector(apiRef, gridRowsMetaSelector);
57
66
  const pinnedColumns = useGridSelector(apiRef, gridVisiblePinnedColumnDefinitionsSelector);
58
67
  const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
59
- const validRowHeight = React.useMemo(() => getValidRowHeight(props.rowHeight, DATA_GRID_PROPS_DEFAULT_VALUES.rowHeight, rowHeightWarning), [props.rowHeight]);
60
- const rowHeight = Math.floor(validRowHeight * densityFactor);
61
- const headerHeight = Math.floor(props.columnHeaderHeight * densityFactor);
62
- const groupHeaderHeight = Math.floor((props.columnGroupHeaderHeight ?? props.columnHeaderHeight) * densityFactor);
63
- const headerFilterHeight = Math.floor((props.headerFilterHeight ?? props.columnHeaderHeight) * densityFactor);
64
- const columnsTotalWidth = roundToDecimalPlaces(gridColumnsTotalWidthSelector(apiRef), 6);
65
- const headersTotalHeight = getTotalHeaderHeight(apiRef, props);
66
- const leftPinnedWidth = pinnedColumns.left.reduce((w, col) => w + col.computedWidth, 0);
67
- const rightPinnedWidth = pinnedColumns.right.reduce((w, col) => w + col.computedWidth, 0);
68
- const [savedSize, setSavedSize] = React.useState();
69
- const debouncedSetSavedSize = React.useMemo(() => throttle(setSavedSize, props.resizeThrottleMs), [props.resizeThrottleMs]);
70
- React.useEffect(() => debouncedSetSavedSize.clear, [debouncedSetSavedSize]);
68
+ const columnsTotalWidth = useGridSelector(apiRef, columnsTotalWidthSelector);
69
+ const isFirstSizing = React.useRef(true);
70
+ const {
71
+ rowHeight,
72
+ headerHeight,
73
+ groupHeaderHeight,
74
+ headerFilterHeight,
75
+ headersTotalHeight,
76
+ leftPinnedWidth,
77
+ rightPinnedWidth
78
+ } = getStaticDimensions(props, apiRef, densityFactor, pinnedColumns);
71
79
  const previousSize = React.useRef(undefined);
72
- const getRootDimensions = () => apiRef.current.state.dimensions;
73
- const setDimensions = useEventCallback(dimensions => {
80
+ const getRootDimensions = React.useCallback(() => gridDimensionsSelector(apiRef.current.state), [apiRef]);
81
+ const setDimensions = React.useCallback(dimensions => {
74
82
  apiRef.current.setState(state => _extends({}, state, {
75
83
  dimensions
76
84
  }));
77
- });
85
+ if (apiRef.current.rootElementRef.current) {
86
+ setCSSVariables(apiRef.current.rootElementRef.current, gridDimensionsSelector(apiRef.current.state));
87
+ }
88
+ }, [apiRef]);
78
89
  const resize = React.useCallback(() => {
79
90
  const element = apiRef.current.mainElementRef.current;
80
91
  if (!element) {
@@ -95,10 +106,7 @@ export function useGridDimensions(apiRef, props) {
95
106
  if (!dimensions.isReady) {
96
107
  return 0;
97
108
  }
98
- const currentPage = getVisibleRows(apiRef, {
99
- pagination: props.pagination,
100
- paginationMode: props.paginationMode
101
- });
109
+ const currentPage = getVisibleRows(apiRef);
102
110
 
103
111
  // TODO: Use a combination of scrollTop, dimensions.viewportInnerSize.height and rowsMeta.possitions
104
112
  // to find out the maximum number of rows that can fit in the visible part of the grid
@@ -109,17 +117,23 @@ export function useGridDimensions(apiRef, props) {
109
117
  }
110
118
  const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
111
119
  return Math.min(maximumPageSizeWithoutScrollBar, currentPage.rows.length);
112
- }, [apiRef, props.pagination, props.paginationMode, props.getRowHeight, rowHeight]);
120
+ }, [apiRef, props.getRowHeight, rowHeight]);
113
121
  const updateDimensions = React.useCallback(() => {
122
+ if (isFirstSizing.current) {
123
+ return;
124
+ }
125
+ // All the floating point dimensions should be rounded to .1 decimal places to avoid subpixel rendering issues
126
+ // https://github.com/mui/mui-x/issues/9550#issuecomment-1619020477
127
+ // https://github.com/mui/mui-x/issues/15721
114
128
  const rootElement = apiRef.current.rootElementRef.current;
115
- const pinnedRowsHeight = calculatePinnedRowsHeight(apiRef);
116
- const scrollbarSize = measureScrollbarSize(rootElement, columnsTotalWidth, props.scrollbarSize);
117
- const topContainerHeight = headersTotalHeight + pinnedRowsHeight.top;
118
- const bottomContainerHeight = pinnedRowsHeight.bottom;
129
+ const scrollbarSize = measureScrollbarSize(rootElement, props.scrollbarSize);
130
+ const rowsMeta = gridRowsMetaSelector(apiRef.current.state);
131
+ const topContainerHeight = headersTotalHeight + rowsMeta.pinnedTopRowsTotalHeight;
132
+ const bottomContainerHeight = rowsMeta.pinnedBottomRowsTotalHeight;
119
133
  const nonPinnedColumnsTotalWidth = columnsTotalWidth - leftPinnedWidth - rightPinnedWidth;
120
134
  const contentSize = {
121
135
  width: nonPinnedColumnsTotalWidth,
122
- height: rowsMeta.currentPageTotalHeight
136
+ height: roundToDecimalPlaces(rowsMeta.currentPageTotalHeight, 1)
123
137
  };
124
138
  let viewportOuterSize;
125
139
  let viewportInnerSize;
@@ -193,12 +207,21 @@ export function useGridDimensions(apiRef, props) {
193
207
  bottomContainerHeight
194
208
  };
195
209
  const prevDimensions = apiRef.current.state.dimensions;
210
+ if (isDeepEqual(prevDimensions, newDimensions)) {
211
+ return;
212
+ }
196
213
  setDimensions(newDimensions);
197
214
  if (!areElementSizesEqual(newDimensions.viewportInnerSize, prevDimensions.viewportInnerSize)) {
198
215
  apiRef.current.publishEvent('viewportInnerSizeChange', newDimensions.viewportInnerSize);
199
216
  }
200
217
  apiRef.current.updateRenderContext?.();
201
- }, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, rowHeight, headerHeight, groupHeaderHeight, headerFilterHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
218
+ }, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowHeight, headerHeight, groupHeaderHeight, headerFilterHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
219
+ const updateDimensionCallback = useEventCallback(updateDimensions);
220
+ const debouncedUpdateDimensions = React.useMemo(() => props.resizeThrottleMs > 0 ? throttle(() => {
221
+ updateDimensionCallback();
222
+ apiRef.current.publishEvent('debouncedResize', rootDimensionsRef.current);
223
+ }, props.resizeThrottleMs) : undefined, [apiRef, props.resizeThrottleMs, updateDimensionCallback]);
224
+ React.useEffect(() => debouncedUpdateDimensions?.clear, [debouncedUpdateDimensions]);
202
225
  const apiPublic = {
203
226
  resize,
204
227
  getRootDimensions
@@ -207,35 +230,12 @@ export function useGridDimensions(apiRef, props) {
207
230
  updateDimensions,
208
231
  getViewportPageSize
209
232
  };
233
+ useEnhancedEffect(updateDimensions, [updateDimensions]);
210
234
  useGridApiMethod(apiRef, apiPublic, 'public');
211
235
  useGridApiMethod(apiRef, apiPrivate, 'private');
212
- useEnhancedEffect(() => {
213
- if (savedSize) {
214
- updateDimensions();
215
- apiRef.current.publishEvent('debouncedResize', rootDimensionsRef.current);
216
- }
217
- }, [apiRef, savedSize, updateDimensions]);
218
- const root = apiRef.current.rootElementRef.current;
219
- useEnhancedEffect(() => {
220
- if (!root) {
221
- return;
222
- }
223
- const set = (k, v) => root.style.setProperty(k, v);
224
- set('--DataGrid-width', `${dimensionsState.viewportOuterSize.width}px`);
225
- set('--DataGrid-hasScrollX', `${Number(dimensionsState.hasScrollX)}`);
226
- set('--DataGrid-hasScrollY', `${Number(dimensionsState.hasScrollY)}`);
227
- set('--DataGrid-scrollbarSize', `${dimensionsState.scrollbarSize}px`);
228
- set('--DataGrid-rowWidth', `${dimensionsState.rowWidth}px`);
229
- set('--DataGrid-columnsTotalWidth', `${dimensionsState.columnsTotalWidth}px`);
230
- set('--DataGrid-leftPinnedWidth', `${dimensionsState.leftPinnedWidth}px`);
231
- set('--DataGrid-rightPinnedWidth', `${dimensionsState.rightPinnedWidth}px`);
232
- set('--DataGrid-headerHeight', `${dimensionsState.headerHeight}px`);
233
- set('--DataGrid-headersTotalHeight', `${dimensionsState.headersTotalHeight}px`);
234
- set('--DataGrid-topContainerHeight', `${dimensionsState.topContainerHeight}px`);
235
- set('--DataGrid-bottomContainerHeight', `${dimensionsState.bottomContainerHeight}px`);
236
- set('--height', `${dimensionsState.rowHeight}px`);
237
- }, [root, dimensionsState]);
238
- const isFirstSizing = React.useRef(true);
236
+ const handleRootMount = React.useCallback(root => {
237
+ setCSSVariables(root, gridDimensionsSelector(apiRef.current.state));
238
+ }, [apiRef]);
239
239
  const handleResize = React.useCallback(size => {
240
240
  rootDimensionsRef.current = size;
241
241
  if (size.height === 0 && !errorShown.current && !props.autoHeight && !isJSDOM) {
@@ -246,28 +246,58 @@ export function useGridDimensions(apiRef, props) {
246
246
  logger.error(['The parent DOM element of the Data Grid has an empty width.', 'Please make sure that this element has an intrinsic width.', 'The grid displays with a width of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
247
247
  errorShown.current = true;
248
248
  }
249
- if (isFirstSizing.current) {
249
+ if (isFirstSizing.current || !debouncedUpdateDimensions) {
250
250
  // We want to initialize the grid dimensions as soon as possible to avoid flickering
251
- setSavedSize(size);
252
251
  isFirstSizing.current = false;
252
+ updateDimensions();
253
253
  return;
254
254
  }
255
- debouncedSetSavedSize(size);
256
- }, [props.autoHeight, debouncedSetSavedSize, logger]);
257
- useEnhancedEffect(updateDimensions, [updateDimensions]);
258
- useGridApiOptionHandler(apiRef, 'sortedRowsSet', updateDimensions);
259
- useGridApiOptionHandler(apiRef, 'paginationModelChange', updateDimensions);
260
- useGridApiOptionHandler(apiRef, 'columnsChange', updateDimensions);
261
- useGridApiEventHandler(apiRef, 'resize', handleResize);
255
+ debouncedUpdateDimensions();
256
+ }, [updateDimensions, props.autoHeight, debouncedUpdateDimensions, logger]);
257
+ useGridApiOptionHandler(apiRef, 'rootMount', handleRootMount);
258
+ useGridApiOptionHandler(apiRef, 'resize', handleResize);
262
259
  useGridApiOptionHandler(apiRef, 'debouncedResize', props.onResize);
263
260
  }
264
- function measureScrollbarSize(rootElement, columnsTotalWidth, scrollbarSize) {
261
+ function setCSSVariables(root, dimensions) {
262
+ const set = (k, v) => root.style.setProperty(k, v);
263
+ set('--DataGrid-hasScrollX', `${Number(dimensions.hasScrollX)}`);
264
+ set('--DataGrid-hasScrollY', `${Number(dimensions.hasScrollY)}`);
265
+ set('--DataGrid-scrollbarSize', `${dimensions.scrollbarSize}px`);
266
+ set('--DataGrid-rowWidth', `${dimensions.rowWidth}px`);
267
+ set('--DataGrid-columnsTotalWidth', `${dimensions.columnsTotalWidth}px`);
268
+ set('--DataGrid-leftPinnedWidth', `${dimensions.leftPinnedWidth}px`);
269
+ set('--DataGrid-rightPinnedWidth', `${dimensions.rightPinnedWidth}px`);
270
+ set('--DataGrid-headerHeight', `${dimensions.headerHeight}px`);
271
+ set('--DataGrid-headersTotalHeight', `${dimensions.headersTotalHeight}px`);
272
+ set('--DataGrid-topContainerHeight', `${dimensions.topContainerHeight}px`);
273
+ set('--DataGrid-bottomContainerHeight', `${dimensions.bottomContainerHeight}px`);
274
+ set('--height', `${dimensions.rowHeight}px`);
275
+ }
276
+ function getStaticDimensions(props, apiRef, density, pinnedColumnns) {
277
+ const validRowHeight = getValidRowHeight(props.rowHeight, DATA_GRID_PROPS_DEFAULT_VALUES.rowHeight, rowHeightWarning);
278
+ return {
279
+ rowHeight: Math.floor(validRowHeight * density),
280
+ headerHeight: Math.floor(props.columnHeaderHeight * density),
281
+ groupHeaderHeight: Math.floor((props.columnGroupHeaderHeight ?? props.columnHeaderHeight) * density),
282
+ headerFilterHeight: Math.floor((props.headerFilterHeight ?? props.columnHeaderHeight) * density),
283
+ columnsTotalWidth: columnsTotalWidthSelector(apiRef),
284
+ headersTotalHeight: getTotalHeaderHeight(apiRef, props),
285
+ leftPinnedWidth: pinnedColumnns.left.reduce((w, col) => w + col.computedWidth, 0),
286
+ rightPinnedWidth: pinnedColumnns.right.reduce((w, col) => w + col.computedWidth, 0)
287
+ };
288
+ }
289
+ const scrollbarSizeCache = new WeakMap();
290
+ function measureScrollbarSize(rootElement, scrollbarSize) {
265
291
  if (scrollbarSize !== undefined) {
266
292
  return scrollbarSize;
267
293
  }
268
- if (rootElement === null || columnsTotalWidth === 0) {
294
+ if (rootElement === null) {
269
295
  return 0;
270
296
  }
297
+ const cachedSize = scrollbarSizeCache.get(rootElement);
298
+ if (cachedSize !== undefined) {
299
+ return cachedSize;
300
+ }
271
301
  const doc = ownerDocument(rootElement);
272
302
  const scrollDiv = doc.createElement('div');
273
303
  scrollDiv.style.width = '99px';
@@ -278,14 +308,9 @@ function measureScrollbarSize(rootElement, columnsTotalWidth, scrollbarSize) {
278
308
  rootElement.appendChild(scrollDiv);
279
309
  const size = scrollDiv.offsetWidth - scrollDiv.clientWidth;
280
310
  rootElement.removeChild(scrollDiv);
311
+ scrollbarSizeCache.set(rootElement, size);
281
312
  return size;
282
313
  }
283
-
284
- // Get rid of floating point imprecision errors
285
- // https://github.com/mui/mui-x/issues/9550#issuecomment-1619020477
286
- function roundToDecimalPlaces(value, decimals) {
287
- return Math.round(value * 10 ** decimals) / 10 ** decimals;
288
- }
289
314
  function areElementSizesEqual(a, b) {
290
315
  return a.width === b.width && a.height === b.height;
291
316
  }
@@ -1,4 +1,15 @@
1
+ import { createSelectorV8 } from "../../../utils/createSelector.js";
2
+ import { GridEditModes } from "../../../models/gridEditRowModel.js";
3
+
1
4
  /**
2
5
  * Select the row editing state.
3
6
  */
4
- export const gridEditRowsStateSelector = state => state.editRows;
7
+ export const gridEditRowsStateSelector = state => state.editRows;
8
+ export const gridRowIsEditingSelector = createSelectorV8(gridEditRowsStateSelector, (editRows, {
9
+ rowId,
10
+ editMode
11
+ }) => editMode === GridEditModes.Row && Boolean(editRows[rowId]));
12
+ export const gridEditCellStateSelector = createSelectorV8(gridEditRowsStateSelector, (editRows, {
13
+ rowId,
14
+ field
15
+ }) => editRows[rowId]?.[field] ?? null);
@@ -1 +1 @@
1
- export * from "./gridEditingSelectors.js";
1
+ export { gridEditRowsStateSelector } from "./gridEditingSelectors.js";
@@ -11,7 +11,7 @@ import { GridEditModes, GridCellModes } from "../../../models/gridEditRowModel.j
11
11
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
12
12
  import { gridEditRowsStateSelector } from "./gridEditingSelectors.js";
13
13
  import { isPrintableKey, isPasteShortcut } from "../../../utils/keyboardUtils.js";
14
- import { gridRowsDataRowIdToIdLookupSelector } from "../rows/gridRowsSelector.js";
14
+ import { gridRowsLookupSelector } from "../rows/gridRowsSelector.js";
15
15
  import { deepClone } from "../../../utils/utils.js";
16
16
  import { GridCellEditStartReasons, GridCellEditStopReasons } from "../../../models/params/gridEditCellParams.js";
17
17
  import { getDefaultCellValue } from "./utils.js";
@@ -442,7 +442,7 @@ export const useGridCellEditing = (apiRef, props) => {
442
442
 
443
443
  // Run this effect synchronously so that the keyboard event can impact the yet-to-be-rendered input.
444
444
  useEnhancedEffect(() => {
445
- const idToIdLookup = gridRowsDataRowIdToIdLookupSelector(apiRef);
445
+ const rowsLookup = gridRowsLookupSelector(apiRef);
446
446
 
447
447
  // Update the ref here because updateStateToStopCellEditMode may change it later
448
448
  const copyOfPrevCellModes = prevCellModesModel.current;
@@ -451,7 +451,7 @@ export const useGridCellEditing = (apiRef, props) => {
451
451
  Object.entries(cellModesModel).forEach(([id, fields]) => {
452
452
  Object.entries(fields).forEach(([field, params]) => {
453
453
  const prevMode = copyOfPrevCellModes[id]?.[field]?.mode || GridCellModes.View;
454
- const originalId = idToIdLookup[id] ?? id;
454
+ const originalId = rowsLookup[id] ? apiRef.current.getRowId(rowsLookup[id]) : id;
455
455
  if (params.mode === GridCellModes.Edit && prevMode === GridCellModes.View) {
456
456
  updateStateToStartCellEditMode(_extends({
457
457
  id: originalId,
@@ -9,10 +9,10 @@ import { warnOnce } from '@mui/x-internals/warning';
9
9
  import { useGridApiEventHandler, useGridApiOptionHandler } from "../../utils/useGridApiEventHandler.js";
10
10
  import { GridEditModes, GridRowModes } from "../../../models/gridEditRowModel.js";
11
11
  import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
12
- import { gridEditRowsStateSelector } from "./gridEditingSelectors.js";
12
+ import { gridEditRowsStateSelector, gridRowIsEditingSelector } from "./gridEditingSelectors.js";
13
13
  import { isPrintableKey, isPasteShortcut } from "../../../utils/keyboardUtils.js";
14
14
  import { gridColumnFieldsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
15
- import { gridRowsDataRowIdToIdLookupSelector } from "../rows/gridRowsSelector.js";
15
+ import { gridRowsLookupSelector } 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";
@@ -232,11 +232,10 @@ export const useGridRowEditing = (apiRef, props) => {
232
232
  useGridApiOptionHandler(apiRef, 'rowEditStart', props.onRowEditStart);
233
233
  useGridApiOptionHandler(apiRef, 'rowEditStop', props.onRowEditStop);
234
234
  const getRowMode = React.useCallback(id => {
235
- if (props.editMode === GridEditModes.Cell) {
236
- return GridRowModes.View;
237
- }
238
- const editingState = gridEditRowsStateSelector(apiRef.current.state);
239
- const isEditing = editingState[id] && Object.keys(editingState[id]).length > 0;
235
+ const isEditing = gridRowIsEditingSelector(apiRef, {
236
+ rowId: id,
237
+ editMode: props.editMode
238
+ });
240
239
  return isEditing ? GridRowModes.Edit : GridRowModes.View;
241
240
  }, [apiRef, props.editMode]);
242
241
  const updateRowModesModel = useEventCallback(newModel => {
@@ -571,7 +570,7 @@ export const useGridRowEditing = (apiRef, props) => {
571
570
 
572
571
  // Run this effect synchronously so that the keyboard event can impact the yet-to-be-rendered input.
573
572
  useEnhancedEffect(() => {
574
- const idToIdLookup = gridRowsDataRowIdToIdLookupSelector(apiRef);
573
+ const rowsLookup = gridRowsLookupSelector(apiRef);
575
574
 
576
575
  // Update the ref here because updateStateToStopRowEditMode may change it later
577
576
  const copyOfPrevRowModesModel = prevRowModesModel.current;
@@ -583,7 +582,7 @@ export const useGridRowEditing = (apiRef, props) => {
583
582
  mode: GridRowModes.View
584
583
  };
585
584
  const prevMode = copyOfPrevRowModesModel[id]?.mode || GridRowModes.View;
586
- const originalId = idToIdLookup[id] ?? id;
585
+ const originalId = rowsLookup[id] ? apiRef.current.getRowId(rowsLookup[id]) : id;
587
586
  if (params.mode === GridRowModes.Edit && prevMode === GridRowModes.View) {
588
587
  updateStateToStartRowEditMode(_extends({
589
588
  id: originalId
@@ -1,4 +1,9 @@
1
1
  import { GridLogicOperator } from "../../../models/gridFilterItem.js";
2
+ export const defaultGridFilterLookup = {
3
+ filteredRowsLookup: {},
4
+ filteredChildrenCountLookup: {},
5
+ filteredDescendantCountLookup: {}
6
+ };
2
7
  export const getDefaultGridFilterModel = () => ({
3
8
  items: [],
4
9
  logicOperator: GridLogicOperator.And,
@@ -8,7 +8,7 @@ import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
8
8
  import { useGridLogger } from "../../utils/useGridLogger.js";
9
9
  import { gridColumnLookupSelector } from "../columns/gridColumnsSelector.js";
10
10
  import { GridPreferencePanelsValue } from "../preferencesPanel/gridPreferencePanelsValue.js";
11
- import { getDefaultGridFilterModel } from "./gridFilterState.js";
11
+ import { defaultGridFilterLookup, getDefaultGridFilterModel } from "./gridFilterState.js";
12
12
  import { gridFilterModelSelector } from "./gridFilterSelector.js";
13
13
  import { useFirstRender } from "../../utils/useFirstRender.js";
14
14
  import { gridRowsLookupSelector } from "../rows/index.js";
@@ -20,12 +20,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
20
20
  export const filterStateInitializer = (state, props, apiRef) => {
21
21
  const filterModel = props.filterModel ?? props.initialState?.filter?.filterModel ?? getDefaultGridFilterModel();
22
22
  return _extends({}, state, {
23
- filter: {
24
- filterModel: sanitizeFilterModel(filterModel, props.disableMultipleColumnsFiltering, apiRef),
25
- filteredRowsLookup: {},
26
- filteredChildrenCountLookup: {},
27
- filteredDescendantCountLookup: {}
28
- },
23
+ filter: _extends({
24
+ filterModel: sanitizeFilterModel(filterModel, props.disableMultipleColumnsFiltering, apiRef)
25
+ }, defaultGridFilterLookup),
29
26
  visibleRowsLookup: {}
30
27
  });
31
28
  };
@@ -271,12 +268,8 @@ export const useGridFilter = (apiRef, props) => {
271
268
  } = props;
272
269
  const getRowsRef = useLazyRef(createMemoizedValues);
273
270
  const flatFilteringMethod = React.useCallback(params => {
274
- if (props.filterMode !== 'client' || !params.isRowMatchingFilters) {
275
- return {
276
- filteredRowsLookup: {},
277
- filteredChildrenCountLookup: {},
278
- filteredDescendantCountLookup: {}
279
- };
271
+ if (props.filterMode !== 'client' || !params.isRowMatchingFilters || !params.filterModel.items.length && !params.filterModel.quickFilterValues?.length) {
272
+ return defaultGridFilterLookup;
280
273
  }
281
274
  const dataRowIdToModelLookup = gridRowsLookupSelector(apiRef);
282
275
  const filteredRowsLookup = {};
@@ -326,10 +326,11 @@ export const useGridFocus = (apiRef, props) => {
326
326
  // If the focused cell is in a row which does not exist anymore,
327
327
  // focus previous row or remove the focus
328
328
  if (cell && !apiRef.current.getRow(cell.id)) {
329
- const lastFocusedRowId = gridFocusCellSelector(apiRef)?.id;
329
+ const lastFocusedRowId = cell.id;
330
330
  let nextRowId = null;
331
331
  if (typeof lastFocusedRowId !== 'undefined') {
332
- const lastFocusedRowIndex = apiRef.current.getRowIndexRelativeToVisibleRows(lastFocusedRowId);
332
+ const rowEl = apiRef.current.getRowElement(lastFocusedRowId);
333
+ const lastFocusedRowIndex = rowEl?.dataset.rowindex ? Number(rowEl?.dataset.rowindex) : 0;
333
334
  const currentPage = getVisibleRows(apiRef, {
334
335
  pagination: props.pagination,
335
336
  paginationMode: props.paginationMode