@mui/x-data-grid 6.2.0 → 6.3.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 (110) hide show
  1. package/CHANGELOG.md +118 -1
  2. package/components/GridHeader.d.ts +2 -2
  3. package/components/GridHeader.js +4 -6
  4. package/components/base/GridBody.d.ts +0 -1
  5. package/components/base/GridBody.js +39 -15
  6. package/components/cell/GridActionsCell.d.ts +2 -3
  7. package/components/cell/GridActionsCell.js +9 -1
  8. package/components/columnSelection/GridCellCheckboxRenderer.d.ts +1 -1
  9. package/components/columnSelection/GridCellCheckboxRenderer.js +1 -1
  10. package/components/columnSelection/GridHeaderCheckbox.d.ts +1 -1
  11. package/components/containers/GridMainContainer.d.ts +3 -1
  12. package/components/containers/GridMainContainer.js +3 -2
  13. package/components/containers/GridRoot.js +0 -5
  14. package/components/containers/GridRootStyles.js +3 -1
  15. package/components/index.d.ts +0 -1
  16. package/components/index.js +0 -1
  17. package/components/panel/GridColumnsPanel.js +3 -2
  18. package/components/panel/GridPanel.d.ts +3 -3
  19. package/components/panel/GridPanel.js +2 -1
  20. package/components/panel/filterPanel/GridFilterPanel.js +5 -2
  21. package/constants/gridClasses.js +1 -1
  22. package/hooks/features/columnGrouping/useGridColumnGrouping.js +22 -15
  23. package/hooks/features/dimensions/gridDimensionsApi.d.ts +4 -0
  24. package/hooks/features/dimensions/useGridDimensions.js +49 -10
  25. package/hooks/features/export/useGridPrintExport.js +3 -1
  26. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -0
  27. package/hooks/features/virtualization/useGridVirtualScroller.js +11 -5
  28. package/index.js +1 -1
  29. package/joy/index.d.ts +2 -0
  30. package/joy/index.js +2 -0
  31. package/joy/joySlots.d.ts +4 -0
  32. package/joy/joySlots.js +179 -0
  33. package/joy/package.json +6 -0
  34. package/legacy/components/GridHeader.js +4 -6
  35. package/legacy/components/base/GridBody.js +40 -16
  36. package/legacy/components/cell/GridActionsCell.js +11 -2
  37. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +1 -1
  38. package/legacy/components/containers/GridMainContainer.js +3 -2
  39. package/legacy/components/containers/GridRoot.js +0 -5
  40. package/legacy/components/containers/GridRootStyles.js +3 -1
  41. package/legacy/components/index.js +0 -1
  42. package/legacy/components/panel/GridColumnsPanel.js +3 -2
  43. package/legacy/components/panel/GridPanel.js +2 -1
  44. package/legacy/components/panel/filterPanel/GridFilterPanel.js +5 -2
  45. package/legacy/constants/gridClasses.js +1 -1
  46. package/legacy/hooks/features/columnGrouping/useGridColumnGrouping.js +22 -15
  47. package/legacy/hooks/features/dimensions/useGridDimensions.js +55 -12
  48. package/legacy/hooks/features/export/useGridPrintExport.js +3 -1
  49. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +12 -6
  50. package/legacy/index.js +1 -1
  51. package/legacy/joy/index.js +2 -0
  52. package/legacy/joy/joySlots.js +180 -0
  53. package/legacy/locales/frFR.js +2 -2
  54. package/legacy/locales/trTR.js +2 -2
  55. package/legacy/locales/zhCN.js +2 -2
  56. package/locales/frFR.js +2 -2
  57. package/locales/trTR.js +2 -2
  58. package/locales/zhCN.js +2 -2
  59. package/material/index.d.ts +2 -2
  60. package/models/gridSlotsComponent.d.ts +2 -2
  61. package/modern/components/GridHeader.js +4 -6
  62. package/modern/components/base/GridBody.js +39 -15
  63. package/modern/components/cell/GridActionsCell.js +9 -1
  64. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +1 -1
  65. package/modern/components/containers/GridMainContainer.js +3 -2
  66. package/modern/components/containers/GridRoot.js +0 -5
  67. package/modern/components/containers/GridRootStyles.js +3 -1
  68. package/modern/components/index.js +0 -1
  69. package/modern/components/panel/GridColumnsPanel.js +3 -2
  70. package/modern/components/panel/GridPanel.js +2 -1
  71. package/modern/components/panel/filterPanel/GridFilterPanel.js +5 -2
  72. package/modern/constants/gridClasses.js +1 -1
  73. package/modern/hooks/features/columnGrouping/useGridColumnGrouping.js +21 -14
  74. package/modern/hooks/features/dimensions/useGridDimensions.js +48 -10
  75. package/modern/hooks/features/export/useGridPrintExport.js +3 -1
  76. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +11 -5
  77. package/modern/index.js +1 -1
  78. package/modern/joy/index.js +2 -0
  79. package/modern/joy/joySlots.js +177 -0
  80. package/modern/locales/frFR.js +2 -2
  81. package/modern/locales/trTR.js +2 -2
  82. package/modern/locales/zhCN.js +2 -2
  83. package/node/components/GridHeader.js +5 -8
  84. package/node/components/base/GridBody.js +39 -15
  85. package/node/components/cell/GridActionsCell.js +9 -1
  86. package/node/components/columnSelection/GridCellCheckboxRenderer.js +1 -1
  87. package/node/components/containers/GridMainContainer.js +5 -3
  88. package/node/components/containers/GridRoot.js +0 -5
  89. package/node/components/containers/GridRootStyles.js +3 -1
  90. package/node/components/index.js +0 -11
  91. package/node/components/panel/GridColumnsPanel.js +3 -2
  92. package/node/components/panel/GridPanel.js +2 -1
  93. package/node/components/panel/filterPanel/GridFilterPanel.js +5 -2
  94. package/node/constants/gridClasses.js +1 -1
  95. package/node/hooks/features/columnGrouping/useGridColumnGrouping.js +20 -11
  96. package/node/hooks/features/dimensions/useGridDimensions.js +47 -9
  97. package/node/hooks/features/export/useGridPrintExport.js +3 -1
  98. package/node/hooks/features/virtualization/useGridVirtualScroller.js +11 -5
  99. package/node/index.js +1 -1
  100. package/node/joy/index.js +13 -0
  101. package/node/joy/joySlots.js +185 -0
  102. package/node/locales/frFR.js +2 -2
  103. package/node/locales/trTR.js +2 -2
  104. package/node/locales/zhCN.js +2 -2
  105. package/package.json +3 -3
  106. package/components/GridAutoSizer.d.ts +0 -44
  107. package/components/GridAutoSizer.js +0 -126
  108. package/legacy/components/GridAutoSizer.js +0 -132
  109. package/modern/components/GridAutoSizer.js +0 -125
  110. package/node/components/GridAutoSizer.js +0 -132
