@mui/x-data-grid 6.14.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 (134) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/DataGrid/useDataGridComponent.js +43 -40
  3. package/components/DataGridVirtualScroller.d.ts +1 -4
  4. package/components/DataGridVirtualScroller.js +3 -5
  5. package/components/GridRow.js +4 -2
  6. package/components/base/GridBody.d.ts +0 -1
  7. package/components/base/GridBody.js +2 -22
  8. package/components/cell/GridActionsCell.js +2 -2
  9. package/components/cell/GridActionsCellItem.d.ts +6 -0
  10. package/components/cell/GridCell.js +4 -2
  11. package/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  12. package/components/menu/GridMenu.d.ts +1 -2
  13. package/components/menu/GridMenu.js +21 -5
  14. package/components/menu/columnMenu/GridColumnHeaderMenu.js +11 -8
  15. package/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  16. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +1 -1
  17. package/components/toolbar/GridToolbarDensitySelector.js +2 -7
  18. package/components/toolbar/GridToolbarExportContainer.js +1 -9
  19. package/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  20. package/hooks/features/export/useGridPrintExport.js +37 -7
  21. package/hooks/features/filter/gridFilterUtils.js +10 -6
  22. package/hooks/features/focus/useGridFocus.js +0 -1
  23. package/hooks/features/index.d.ts +1 -0
  24. package/hooks/features/index.js +2 -1
  25. package/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +16 -0
  26. package/hooks/features/virtualization/gridVirtualizationSelectors.js +18 -0
  27. package/hooks/features/virtualization/index.d.ts +2 -0
  28. package/hooks/features/virtualization/index.js +2 -0
  29. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +0 -1
  30. package/hooks/features/virtualization/useGridVirtualScroller.js +53 -36
  31. package/hooks/features/virtualization/useGridVirtualization.d.ts +12 -0
  32. package/hooks/features/virtualization/useGridVirtualization.js +47 -0
  33. package/index.js +1 -1
  34. package/internals/index.d.ts +4 -0
  35. package/internals/index.js +4 -0
  36. package/legacy/DataGrid/useDataGridComponent.js +43 -40
  37. package/legacy/components/DataGridVirtualScroller.js +2 -4
  38. package/legacy/components/GridRow.js +4 -2
  39. package/legacy/components/base/GridBody.js +2 -26
  40. package/legacy/components/cell/GridActionsCell.js +2 -2
  41. package/legacy/components/cell/GridCell.js +4 -2
  42. package/legacy/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  43. package/legacy/components/menu/GridMenu.js +21 -5
  44. package/legacy/components/menu/columnMenu/GridColumnHeaderMenu.js +11 -8
  45. package/legacy/components/panel/filterPanel/GridFilterInputBoolean.js +2 -1
  46. package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +2 -1
  47. package/legacy/components/toolbar/GridToolbarDensitySelector.js +2 -7
  48. package/legacy/components/toolbar/GridToolbarExportContainer.js +1 -9
  49. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  50. package/legacy/hooks/features/export/useGridPrintExport.js +44 -12
  51. package/legacy/hooks/features/filter/gridFilterUtils.js +10 -6
  52. package/legacy/hooks/features/focus/useGridFocus.js +0 -1
  53. package/legacy/hooks/features/index.js +2 -1
  54. package/legacy/hooks/features/virtualization/gridVirtualizationSelectors.js +24 -0
  55. package/legacy/hooks/features/virtualization/index.js +2 -0
  56. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +61 -39
  57. package/legacy/hooks/features/virtualization/useGridVirtualization.js +51 -0
  58. package/legacy/index.js +1 -1
  59. package/legacy/internals/index.js +4 -0
  60. package/legacy/models/api/index.js +1 -2
  61. package/legacy/utils/createControllablePromise.js +11 -0
  62. package/models/api/gridApiCommon.d.ts +3 -4
  63. package/models/api/gridVirtualizationApi.d.ts +20 -0
  64. package/models/api/index.d.ts +1 -2
  65. package/models/api/index.js +1 -2
  66. package/models/events/gridEventLookup.d.ts +8 -0
  67. package/models/gridExport.d.ts +17 -4
  68. package/models/gridStateCommunity.d.ts +2 -1
  69. package/models/index.d.ts +1 -1
  70. package/modern/DataGrid/useDataGridComponent.js +43 -40
  71. package/modern/components/DataGridVirtualScroller.js +3 -5
  72. package/modern/components/GridRow.js +4 -2
  73. package/modern/components/base/GridBody.js +2 -22
  74. package/modern/components/cell/GridActionsCell.js +2 -2
  75. package/modern/components/cell/GridCell.js +4 -2
  76. package/modern/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  77. package/modern/components/menu/GridMenu.js +20 -5
  78. package/modern/components/menu/columnMenu/GridColumnHeaderMenu.js +11 -8
  79. package/modern/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  80. package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +1 -1
  81. package/modern/components/toolbar/GridToolbarDensitySelector.js +2 -7
  82. package/modern/components/toolbar/GridToolbarExportContainer.js +1 -9
  83. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  84. package/modern/hooks/features/export/useGridPrintExport.js +37 -7
  85. package/modern/hooks/features/filter/gridFilterUtils.js +10 -6
  86. package/modern/hooks/features/focus/useGridFocus.js +0 -1
  87. package/modern/hooks/features/index.js +2 -1
  88. package/modern/hooks/features/virtualization/gridVirtualizationSelectors.js +18 -0
  89. package/modern/hooks/features/virtualization/index.js +2 -0
  90. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +52 -36
  91. package/modern/hooks/features/virtualization/useGridVirtualization.js +47 -0
  92. package/modern/index.js +1 -1
  93. package/modern/internals/index.js +4 -0
  94. package/modern/models/api/index.js +1 -2
  95. package/modern/utils/createControllablePromise.js +11 -0
  96. package/node/DataGrid/useDataGridComponent.js +43 -40
  97. package/node/components/DataGridVirtualScroller.js +3 -5
  98. package/node/components/GridRow.js +4 -2
  99. package/node/components/base/GridBody.js +2 -22
  100. package/node/components/cell/GridActionsCell.js +2 -2
  101. package/node/components/cell/GridCell.js +4 -2
  102. package/node/components/columnHeaders/GridColumnHeaderItem.js +2 -1
  103. package/node/components/menu/GridMenu.js +19 -4
  104. package/node/components/menu/columnMenu/GridColumnHeaderMenu.js +10 -7
  105. package/node/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
  106. package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +1 -1
  107. package/node/components/toolbar/GridToolbarDensitySelector.js +2 -7
  108. package/node/components/toolbar/GridToolbarExportContainer.js +1 -9
  109. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -2
  110. package/node/hooks/features/export/useGridPrintExport.js +37 -7
  111. package/node/hooks/features/filter/gridFilterUtils.js +9 -6
  112. package/node/hooks/features/focus/useGridFocus.js +0 -1
  113. package/node/hooks/features/index.js +11 -0
  114. package/node/hooks/features/virtualization/gridVirtualizationSelectors.js +27 -0
  115. package/node/hooks/features/virtualization/index.js +27 -0
  116. package/node/hooks/features/virtualization/useGridVirtualScroller.js +51 -37
  117. package/node/hooks/features/virtualization/useGridVirtualization.js +58 -0
  118. package/node/index.js +1 -1
  119. package/node/internals/index.js +44 -0
  120. package/node/models/api/index.js +4 -15
  121. package/node/utils/createControllablePromise.js +17 -0
  122. package/package.json +1 -1
  123. package/utils/createControllablePromise.d.ts +5 -0
  124. package/utils/createControllablePromise.js +11 -0
  125. package/models/api/gridDisableVirtualizationApi.d.ts +0 -15
  126. package/models/api/gridVirtualScrollerApi.d.ts +0 -8
  127. package/models/api/gridVirtualScrollerApi.js +0 -1
  128. package/modern/models/api/gridDisableVirtualizationApi.js +0 -1
  129. package/modern/models/api/gridVirtualScrollerApi.js +0 -1
  130. package/node/models/api/gridVirtualScrollerApi.js +0 -5
  131. /package/legacy/models/api/{gridDisableVirtualizationApi.js → gridVirtualizationApi.js} +0 -0
  132. /package/{legacy/models/api/gridVirtualScrollerApi.js → models/api/gridVirtualizationApi.js} +0 -0
  133. /package/{models/api/gridDisableVirtualizationApi.js → modern/models/api/gridVirtualizationApi.js} +0 -0
  134. /package/node/models/api/{gridDisableVirtualizationApi.js → gridVirtualizationApi.js} +0 -0
