@mui/x-data-grid 6.13.0 → 6.15.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 (155) hide show
  1. package/CHANGELOG.md +162 -1
  2. package/DataGrid/useDataGridComponent.js +43 -40
  3. package/README.md +3 -7
  4. package/components/DataGridVirtualScroller.d.ts +1 -4
  5. package/components/DataGridVirtualScroller.js +3 -5
  6. package/components/GridColumnHeaders.js +2 -3
  7. package/components/GridPagination.d.ts +2 -44
  8. package/components/GridRow.js +4 -2
  9. package/components/base/GridBody.d.ts +0 -1
  10. package/components/base/GridBody.js +2 -22
  11. package/components/cell/GridActionsCell.js +2 -2
  12. package/components/cell/GridActionsCellItem.d.ts +10 -54
  13. package/components/cell/GridCell.js +4 -2
  14. package/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  15. package/components/menu/GridMenu.d.ts +1 -2
  16. package/components/menu/GridMenu.js +21 -5
  17. package/components/menu/columnMenu/GridColumnHeaderMenu.js +11 -8
  18. package/components/panel/GridPanelWrapper.js +2 -2
  19. package/components/panel/filterPanel/GridFilterInputBoolean.js +3 -5
  20. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +1 -1
  21. package/components/toolbar/GridToolbarDensitySelector.js +2 -7
  22. package/components/toolbar/GridToolbarExportContainer.js +1 -9
  23. package/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  24. package/hooks/features/export/useGridPrintExport.js +37 -7
  25. package/hooks/features/filter/gridFilterUtils.js +10 -6
  26. package/hooks/features/focus/useGridFocus.js +0 -1
  27. package/hooks/features/index.d.ts +1 -0
  28. package/hooks/features/index.js +2 -1
  29. package/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +16 -0
  30. package/hooks/features/virtualization/gridVirtualizationSelectors.js +18 -0
  31. package/hooks/features/virtualization/index.d.ts +2 -0
  32. package/hooks/features/virtualization/index.js +2 -0
  33. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +0 -1
  34. package/hooks/features/virtualization/useGridVirtualScroller.js +53 -36
  35. package/hooks/features/virtualization/useGridVirtualization.d.ts +12 -0
  36. package/hooks/features/virtualization/useGridVirtualization.js +47 -0
  37. package/index.js +1 -1
  38. package/internals/index.d.ts +4 -0
  39. package/internals/index.js +4 -0
  40. package/legacy/DataGrid/useDataGridComponent.js +43 -40
  41. package/legacy/components/DataGridVirtualScroller.js +2 -4
  42. package/legacy/components/GridColumnHeaders.js +2 -3
  43. package/legacy/components/GridRow.js +4 -2
  44. package/legacy/components/base/GridBody.js +2 -26
  45. package/legacy/components/cell/GridActionsCell.js +2 -2
  46. package/legacy/components/cell/GridCell.js +4 -2
  47. package/legacy/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  48. package/legacy/components/menu/GridMenu.js +21 -5
  49. package/legacy/components/menu/columnMenu/GridColumnHeaderMenu.js +11 -8
  50. package/legacy/components/panel/GridPanelWrapper.js +2 -2
  51. package/legacy/components/panel/filterPanel/GridFilterInputBoolean.js +4 -5
  52. package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +2 -1
  53. package/legacy/components/toolbar/GridToolbarDensitySelector.js +2 -7
  54. package/legacy/components/toolbar/GridToolbarExportContainer.js +1 -9
  55. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  56. package/legacy/hooks/features/export/useGridPrintExport.js +44 -12
  57. package/legacy/hooks/features/filter/gridFilterUtils.js +10 -6
  58. package/legacy/hooks/features/focus/useGridFocus.js +0 -1
  59. package/legacy/hooks/features/index.js +2 -1
  60. package/legacy/hooks/features/virtualization/gridVirtualizationSelectors.js +24 -0
  61. package/legacy/hooks/features/virtualization/index.js +2 -0
  62. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +61 -39
  63. package/legacy/hooks/features/virtualization/useGridVirtualization.js +51 -0
  64. package/legacy/index.js +1 -1
  65. package/legacy/internals/index.js +4 -0
  66. package/legacy/locales/faIR.js +25 -27
  67. package/legacy/locales/jaJP.js +25 -27
  68. package/legacy/locales/viVN.js +35 -39
  69. package/legacy/models/api/index.js +1 -2
  70. package/legacy/utils/createControllablePromise.js +11 -0
  71. package/locales/faIR.js +25 -27
  72. package/locales/jaJP.js +25 -27
  73. package/locales/viVN.js +35 -39
  74. package/models/api/gridApiCommon.d.ts +3 -4
  75. package/models/api/gridVirtualizationApi.d.ts +20 -0
  76. package/models/api/index.d.ts +1 -2
  77. package/models/api/index.js +1 -2
  78. package/models/events/gridEventLookup.d.ts +8 -0
  79. package/models/gridExport.d.ts +17 -4
  80. package/models/gridStateCommunity.d.ts +2 -1
  81. package/models/index.d.ts +1 -1
  82. package/modern/DataGrid/useDataGridComponent.js +43 -40
  83. package/modern/components/DataGridVirtualScroller.js +3 -5
  84. package/modern/components/GridColumnHeaders.js +2 -3
  85. package/modern/components/GridRow.js +4 -2
  86. package/modern/components/base/GridBody.js +2 -22
  87. package/modern/components/cell/GridActionsCell.js +2 -2
  88. package/modern/components/cell/GridCell.js +4 -2
  89. package/modern/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  90. package/modern/components/menu/GridMenu.js +20 -5
  91. package/modern/components/menu/columnMenu/GridColumnHeaderMenu.js +11 -8
  92. package/modern/components/panel/GridPanelWrapper.js +2 -2
  93. package/modern/components/panel/filterPanel/GridFilterInputBoolean.js +3 -5
  94. package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +1 -1
  95. package/modern/components/toolbar/GridToolbarDensitySelector.js +2 -7
  96. package/modern/components/toolbar/GridToolbarExportContainer.js +1 -9
  97. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  98. package/modern/hooks/features/export/useGridPrintExport.js +37 -7
  99. package/modern/hooks/features/filter/gridFilterUtils.js +10 -6
  100. package/modern/hooks/features/focus/useGridFocus.js +0 -1
  101. package/modern/hooks/features/index.js +2 -1
  102. package/modern/hooks/features/virtualization/gridVirtualizationSelectors.js +18 -0
  103. package/modern/hooks/features/virtualization/index.js +2 -0
  104. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +52 -36
  105. package/modern/hooks/features/virtualization/useGridVirtualization.js +47 -0
  106. package/modern/index.js +1 -1
  107. package/modern/internals/index.js +4 -0
  108. package/modern/locales/faIR.js +25 -27
  109. package/modern/locales/jaJP.js +25 -27
  110. package/modern/locales/viVN.js +35 -39
  111. package/modern/models/api/index.js +1 -2
  112. package/modern/utils/createControllablePromise.js +11 -0
  113. package/node/DataGrid/useDataGridComponent.js +43 -40
  114. package/node/components/DataGridVirtualScroller.js +3 -5
  115. package/node/components/GridColumnHeaders.js +2 -3
  116. package/node/components/GridRow.js +4 -2
  117. package/node/components/base/GridBody.js +2 -22
  118. package/node/components/cell/GridActionsCell.js +2 -2
  119. package/node/components/cell/GridCell.js +4 -2
  120. package/node/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  121. package/node/components/menu/GridMenu.js +19 -4
  122. package/node/components/menu/columnMenu/GridColumnHeaderMenu.js +10 -7
  123. package/node/components/panel/filterPanel/GridFilterInputBoolean.js +2 -4
  124. package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +1 -1
  125. package/node/components/toolbar/GridToolbarDensitySelector.js +2 -7
  126. package/node/components/toolbar/GridToolbarExportContainer.js +1 -9
  127. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  128. package/node/hooks/features/export/useGridPrintExport.js +37 -7
  129. package/node/hooks/features/filter/gridFilterUtils.js +9 -6
  130. package/node/hooks/features/focus/useGridFocus.js +0 -1
  131. package/node/hooks/features/index.js +11 -0
  132. package/node/hooks/features/virtualization/gridVirtualizationSelectors.js +27 -0
  133. package/node/hooks/features/virtualization/index.js +27 -0
  134. package/node/hooks/features/virtualization/useGridVirtualScroller.js +51 -37
  135. package/node/hooks/features/virtualization/useGridVirtualization.js +58 -0
  136. package/node/index.js +1 -1
  137. package/node/internals/index.js +44 -0
  138. package/node/locales/faIR.js +25 -27
  139. package/node/locales/jaJP.js +25 -27
  140. package/node/locales/viVN.js +35 -39
  141. package/node/models/api/index.js +4 -15
  142. package/node/utils/createControllablePromise.js +17 -0
  143. package/package.json +2 -2
  144. package/utils/createControllablePromise.d.ts +5 -0
  145. package/utils/createControllablePromise.js +11 -0
  146. package/models/api/gridDisableVirtualizationApi.d.ts +0 -15
  147. package/models/api/gridVirtualScrollerApi.d.ts +0 -8
  148. package/models/api/gridVirtualScrollerApi.js +0 -1
  149. package/modern/models/api/gridDisableVirtualizationApi.js +0 -1
  150. package/modern/models/api/gridVirtualScrollerApi.js +0 -1
  151. package/node/models/api/gridVirtualScrollerApi.js +0 -5
  152. /package/legacy/models/api/{gridDisableVirtualizationApi.js → gridVirtualizationApi.js} +0 -0
  153. /package/{legacy/models/api/gridVirtualScrollerApi.js → models/api/gridVirtualizationApi.js} +0 -0
  154. /package/{models/api/gridDisableVirtualizationApi.js → modern/models/api/gridVirtualizationApi.js} +0 -0
  155. /package/node/models/api/{gridDisableVirtualizationApi.js → gridVirtualizationApi.js} +0 -0