@@ -1,10 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
+ import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
4
5
  import { useGridPrivateApiContext } from '../../hooks/utils/useGridPrivateApiContext';
5
6
  import { useGridSelector } from '../../hooks/utils/useGridSelector';
6
7
  import { GridMainContainer } from '../containers/GridMainContainer';
7
- import { GridAutoSizer } from '../GridAutoSizer';
8
8
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
9
9
  import { gridColumnPositionsSelector, gridColumnVisibilityModelSelector, gridVisibleColumnDefinitionsSelector } from '../../hooks/features/columns/gridColumnsSelector';
10
10
  import { gridFilterActiveItemsLookupSelector } from '../../hooks/features/filter/gridFilterSelector';
@@ -17,12 +17,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
17
17
  import { jsxs as _jsxs } from "react/jsx-runtime";
18
18
  function GridBody(props) {
19
19
  const {
20
- children,
21
20
  VirtualScrollerComponent,
22
21
  ColumnHeadersProps
23
22
  } = props;
24
23
  const apiRef = useGridPrivateApiContext();
25
24
  const rootProps = useGridRootProps();
25
+ const rootRef = React.useRef(null);
26
26
  const visibleColumns = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector);
27
27
  const filterColumnLookup = useGridSelector(apiRef, gridFilterActiveItemsLookupSelector);
28
28
  const sortColumnLookup = useGridSelector(apiRef, gridSortColumnLookupSelector);