@@ -25,53 +25,56 @@ import { rowsMetaStateInitializer, useGridRowsMeta } from '../hooks/features/row
25
25
  import { useGridStatePersistence } from '../hooks/features/statePersistence/useGridStatePersistence';
26
26
  import { useGridColumnSpanning } from '../hooks/features/columns/useGridColumnSpanning';
27
27
  import { useGridColumnGrouping, columnGroupsStateInitializer } from '../hooks/features/columnGrouping/useGridColumnGrouping';
28
+ import { useGridVirtualization, virtualizationStateInitializer } from '../hooks/features/virtualization';
28
29
  export const useDataGridComponent = (inputApiRef, props) => {
29
- const privateApiRef = useGridInitialization(inputApiRef, props);
30
+ const apiRef = useGridInitialization(inputApiRef, props);
30
31
 
31
32
  /**
32
33
  * Register all pre-processors called during state initialization here.
33
34
  */
34
- useGridRowSelectionPreProcessors(privateApiRef, props);
35
- useGridRowsPreProcessors(privateApiRef);
35
+ useGridRowSelectionPreProcessors(apiRef, props);
36
+ useGridRowsPreProcessors(apiRef);
36
37
 
37
38
  /**
38
39
  * Register all state initializers here.
39
40
  */
40
- useGridInitializeState(rowSelectionStateInitializer, privateApiRef, props);
41
- useGridInitializeState(columnsStateInitializer, privateApiRef, props);
42
- useGridInitializeState(rowsStateInitializer, privateApiRef, props);
43
- useGridInitializeState(editingStateInitializer, privateApiRef, props);
44
- useGridInitializeState(focusStateInitializer, privateApiRef, props);
45
- useGridInitializeState(sortingStateInitializer, privateApiRef, props);
46
- useGridInitializeState(preferencePanelStateInitializer, privateApiRef, props);
47
- useGridInitializeState(filterStateInitializer, privateApiRef, props);
48
- useGridInitializeState(densityStateInitializer, privateApiRef, props);
49
- useGridInitializeState(paginationStateInitializer, privateApiRef, props);
50
- useGridInitializeState(rowsMetaStateInitializer, privateApiRef, props);
51
- useGridInitializeState(columnMenuStateInitializer, privateApiRef, props);
52
- useGridInitializeState(columnGroupsStateInitializer, privateApiRef, props);
53
- useGridKeyboardNavigation(privateApiRef, props);
54
- useGridRowSelection(privateApiRef, props);
55
- useGridColumns(privateApiRef, props);
56
- useGridRows(privateApiRef, props);
57
- useGridParamsApi(privateApiRef, props);
58
- useGridColumnSpanning(privateApiRef);
59
- useGridColumnGrouping(privateApiRef, props);
60
- useGridEditing(privateApiRef, props);
61
- useGridFocus(privateApiRef, props);
62
- useGridPreferencesPanel(privateApiRef, props);
63
- useGridFilter(privateApiRef, props);
64
- useGridSorting(privateApiRef, props);
65
- useGridDensity(privateApiRef, props);
66
- useGridPagination(privateApiRef, props);
67
- useGridRowsMeta(privateApiRef, props);
68
- useGridScroll(privateApiRef, props);
69
- useGridColumnMenu(privateApiRef);
70
- useGridCsvExport(privateApiRef, props);
71
- useGridPrintExport(privateApiRef, props);
72
- useGridClipboard(privateApiRef, props);
73
- useGridDimensions(privateApiRef, props);
74
- useGridEvents(privateApiRef, props);
75
- useGridStatePersistence(privateApiRef);
76
- return privateApiRef;
41
+ useGridInitializeState(rowSelectionStateInitializer, apiRef, props);
42
+ useGridInitializeState(columnsStateInitializer, apiRef, props);
43
+ useGridInitializeState(rowsStateInitializer, apiRef, props);
44
+ useGridInitializeState(editingStateInitializer, apiRef, props);
45
+ useGridInitializeState(focusStateInitializer, apiRef, props);
46
+ useGridInitializeState(sortingStateInitializer, apiRef, props);
47
+ useGridInitializeState(preferencePanelStateInitializer, apiRef, props);
48
+ useGridInitializeState(filterStateInitializer, apiRef, props);
49
+ useGridInitializeState(densityStateInitializer, apiRef, props);
50
+ useGridInitializeState(paginationStateInitializer, apiRef, props);
51
+ useGridInitializeState(rowsMetaStateInitializer, apiRef, props);
52
+ useGridInitializeState(columnMenuStateInitializer, apiRef, props);
53
+ useGridInitializeState(columnGroupsStateInitializer, apiRef, props);
54
+ useGridInitializeState(virtualizationStateInitializer, apiRef, props);
55
+ useGridKeyboardNavigation(apiRef, props);
56
+ useGridRowSelection(apiRef, props);
57
+ useGridColumns(apiRef, props);
58
+ useGridRows(apiRef, props);
59
+ useGridParamsApi(apiRef, props);
60
+ useGridColumnSpanning(apiRef);
61
+ useGridColumnGrouping(apiRef, props);
62
+ useGridEditing(apiRef, props);
63
+ useGridFocus(apiRef, props);
64
+ useGridPreferencesPanel(apiRef, props);
65
+ useGridFilter(apiRef, props);
66
+ useGridSorting(apiRef, props);
67
+ useGridDensity(apiRef, props);
68
+ useGridPagination(apiRef, props);
69
+ useGridRowsMeta(apiRef, props);
70
+ useGridScroll(apiRef, props);
71
+ useGridColumnMenu(apiRef);
72
+ useGridCsvExport(apiRef, props);
73
+ useGridPrintExport(apiRef, props);
74
+ useGridClipboard(apiRef, props);
75
+ useGridDimensions(apiRef, props);
76
+ useGridEvents(apiRef, props);
77
+ useGridStatePersistence(apiRef);
78
+ useGridVirtualization(apiRef, props);
79
+ return apiRef;
77
80
  };
