@mui/x-data-grid-pro 5.12.3 → 5.13.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 (44) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/DataGridPro/DataGridPro.js +1 -1
  3. package/components/DataGridProVirtualScroller.js +7 -18
  4. package/components/GridDetailPanel.d.ts +19 -0
  5. package/components/GridDetailPanel.js +65 -0
  6. package/hooks/features/detailPanel/gridDetailPanelInterface.d.ts +20 -1
  7. package/hooks/features/detailPanel/gridDetailPanelSelector.d.ts +14 -3
  8. package/hooks/features/detailPanel/gridDetailPanelSelector.js +9 -1
  9. package/hooks/features/detailPanel/index.d.ts +1 -1
  10. package/hooks/features/detailPanel/index.js +1 -1
  11. package/hooks/features/detailPanel/useGridDetailPanel.js +41 -7
  12. package/hooks/features/detailPanel/useGridDetailPanelCache.d.ts +4 -0
  13. package/hooks/features/detailPanel/useGridDetailPanelCache.js +64 -0
  14. package/index.js +1 -1
  15. package/legacy/DataGridPro/DataGridPro.js +1 -1
  16. package/legacy/components/DataGridProVirtualScroller.js +12 -26
  17. package/legacy/components/GridDetailPanel.js +72 -0
  18. package/legacy/hooks/features/detailPanel/gridDetailPanelSelector.js +15 -2
  19. package/legacy/hooks/features/detailPanel/index.js +1 -1
  20. package/legacy/hooks/features/detailPanel/useGridDetailPanel.js +40 -7
  21. package/legacy/hooks/features/detailPanel/useGridDetailPanelCache.js +64 -0
  22. package/legacy/index.js +1 -1
  23. package/legacy/utils/releaseInfo.js +1 -1
  24. package/models/dataGridProProps.d.ts +2 -2
  25. package/modern/DataGridPro/DataGridPro.js +1 -1
  26. package/modern/components/DataGridProVirtualScroller.js +7 -18
  27. package/modern/components/GridDetailPanel.js +65 -0
  28. package/modern/hooks/features/detailPanel/gridDetailPanelSelector.js +9 -1
  29. package/modern/hooks/features/detailPanel/index.js +1 -1
  30. package/modern/hooks/features/detailPanel/useGridDetailPanel.js +39 -7
  31. package/modern/hooks/features/detailPanel/useGridDetailPanelCache.js +62 -0
  32. package/modern/index.js +1 -1
  33. package/modern/utils/releaseInfo.js +1 -1
  34. package/node/DataGridPro/DataGridPro.js +1 -1
  35. package/node/components/DataGridProVirtualScroller.js +8 -19
  36. package/node/components/GridDetailPanel.js +83 -0
  37. package/node/hooks/features/detailPanel/gridDetailPanelSelector.js +12 -2
  38. package/node/hooks/features/detailPanel/index.js +25 -11
  39. package/node/hooks/features/detailPanel/useGridDetailPanel.js +40 -6
  40. package/node/hooks/features/detailPanel/useGridDetailPanelCache.js +81 -0
  41. package/node/index.js +1 -1
  42. package/node/utils/releaseInfo.js +1 -1
  43. package/package.json +3 -3
  44. package/utils/releaseInfo.js +1 -1
@@ -1,9 +1,22 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import { createSelector } from '@mui/x-data-grid/internals';
1
3
  export var gridDetailPanelExpandedRowIdsSelector = function gridDetailPanelExpandedRowIdsSelector(state) {
2
4
  return state.detailPanel.expandedRowIds;
3
5
  };
4
6
  export var gridDetailPanelExpandedRowsContentCacheSelector = function gridDetailPanelExpandedRowsContentCacheSelector(state) {
5
7
  return state.detailPanel.contentCache;
6
8
  };