@@ -39,6 +39,31 @@ function GridBody(props) {
39
39
  const columnGroupsHeaderStructure = useGridSelector(apiRef, gridColumnGroupsHeaderStructureSelector);
40
40
  const hasOtherElementInTabSequence = !(columnGroupHeaderTabIndexState === null && columnHeaderTabIndexState === null && cellTabIndexState === null);
41
41
  const [isVirtualizationDisabled, setIsVirtualizationDisabled] = React.useState(rootProps.disableVirtualization);
42
+ useEnhancedEffect(() => {
43
+ apiRef.current.computeSizeAndPublishResizeEvent();
44
+ const elementToObserve = rootRef.current;
45
+ if (typeof ResizeObserver === 'undefined') {
46
+ return () => {};
47
+ }
48
+ let animationFrame;
49
+ const observer = new ResizeObserver(() => {
50
+ // See https://github.com/mui/mui-x/issues/8733
51
+ animationFrame = window.requestAnimationFrame(() => {
52
+ apiRef.current.computeSizeAndPublishResizeEvent();
53
+ });
54
+ });
55
+ if (elementToObserve) {
56
+ observer.observe(elementToObserve);
57
+ }
58
+ return () => {
59
+ if (animationFrame) {
60
+ window.cancelAnimationFrame(animationFrame);
61
+ }
62
+ if (elementToObserve) {
63
+ observer.unobserve(elementToObserve);
64
+ }
65
+ };
66
+ }, [apiRef]);
42
67
  const disableVirtualization = React.useCallback(() => {
43
68
  setIsVirtualizationDisabled(true);
44
69
  }, []);
@@ -65,10 +90,9 @@ function GridBody(props) {
65
90
  columnHeadersElementRef: columnHeadersRef,
66
91
  virtualScrollerRef
67
92
  });
68
- const handleResize = React.useCallback(size => {
69
- apiRef.current.publishEvent('resize', size);
70
- }, [apiRef]);
93
+ const hasDimensions = !!apiRef.current.getRootDimensions();
71
94
  return /*#__PURE__*/_jsxs(GridMainContainer, {
95
+ ref: rootRef,
72
96
  children: [/*#__PURE__*/_jsx(rootProps.slots.columnHeaders, _extends({
73
97
  ref: columnsContainerRef,
74
98
  innerRef: columnHeadersRef,
@@ -86,15 +110,16 @@ function GridBody(props) {
86
110
  columnVisibility: columnVisibility,
87
111
  columnGroupsHeaderStructure: columnGroupsHeaderStructure,
88
112
  hasOtherElementInTabSequence: hasOtherElementInTabSequence
89
- }, ColumnHeadersProps)), /*#__PURE__*/_jsx(GridAutoSizer, {
90
- nonce: rootProps.nonce,
91
- disableHeight: rootProps.autoHeight,
92
- onResize: handleResize,
93
- children: /*#__PURE__*/_jsx(VirtualScrollerComponent, {
94
- ref: virtualScrollerRef,
95
- disableVirtualization: isVirtualizationDisabled
96
- })
97
- }), children]
113
+ }, ColumnHeadersProps)), hasDimensions && /*#__PURE__*/_jsx(VirtualScrollerComponent
114
+ // The content is only rendered after dimensions are computed because
115
+ // the lazy-loading hook is listening to `renderedRowsIntervalChange`,
116
+ // but only does something if the dimensions are also available.
117
+ // If this event is published while dimensions haven't been computed,
118
+ // the `onFetchRows` prop won't be called during mount.
119
+ , {
120
+ ref: virtualScrollerRef,
121
+ disableVirtualization: isVirtualizationDisabled
122
+ })]
98
123
  });
99
124
  }
100
125
  process.env.NODE_ENV !== "production" ? GridBody.propTypes = {
@@ -102,7 +127,6 @@ process.env.NODE_ENV !== "production" ? GridBody.propTypes = {
102
127
  // | These PropTypes are generated from the TypeScript type definitions |
103
128
  // | To update them edit the TypeScript types and run "yarn proptypes" |
104
129
  // ----------------------------------------------------------------------
105
- children: PropTypes.node,
106
130
  ColumnHeadersProps: PropTypes.object,
107
131
  VirtualScrollerComponent: PropTypes.elementType.isRequired
108
132
  } : void 0;
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "focusElementRef"];
3
+ const _excluded = ["api", "colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "focusElementRef"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import MenuList from '@mui/material/MenuList';
@@ -188,6 +188,7 @@ process.env.NODE_ENV !== "production" ? GridActionsCell.propTypes = {
188
188
  // | These PropTypes are generated from the TypeScript type definitions |
189
189
  // | To update them edit the TypeScript types and run "yarn proptypes" |
190
190
  // ----------------------------------------------------------------------
191
+ api: PropTypes.object,
191
192
  /**
192
193
  * The mode of the cell.
193
194
  */
@@ -210,6 +211,9 @@ process.env.NODE_ENV !== "production" ? GridActionsCell.propTypes = {
210
211
  focus: PropTypes.func.isRequired
211
212
  })
212
213
  })]),
214
+ /**
215
+ * The cell value formatted with the column valueFormatter.
216
+ */
213
217
  formattedValue: PropTypes.any,