@@ -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 = ["className", "disableVirtualization"];
3
+ const _excluded = ["className"];
4
4
  import * as React from 'react';
5
5
  import { GridVirtualScroller } from './virtualization/GridVirtualScroller';
6
6
  import { GridVirtualScrollerContent } from './virtualization/GridVirtualScrollerContent';
@@ -11,8 +11,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
11
11
  import { jsxs as _jsxs } from "react/jsx-runtime";
12
12
  const DataGridVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGridVirtualScroller(props, ref) {
13
13
  const {
14
- className,
15
- disableVirtualization
14
+ className
16
15
  } = props,
17
16
  other = _objectWithoutPropertiesLoose(props, _excluded);
18
17
  const {
@@ -21,8 +20,7 @@ const DataGridVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGridV
21
20
  getRenderZoneProps,
22
21
  getRows
23
22
  } = useGridVirtualScroller({
24
- ref,
25
- disableVirtualization
23
+ ref
26
24
  });
27
25
  return /*#__PURE__*/_jsxs(GridVirtualScroller, _extends({
28
26
  className: className
@@ -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 = ["selected", "rowId", "row", "index", "style", "position", "rowHeight", "className", "visibleColumns", "renderedColumns", "containerWidth", "firstColumnToRender", "lastColumnToRender", "isLastVisible", "focusedCellColumnIndexNotInRange", "isNotVisible", "focusedCell", "tabbableCell", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave"];
3
+ const _excluded = ["selected", "hovered", "rowId", "row", "index", "style", "position", "rowHeight", "className", "visibleColumns", "renderedColumns", "containerWidth", "firstColumnToRender", "lastColumnToRender", "isLastVisible", "focusedCellColumnIndexNotInRange", "isNotVisible", "focusedCell", "tabbableCell", "onClick", "onDoubleClick", "onMouseEnter", "onMouseLeave"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
@@ -57,6 +57,7 @@ function EmptyCell({
57
57
  const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
58
58
  const {
59
59
  selected,
60
+ hovered,
60
61
  rowId,
61
62
  row,
62
63
  index,
@@ -92,6 +93,7 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
92
93
 
93
94
  const ownerState = {
94
95
  selected,
96
+ hovered,
95
97
  isLastVisible,
96
98
  classes: rootProps.classes,
97
99
  editing: apiRef.current.getRowMode(rowId) === GridRowModes.Edit,
@@ -326,7 +328,7 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
326
328
  "data-id": rowId,
327
329
  "data-rowindex": index,
328
330
  role: "row",
329
- className: clsx(...rowClassNames, classes.root, className),
331
+ className: clsx(...rowClassNames, classes.root, className, hovered && 'Mui-hovered'),
330
332
  "aria-rowindex": ariaRowIndex,
331
333
  "aria-selected": selected,
332
334
  style: style
@@ -39,7 +39,6 @@ function GridBody(props) {
39
39
  const columnVisibility = useGridSelector(apiRef, gridColumnVisibilityModelSelector);
40
40
  const columnGroupsHeaderStructure = useGridSelector(apiRef, gridColumnGroupsHeaderStructureSelector);
41
41
  const hasOtherElementInTabSequence = !(columnGroupHeaderTabIndexState === null && columnHeaderTabIndexState === null && cellTabIndexState === null);
42
- const [isVirtualizationDisabled, setIsVirtualizationDisabled] = React.useState(rootProps.disableVirtualization);
43
42
  useEnhancedEffect(() => {
44
43
  apiRef.current.computeSizeAndPublishResizeEvent();
45
44
  const elementToObserve = rootRef.current;
@@ -49,7 +48,7 @@ function GridBody(props) {
49
48
  let animationFrame;
50
49
  const observer = new ResizeObserver(() => {
51
50
  // See https://github.com/mui/mui-x/issues/8733
52
- animationFrame = window.requestAnimationFrame(() => {
51
+ animationFrame = requestAnimationFrame(() => {
53
52
  apiRef.current.computeSizeAndPublishResizeEvent();
54
53
  });
55
54
  });
@@ -65,24 +64,6 @@ function GridBody(props) {
65
64
  }
66
65
  };
67
66
  }, [apiRef]);
68
- const disableVirtualization = React.useCallback(() => {
69
- setIsVirtualizationDisabled(true);
70
- }, []);
71
- const enableVirtualization = React.useCallback(() => {
72
- setIsVirtualizationDisabled(false);
73
- }, []);
74
- React.useEffect(() => {
75
- setIsVirtualizationDisabled(rootProps.disableVirtualization);
76
- }, [rootProps.disableVirtualization]);
77
-
78
- // The `useGridApiMethod` hook can't be used here, because it only installs the
79
- // method if it doesn't exist yet. Once installed, it's never updated again.
80
- // This break the methods above, since their closure comes from the first time
81
- // they were installed. Which means that calling `setIsVirtualizationDisabled`
82
- // will trigger a re-render, but it won't update the state. That can be solved
83
- // by migrating the virtualization status to the global state.
84
- apiRef.current.unstable_disableVirtualization = disableVirtualization;
85
- apiRef.current.unstable_enableVirtualization = enableVirtualization;
86
67
  const columnHeadersRef = React.useRef(null);
87
68
  const columnsContainerRef = React.useRef(null);
88
69
  const virtualScrollerRef = React.useRef(null);
@@ -119,8 +100,7 @@ function GridBody(props) {
119
100
  // If this event is published while dimensions haven't been computed,
120
101
  // the `onFetchRows` prop won't be called during mount.
121
102
  , {
122
- ref: virtualScrollerRef,
123
- disableVirtualization: isVirtualizationDisabled
103
+ ref: virtualScrollerRef
124
104
  }), children]
125
105
  });
126
106
  }
@@ -164,11 +164,11 @@ function GridActionsCell(props) {
164
164
  fontSize: "small"
165
165
  })
166
166
  })), menuButtons.length > 0 && /*#__PURE__*/_jsx(GridMenu, {
167
- onClickAway: hideMenu,
168
- onClick: hideMenu,
169
167
  open: open,
170
168
  target: buttonRef.current,
171
169
  position: position,
170
+ onClose: hideMenu,
171
+ onClick: hideMenu,
172
172
  children: /*#__PURE__*/_jsx(MenuList, {
173
173
  id: menuId,
174
174
  className: gridClasses.menuList,
@@ -231,7 +231,8 @@ const GridCell = /*#__PURE__*/React.forwardRef((props, ref) => {
231
231
  return {
232
232
  padding: 0,
233
233
  opacity: 0,
234
- width: 0
234
+ width: 0,
235
+ border: 0
235
236
  };
236
237
  }
237
238
  const cellStyle = {
@@ -495,7 +496,8 @@ const GridCellV7 = /*#__PURE__*/React.forwardRef((props, ref) => {
495
496
  return {
496
497
  padding: 0,
497
498
  opacity: 0,
498
- width: 0
499
+ width: 0,
500
+ border: 0
499
501
  };
500
502
  }
501
503
  const cellStyle = {
@@ -94,7 +94,8 @@ function GridColumnHeaderItem(props) {
94
94
  onDragEnd: publish('columnHeaderDragEnd')
95
95
  } : {}, [isDraggable, publish]);
96
96
  const columnHeaderSeparatorProps = React.useMemo(() => ({
97
- onMouseDown: publish('columnSeparatorMouseDown')
97
+ onMouseDown: publish('columnSeparatorMouseDown'),
98
+ onDoubleClick: publish('columnSeparatorDoubleClick')
98
99
  }), [publish]);
99
100
  React.useEffect(() => {
100
101
  if (!showColumnMenuIcon) {
@@ -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,
@@ -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 = ["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
6
  import { refType, unstable_useId as useId } from '@mui/utils';
@@ -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);