7
- export var gridDetailPanelExpandedRowsHeightCacheSelector = function gridDetailPanelExpandedRowsHeightCacheSelector(state) {
9
+ export var gridDetailPanelRawHeightCacheSelector = function gridDetailPanelRawHeightCacheSelector(state) {
8
10
  return state.detailPanel.heightCache;
9
- };
11
+ }; // TODO v6: Make this selector return the full object, including the autoHeight flag
12
+
13
+ export var gridDetailPanelExpandedRowsHeightCacheSelector = createSelector(gridDetailPanelRawHeightCacheSelector, function (heightCache) {
14
+ return Object.entries(heightCache).reduce(function (acc, _ref) {
15
+ var _ref2 = _slicedToArray(_ref, 2),
16
+ id = _ref2[0],
17
+ height = _ref2[1].height;
18
+
19
+ acc[id] = height || 0;
20
+ return acc;
21
+ }, {});
22
+ });
@@ -1,3 +1,3 @@
1
1
  export * from './gridDetailPanelToggleColDef';
2
- export * from './gridDetailPanelSelector';
2
+ export { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector } from './gridDetailPanelSelector';
3
3
  export * from './gridDetailPanelInterface';
@@ -1,21 +1,23 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
1
2
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
3
  import _extends from "@babel/runtime/helpers/esm/extends";
3
4
  import * as React from 'react';
4
5
  import { useGridSelector, useGridApiEventHandler, useGridApiMethod, gridRowIdsSelector } from '@mui/x-data-grid';
5
6
  import { useGridRegisterPipeProcessor } from '@mui/x-data-grid/internals';
6
7
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from './gridDetailPanelToggleColDef';
7
- import { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector } from './gridDetailPanelSelector';
8
+ import { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector, gridDetailPanelRawHeightCacheSelector } from './gridDetailPanelSelector';
8
9
  export var detailPanelStateInitializer = function detailPanelStateInitializer(state, props) {
9
10
  var _ref, _props$detailPanelExp, _props$initialState, _props$initialState$d;
10
11
 
11
12
  return _extends({}, state, {
12
13
  detailPanel: {
14
+ heightCache: {},
13
15
  expandedRowIds: (_ref = (_props$detailPanelExp = props.detailPanelExpandedRowIds) != null ? _props$detailPanelExp : (_props$initialState = props.initialState) == null ? void 0 : (_props$initialState$d = _props$initialState.detailPanel) == null ? void 0 : _props$initialState$d.expandedRowIds) != null ? _ref : []
14
16
  }
15
17
  });
16
18
  };
17
19
 
18
- function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight) {
20
+ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight, previousHeightCache) {
19
21
  if (typeof getDetailPanelContent !== 'function') {
20
22
  return {};
21
23
  } // TODO change to lazy approach using a Proxy
@@ -29,12 +31,19 @@ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeig
29
31
  return acc;
30
32
  }, {});
31
33
  var heightCache = rowIds.reduce(function (acc, id) {
34
+ var _previousHeightCache$;
35
+
32
36
  if (contentCache[id] == null) {
33
37
  return acc;
34
38
  }
35
39
 
36
40
  var params = apiRef.current.getRowParams(id);
37
- acc[id] = getDetailPanelHeight(params);
41
+ var height = getDetailPanelHeight(params);
42
+ var autoHeight = height === 'auto';
43
+ acc[id] = {
44
+ autoHeight: autoHeight,
45
+ height: autoHeight ? (_previousHeightCache$ = previousHeightCache[id]) == null ? void 0 : _previousHeightCache$.height : height
46
+ };
38
47
  return acc;
39
48
  }, {});
40
49
  return {
@@ -117,10 +126,34 @@ export var useGridDetailPanel = function useGridDetailPanel(apiRef, props) {
117
126
  });
118
127
  apiRef.current.forceUpdate();
119
128
  }, [apiRef]);