214
218
  /**
215
219
  * If true, the cell is the active element.
@@ -236,6 +240,10 @@ process.env.NODE_ENV !== "production" ? GridActionsCell.propTypes = {
236
240
  * the tabIndex value.
237
241
  */
238
242
  tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
243
+ /**
244
+ * The cell value.
245
+ * If the column has `valueGetter`, use `params.row` to directly access the fields.
246
+ */
239
247
  value: PropTypes.any
240
248
  } : void 0;
241
249
  export { GridActionsCell };
@@ -35,7 +35,7 @@ const GridCellCheckboxForwardRef = /*#__PURE__*/React.forwardRef(function GridCe
35
35
  };
36
36
  const classes = useUtilityClasses(ownerState);
37
37
  const checkboxElement = React.useRef(null);
38
- const rippleRef = React.useRef();
38
+ const rippleRef = React.useRef(null);
39
39
  const handleRef = useForkRef(checkboxElement, ref);
40
40
  const element = apiRef.current.getCellElement(id, field);
41
41
  const handleChange = event => {
@@ -24,12 +24,13 @@ const GridMainContainerRoot = styled('div', {
24
24
  flexDirection: 'column',
25
25
  overflow: 'hidden'
26
26
  }));
27
- export function GridMainContainer(props) {
27
+ export const GridMainContainer = /*#__PURE__*/React.forwardRef((props, ref) => {
28
28
  const rootProps = useGridRootProps();
29
29
  const classes = useUtilityClasses(rootProps);
30
30
  return /*#__PURE__*/_jsx(GridMainContainerRoot, {
31
+ ref: ref,
31
32
  className: classes.root,
32
33
  ownerState: rootProps,
33
34
  children: props.children
34
35
  });
35
- }
36
+ });
@@ -54,11 +54,6 @@ const GridRoot = /*#__PURE__*/React.forwardRef(function GridRoot(props, ref) {
54
54
  useEnhancedEffect(() => {
55
55
  setMountedState(true);
56
56
  }, []);
57
- useEnhancedEffect(() => {
58
- if (mountedState) {
59
- apiRef.current.updateGridDimensionsRef();
60
- }
61
- }, [apiRef, mountedState]);
62
57
  if (!mountedState) {
63
58
  return null;
64
59
  }
@@ -204,7 +204,9 @@ export const GridRootStyles = styled('div', {
204
204
  minWidth: 0,
205
205
  flex: 1,
206
206
  whiteSpace: 'nowrap',
207
- overflow: 'hidden'
207
+ overflow: 'hidden',
208
+ // to anchor the aggregation label
209
+ position: 'relative'
208
210
  },
209
211
  [`& .${gridClasses.columnHeaderTitleContainerContent}`]: {
210
212
  overflow: 'hidden',
@@ -8,7 +8,6 @@ export * from './menu';
8
8
  export * from './panel';
9
9
  export * from './toolbar';
10
10
  export * from './GridApiContext';
11
- export * from './GridAutoSizer';
12
11
  export * from './GridFooter';
13
12
  export * from './GridHeader';
14
13
  export * from './GridLoadingOverlay';
@@ -94,8 +94,9 @@ function GridColumnsPanel(props) {
94
94
  const toggleAllColumns = React.useCallback(isVisible => {
95
95
  const currentModel = gridColumnVisibilityModelSelector(apiRef);
96
96
  const newModel = _extends({}, currentModel);
97
+ const togglableColumns = getTogglableColumns ? getTogglableColumns(columns) : null;
97
98
  columns.forEach(col => {
98
- if (col.hideable) {
99
+ if (col.hideable && (togglableColumns == null || togglableColumns.includes(col.field))) {
99
100
  if (isVisible) {
100
101
  // delete the key from the model instead of setting it to `true`
101
102
  delete newModel[col.field];
@@ -105,7 +106,7 @@ function GridColumnsPanel(props) {
105
106
  }
106
107
  });
107
108
  return apiRef.current.setColumnVisibilityModel(newModel);
108
- }, [apiRef, columns]);
109
+ }, [apiRef, columns, getTogglableColumns]);
109
110
  const handleSearchValueChange = React.useCallback(event => {
110
111
  setSearchValue(event.target.value);
111
112
  }, []);
@@ -115,6 +115,7 @@ process.env.NODE_ENV !== "production" ? GridPanel.propTypes = {
115
115
  /**
116
116
  * If `true`, the component is shown.
117
117
  */
118
- open: PropTypes.bool.isRequired
118
+ open: PropTypes.bool.isRequired,
119
+ ownerState: PropTypes.object
119
120
  } : void 0;
120
121
  export { GridPanel };
@@ -26,6 +26,7 @@ const GridFilterPanel = /*#__PURE__*/React.forwardRef(function GridFilterPanel(p
26
26
  const filterModel = useGridSelector(apiRef, gridFilterModelSelector);
27
27
  const filterableColumns = useGridSelector(apiRef, gridFilterableColumnDefinitionsSelector);
28
28
  const lastFilterRef = React.useRef(null);
29
+ const placeholderFilter = React.useRef(null);
29
30
  const {
30
31
  logicOperators = [GridLogicOperator.And, GridLogicOperator.Or],
31
32
  columnsSort,
@@ -89,8 +90,10 @@ const GridFilterPanel = /*#__PURE__*/React.forwardRef(function GridFilterPanel(p
89
90
  if (filterModel.items.length) {
90
91
  return filterModel.items;
91
92
  }
92
- const defaultFilter = getDefaultFilter();
93
- return defaultFilter ? [defaultFilter] : [];
93
+ if (!placeholderFilter.current) {
94
+ placeholderFilter.current = getDefaultFilter();
95
+ }
96
+ return placeholderFilter.current ? [placeholderFilter.current] : [];
94
97
  }, [filterModel.items, getDefaultFilter]);
95
98
  const hasMultipleFilters = items.length > 1;
96
99
  const addNewFilter = () => {
@@ -2,4 +2,4 @@ import { unstable_generateUtilityClasses as generateUtilityClasses, unstable_gen
2
2
  export function getDataGridUtilityClass(slot) {
3
3
  return generateUtilityClass('MuiDataGrid', slot);
4
4
  }
5
- export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell--rangeTop', 'cell--rangeBottom', 'cell--rangeLeft', 'cell--rangeRight', 'cell', 'cellContent', 'cellCheckbox', 'cellSkeleton', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnGroupHeader', 'columnHeader--filledGroup', 'columnHeader--emptyGroup', 'columnHeader--showColumnBorder', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLogicOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'root--disableUserSelection', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'row--detailPanelExpanded', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorderColor', 'cell--withRightBorder', 'columnHeader--withRightBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
5
+ export const gridClasses = generateUtilityClasses('MuiDataGrid', ['actionsCell', 'aggregationColumnHeader', 'aggregationColumnHeader--alignLeft', 'aggregationColumnHeader--alignCenter', 'aggregationColumnHeader--alignRight', 'aggregationColumnHeaderLabel', 'autoHeight', 'booleanCell', 'cell--editable', 'cell--editing', 'cell--textCenter', 'cell--textLeft', 'cell--textRight', 'cell--withRenderer', 'cell--rangeTop', 'cell--rangeBottom', 'cell--rangeLeft', 'cell--rangeRight', 'cell', 'cellContent', 'cellCheckbox', 'cellSkeleton', 'checkboxInput', 'columnHeader--alignCenter', 'columnHeader--alignLeft', 'columnHeader--alignRight', 'columnHeader--dragging', 'columnHeader--moving', 'columnHeader--numeric', 'columnHeader--sortable', 'columnHeader--sorted', 'columnHeader--filtered', 'columnHeader', 'columnHeaderCheckbox', 'columnHeaderDraggableContainer', 'columnHeaderDropZone', 'columnHeaderTitle', 'columnHeaderTitleContainer', 'columnHeaderTitleContainerContent', 'columnGroupHeader', 'columnHeader--filledGroup', 'columnHeader--emptyGroup', 'columnHeader--showColumnBorder', 'columnHeaders', 'columnHeadersInner', 'columnHeadersInner--scrollable', 'columnSeparator--resizable', 'columnSeparator--resizing', 'columnSeparator--sideLeft', 'columnSeparator--sideRight', 'columnSeparator', 'columnsPanel', 'columnsPanelRow', 'detailPanel', 'detailPanels', 'detailPanelToggleCell', 'detailPanelToggleCell--expanded', 'footerCell', 'panel', 'panelHeader', 'panelWrapper', 'panelContent', 'panelFooter', 'paper', 'editBooleanCell', 'editInputCell', 'filterForm', 'filterFormDeleteIcon', 'filterFormLogicOperatorInput', 'filterFormColumnInput', 'filterFormOperatorInput', 'filterFormValueInput', 'filterIcon', 'footerContainer', 'iconButtonContainer', 'iconSeparator', 'main', 'menu', 'menuIcon', 'menuIconButton', 'menuOpen', 'menuList', 'overlay', 'overlayWrapper', 'overlayWrapperInner', 'root', 'root--densityStandard', 'root--densityComfortable', 'root--densityCompact', 'root--disableUserSelection', 'row', 'row--editable', 'row--editing', 'row--lastVisible', 'row--dragging', 'row--dynamicHeight', 'row--detailPanelExpanded', 'rowReorderCellPlaceholder', 'rowCount', 'rowReorderCellContainer', 'rowReorderCell', 'rowReorderCell--draggable', 'scrollArea--left', 'scrollArea--right', 'scrollArea', 'selectedRowCount', 'sortIcon', 'toolbarContainer', 'toolbarFilterList', 'virtualScroller', 'virtualScrollerContent', 'virtualScrollerContent--overflowed', 'virtualScrollerRenderZone', 'pinnedColumns', 'pinnedColumns--left', 'pinnedColumns--right', 'pinnedColumnHeaders', 'pinnedColumnHeaders--left', 'pinnedColumnHeaders--right', 'withBorderColor', 'cell--withRightBorder', 'columnHeader--withRightBorder', 'treeDataGroupingCell', 'treeDataGroupingCellToggle', 'groupingCriteriaCell', 'groupingCriteriaCellToggle', 'pinnedRows', 'pinnedRows--top', 'pinnedRows--bottom', 'pinnedRowsRenderZone']);
@@ -7,10 +7,7 @@ import { gridColumnGroupsLookupSelector, gridColumnGroupsUnwrappedModelSelector
7
7
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
8
8
  import { getColumnGroupsHeaderStructure, unwrapGroupingColumnModel } from './gridColumnGroupsUtils';
9
9
  import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
10
- import { gridColumnFieldsSelector,
11
- // GridColumnsState,
12
- gridVisibleColumnFieldsSelector } from '../columns';
13
- import { useGridSelector } from '../../utils/useGridSelector';
10
+ import { gridColumnFieldsSelector, gridVisibleColumnFieldsSelector } from '../columns';
14
11
  const createGroupLookup = columnGroupingModel => {
15
12
  let groupLookup = {};
16
13
  columnGroupingModel.forEach(node => {
@@ -94,18 +91,14 @@ export const useGridColumnGrouping = (apiRef, props) => {
94
91
  });
95
92
  });
96
93
  }, [apiRef, props.columnGroupingModel]);
97
- useGridApiEventHandler(apiRef, 'columnIndexChange', handleColumnIndexChange);
98
- const columnFields = useGridSelector(apiRef, gridColumnFieldsSelector);
99
- const visibleColumnFields = useGridSelector(apiRef, gridVisibleColumnFieldsSelector);
100
- /**
101
- * EFFECTS
102
- */
103
- React.useEffect(() => {
94
+ const updateColumnGroupingState = React.useCallback(columnGroupingModel => {
104
95
  if (!props.experimentalFeatures?.columnGrouping) {
105
96
  return;
106
97
  }
107
- const groupLookup = createGroupLookup(props.columnGroupingModel ?? []);
108
- const unwrappedGroupingModel = unwrapGroupingColumnModel(props.columnGroupingModel ?? []);
98
+ const columnFields = gridColumnFieldsSelector(apiRef);
99
+ const visibleColumnFields = gridVisibleColumnFieldsSelector(apiRef);
100
+ const groupLookup = createGroupLookup(columnGroupingModel ?? []);
101
+ const unwrappedGroupingModel = unwrapGroupingColumnModel(columnGroupingModel ?? []);
109
102
  const columnGroupsHeaderStructure = getColumnGroupsHeaderStructure(columnFields, unwrappedGroupingModel);
110
103
  const maxDepth = visibleColumnFields.length === 0 ? 0 : Math.max(...visibleColumnFields.map(field => unwrappedGroupingModel[field]?.length ?? 0));
111
104
  apiRef.current.setState(state => {
@@ -118,5 +111,19 @@ export const useGridColumnGrouping = (apiRef, props) => {
118
111
  }
119
112
  });
120
113
  });
121
- }, [apiRef, columnFields, visibleColumnFields, props.columnGroupingModel, props.experimentalFeatures?.columnGrouping]);
114
+ }, [apiRef, props.experimentalFeatures?.columnGrouping]);
115
+ useGridApiEventHandler(apiRef, 'columnIndexChange', handleColumnIndexChange);
116
+ useGridApiEventHandler(apiRef, 'columnsChange', () => {
117
+ updateColumnGroupingState(props.columnGroupingModel);
118
+ });
119
+ useGridApiEventHandler(apiRef, 'columnVisibilityModelChange', () => {
120
+ updateColumnGroupingState(props.columnGroupingModel);
121
+ });
122
+
123
+ /**
124
+ * EFFECTS
125
+ */
126
+ React.useEffect(() => {
127
+ updateColumnGroupingState(props.columnGroupingModel);
128
+ }, [updateColumnGroupingState, props.columnGroupingModel]);
122
129
  };
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { unstable_debounce as debounce, unstable_ownerDocument as ownerDocument, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
2
+ import { unstable_debounce as debounce, unstable_ownerDocument as ownerDocument, unstable_useEnhancedEffect as useEnhancedEffect, unstable_ownerWindow as ownerWindow } from '@mui/utils';
3
3
  import { useGridApiEventHandler, useGridApiOptionHandler } from '../../utils/useGridApiEventHandler';
4
4
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
5
5
  import { useGridLogger } from '../../utils/useGridLogger';
@@ -10,6 +10,7 @@ import { getVisibleRows } from '../../utils/useGridVisibleRows';
10
10
  import { gridRowsMetaSelector } from '../rows/gridRowsMetaSelector';
11
11
  import { calculatePinnedRowsHeight } from '../rows/gridRowsUtils';
12
12
  import { getTotalHeaderHeight } from '../columns/gridColumnsUtils';
13
+ import { gridClasses } from '../../../constants/gridClasses';
13
14
  const isTestEnvironment = process.env.NODE_ENV === 'test';
14
15
  const hasScroll = ({
15
16
  content,
@@ -113,10 +114,20 @@ export function useGridDimensions(apiRef, props) {
113
114
  apiRef.current.publishEvent('viewportInnerSizeChange', newFullDimensions.viewportInnerSize);
114
115
  }
115
116
  }, [apiRef, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, totalHeaderHeight]);
117
+ const [savedSize, setSavedSize] = React.useState();
118
+ const debouncedSetSavedSize = React.useMemo(() => debounce(setSavedSize, 60), []);
119
+ const previousSize = React.useRef();
120
+ useEnhancedEffect(() => {
121
+ if (savedSize) {
122
+ updateGridDimensionsRef();
123
+ apiRef.current.publishEvent('debouncedResize', rootDimensionsRef.current);
124
+ }
125
+ }, [apiRef, savedSize, updateGridDimensionsRef]);
126
+
127
+ // This is the function called by apiRef.current.resize()
116
128
  const resize = React.useCallback(() => {
117
- updateGridDimensionsRef();
118
- apiRef.current.publishEvent('debouncedResize', rootDimensionsRef.current);
119
- }, [apiRef, updateGridDimensionsRef]);
129
+ apiRef.current.computeSizeAndPublishResizeEvent();
130
+ }, [apiRef]);
120
131
  const getRootDimensions = React.useCallback(() => fullDimensionsRef.current, []);
121
132
  const getViewportPageSize = React.useCallback(() => {
122
133
  const dimensions = apiRef.current.getRootDimensions();
@@ -138,17 +149,44 @@ export function useGridDimensions(apiRef, props) {
138
149
  const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
139
150
  return Math.min(maximumPageSizeWithoutScrollBar, currentPage.rows.length);
140
151
  }, [apiRef, props.pagination, props.paginationMode, props.getRowHeight, rowHeight]);
152
+ const computeSizeAndPublishResizeEvent = React.useCallback(() => {
153
+ const rootEl = apiRef.current.rootElementRef?.current;
154
+ const mainEl = rootEl?.querySelector(`.${gridClasses.main}`);
155
+ if (!mainEl) {
156
+ return;
157
+ }
158
+ const height = mainEl.offsetHeight || 0;
159
+ const width = mainEl.offsetWidth || 0;
160
+ const win = ownerWindow(mainEl);
161
+ const computedStyle = win.getComputedStyle(mainEl);
162
+ const paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
163
+ const paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
164
+ const paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
165
+ const paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
166
+ const newHeight = height - paddingTop - paddingBottom;
167
+ const newWidth = width - paddingLeft - paddingRight;
168
+ const hasHeightChanged = newHeight !== previousSize.current?.height;
169
+ const hasWidthChanged = newWidth !== previousSize.current?.width;
170
+ if (!previousSize.current || hasHeightChanged || hasWidthChanged) {
171
+ const size = {
172
+ width: newWidth,
173
+ height: newHeight
174
+ };
175
+ apiRef.current.publishEvent('resize', size);
176
+ previousSize.current = size;
177
+ }
178
+ }, [apiRef]);
141
179
  const dimensionsApi = {
142
180
  resize,
143
181
  getRootDimensions
144
182
  };
145
183
  const dimensionsPrivateApi = {
146
184
  getViewportPageSize,
147
- updateGridDimensionsRef
185
+ updateGridDimensionsRef,
186
+ computeSizeAndPublishResizeEvent
148
187
  };
149
188
  useGridApiMethod(apiRef, dimensionsApi, 'public');
150
189
  useGridApiMethod(apiRef, dimensionsPrivateApi, 'private');
151
- const debounceResize = React.useMemo(() => debounce(resize, 60), [resize]);
152
190
  const isFirstSizing = React.useRef(true);
153
191
  const handleResize = React.useCallback(size => {
154
192
  rootDimensionsRef.current = size;
@@ -165,18 +203,18 @@ export function useGridDimensions(apiRef, props) {
165
203
  }
166
204
  if (isTestEnvironment) {
167
205
  // We don't need to debounce the resize for tests.
168
- resize();
206
+ setSavedSize(size);
169
207
  isFirstSizing.current = false;
170
208
  return;
171
209
  }
172
210
  if (isFirstSizing.current) {
173
211
  // We want to initialize the grid dimensions as soon as possible to avoid flickering
174
- resize();
212
+ setSavedSize(size);
175
213
  isFirstSizing.current = false;
176
214
  return;
177
215
  }
178
- debounceResize();
179
- }, [props.autoHeight, debounceResize, logger, resize]);
216
+ debouncedSetSavedSize(size);
217
+ }, [props.autoHeight, debouncedSetSavedSize, logger]);
180
218
  useEnhancedEffect(() => updateGridDimensionsRef(), [updateGridDimensionsRef]);
181
219
  useGridApiOptionHandler(apiRef, 'sortedRowsSet', updateGridDimensionsRef);
182
220
  useGridApiOptionHandler(apiRef, 'paginationModelChange', updateGridDimensionsRef);
@@ -121,7 +121,9 @@ export const useGridPrintExport = (apiRef, props) => {
121
121
  printDoc.body.classList.add(...normalizeOptions.bodyClassName.split(' '));
122
122
  }
123
123
  if (normalizeOptions.copyStyles) {
124
- const headStyleElements = doc.current.querySelectorAll("style, link[rel='stylesheet']");
124
+ const rootCandidate = gridRootElement.getRootNode();
125
+ const root = rootCandidate.constructor.name === 'ShadowRoot' ? rootCandidate : doc.current;
126
+ const headStyleElements = root.querySelectorAll("style, link[rel='stylesheet']");
125
127
  for (let i = 0; i < headStyleElements.length; i += 1) {
126
128
  const node = headStyleElements[i];
127
129
  if (node.tagName === 'STYLE') {
@@ -174,11 +174,13 @@ export const useGridVirtualScroller = props => {
174
174
  height: rootRef.current.clientHeight
175
175
  });
176
176
  }, [rowsMeta.currentPageTotalHeight]);
177
- const handleResize = React.useCallback(params => {
178
- setContainerDimensions({
179
- width: params.width,
180
- height: params.height
181
- });
177
+ const handleResize = React.useCallback(() => {
178
+ if (rootRef.current) {
179
+ setContainerDimensions({
180
+ width: rootRef.current.clientWidth,
181
+ height: rootRef.current.clientHeight
182
+ });
183
+ }
182
184
  }, []);
183
185
  useGridApiEventHandler(apiRef, 'debouncedResize', handleResize);
184
186
  const updateRenderZonePosition = React.useCallback(nextRenderContext => {
@@ -304,6 +306,7 @@ export const useGridVirtualScroller = props => {
304
306
  renderContext
305
307
  }) => {
306
308
  const {
309
+ onRowRender,
307
310
  renderContext: nextRenderContext,
308
311
  minFirstColumn = renderZoneMinColumnIndex,
309
312
  maxLastColumn = renderZoneMaxColumnIndex,
@@ -387,6 +390,9 @@ export const useGridVirtualScroller = props => {
387
390
  } else {
388
391
  isSelected = apiRef.current.isRowSelectable(id);
389
392
  }
393
+ if (onRowRender) {
394
+ onRowRender(id);
395
+ }
390
396
  const focusedCell = cellFocus !== null && cellFocus.id === id ? cellFocus.field : null;
391
397
  let tabbableCell = null;
392
398
  if (cellTabIndex !== null && cellTabIndex.id === id) {
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v6.2.0
2
+ * @mui/x-data-grid v6.3.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -0,0 +1,2 @@
1
+ import joySlots from './joySlots';
2
+ export { joySlots as unstable_joySlots };