@@ -1,11 +1,11 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["open", "target", "onClickAway", "children", "position", "className", "onExited"];
3
+ const _excluded = ["open", "target", "onClose", "children", "position", "className", "onExited"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
7
7
  import ClickAwayListener from '@mui/material/ClickAwayListener';
8
- import { unstable_composeClasses as composeClasses, HTMLElementType } from '@mui/utils';
8
+ import { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect, HTMLElementType } from '@mui/utils';
9
9
  import Grow from '@mui/material/Grow';
10
10
  import Paper from '@mui/material/Paper';
11
11
  import Popper from '@mui/material/Popper';
@@ -43,7 +43,7 @@ function GridMenu(props) {
43
43
  const {
44
44
  open,
45
45
  target,
46
- onClickAway,
46
+ onClose,
47
47
  children,
48
48
  position,
49
49
  className,
@@ -53,6 +53,15 @@ function GridMenu(props) {
53
53
  const apiRef = useGridApiContext();
54
54
  const rootProps = useGridRootProps();
55
55
  const classes = useUtilityClasses(rootProps);
56
+ const savedFocusRef = React.useRef(null);
57
+ useEnhancedEffect(() => {
58
+ if (open) {
59
+ savedFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
60
+ } else {
61
+ savedFocusRef.current?.focus?.();
62
+ savedFocusRef.current = null;
63
+ }
64
+ }, [open]);
56
65
  React.useEffect(() => {
57
66
  // Emit menuOpen or menuClose events
58
67
  const eventName = open ? 'menuOpen' : 'menuClose';
@@ -68,6 +77,12 @@ function GridMenu(props) {
68
77
  onExited(node);
69
78
  }
70
79
  };
80
+ const handleClickAway = event => {
81
+ if (event.target && (target === event.target || target?.contains(event.target))) {
82
+ return;
83
+ }
84
+ onClose(event);
85
+ };
71
86
  return /*#__PURE__*/_jsx(GridMenuRoot, _extends({
72
87
  as: rootProps.slots.basePopper,
73
88
  className: clsx(className, classes.root),
@@ -81,7 +96,7 @@ function GridMenu(props) {
81
96
  TransitionProps,
82
97
  placement
83
98
  }) => /*#__PURE__*/_jsx(ClickAwayListener, {
84
- onClickAway: onClickAway,
99
+ onClickAway: handleClickAway,
85
100
  mouseEvent: "onMouseDown",
86
101
  children: /*#__PURE__*/_jsx(Grow, _extends({}, TransitionProps, {
87
102
  style: {
@@ -101,7 +116,7 @@ process.env.NODE_ENV !== "production" ? GridMenu.propTypes = {
101
116
  // | To update them edit the TypeScript types and run "yarn proptypes" |
102
117
  // ----------------------------------------------------------------------
103
118
  children: PropTypes.node,
104
- onClickAway: PropTypes.func.isRequired,
119
+ onClose: PropTypes.func.isRequired,
105
120
  onExited: PropTypes.func,
106
121
  /**
107
122
  * If `true`, the component is shown.
@@ -1,7 +1,7 @@
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 { HTMLElementType } from '@mui/utils';
4
+ import { unstable_useEventCallback as useEventCallback, HTMLElementType } from '@mui/utils';
5
5
  import { useGridApiContext } from '../../../hooks/utils/useGridApiContext';
6
6
  import { GridMenu } from '../GridMenu';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -17,13 +17,16 @@ function GridColumnHeaderMenu({
17
17
  }) {
18
18
  const apiRef = useGridApiContext();
19
19
  const colDef = apiRef.current.getColumn(field);
20
- const hideMenu = React.useCallback(event => {
21
- // Prevent triggering the sorting
22
- event.stopPropagation();
23
- if (!target?.contains(event.target)) {
24
- apiRef.current.hideColumnMenu();
20
+ const hideMenu = useEventCallback(event => {
21
+ if (event) {
22
+ // Prevent triggering the sorting
23
+ event.stopPropagation();
24
+ if (target?.contains(event.target)) {
25
+ return;
26
+ }
25
27
  }
26
- }, [apiRef, target]);
28
+ apiRef.current.hideColumnMenu();
29
+ });
27
30
  if (!target || !colDef) {
28
31
  return null;
29
32
  }
@@ -31,7 +34,7 @@ function GridColumnHeaderMenu({
31
34
  placement: `bottom-${colDef.align === 'right' ? 'start' : 'end'}`,
32
35
  open: open,
33
36
  target: target,
34
- onClickAway: hideMenu,
37
+ onClose: hideMenu,
35
38
  onExited: onExited,
36
39
  children: /*#__PURE__*/_jsx(ContentComponent, _extends({
37
40
  colDef: colDef,
@@ -4,7 +4,7 @@ const _excluded = ["className", "slotProps"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
7
- import TrapFocus from '@mui/material/Unstable_TrapFocus';
7
+ import FocusTrap from '@mui/material/Unstable_TrapFocus';
8
8
  import { styled } from '@mui/material/styles';
9
9
  import { unstable_composeClasses as composeClasses } from '@mui/utils';
10
10
  import { getDataGridUtilityClass } from '../../constants/gridClasses';
@@ -40,7 +40,7 @@ const GridPanelWrapper = /*#__PURE__*/React.forwardRef(function GridPanelWrapper
40
40
  other = _objectWithoutPropertiesLoose(props, _excluded);
41
41
  const rootProps = useGridRootProps();
42
42
  const classes = useUtilityClasses(rootProps);
43
- return /*#__PURE__*/_jsx(TrapFocus, _extends({
43
+ return /*#__PURE__*/_jsx(FocusTrap, _extends({
44
44
  open: true,
45
45
  disableEnforceFocus: true,
46
46
  isEnabled: isEnabled
@@ -1,9 +1,9 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["item", "applyValue", "apiRef", "focusElementRef", "isFilterActive", "clearButton", "tabIndex", "label"];
3
+ const _excluded = ["item", "applyValue", "apiRef", "focusElementRef", "isFilterActive", "clearButton", "tabIndex", "label", "InputLabelProps"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
- import { unstable_useId as useId } from '@mui/utils';
6
+ import { refType, unstable_useId as useId } from '@mui/utils';
7
7
  import { styled } from '@mui/material/styles';
8
8
  import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -94,9 +94,7 @@ process.env.NODE_ENV !== "production" ? GridFilterInputBoolean.propTypes = {
94
94
  }).isRequired,
95
95
  applyValue: PropTypes.func.isRequired,
96
96
  clearButton: PropTypes.node,
97
- focusElementRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
98
- current: PropTypes.any.isRequired
99
- })]),
97
+ focusElementRef: refType,
100
98
  /**
101
99
  * It is `true` if the filter either has a value or an operator with no value
102
100
  * required is selected (e.g. `isEmpty`)
@@ -1,6 +1,6 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "getOptionLabel", "getOptionValue", "placeholder", "tabIndex", "label", "isFilterActive", "clearButton"];
3
+ const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "getOptionLabel", "getOptionValue", "placeholder", "tabIndex", "label", "isFilterActive", "clearButton", "InputLabelProps"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { unstable_useId as useId } from '@mui/utils';
@@ -55,12 +55,7 @@ export const GridToolbarDensitySelector = /*#__PURE__*/React.forwardRef(function
55
55
  setOpen(prevOpen => !prevOpen);
56
56
  onClick?.(event);
57
57
  };
58
- const handleDensitySelectorClickAway = event => {
59
- if (buttonRef.current === event.target ||
60
- // if user clicked on the icon
61
- buttonRef.current?.contains(event.target)) {
62
- return;
63
- }
58
+ const handleDensitySelectorClose = () => {
64
59
  setOpen(false);
65
60
  };
66
61
  const handleDensityUpdate = newDensity => {
@@ -104,7 +99,7 @@ export const GridToolbarDensitySelector = /*#__PURE__*/React.forwardRef(function
104
99
  })), /*#__PURE__*/_jsx(GridMenu, {
105
100
  open: open,
106
101
  target: buttonRef.current,
107
- onClickAway: handleDensitySelectorClickAway,
102
+ onClose: handleDensitySelectorClose,
108
103
  position: "bottom-start",
109
104
  children: /*#__PURE__*/_jsx(MenuList, {
110
105
  id: densityMenuId,
@@ -37,14 +37,6 @@ export const GridToolbarExportContainer = /*#__PURE__*/React.forwardRef(function
37
37
  handleMenuClose();
38
38
  }
39
39
  };
40
- const handleMenuClickAway = event => {
41
- if (buttonRef.current === event.target ||
42
- // if user clicked on the icon
43
- buttonRef.current?.contains(event.target)) {
44
- return;
45
- }
46
- setOpen(false);
47
- };
48
40
  if (children == null) {
49
41
  return null;
50
42
  }
@@ -65,7 +57,7 @@ export const GridToolbarExportContainer = /*#__PURE__*/React.forwardRef(function
65
57
  })), /*#__PURE__*/_jsx(GridMenu, {
66
58
  open: open,
67
59
  target: buttonRef.current,
68
- onClickAway: handleMenuClickAway,
60
+ onClose: handleMenuClose,
69
61
  position: "bottom-start",
70
62
  children: /*#__PURE__*/_jsx(MenuList, {
71
63
  id: exportMenuId,
@@ -4,6 +4,7 @@ import * as ReactDOM from 'react-dom';
4
4
  import { unstable_useForkRef as useForkRef } from '@mui/utils';
5
5
  import { styled, useTheme } from '@mui/system';
6
6
  import { defaultMemoize } from 'reselect';
7
+ import { useGridSelector } from '../../utils';
7
8
  import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext';
8
9
  import { useGridRootProps } from '../../utils/useGridRootProps';
9
10
  import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
@@ -11,6 +12,7 @@ import { GridColumnHeaderItem } from '../../../components/columnHeaders/GridColu
11
12
  import { getFirstColumnIndexToRender, getTotalHeaderHeight } from '../columns/gridColumnsUtils';
12
13
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
13
14
  import { areRenderContextsEqual, getRenderableIndexes } from '../virtualization/useGridVirtualScroller';
15
+ import { gridVirtualizationColumnEnabledSelector } from '../virtualization';
14
16
  import { GridColumnGroupHeader } from '../../../components/columnHeaders/GridColumnGroupHeader';
15
17
  import { jsx as _jsx } from "react/jsx-runtime";
16
18
  const GridColumnHeaderRow = styled('div', {
@@ -46,6 +48,7 @@ export const useGridColumnHeaders = props => {
46
48
  const [dragCol, setDragCol] = React.useState('');
47
49
  const [resizeCol, setResizeCol] = React.useState('');
48
50
  const apiRef = useGridPrivateApiContext();
51
+ const hasVirtualization = useGridSelector(apiRef, gridVirtualizationColumnEnabledSelector);
49
52
  const rootProps = useGridRootProps();
50
53
  const innerRef = React.useRef(null);
51
54
  const handleInnerRef = useForkRef(innerRefProp, innerRef);
@@ -163,7 +166,7 @@ export const useGridColumnHeaders = props => {
163
166
  maxLastIndex: currentPage.rows.length,
164
167
  buffer: rootProps.rowBuffer
165
168
  });
166
- const firstColumnToRender = getFirstColumnIndexToRenderRef.current({
169
+ const firstColumnToRender = !hasVirtualization ? 0 : getFirstColumnIndexToRenderRef.current({
167
170
  firstColumnIndex: nextRenderContext.firstColumnIndex,
168
171
  minColumnIndex: minFirstColumn,
169
172
  columnBuffer: rootProps.columnBuffer,
@@ -172,7 +175,7 @@ export const useGridColumnHeaders = props => {
172
175
  lastRowToRender,
173
176
  visibleRows: currentPage.rows
174
177
  });
175
- const lastColumnToRender = Math.min(nextRenderContext.lastColumnIndex + rootProps.columnBuffer, maxLastColumn);
178
+ const lastColumnToRender = !hasVirtualization ? maxLastColumn : Math.min(nextRenderContext.lastColumnIndex + rootProps.columnBuffer, maxLastColumn);
176
179
  const renderedColumns = visibleColumns.slice(firstColumnToRender, lastColumnToRender);
177
180
  return {
178
181
  renderedColumns,
@@ -12,6 +12,7 @@ import { mergeStateWithPaginationModel } from '../pagination/useGridPagination';
12
12
  import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
13
13
  import { GridPrintExportMenuItem } from '../../../components/toolbar/GridToolbarExport';
14
14
  import { getTotalHeaderHeight } from '../columns/gridColumnsUtils';
15
+ import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../colDef/gridCheckboxSelectionColDef';
15
16
  import { jsx as _jsx } from "react/jsx-runtime";
16
17
  function raf() {
17
18
  return new Promise(resolve => {
@@ -40,13 +41,14 @@ export const useGridPrintExport = (apiRef, props) => {
40
41
  const doc = React.useRef(null);
41
42
  const previousGridState = React.useRef(null);
42
43
  const previousColumnVisibility = React.useRef({});
44
+ const previousRows = React.useRef([]);
43
45
  React.useEffect(() => {
44
46
  doc.current = ownerDocument(apiRef.current.rootElementRef.current);
45
47
  }, [apiRef]);
46
48
 
47
49
  // Returns a promise because updateColumns triggers state update and
48
50
  // the new state needs to be in place before the grid can be sized correctly
49
- const updateGridColumnsForPrint = React.useCallback((fields, allColumns) => new Promise(resolve => {
51
+ const updateGridColumnsForPrint = React.useCallback((fields, allColumns, includeCheckboxes) => new Promise(resolve => {
50
52
  const exportedColumnFields = getColumnsToExport({
51
53
  apiRef,
52
54
  options: {
@@ -59,14 +61,25 @@ export const useGridPrintExport = (apiRef, props) => {
59
61
  columns.forEach(column => {
60
62
  newColumnVisibilityModel[column.field] = exportedColumnFields.includes(column.field);
61
63
  });
64
+ if (includeCheckboxes) {
65
+ newColumnVisibilityModel[GRID_CHECKBOX_SELECTION_COL_DEF.field] = true;
66
+ }
62
67
  apiRef.current.setColumnVisibilityModel(newColumnVisibilityModel);
63
68
  resolve();
64
69
  }), [apiRef]);
70
+ const updateGridRowsForPrint = React.useCallback(getRowsToExport => {
71
+ const rowsToExportIds = getRowsToExport({
72
+ apiRef
73
+ });
74
+ const newRows = rowsToExportIds.map(id => apiRef.current.getRow(id));
75
+ apiRef.current.setRows(newRows);
76
+ }, [apiRef]);
65
77
  const handlePrintWindowLoad = React.useCallback((printWindow, options) => {
66
78
  const normalizeOptions = _extends({
67
79
  copyStyles: true,
68
80
  hideToolbar: false,
69
- hideFooter: false
81
+ hideFooter: false,
82
+ includeCheckboxes: false
70
83
  }, options);
71
84
  const printDoc = printWindow.contentDocument;
72
85
  if (!printDoc) {
@@ -97,10 +110,21 @@ export const useGridPrintExport = (apiRef, props) => {
97
110
  }
98
111
 
99
112
  // Expand container height to accommodate all rows
100
- gridClone.style.height = `${rowsMeta.currentPageTotalHeight + getTotalHeaderHeight(apiRef, props.columnHeaderHeight) + gridToolbarElementHeight + gridFooterElementHeight}px`;
113
+ const computedTotalHeight = rowsMeta.currentPageTotalHeight + getTotalHeaderHeight(apiRef, props.columnHeaderHeight) + gridToolbarElementHeight + gridFooterElementHeight;
114
+ gridClone.style.height = `${computedTotalHeight}px`;
101
115
  // The height above does not include grid border width, so we need to exclude it
102
116
  gridClone.style.boxSizing = 'content-box';
103
117
 
118
+ // the footer is always being placed at the bottom of the page as if all rows are exported
119
+ // so if getRowsToExport is being used to only export a subset of rows then we need to
120
+ // adjust the footer position to be correctly placed at the bottom of the grid
121
+ if (options?.getRowsToExport) {
122
+ const gridFooterElement = gridClone.querySelector(`.${gridClasses.footerContainer}`);
123
+ gridFooterElement.style.position = 'absolute';
124
+ gridFooterElement.style.width = '100%';
125
+ gridFooterElement.style.top = `${computedTotalHeight - gridFooterElementHeight}px`;
126
+ }
127
+
104
128
  // printDoc.body.appendChild(gridClone); should be enough but a clone isolation bug in Safari
105
129
  // prevents us to do it
106
130
  const container = document.createElement('div');
@@ -173,11 +197,13 @@ export const useGridPrintExport = (apiRef, props) => {
173
197
  // if the apiRef.current.exportState(); did not exported the column visibility, we update it
174
198
  apiRef.current.setColumnVisibilityModel(previousColumnVisibility.current);
175
199
  }
176
- apiRef.current.unstable_enableVirtualization();
200
+ apiRef.current.unstable_setVirtualization(true);
201
+ apiRef.current.setRows(previousRows.current);
177
202
 
178
203
  // Clear local state
179
204
  previousGridState.current = null;
180
205
  previousColumnVisibility.current = {};
206
+ previousRows.current = [];
181
207
  }, [apiRef]);
182
208
  const exportDataAsPrint = React.useCallback(async options => {
183
209
  logger.debug(`Export data as Print`);
@@ -187,6 +213,7 @@ export const useGridPrintExport = (apiRef, props) => {
187
213
  previousGridState.current = apiRef.current.exportState();
188
214
  // It appends that the visibility model is not exported, especially if columnVisibility is not controlled
189
215
  previousColumnVisibility.current = gridColumnVisibilityModelSelector(apiRef);
216
+ previousRows.current = apiRef.current.getSortedRows();
190
217
  if (props.pagination) {
191
218
  const visibleRowCount = gridExpandedRowCountSelector(apiRef);
192
219
  const paginationModel = {
@@ -198,8 +225,11 @@ export const useGridPrintExport = (apiRef, props) => {
198
225
  mergeStateWithPaginationModel(visibleRowCount, 'DataGridPro', paginationModel));
199
226
  apiRef.current.forceUpdate();
200
227
  }
201
- await updateGridColumnsForPrint(options?.fields, options?.allColumns);
202
- apiRef.current.unstable_disableVirtualization();
228
+ await updateGridColumnsForPrint(options?.fields, options?.allColumns, options?.includeCheckboxes);
229
+ if (options?.getRowsToExport) {
230
+ updateGridRowsForPrint(options.getRowsToExport);
231
+ }
232
+ apiRef.current.unstable_setVirtualization(false);
203
233
  await raf(); // wait for the state changes to take action
204
234
  const printWindow = buildPrintWindow(options?.fileName);
205
235
  if (process.env.NODE_ENV === 'test') {
@@ -220,7 +250,7 @@ export const useGridPrintExport = (apiRef, props) => {
220
250
  };
221
251
  doc.current.body.appendChild(printWindow);
222
252
  }
223
- }, [props, logger, apiRef, handlePrintWindowLoad, handlePrintWindowAfterPrint, updateGridColumnsForPrint]);
253
+ }, [props, logger, apiRef, handlePrintWindowLoad, handlePrintWindowAfterPrint, updateGridColumnsForPrint, updateGridRowsForPrint]);
224
254
  const printExportApi = {
225
255
  exportDataAsPrint
226
256
  };
@@ -4,10 +4,13 @@ import { GLOBAL_API_REF, isInternalFilter } from '../../../colDef/utils';
4
4
  import { getDefaultGridFilterModel } from './gridFilterState';
5
5
  import { buildWarning } from '../../../utils/warning';
6
6
  import { gridColumnFieldsSelector, gridColumnLookupSelector, gridVisibleColumnFieldsSelector } from '../columns';
7
+
8
+ // Fixes https://github.com/mui/mui-x/issues/10056
9
+ const global = typeof window === 'undefined' ? globalThis : window;
10
+ const evalCode = global[atob('ZXZhbA==')];
7
11
  let hasEval;
8
12
  try {
9
- // eslint-disable-next-line no-eval
10
- hasEval = eval('true');
13
+ hasEval = evalCode('true');
11
14
  } catch (_) {
12
15
  hasEval = false;
13
16
  }
@@ -157,7 +160,7 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
157
160
 
158
161
  // We generate a new function with `eval()` to avoid expensive patterns for JS engines
159
162
  // such as a dynamic object assignment, e.g. `{ [dynamicKey]: value }`.
160
- const filterItemTemplate = `(function filterItem$$(row, shouldApplyFilter) {
163
+ const filterItemTemplate = `(function filterItem$$(appliers, row, shouldApplyFilter) {
161
164
  ${appliers.map((applier, i) => `const shouldApply${i} = !shouldApplyFilter || shouldApplyFilter(${JSON.stringify(applier.item.field)});`).join('\n')}
162
165
 
163
166
  const result$$ = {
@@ -169,9 +172,10 @@ export const buildAggregatedFilterItemsApplier = (getRowId, filterModel, apiRef,
169
172
 
170
173
  return result$$;
171
174
  })`;
172
-
173
- // eslint-disable-next-line no-eval
174
- const filterItem = eval(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
175
+ const filterItemCore = evalCode(filterItemTemplate.replaceAll('$$', String(filterItemsApplierId)));
176
+ const filterItem = (row, shouldApplyItem) => {
177
+ return filterItemCore(appliers, row, shouldApplyItem);
178
+ };
175
179
  filterItemsApplierId += 1;
176
180
  return filterItem;
177
181
  };
@@ -382,7 +382,6 @@ export const useGridFocus = (apiRef, props) => {
382
382
  };
383
383
  }, [apiRef, handleDocumentClick]);
384
384
  useGridApiEventHandler(apiRef, 'columnHeaderBlur', handleBlur);
385
- useGridApiEventHandler(apiRef, 'headerFilterBlur', handleBlur);
386
385
  useGridApiEventHandler(apiRef, 'cellDoubleClick', handleCellDoubleClick);
387
386
  useGridApiEventHandler(apiRef, 'cellMouseDown', handleCellMouseDown);
388
387
  useGridApiEventHandler(apiRef, 'cellKeyDown', handleCellKeyDown);
@@ -12,4 +12,5 @@ export * from './rowSelection';
12
12
  export * from './sorting';
13
13
  export * from './dimensions';
14
14
  export * from './statePersistence';
15
- export * from './headerFiltering';
15
+ export * from './headerFiltering';
16
+ export * from './virtualization';
@@ -0,0 +1,18 @@
1
+ import { createSelector } from '../../../utils/createSelector';
2
+ /**
3
+ * Get the columns state
4
+ * @category Virtualization
5
+ */
6
+ export const gridVirtualizationSelector = state => state.virtualization;
7
+
8
+ /**
9
+ * Get the enabled state for virtualization
10
+ * @category Virtualization
11
+ */
12
+ export const gridVirtualizationEnabledSelector = createSelector(gridVirtualizationSelector, state => state.enabled);
13
+
14
+ /**
15
+ * Get the enabled state for virtualization
16
+ * @category Virtualization
17
+ */
18
+ export const gridVirtualizationColumnEnabledSelector = createSelector(gridVirtualizationSelector, state => state.enabledForColumns);
@@ -0,0 +1,2 @@
1
+ export * from './useGridVirtualization';
2
+ export * from './gridVirtualizationSelectors';