129
+ var storeDetailPanelHeight = React.useCallback(function (id, height) {
130
+ var heightCache = gridDetailPanelRawHeightCacheSelector(apiRef.current.state);
131
+
132
+ if (!heightCache[id] || heightCache[id].height === height) {
133
+ return;
134
+ }
135
+
136
+ apiRef.current.setState(function (state) {
137
+ return _extends({}, state, {
138
+ detailPanel: _extends({}, state.detailPanel, {
139
+ heightCache: _extends({}, heightCache, _defineProperty({}, id, _extends({}, heightCache[id], {
140
+ height: height
141
+ })))
142
+ })
143
+ });
144
+ });
145
+ apiRef.current.unstable_requestPipeProcessorsApplication('rowHeight');
146
+ }, [apiRef]);
147
+ var detailPanelHasAutoHeight = React.useCallback(function (id) {
148
+ var heightCache = gridDetailPanelRawHeightCacheSelector(apiRef.current.state);
149
+ return heightCache[id] ? heightCache[id].autoHeight : false;
150
+ }, [apiRef]);
120
151
  var detailPanelApi = {
121
152
  toggleDetailPanel: toggleDetailPanel,
122
153
  getExpandedDetailPanels: getExpandedDetailPanels,
123
- setExpandedDetailPanels: setExpandedDetailPanels
154
+ setExpandedDetailPanels: setExpandedDetailPanels,
155
+ unstable_storeDetailPanelHeight: storeDetailPanelHeight,
156
+ unstable_detailPanelHasAutoHeight: detailPanelHasAutoHeight
124
157
  };
125
158
  useGridApiMethod(apiRef, detailPanelApi, 'detailPanelApi');
126
159
  React.useEffect(function () {
@@ -135,7 +168,7 @@ export var useGridDetailPanel = function useGridDetailPanel(apiRef, props) {
135
168
  var updateCachesAndForceUpdate = React.useCallback(function () {
136
169
  apiRef.current.setState(function (state) {
137
170
  return _extends({}, state, {
138
- detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight))
171
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
139
172
  });
140
173
  });
141
174
  apiRef.current.forceUpdate();
@@ -150,7 +183,7 @@ export var useGridDetailPanel = function useGridDetailPanel(apiRef, props) {
150
183
 
151
184
  apiRef.current.setState(function (state) {
152
185
  return _extends({}, state, {
153
- detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight))
186
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
154
187
  });
155
188
  });
156
189
  previousGetDetailPanelContentProp.current = props.getDetailPanelContent;
@@ -166,7 +199,7 @@ export var useGridDetailPanel = function useGridDetailPanel(apiRef, props) {
166
199
  }
167
200
 
168
201
  updateCachesIfNeeded();
169
- var heightCache = gridDetailPanelExpandedRowsHeightCacheSelector(apiRef.current.state);
202
+ var heightCache = gridDetailPanelExpandedRowsHeightCacheSelector(apiRef);
170
203
  return _extends({}, initialValue, {
171
204
  detail: (_heightCache$row$id = heightCache[row.id]) != null ? _heightCache$row$id : 0 // Fallback to zero because the cache might not be ready yet (e.g. page was changed)
172
205
 
@@ -0,0 +1,64 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { useGridApiEventHandler, gridRowIdsSelector } from '@mui/x-data-grid';
4
+
5
+ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight, previousHeightCache) {
6
+ if (typeof getDetailPanelContent !== 'function') {
7
+ return {};
8
+ } // TODO change to lazy approach using a Proxy
9
+ // only call getDetailPanelContent when asked for an id
10
+
11
+
12
+ var rowIds = gridRowIdsSelector(apiRef);
13
+ var contentCache = rowIds.reduce(function (acc, id) {
14
+ var params = apiRef.current.getRowParams(id);
15
+ acc[id] = getDetailPanelContent(params);
16
+ return acc;
17
+ }, {});
18
+ var heightCache = rowIds.reduce(function (acc, id) {
19
+ var _previousHeightCache$;
20
+
21
+ if (contentCache[id] == null) {
22
+ return acc;
23
+ }
24
+
25
+ var params = apiRef.current.getRowParams(id);
26
+ var height = getDetailPanelHeight(params);
27
+ var autoHeight = height === 'auto';
28
+ acc[id] = {
29
+ autoHeight: autoHeight,
30
+ height: !autoHeight ? height : (_previousHeightCache$ = previousHeightCache[id]) == null ? void 0 : _previousHeightCache$.height
31
+ };
32
+ return acc;
33
+ }, {});
34
+ return {
35
+ contentCache: contentCache,
36
+ heightCache: heightCache
37
+ };
38
+ }
39
+
40
+ export var useGridDetailPanelCache = function useGridDetailPanelCache(apiRef, props) {
41
+ var updateCaches = React.useCallback(function () {
42
+ apiRef.current.setState(function (state) {
43
+ return _extends({}, state, {
44
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
45
+ });
46
+ });
47
+ apiRef.current.forceUpdate();
48
+ }, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]);
49
+ useGridApiEventHandler(apiRef, 'sortedRowsSet', updateCaches);
50
+ var isFirstRender = React.useRef(true);
51
+
52
+ if (isFirstRender.current) {
53
+ isFirstRender.current = false;
54
+ updateCaches();
55
+ }
56
+
57
+ React.useEffect(function () {
58
+ if (isFirstRender.current) {
59
+ return;
60
+ }
61
+
62
+ updateCaches();
63
+ }, [updateCaches]);
64
+ };
package/legacy/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.12.3
1
+ /** @license MUI v5.13.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export var getReleaseInfo = function getReleaseInfo() {
3
- var releaseInfo = "MTY1NjAyMTYwMDAwMA==";
3
+ var releaseInfo = "MTY1NzE0NDgwMDAwMA==";
4
4
 
5
5
  if (process.env.NODE_ENV !== 'production') {
6
6
  // A simple hack to set the value in the test environment (has no build step).
@@ -70,10 +70,10 @@ export interface DataGridProPropsWithDefaultValue extends DataGridPropsWithDefau
70
70
  /**
71
71
  * Function that returns the height of the row detail panel.
72
72
  * @param {GridRowParams} params With all properties from [[GridRowParams]].
73
- * @returns {number} The height in pixels.
73
+ * @returns {number | string} The height in pixels or "auto" to use the content height.
74
74
  * @default "() => 500"
75
75
  */
76
- getDetailPanelHeight: (params: GridRowParams) => number;
76
+ getDetailPanelHeight: (params: GridRowParams) => number | 'auto';
77
77
  /**
78
78
  * If `true`, the reordering of rows is enabled.
79
79
  * @default false
@@ -318,7 +318,7 @@ DataGridProRaw.propTypes = {
318
318
  /**
319
319
  * Function that returns the height of the row detail panel.
320
320
  * @param {GridRowParams} params With all properties from [[GridRowParams]].
321
- * @returns {number} The height in pixels.
321
+ * @returns {number | string} The height in pixels or "auto" to use the content height.
322
322
  * @default "() => 500"
323
323
  */
324
324
  getDetailPanelHeight: PropTypes.func,
@@ -3,7 +3,6 @@ import _extends from "@babel/runtime/helpers/esm/extends";
3
3
  const _excluded = ["className", "disableVirtualization"];
4
4
  import * as React from 'react';
5
5
  import { styled, alpha } from '@mui/material/styles';
6
- import Box from '@mui/material/Box';
7
6
  import { unstable_composeClasses as composeClasses } from '@mui/material';
8
7
  import { useGridSelector, getDataGridUtilityClass, gridClasses, gridVisibleColumnFieldsSelector, gridRowsMetaSelector, useGridApiEventHandler } from '@mui/x-data-grid';
9
8
  import { GridVirtualScroller, GridVirtualScrollerContent, GridVirtualScrollerRenderZone, useGridVirtualScroller } from '@mui/x-data-grid/internals';
@@ -11,6 +10,7 @@ import { useGridApiContext } from '../hooks/utils/useGridApiContext';
11
10
  import { useGridRootProps } from '../hooks/utils/useGridRootProps';
12
11
  import { gridPinnedColumnsSelector, GridPinnedPosition } from '../hooks/features/columnPinning';
13
12
  import { gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector, gridDetailPanelExpandedRowIdsSelector } from '../hooks/features/detailPanel';
13
+ import { GridDetailPanel } from './GridDetailPanel';
14
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
15
  import { jsxs as _jsxs } from "react/jsx-runtime";
16
16
  export const filterColumns = (pinnedColumns, columns) => {
@@ -72,19 +72,6 @@ const VirtualScrollerDetailPanels = styled('div', {
72
72
  })({
73
73
  position: 'relative'
74
74
  });
75
- const VirtualScrollerDetailPanel = styled(Box, {
76
- name: 'MuiDataGrid',
77
- slot: 'DetailPanel',
78
- overridesResolver: (props, styles) => styles.detailPanel
79
- })(({
80
- theme
81
- }) => ({
82
- zIndex: 2,
83
- width: '100%',
84
- position: 'absolute',
85
- backgroundColor: theme.palette.background.default,
86
- overflow: 'auto'
87
- }));
88
75
  const VirtualScrollerPinnedColumns = styled('div', {
89
76
  name: 'MuiDataGrid',
90
77
  slot: 'PinnedColumns',
@@ -208,15 +195,17 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
208
195
  const exists = rowIndex !== undefined;
209
196
 
210
197
  if ( /*#__PURE__*/React.isValidElement(content) && exists) {
211
- const height = detailPanelsHeights[id];
198
+ const hasAutoHeight = apiRef.current.unstable_detailPanelHasAutoHeight(id);
199
+ const height = hasAutoHeight ? 'auto' : detailPanelsHeights[id];
212
200
  const sizes = apiRef.current.unstable_getRowInternalSizes(id);
213
201
  const spacingTop = sizes?.spacingTop || 0;
214
202
  const top = rowsMeta.positions[rowIndex] + apiRef.current.unstable_getRowHeight(id) + spacingTop;
215
- panels.push( /*#__PURE__*/_jsx(VirtualScrollerDetailPanel, {
203
+ panels.push( /*#__PURE__*/_jsx(GridDetailPanel, {
204
+ rowId: id,
216
205
  style: {
217
- top,
218
- height
206
+ top
219
207
  },
208
+ height: height,
220
209
  className: classes.detailPanel,
221
210
  children: content
222
211
  }, i));
@@ -0,0 +1,65 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["rowId", "height", "style"];
4
+ import * as React from 'react';
5
+ import Box from '@mui/material/Box';
6
+ import { styled } from '@mui/material/styles';
7
+ import { useGridApiContext } from '../hooks/utils/useGridApiContext';
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ const DetailPanel = styled(Box, {
10
+ name: 'MuiDataGrid',
11
+ slot: 'DetailPanel',
12
+ overridesResolver: (props, styles) => styles.detailPanel
13
+ })(({
14
+ theme
15
+ }) => ({
16
+ zIndex: 2,
17
+ width: '100%',
18
+ position: 'absolute',
19
+ backgroundColor: theme.palette.background.default,
20
+ overflow: 'auto'
21
+ }));
22
+
23
+ const GridDetailPanel = props => {
24
+ const {
25
+ rowId,
26
+ height,
27
+ style: styleProp = {}
28
+ } = props,
29
+ other = _objectWithoutPropertiesLoose(props, _excluded);
30
+
31
+ const apiRef = useGridApiContext();
32
+ const ref = React.useRef();
33
+ React.useLayoutEffect(() => {
34
+ if (height === 'auto' && ref.current && typeof ResizeObserver === 'undefined') {
35
+ // Fallback for IE
36
+ apiRef.current.unstable_storeDetailPanelHeight(rowId, ref.current.clientHeight);
37
+ }
38
+ }, [apiRef, height, rowId]);
39
+ React.useLayoutEffect(() => {
40
+ const hasFixedHeight = height !== 'auto';
41
+
42
+ if (!ref.current || hasFixedHeight || typeof ResizeObserver === 'undefined') {
43
+ return undefined;
44
+ }
45
+
46
+ const resizeObserver = new ResizeObserver(entries => {
47
+ const [entry] = entries;
48
+ const observedHeight = entry.borderBoxSize && entry.borderBoxSize.length > 0 ? entry.borderBoxSize[0].blockSize : entry.contentRect.height;
49
+ apiRef.current.unstable_storeDetailPanelHeight(rowId, observedHeight);
50
+ });
51
+ resizeObserver.observe(ref.current);
52
+ return () => resizeObserver.disconnect();
53
+ }, [apiRef, height, rowId]);
54
+
55
+ const style = _extends({}, styleProp, {
56
+ height
57
+ });
58
+
59
+ return /*#__PURE__*/_jsx(DetailPanel, _extends({
60
+ ref: ref,
61
+ style: style
62
+ }, other));
63
+ };
64
+
65
+ export { GridDetailPanel };
@@ -1,3 +1,11 @@
1
+ import { createSelector } from '@mui/x-data-grid/internals';
1
2
  export const gridDetailPanelExpandedRowIdsSelector = state => state.detailPanel.expandedRowIds;
2
3
  export const gridDetailPanelExpandedRowsContentCacheSelector = state => state.detailPanel.contentCache;
3
- export const gridDetailPanelExpandedRowsHeightCacheSelector = state => state.detailPanel.heightCache;
4
+ export const gridDetailPanelRawHeightCacheSelector = state => state.detailPanel.heightCache; // TODO v6: Make this selector return the full object, including the autoHeight flag
5
+
6
+ export const gridDetailPanelExpandedRowsHeightCacheSelector = createSelector(gridDetailPanelRawHeightCacheSelector, heightCache => Object.entries(heightCache).reduce((acc, [id, {
7
+ height
8
+ }]) => {
9
+ acc[id] = height || 0;
10
+ return acc;
11
+ }, {}));
@@ -1,3 +1,3 @@
1
1
  export * from './gridDetailPanelToggleColDef';
2
- export * from './gridDetailPanelSelector';
2
+ export { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector } from './gridDetailPanelSelector';
3
3
  export * from './gridDetailPanelInterface';
@@ -3,16 +3,17 @@ import * as React from 'react';
3
3
  import { useGridSelector, useGridApiEventHandler, useGridApiMethod, gridRowIdsSelector } from '@mui/x-data-grid';
4
4
  import { useGridRegisterPipeProcessor } from '@mui/x-data-grid/internals';
5
5
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from './gridDetailPanelToggleColDef';
6
- import { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector } from './gridDetailPanelSelector';
6
+ import { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowsHeightCacheSelector, gridDetailPanelRawHeightCacheSelector } from './gridDetailPanelSelector';
7
7
  export const detailPanelStateInitializer = (state, props) => {
8
8
  return _extends({}, state, {
9
9
  detailPanel: {
10
+ heightCache: {},
10
11
  expandedRowIds: props.detailPanelExpandedRowIds ?? props.initialState?.detailPanel?.expandedRowIds ?? []
11
12
  }
12
13
  });
13
14
  };
14
15
 
15
- function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight) {
16
+ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight, previousHeightCache) {
16
17
  if (typeof getDetailPanelContent !== 'function') {
17
18
  return {};
18
19
  } // TODO change to lazy approach using a Proxy
@@ -31,7 +32,12 @@ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeig
31
32
  }
32
33
 
33
34
  const params = apiRef.current.getRowParams(id);
34
- acc[id] = getDetailPanelHeight(params);
35
+ const height = getDetailPanelHeight(params);
36
+ const autoHeight = height === 'auto';
37
+ acc[id] = {
38
+ autoHeight,
39
+ height: autoHeight ? previousHeightCache[id]?.height : height
40
+ };
35
41
  return acc;
36
42
  }, {});
37
43
  return {
@@ -110,10 +116,36 @@ export const useGridDetailPanel = (apiRef, props) => {
110
116
  });
111
117
  apiRef.current.forceUpdate();
112
118
  }, [apiRef]);
119
+ const storeDetailPanelHeight = React.useCallback((id, height) => {
120
+ const heightCache = gridDetailPanelRawHeightCacheSelector(apiRef.current.state);
121
+
122
+ if (!heightCache[id] || heightCache[id].height === height) {
123
+ return;
124
+ }
125
+
126
+ apiRef.current.setState(state => {
127
+ return _extends({}, state, {
128
+ detailPanel: _extends({}, state.detailPanel, {
129
+ heightCache: _extends({}, heightCache, {
130
+ [id]: _extends({}, heightCache[id], {
131
+ height
132
+ })
133
+ })
134
+ })
135
+ });
136
+ });
137
+ apiRef.current.unstable_requestPipeProcessorsApplication('rowHeight');
138
+ }, [apiRef]);
139
+ const detailPanelHasAutoHeight = React.useCallback(id => {
140
+ const heightCache = gridDetailPanelRawHeightCacheSelector(apiRef.current.state);
141
+ return heightCache[id] ? heightCache[id].autoHeight : false;
142
+ }, [apiRef]);
113
143
  const detailPanelApi = {
114
144
  toggleDetailPanel,
115
145
  getExpandedDetailPanels,
116
- setExpandedDetailPanels
146
+ setExpandedDetailPanels,
147
+ unstable_storeDetailPanelHeight: storeDetailPanelHeight,
148
+ unstable_detailPanelHasAutoHeight: detailPanelHasAutoHeight
117
149
  };
118
150
  useGridApiMethod(apiRef, detailPanelApi, 'detailPanelApi');
119
151
  React.useEffect(() => {
@@ -128,7 +160,7 @@ export const useGridDetailPanel = (apiRef, props) => {
128
160
  const updateCachesAndForceUpdate = React.useCallback(() => {
129
161
  apiRef.current.setState(state => {
130
162
  return _extends({}, state, {
131
- detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight))
163
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
132
164
  });
133
165
  });
134
166
  apiRef.current.forceUpdate();
@@ -143,7 +175,7 @@ export const useGridDetailPanel = (apiRef, props) => {
143
175
 
144
176
  apiRef.current.setState(state => {
145
177
  return _extends({}, state, {
146
- detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight))
178
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
147
179
  });
148
180
  });
149
181
  previousGetDetailPanelContentProp.current = props.getDetailPanelContent;
@@ -157,7 +189,7 @@ export const useGridDetailPanel = (apiRef, props) => {
157
189
  }
158
190
 
159
191
  updateCachesIfNeeded();
160
- const heightCache = gridDetailPanelExpandedRowsHeightCacheSelector(apiRef.current.state);
192
+ const heightCache = gridDetailPanelExpandedRowsHeightCacheSelector(apiRef);
161
193
  return _extends({}, initialValue, {
162
194
  detail: heightCache[row.id] ?? 0 // Fallback to zero because the cache might not be ready yet (e.g. page was changed)
163
195
 
@@ -0,0 +1,62 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { useGridApiEventHandler, gridRowIdsSelector } from '@mui/x-data-grid';
4
+
5
+ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeight, previousHeightCache) {
6
+ if (typeof getDetailPanelContent !== 'function') {
7
+ return {};
8
+ } // TODO change to lazy approach using a Proxy
9
+ // only call getDetailPanelContent when asked for an id
10
+
11
+
12
+ const rowIds = gridRowIdsSelector(apiRef);
13
+ const contentCache = rowIds.reduce((acc, id) => {
14
+ const params = apiRef.current.getRowParams(id);
15
+ acc[id] = getDetailPanelContent(params);
16
+ return acc;
17
+ }, {});
18
+ const heightCache = rowIds.reduce((acc, id) => {
19
+ if (contentCache[id] == null) {
20
+ return acc;
21
+ }
22
+
23
+ const params = apiRef.current.getRowParams(id);
24
+ const height = getDetailPanelHeight(params);
25
+ const autoHeight = height === 'auto';
26
+ acc[id] = {
27
+ autoHeight,
28
+ height: !autoHeight ? height : previousHeightCache[id]?.height
29
+ };
30
+ return acc;
31
+ }, {});
32
+ return {
33
+ contentCache,
34
+ heightCache
35
+ };
36
+ }
37
+
38
+ export const useGridDetailPanelCache = (apiRef, props) => {
39
+ const updateCaches = React.useCallback(() => {
40
+ apiRef.current.setState(state => {
41
+ return _extends({}, state, {
42
+ detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
43
+ });
44
+ });
45
+ apiRef.current.forceUpdate();
46
+ }, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]);
47
+ useGridApiEventHandler(apiRef, 'sortedRowsSet', updateCaches);
48
+ const isFirstRender = React.useRef(true);
49
+
50
+ if (isFirstRender.current) {
51
+ isFirstRender.current = false;
52
+ updateCaches();
53
+ }
54
+
55
+ React.useEffect(() => {
56
+ if (isFirstRender.current) {
57
+ return;
58
+ }
59
+
60
+ updateCaches();
61
+ }, [updateCaches]);
62
+ };
package/modern/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.12.3
1
+ /** @license MUI v5.13.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTY1NjAyMTYwMDAwMA==";
3
+ const releaseInfo = "MTY1NzE0NDgwMDAwMA==";
4
4
 
5
5
  if (process.env.NODE_ENV !== 'production') {
6
6
  // A simple hack to set the value in the test environment (has no build step).
@@ -342,7 +342,7 @@ DataGridProRaw.propTypes = {
342
342
  /**
343
343
  * Function that returns the height of the row detail panel.
344
344
  * @param {GridRowParams} params With all properties from [[GridRowParams]].
345
- * @returns {number} The height in pixels.
345
+ * @returns {number | string} The height in pixels or "auto" to use the content height.
346
346
  * @default "() => 500"
347
347
  */
348
348
  getDetailPanelHeight: _propTypes.default.func,
@@ -15,8 +15,6 @@ var React = _interopRequireWildcard(require("react"));
15
15
 
16
16
  var _styles = require("@mui/material/styles");
17
17
 
18
- var _Box = _interopRequireDefault(require("@mui/material/Box"));
19
-
20
18
  var _material = require("@mui/material");
21
19
 
22
20
  var _xDataGrid = require("@mui/x-data-grid");
@@ -31,6 +29,8 @@ var _columnPinning = require("../hooks/features/columnPinning");
31
29
 
32
30
  var _detailPanel = require("../hooks/features/detailPanel");
33
31
 
32
+ var _GridDetailPanel = require("./GridDetailPanel");
33
+
34
34
  var _jsxRuntime = require("react/jsx-runtime");
35
35
 
36
36
  const _excluded = ["className", "disableVirtualization"];
@@ -102,19 +102,6 @@ const VirtualScrollerDetailPanels = (0, _styles.styled)('div', {
102
102
  })({
103
103
  position: 'relative'
104
104
  });
105
- const VirtualScrollerDetailPanel = (0, _styles.styled)(_Box.default, {
106
- name: 'MuiDataGrid',
107
- slot: 'DetailPanel',
108
- overridesResolver: (props, styles) => styles.detailPanel
109
- })(({
110
- theme
111
- }) => ({
112
- zIndex: 2,
113
- width: '100%',
114
- position: 'absolute',
115
- backgroundColor: theme.palette.background.default,
116
- overflow: 'auto'
117
- }));
118
105
  const VirtualScrollerPinnedColumns = (0, _styles.styled)('div', {
119
106
  name: 'MuiDataGrid',
120
107
  slot: 'PinnedColumns',
@@ -237,15 +224,17 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
237
224
  const exists = rowIndex !== undefined;
238
225
 
239
226
  if ( /*#__PURE__*/React.isValidElement(content) && exists) {
240
- const height = detailPanelsHeights[id];
227
+ const hasAutoHeight = apiRef.current.unstable_detailPanelHasAutoHeight(id);
228
+ const height = hasAutoHeight ? 'auto' : detailPanelsHeights[id];
241
229
  const sizes = apiRef.current.unstable_getRowInternalSizes(id);
242
230
  const spacingTop = (sizes == null ? void 0 : sizes.spacingTop) || 0;
243
231
  const top = rowsMeta.positions[rowIndex] + apiRef.current.unstable_getRowHeight(id) + spacingTop;
244
- panels.push( /*#__PURE__*/(0, _jsxRuntime.jsx)(VirtualScrollerDetailPanel, {
232
+ panels.push( /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridDetailPanel.GridDetailPanel, {
233
+ rowId: id,
245
234
  style: {
246
- top,
247
- height
235
+ top
248
236
  },
237
+ height: height,
249
238
  className: classes.detailPanel,
250
239
  children: content
251
240
  }, i));