@mui/x-data-grid-premium 8.25.0 → 8.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/DataGridPremium/DataGridPremium.js +25 -1
  3. package/DataGridPremium/useDataGridPremiumComponent.js +3 -0
  4. package/DataGridPremium/useDataGridPremiumProps.js +5 -1
  5. package/components/GridPremiumToolbar.js +55 -3
  6. package/esm/DataGridPremium/DataGridPremium.js +25 -1
  7. package/esm/DataGridPremium/useDataGridPremiumComponent.js +3 -0
  8. package/esm/DataGridPremium/useDataGridPremiumProps.js +5 -1
  9. package/esm/components/GridPremiumToolbar.js +57 -5
  10. package/esm/hooks/features/clipboard/useGridClipboardImport.js +20 -9
  11. package/esm/hooks/features/history/constants.d.ts +2 -0
  12. package/esm/hooks/features/history/constants.js +1 -0
  13. package/esm/hooks/features/history/defaultHistoryHandlers.d.ts +20 -0
  14. package/esm/hooks/features/history/defaultHistoryHandlers.js +365 -0
  15. package/esm/hooks/features/history/gridHistoryInterfaces.d.ts +95 -0
  16. package/esm/hooks/features/history/gridHistoryInterfaces.js +1 -0
  17. package/esm/hooks/features/history/gridHistorySelectors.d.ts +16 -0
  18. package/esm/hooks/features/history/gridHistorySelectors.js +7 -0
  19. package/esm/hooks/features/history/index.d.ts +3 -0
  20. package/esm/hooks/features/history/index.js +2 -0
  21. package/esm/hooks/features/history/useGridHistory.d.ts +6 -0
  22. package/esm/hooks/features/history/useGridHistory.js +294 -0
  23. package/esm/hooks/features/index.d.ts +2 -1
  24. package/esm/hooks/features/index.js +2 -1
  25. package/esm/index.js +1 -1
  26. package/esm/models/dataGridPremiumProps.d.ts +26 -1
  27. package/esm/models/gridApiPremium.d.ts +2 -1
  28. package/esm/models/gridStatePremium.d.ts +2 -0
  29. package/esm/typeOverloads/modules.d.ts +25 -2
  30. package/esm/typeOverloads/modules.js +5 -1
  31. package/hooks/features/clipboard/useGridClipboardImport.js +20 -9
  32. package/hooks/features/history/constants.d.ts +2 -0
  33. package/hooks/features/history/constants.js +7 -0
  34. package/hooks/features/history/defaultHistoryHandlers.d.ts +20 -0
  35. package/hooks/features/history/defaultHistoryHandlers.js +376 -0
  36. package/hooks/features/history/gridHistoryInterfaces.d.ts +95 -0
  37. package/hooks/features/history/gridHistoryInterfaces.js +5 -0
  38. package/hooks/features/history/gridHistorySelectors.d.ts +16 -0
  39. package/hooks/features/history/gridHistorySelectors.js +13 -0
  40. package/hooks/features/history/index.d.ts +3 -0
  41. package/hooks/features/history/index.js +43 -0
  42. package/hooks/features/history/useGridHistory.d.ts +6 -0
  43. package/hooks/features/history/useGridHistory.js +303 -0
  44. package/hooks/features/index.d.ts +2 -1
  45. package/hooks/features/index.js +11 -0
  46. package/index.js +1 -1
  47. package/models/dataGridPremiumProps.d.ts +26 -1
  48. package/models/gridApiPremium.d.ts +2 -1
  49. package/models/gridStatePremium.d.ts +2 -0
  50. package/package.json +5 -5
  51. package/typeOverloads/modules.d.ts +25 -2
  52. package/typeOverloads/modules.js +1 -3
package/CHANGELOG.md CHANGED
@@ -5,6 +5,90 @@
5
5
  All notable changes to this project will be documented in this file.
6
6
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
7
7
 
8
+ ## 8.26.0
9
+
10
+ _Jan 22, 2026_
11
+
12
+ We'd like to extend a big thank you to the 6 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🔄 Data Grid now supports undo and redo actions. See the [Undo and redo](https://mui.com/x/react-data-grid/undo-redo/) page for details about out-of-the-box support and customization options.
15
+ - 🐞 Bugfixes
16
+
17
+ Special thanks go out to these community members for their valuable contributions:
18
+ @jhe-iqbis
19
+
20
+ The following team members contributed to this release:
21
+ @arminmeh, @cherniavskii, @flaviendelangle, @JCQuintas, @romgrk
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@8.26.0`
26
+
27
+ - [DataGrid] Add `onMenuOpen()` and `onMenuClose()` event handlers in `GridActionsCell` (#20994) @jhe-iqbis
28
+ - [DataGrid] Fix scroll position when virtualization is disabled (#20958) @romgrk
29
+
30
+ #### `@mui/x-data-grid-pro@8.26.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
31
+
32
+ Same changes as in `@mui/x-data-grid@8.26.0`.
33
+
34
+ #### `@mui/x-data-grid-premium@8.26.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
35
+
36
+ Same changes as in `@mui/x-data-grid-pro@8.26.0`, plus:
37
+
38
+ - [DataGridPremium] Undo and redo (#20993) @arminmeh
39
+
40
+ ### Date and Time Pickers
41
+
42
+ #### `@mui/x-date-pickers@8.26.0`
43
+
44
+ Internal changes.
45
+
46
+ #### `@mui/x-date-pickers-pro@8.26.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
47
+
48
+ Same changes as in `@mui/x-date-pickers@8.26.0`.
49
+
50
+ ### Charts
51
+
52
+ #### `@mui/x-charts@8.26.0`
53
+
54
+ Internal changes.
55
+
56
+ #### `@mui/x-charts-pro@8.26.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
57
+
58
+ Same changes as in `@mui/x-charts@8.26.0`.
59
+
60
+ #### `@mui/x-charts-premium@8.26.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
61
+
62
+ Same changes as in `@mui/x-charts-pro@8.26.0`.
63
+
64
+ ### Tree View
65
+
66
+ #### `@mui/x-tree-view@8.26.0`
67
+
68
+ - [tree view] Fix `props.id` not passed to the root element (#20976) @flaviendelangle
69
+
70
+ #### `@mui/x-tree-view-pro@8.26.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
71
+
72
+ Same changes as in `@mui/x-tree-view@8.26.0`.
73
+
74
+ ### Codemod
75
+
76
+ #### `@mui/x-codemod@8.26.0`
77
+
78
+ Internal changes.
79
+
80
+ ### Docs
81
+
82
+ - [docs] Recipe for lazy loading DataGrid's detail panels with auto height (#20995) @arminmeh
83
+
84
+ ### Core
85
+
86
+ - [code-infra] Update `master` to `v8` references (#20864) @JCQuintas
87
+ - [code-infra] Update v8 branch tags (#20926) @JCQuintas
88
+ - [code-infra] V8 changes in master (#20919) @JCQuintas
89
+ - [code-infra] Allow user to select target branch if it exists for current major (#21005) @JCQuintas
90
+ - [internal] Set up shared instructions for coding agents (#21000) @cherniavskii
91
+
8
92
  ## 8.25.0
9
93
 
10
94
  <!-- generated comparing v8.24.0..master -->
@@ -50,7 +50,7 @@ const configuration = {
50
50
  useGridParamsOverridableMethods: _useGridParamsOverridableMethods.useGridParamsOverridableMethods
51
51
  }
52
52
  };
53
- const releaseInfo = "MTc2ODM0ODgwMDAwMA==";
53
+ const releaseInfo = "MTc2OTA0MDAwMDAwMA==";
54
54
  const watermark = /*#__PURE__*/(0, _jsxRuntime.jsx)(_xLicense.Watermark, {
55
55
  packageName: "x-data-grid-premium",
56
56
  releaseInfo: releaseInfo
@@ -565,6 +565,22 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
565
565
  * @default false
566
566
  */
567
567
  hideFooterSelectedRowCount: _propTypes.default.bool,
568
+ /**
569
+ * Map of grid events to their undo/redo handlers.
570
+ * @default Handlers for `rowEditStop`, `cellEditStop` and `clipboardPasteEnd` events
571
+ */
572
+ historyEventHandlers: _propTypes.default.object,
573
+ /**
574
+ * The maximum size of the history stack.
575
+ * Set to 0 to disable the undo/redo feature.
576
+ * @default 30
577
+ */
578
+ historyStackSize: _propTypes.default.number,
579
+ /**
580
+ * List of grid events after which the history stack items should be re-validated.
581
+ * @default ['columnsChange', 'rowsSet', 'sortedRowsSet', 'filteredRowsSet', 'paginationModelChange']
582
+ */
583
+ historyValidationEvents: _propTypes.default.arrayOf(_propTypes.default.oneOf(['activeChartIdChange', 'activeStrategyProcessorChange', 'aggregationLookupSet', 'aggregationModelChange', 'aiAssistantActiveConversationIndexChange', 'aiAssistantConversationsChange', 'cellClick', 'cellDoubleClick', 'cellDragEnter', 'cellDragOver', 'cellEditStart', 'cellEditStop', 'cellFocusIn', 'cellFocusOut', 'cellKeyDown', 'cellKeyUp', 'cellModeChange', 'cellModesModelChange', 'cellMouseDown', 'cellMouseOver', 'cellMouseUp', 'cellSelectionChange', 'chartSynchronizationStateChange', 'clipboardCopy', 'clipboardPasteEnd', 'clipboardPasteStart', 'columnGroupHeaderBlur', 'columnGroupHeaderFocus', 'columnGroupHeaderKeyDown', 'columnHeaderBlur', 'columnHeaderClick', 'columnHeaderContextMenu', 'columnHeaderDoubleClick', 'columnHeaderDragEnd', 'columnHeaderDragEndNative', 'columnHeaderDragEnter', 'columnHeaderDragOver', 'columnHeaderDragStart', 'columnHeaderEnter', 'columnHeaderFocus', 'columnHeaderKeyDown', 'columnHeaderLeave', 'columnHeaderOut', 'columnHeaderOver', 'columnIndexChange', 'columnOrderChange', 'columnResize', 'columnResizeStart', 'columnResizeStop', 'columnsChange', 'columnSeparatorDoubleClick', 'columnSeparatorMouseDown', 'columnVisibilityModelChange', 'columnWidthChange', 'debouncedResize', 'densityChange', 'detailPanelsExpandedRowIdsChange', 'excelExportStateChange', 'fetchRows', 'filteredRowsSet', 'filterModelChange', 'headerFilterBlur', 'headerFilterClick', 'headerFilterKeyDown', 'headerFilterMouseDown', 'headerSelectionCheckboxChange', 'menuClose', 'menuOpen', 'paginationMetaChange', 'paginationModelChange', 'pinnedColumnsChange', 'pivotModeChange', 'pivotModelChange', 'pivotPanelOpenChange', 'preferencePanelClose', 'preferencePanelOpen', 'redo', 'renderedRowsIntervalChange', 'resize', 'rootMount', 'rowClick', 'rowCountChange', 'rowDoubleClick', 'rowDragEnd', 'rowDragOver', 'rowDragStart', 'rowEditStart', 'rowEditStop', 'rowExpansionChange', 'rowGroupingModelChange', 'rowModesModelChange', 'rowMouseEnter', 'rowMouseLeave', 'rowMouseOut', 'rowMouseOver', 'rowOrderChange', 'rowSelectionChange', 'rowSelectionCheckboxChange', 'rowsScrollEnd', 'rowsScrollEndIntersection', 'rowsSet', 'scrollPositionChange', 'sidebarClose', 'sidebarOpen', 'sortedRowsSet', 'sortModelChange', 'stateChange', 'strategyAvailabilityChange', 'undo', 'unmount', 'viewportInnerSizeChange', 'virtualScrollerContentSizeChange', 'virtualScrollerTouchMove', 'virtualScrollerWheel']).isRequired),
568
584
  /**
569
585
  * If `true`, the diacritics (accents) are ignored when filtering or quick filtering.
570
586
  * E.g. when filter value is `cafe`, the rows with `café` will be visible.
@@ -975,6 +991,10 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
975
991
  * @returns {Promise<PromptResponse>} The prompt response.
976
992
  */
977
993
  onPrompt: _propTypes.default.func,
994
+ /**
995
+ * Callback fired when a redo operation is executed.
996
+ */
997
+ onRedo: _propTypes.default.func,
978
998
  /**
979
999
  * Callback fired when the Data Grid is resized.
980
1000
  * @param {ElementSize} containerSize With all properties from [[ElementSize]].
@@ -1075,6 +1095,10 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
1075
1095
  * @ignore - do not document.
1076
1096
  */
1077
1097
  onStateChange: _propTypes.default.func,
1098
+ /**
1099
+ * Callback fired when an undo operation is executed.
1100
+ */
1101
+ onUndo: _propTypes.default.func,
1078
1102
  /**
1079
1103
  * Select the pageSize dynamically using the component UI.
1080
1104
  * @default [25, 50, 100]
@@ -25,6 +25,7 @@ var _gridPivotingSelectors = require("../hooks/features/pivoting/gridPivotingSel
25
25
  var _useGridAiAssistant = require("../hooks/features/aiAssistant/useGridAiAssistant");
26
26
  var _useGridSidebar = require("../hooks/features/sidebar/useGridSidebar");
27
27
  var _useGridChartsIntegration = require("../hooks/features/chartsIntegration/useGridChartsIntegration");
28
+ var _useGridHistory = require("../hooks/features/history/useGridHistory");
28
29
  // Premium-only features
29
30
 
30
31
  const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
@@ -100,6 +101,7 @@ const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
100
101
  (0, _internals.useGridInitializeState)(_internals.listViewStateInitializer, apiRef, props);
101
102
  (0, _internals.useGridInitializeState)(_useGridAiAssistant.aiAssistantStateInitializer, apiRef, props);
102
103
  (0, _internals.useGridInitializeState)(_useGridChartsIntegration.chartsIntegrationStateInitializer, apiRef, props);
104
+ (0, _internals.useGridInitializeState)(_useGridHistory.historyStateInitializer, apiRef, props);
103
105
  (0, _useGridSidebar.useGridSidebar)(apiRef, props);
104
106
  (0, _useGridPivoting.useGridPivoting)(apiRef, props, inProps.columns, inProps.rows);
105
107
  (0, _useGridRowGrouping.useGridRowGrouping)(apiRef, props);
@@ -147,6 +149,7 @@ const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
147
149
  (0, _internals.useGridListView)(apiRef, props);
148
150
  (0, _useGridAiAssistant.useGridAiAssistant)(apiRef, props);
149
151
  (0, _useGridChartsIntegration.useGridChartsIntegration)(apiRef, props);
152
+ (0, _useGridHistory.useGridHistory)(apiRef, props);
150
153
  (0, _useGridPivoting.useGridPivotingExportState)(apiRef);
151
154
 
152
155
  // Should be the last thing to run, because all pre-processors should have been registered by now.
@@ -16,6 +16,7 @@ var _aggregation = require("../hooks/features/aggregation");
16
16
  var _dataGridPremiumDefaultSlotsComponents = require("../constants/dataGridPremiumDefaultSlotsComponents");
17
17
  var _utils = require("../hooks/features/pivoting/utils");
18
18
  var _gridAggregationUtils = require("../hooks/features/aggregation/gridAggregationUtils");
19
+ var _constants = require("../hooks/features/history/constants");
19
20
  const getDataGridPremiumForcedProps = themedProps => (0, _extends2.default)({
20
21
  signature: _xDataGridPro.GridSignature.DataGridPremium
21
22
  }, themedProps.dataSource ? {
@@ -44,7 +45,10 @@ const DATA_GRID_PREMIUM_PROPS_DEFAULT_VALUES = exports.DATA_GRID_PREMIUM_PROPS_D
44
45
  },
45
46
  disablePivoting: false,
46
47
  aiAssistant: false,
47
- chartsIntegration: false
48
+ chartsIntegration: false,
49
+ historyStackSize: 30,
50
+ historyEventHandlers: {},
51
+ historyValidationEvents: _constants.DEFAULT_HISTORY_VALIDATION_EVENTS
48
52
  });
49
53
  const defaultSlots = _dataGridPremiumDefaultSlotsComponents.DATA_GRID_PREMIUM_DEFAULT_SLOTS_COMPONENTS;
50
54
  const useDataGridPremiumProps = inProps => {
@@ -17,14 +17,66 @@ var _useGridApiContext = require("../hooks/utils/useGridApiContext");
17
17
  var _PivotPanelTrigger = require("./pivotPanel/PivotPanelTrigger");
18
18
  var _aiAssistantPanel = require("./aiAssistantPanel");
19
19
  var _ChartsPanelTrigger = require("./chartsPanel/ChartsPanelTrigger");
20
+ var _history = require("../hooks/features/history");
20
21
  var _jsxRuntime = require("react/jsx-runtime");
21
22
  const _excluded = ["excelOptions"];
22
23
  function GridPremiumToolbar(props) {
23
24
  const rootProps = (0, _useGridRootProps.useGridRootProps)();
24
25
  const apiRef = (0, _useGridApiContext.useGridApiContext)();
25
26
  const other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
26
- const additionalItems = /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
27
- children: [!rootProps.disablePivoting && /*#__PURE__*/(0, _jsxRuntime.jsx)(_PivotPanelTrigger.PivotPanelTrigger, {
27
+ const historyEnabled = (0, _internals.useGridSelector)(apiRef, _history.gridHistoryEnabledSelector);
28
+ const showHistoryControls = rootProps.slotProps?.toolbar?.showHistoryControls !== false && historyEnabled;
29
+ const canUndo = (0, _internals.useGridSelector)(apiRef, _history.gridHistoryCanUndoSelector);
30
+ const canRedo = (0, _internals.useGridSelector)(apiRef, _history.gridHistoryCanRedoSelector);
31
+ const mainControls = /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
32
+ children: [showHistoryControls && /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
33
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
34
+ title: apiRef.current.getLocaleText('toolbarUndo'),
35
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
36
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGridPro.ToolbarButton, {
37
+ disabled: !canUndo,
38
+ onClick: () => apiRef.current.history.undo(),
39
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.undoIcon, {
40
+ fontSize: "small"
41
+ })
42
+ })
43
+ })
44
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
45
+ title: apiRef.current.getLocaleText('toolbarRedo'),
46
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
47
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGridPro.ToolbarButton, {
48
+ disabled: !canRedo,
49
+ onClick: () => apiRef.current.history.redo(),
50
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.redoIcon, {
51
+ fontSize: "small"
52
+ })
53
+ })
54
+ })
55
+ })]
56
+ }), showHistoryControls && /*#__PURE__*/(0, _jsxRuntime.jsx)(_internals.GridToolbarDivider, {}), !rootProps.disableColumnSelector && /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
57
+ title: apiRef.current.getLocaleText('toolbarColumns'),
58
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGridPro.ColumnsPanelTrigger, {
59
+ render: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGridPro.ToolbarButton, {}),
60
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.columnSelectorIcon, {
61
+ fontSize: "small"
62
+ })
63
+ })
64
+ }), !rootProps.disableColumnFilter && /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
65
+ title: apiRef.current.getLocaleText('toolbarFilters'),
66
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGridPro.FilterPanelTrigger, {
67
+ render: (triggerProps, state) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGridPro.ToolbarButton, (0, _extends2.default)({}, triggerProps, {
68
+ color: state.filterCount > 0 ? 'primary' : 'default',
69
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseBadge, {
70
+ badgeContent: state.filterCount,
71
+ color: "primary",
72
+ variant: "dot",
73
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.openFilterButtonIcon, {
74
+ fontSize: "small"
75
+ })
76
+ })
77
+ }))
78
+ })
79
+ }), !rootProps.disablePivoting && /*#__PURE__*/(0, _jsxRuntime.jsx)(_PivotPanelTrigger.PivotPanelTrigger, {
28
80
  render: (triggerProps, state) => /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
29
81
  title: apiRef.current.getLocaleText('toolbarPivot'),
30
82
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGridPro.ToolbarButton, (0, _extends2.default)({}, triggerProps, {
@@ -63,7 +115,7 @@ function GridPremiumToolbar(props) {
63
115
  children: apiRef.current.getLocaleText('toolbarExportExcel')
64
116
  }) : undefined;
65
117
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_internals.GridToolbar, (0, _extends2.default)({}, other, {
66
- additionalItems: additionalItems,
118
+ mainControls: mainControls,
67
119
  additionalExportMenuItems: additionalExportMenuItems
68
120
  }));
69
121
  }
@@ -43,7 +43,7 @@ const configuration = {
43
43
  useGridParamsOverridableMethods
44
44
  }
45
45
  };
46
- const releaseInfo = "MTc2ODM0ODgwMDAwMA==";
46
+ const releaseInfo = "MTc2OTA0MDAwMDAwMA==";
47
47
  const watermark = /*#__PURE__*/_jsx(Watermark, {
48
48
  packageName: "x-data-grid-premium",
49
49
  releaseInfo: releaseInfo
@@ -558,6 +558,22 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
558
558
  * @default false
559
559
  */
560
560
  hideFooterSelectedRowCount: PropTypes.bool,
561
+ /**
562
+ * Map of grid events to their undo/redo handlers.
563
+ * @default Handlers for `rowEditStop`, `cellEditStop` and `clipboardPasteEnd` events
564
+ */
565
+ historyEventHandlers: PropTypes.object,
566
+ /**
567
+ * The maximum size of the history stack.
568
+ * Set to 0 to disable the undo/redo feature.
569
+ * @default 30
570
+ */
571
+ historyStackSize: PropTypes.number,
572
+ /**
573
+ * List of grid events after which the history stack items should be re-validated.
574
+ * @default ['columnsChange', 'rowsSet', 'sortedRowsSet', 'filteredRowsSet', 'paginationModelChange']
575
+ */
576
+ historyValidationEvents: PropTypes.arrayOf(PropTypes.oneOf(['activeChartIdChange', 'activeStrategyProcessorChange', 'aggregationLookupSet', 'aggregationModelChange', 'aiAssistantActiveConversationIndexChange', 'aiAssistantConversationsChange', 'cellClick', 'cellDoubleClick', 'cellDragEnter', 'cellDragOver', 'cellEditStart', 'cellEditStop', 'cellFocusIn', 'cellFocusOut', 'cellKeyDown', 'cellKeyUp', 'cellModeChange', 'cellModesModelChange', 'cellMouseDown', 'cellMouseOver', 'cellMouseUp', 'cellSelectionChange', 'chartSynchronizationStateChange', 'clipboardCopy', 'clipboardPasteEnd', 'clipboardPasteStart', 'columnGroupHeaderBlur', 'columnGroupHeaderFocus', 'columnGroupHeaderKeyDown', 'columnHeaderBlur', 'columnHeaderClick', 'columnHeaderContextMenu', 'columnHeaderDoubleClick', 'columnHeaderDragEnd', 'columnHeaderDragEndNative', 'columnHeaderDragEnter', 'columnHeaderDragOver', 'columnHeaderDragStart', 'columnHeaderEnter', 'columnHeaderFocus', 'columnHeaderKeyDown', 'columnHeaderLeave', 'columnHeaderOut', 'columnHeaderOver', 'columnIndexChange', 'columnOrderChange', 'columnResize', 'columnResizeStart', 'columnResizeStop', 'columnsChange', 'columnSeparatorDoubleClick', 'columnSeparatorMouseDown', 'columnVisibilityModelChange', 'columnWidthChange', 'debouncedResize', 'densityChange', 'detailPanelsExpandedRowIdsChange', 'excelExportStateChange', 'fetchRows', 'filteredRowsSet', 'filterModelChange', 'headerFilterBlur', 'headerFilterClick', 'headerFilterKeyDown', 'headerFilterMouseDown', 'headerSelectionCheckboxChange', 'menuClose', 'menuOpen', 'paginationMetaChange', 'paginationModelChange', 'pinnedColumnsChange', 'pivotModeChange', 'pivotModelChange', 'pivotPanelOpenChange', 'preferencePanelClose', 'preferencePanelOpen', 'redo', 'renderedRowsIntervalChange', 'resize', 'rootMount', 'rowClick', 'rowCountChange', 'rowDoubleClick', 'rowDragEnd', 'rowDragOver', 'rowDragStart', 'rowEditStart', 'rowEditStop', 'rowExpansionChange', 'rowGroupingModelChange', 'rowModesModelChange', 'rowMouseEnter', 'rowMouseLeave', 'rowMouseOut', 'rowMouseOver', 'rowOrderChange', 'rowSelectionChange', 'rowSelectionCheckboxChange', 'rowsScrollEnd', 'rowsScrollEndIntersection', 'rowsSet', 'scrollPositionChange', 'sidebarClose', 'sidebarOpen', 'sortedRowsSet', 'sortModelChange', 'stateChange', 'strategyAvailabilityChange', 'undo', 'unmount', 'viewportInnerSizeChange', 'virtualScrollerContentSizeChange', 'virtualScrollerTouchMove', 'virtualScrollerWheel']).isRequired),
561
577
  /**
562
578
  * If `true`, the diacritics (accents) are ignored when filtering or quick filtering.
563
579
  * E.g. when filter value is `cafe`, the rows with `café` will be visible.
@@ -968,6 +984,10 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
968
984
  * @returns {Promise<PromptResponse>} The prompt response.
969
985
  */
970
986
  onPrompt: PropTypes.func,
987
+ /**
988
+ * Callback fired when a redo operation is executed.
989
+ */
990
+ onRedo: PropTypes.func,
971
991
  /**
972
992
  * Callback fired when the Data Grid is resized.
973
993
  * @param {ElementSize} containerSize With all properties from [[ElementSize]].
@@ -1068,6 +1088,10 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
1068
1088
  * @ignore - do not document.
1069
1089
  */
1070
1090
  onStateChange: PropTypes.func,
1091
+ /**
1092
+ * Callback fired when an undo operation is executed.
1093
+ */
1094
+ onUndo: PropTypes.func,
1071
1095
  /**
1072
1096
  * Select the pageSize dynamically using the component UI.
1073
1097
  * @default [25, 50, 100]
@@ -19,6 +19,7 @@ import { gridPivotPropsOverridesSelector } from "../hooks/features/pivoting/grid
19
19
  import { useGridAiAssistant, aiAssistantStateInitializer } from "../hooks/features/aiAssistant/useGridAiAssistant.js";
20
20
  import { useGridSidebar, sidebarStateInitializer } from "../hooks/features/sidebar/useGridSidebar.js";
21
21
  import { chartsIntegrationStateInitializer, useGridChartsIntegration } from "../hooks/features/chartsIntegration/useGridChartsIntegration.js";
22
+ import { historyStateInitializer, useGridHistory } from "../hooks/features/history/useGridHistory.js";
22
23
  export const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
23
24
  const pivotPropsOverrides = useGridSelector(apiRef, gridPivotPropsOverridesSelector);
24
25
  const props = React.useMemo(() => {
@@ -92,6 +93,7 @@ export const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
92
93
  useGridInitializeState(listViewStateInitializer, apiRef, props);
93
94
  useGridInitializeState(aiAssistantStateInitializer, apiRef, props);
94
95
  useGridInitializeState(chartsIntegrationStateInitializer, apiRef, props);
96
+ useGridInitializeState(historyStateInitializer, apiRef, props);
95
97
  useGridSidebar(apiRef, props);
96
98
  useGridPivoting(apiRef, props, inProps.columns, inProps.rows);
97
99
  useGridRowGrouping(apiRef, props);
@@ -139,6 +141,7 @@ export const useDataGridPremiumComponent = (apiRef, inProps, configuration) => {
139
141
  useGridListView(apiRef, props);
140
142
  useGridAiAssistant(apiRef, props);
141
143
  useGridChartsIntegration(apiRef, props);
144
+ useGridHistory(apiRef, props);
142
145
  useGridPivotingExportState(apiRef);
143
146
 
144
147
  // Should be the last thing to run, because all pre-processors should have been registered by now.
@@ -8,6 +8,7 @@ import { GRID_AGGREGATION_FUNCTIONS } from "../hooks/features/aggregation/index.
8
8
  import { DATA_GRID_PREMIUM_DEFAULT_SLOTS_COMPONENTS } from "../constants/dataGridPremiumDefaultSlotsComponents.js";
9
9
  import { defaultGetPivotDerivedColumns } from "../hooks/features/pivoting/utils.js";
10
10
  import { defaultGetAggregationPosition } from "../hooks/features/aggregation/gridAggregationUtils.js";
11
+ import { DEFAULT_HISTORY_VALIDATION_EVENTS } from "../hooks/features/history/constants.js";
11
12
  const getDataGridPremiumForcedProps = themedProps => _extends({
12
13
  signature: GridSignature.DataGridPremium
13
14
  }, themedProps.dataSource ? {
@@ -36,7 +37,10 @@ export const DATA_GRID_PREMIUM_PROPS_DEFAULT_VALUES = _extends({}, DATA_GRID_PRO
36
37
  },
37
38
  disablePivoting: false,
38
39
  aiAssistant: false,
39
- chartsIntegration: false
40
+ chartsIntegration: false,
41
+ historyStackSize: 30,
42
+ historyEventHandlers: {},
43
+ historyValidationEvents: DEFAULT_HISTORY_VALIDATION_EVENTS
40
44
  });
41
45
  const defaultSlots = DATA_GRID_PREMIUM_DEFAULT_SLOTS_COMPONENTS;
42
46
  export const useDataGridPremiumProps = inProps => {
@@ -2,21 +2,73 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["excelOptions"];
4
4
  import * as React from 'react';
5
- import { GridToolbar } from '@mui/x-data-grid-pro/internals';
6
- import { ToolbarButton } from '@mui/x-data-grid-pro';
5
+ import { GridToolbar, GridToolbarDivider, useGridSelector } from '@mui/x-data-grid-pro/internals';
6
+ import { ColumnsPanelTrigger, FilterPanelTrigger, ToolbarButton } from '@mui/x-data-grid-pro';
7
7
  import { ExportExcel } from "./export/index.js";
8
8
  import { useGridRootProps } from "../hooks/utils/useGridRootProps.js";
9
9
  import { useGridApiContext } from "../hooks/utils/useGridApiContext.js";
10
10
  import { PivotPanelTrigger } from "./pivotPanel/PivotPanelTrigger.js";
11
11
  import { AiAssistantPanelTrigger } from "./aiAssistantPanel/index.js";
12
12
  import { ChartsPanelTrigger } from "./chartsPanel/ChartsPanelTrigger.js";
13
+ import { gridHistoryCanRedoSelector, gridHistoryCanUndoSelector, gridHistoryEnabledSelector } from "../hooks/features/history/index.js";
13
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
15
  export function GridPremiumToolbar(props) {
15
16
  const rootProps = useGridRootProps();
16
17
  const apiRef = useGridApiContext();
17
18
  const other = _objectWithoutPropertiesLoose(props, _excluded);
18
- const additionalItems = /*#__PURE__*/_jsxs(React.Fragment, {
19
- children: [!rootProps.disablePivoting && /*#__PURE__*/_jsx(PivotPanelTrigger, {
19
+ const historyEnabled = useGridSelector(apiRef, gridHistoryEnabledSelector);
20
+ const showHistoryControls = rootProps.slotProps?.toolbar?.showHistoryControls !== false && historyEnabled;
21
+ const canUndo = useGridSelector(apiRef, gridHistoryCanUndoSelector);
22
+ const canRedo = useGridSelector(apiRef, gridHistoryCanRedoSelector);
23
+ const mainControls = /*#__PURE__*/_jsxs(React.Fragment, {
24
+ children: [showHistoryControls && /*#__PURE__*/_jsxs(React.Fragment, {
25
+ children: [/*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
26
+ title: apiRef.current.getLocaleText('toolbarUndo'),
27
+ children: /*#__PURE__*/_jsx("div", {
28
+ children: /*#__PURE__*/_jsx(ToolbarButton, {
29
+ disabled: !canUndo,
30
+ onClick: () => apiRef.current.history.undo(),
31
+ children: /*#__PURE__*/_jsx(rootProps.slots.undoIcon, {
32
+ fontSize: "small"
33
+ })
34
+ })
35
+ })
36
+ }), /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
37
+ title: apiRef.current.getLocaleText('toolbarRedo'),
38
+ children: /*#__PURE__*/_jsx("div", {
39
+ children: /*#__PURE__*/_jsx(ToolbarButton, {
40
+ disabled: !canRedo,
41
+ onClick: () => apiRef.current.history.redo(),
42
+ children: /*#__PURE__*/_jsx(rootProps.slots.redoIcon, {
43
+ fontSize: "small"
44
+ })
45
+ })
46
+ })
47
+ })]
48
+ }), showHistoryControls && /*#__PURE__*/_jsx(GridToolbarDivider, {}), !rootProps.disableColumnSelector && /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
49
+ title: apiRef.current.getLocaleText('toolbarColumns'),
50
+ children: /*#__PURE__*/_jsx(ColumnsPanelTrigger, {
51
+ render: /*#__PURE__*/_jsx(ToolbarButton, {}),
52
+ children: /*#__PURE__*/_jsx(rootProps.slots.columnSelectorIcon, {
53
+ fontSize: "small"
54
+ })
55
+ })
56
+ }), !rootProps.disableColumnFilter && /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
57
+ title: apiRef.current.getLocaleText('toolbarFilters'),
58
+ children: /*#__PURE__*/_jsx(FilterPanelTrigger, {
59
+ render: (triggerProps, state) => /*#__PURE__*/_jsx(ToolbarButton, _extends({}, triggerProps, {
60
+ color: state.filterCount > 0 ? 'primary' : 'default',
61
+ children: /*#__PURE__*/_jsx(rootProps.slots.baseBadge, {
62
+ badgeContent: state.filterCount,
63
+ color: "primary",
64
+ variant: "dot",
65
+ children: /*#__PURE__*/_jsx(rootProps.slots.openFilterButtonIcon, {
66
+ fontSize: "small"
67
+ })
68
+ })
69
+ }))
70
+ })
71
+ }), !rootProps.disablePivoting && /*#__PURE__*/_jsx(PivotPanelTrigger, {
20
72
  render: (triggerProps, state) => /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
21
73
  title: apiRef.current.getLocaleText('toolbarPivot'),
22
74
  children: /*#__PURE__*/_jsx(ToolbarButton, _extends({}, triggerProps, {
@@ -55,7 +107,7 @@ export function GridPremiumToolbar(props) {
55
107
  children: apiRef.current.getLocaleText('toolbarExportExcel')
56
108
  }) : undefined;
57
109
  return /*#__PURE__*/_jsx(GridToolbar, _extends({}, other, {
58
- additionalItems: additionalItems,
110
+ mainControls: mainControls,
59
111
  additionalExportMenuItems: additionalExportMenuItems
60
112
  }));
61
113
  }
@@ -53,7 +53,7 @@ async function getTextFromClipboard(rootEl) {
53
53
 
54
54
  // Keeps track of updated rows during clipboard paste
55
55
  class CellValueUpdater {
56
- rowsToUpdate = {};
56
+ rowsToUpdate = (() => new Map())();
57
57
  constructor(options) {
58
58
  this.options = options;
59
59
  this.updateRow = batchRowUpdates(options.apiRef.current.updateRows, 50);
@@ -74,7 +74,7 @@ class CellValueUpdater {
74
74
  if (!colDef || !colDef.editable) {
75
75
  return;
76
76
  }
77
- const row = this.rowsToUpdate[rowId] || _extends({}, apiRef.current.getRow(rowId));
77
+ const row = this.rowsToUpdate.get(rowId) || _extends({}, apiRef.current.getRow(rowId));
78
78
  if (!row) {
79
79
  return;
80
80
  }
@@ -104,7 +104,7 @@ class CellValueUpdater {
104
104
  // We cannot update row id, so this cell value update should be ignored
105
105
  return;
106
106
  }
107
- this.rowsToUpdate[rowId] = rowCopy;
107
+ this.rowsToUpdate.set(rowId, rowCopy);
108
108
  }
109
109
  applyUpdates() {
110
110
  const {
@@ -113,13 +113,20 @@ class CellValueUpdater {
113
113
  onProcessRowUpdateError
114
114
  } = this.options;
115
115
  const rowsToUpdate = this.rowsToUpdate;
116
- const rowIdsToUpdate = Object.keys(rowsToUpdate);
116
+ const rowIdsToUpdate = Array.from(rowsToUpdate.keys());
117
117
  if (rowIdsToUpdate.length === 0) {
118
- apiRef.current.publishEvent('clipboardPasteEnd');
118
+ apiRef.current.publishEvent('clipboardPasteEnd', {
119
+ oldRows: new Map(),
120
+ newRows: new Map()
121
+ });
119
122
  return;
120
123
  }
124
+ const oldRows = new Map();
125
+ const newRows = new Map();
121
126
  const handleRowUpdate = async rowId => {
122
- const newRow = rowsToUpdate[rowId];
127
+ const oldRow = apiRef.current.getRow(rowId);
128
+ const newRow = rowsToUpdate.get(rowId);
129
+ oldRows.set(rowId, oldRow);
123
130
  if (typeof processRowUpdate === 'function') {
124
131
  const handleError = errorThrown => {
125
132
  if (onProcessRowUpdateError) {
@@ -129,15 +136,16 @@ class CellValueUpdater {
129
136
  }
130
137
  };
131
138
  try {
132
- const oldRow = apiRef.current.getRow(rowId);
133
139
  const finalRowUpdate = await processRowUpdate(newRow, oldRow, {
134
140
  rowId
135
141
  });
142
+ newRows.set(rowId, finalRowUpdate);
136
143
  this.updateRow(finalRowUpdate);
137
144
  } catch (error) {
138
145
  handleError(error);
139
146
  }
140
147
  } else {
148
+ newRows.set(rowId, newRow);
141
149
  this.updateRow(newRow);
142
150
  }
143
151
  };
@@ -149,8 +157,11 @@ class CellValueUpdater {
149
157
  });
150
158
  });
151
159
  Promise.all(promises).then(() => {
152
- this.rowsToUpdate = {};
153
- apiRef.current.publishEvent('clipboardPasteEnd');
160
+ apiRef.current.publishEvent('clipboardPasteEnd', {
161
+ oldRows,
162
+ newRows
163
+ });
164
+ this.rowsToUpdate.clear();
154
165
  });
155
166
  }
156
167
  }
@@ -0,0 +1,2 @@
1
+ import type { GridEvents } from '@mui/x-data-grid-pro';
2
+ export declare const DEFAULT_HISTORY_VALIDATION_EVENTS: GridEvents[];
@@ -0,0 +1 @@
1
+ export const DEFAULT_HISTORY_VALIDATION_EVENTS = ['columnsChange', 'rowsSet', 'sortedRowsSet', 'filteredRowsSet', 'paginationModelChange'];
@@ -0,0 +1,20 @@
1
+ import { RefObject } from '@mui/x-internals/types';
2
+ import type { GridApiPremium } from "../../../models/gridApiPremium.js";
3
+ import type { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
4
+ import type { GridHistoryEventHandler, GridCellEditHistoryData, GridRowEditHistoryData, GridClipboardPasteHistoryData } from "./gridHistoryInterfaces.js";
5
+ /**
6
+ * Create the default handler for cellEditStop events.
7
+ */
8
+ export declare const createCellEditHistoryHandler: (apiRef: RefObject<GridApiPremium>) => GridHistoryEventHandler<GridCellEditHistoryData>;
9
+ /**
10
+ * Create the default handler for rowEditStop events.
11
+ */
12
+ export declare const createRowEditHistoryHandler: (apiRef: RefObject<GridApiPremium>) => GridHistoryEventHandler<GridRowEditHistoryData>;
13
+ /**
14
+ * Create the default handler for clipboardPasteEnd events.
15
+ */
16
+ export declare const createClipboardPasteHistoryHandler: (apiRef: RefObject<GridApiPremium>) => GridHistoryEventHandler<GridClipboardPasteHistoryData>;
17
+ /**
18
+ * Create the default history events map.
19
+ */
20
+ export declare const createDefaultHistoryHandlers: (apiRef: RefObject<GridApiPremium>, props: Pick<DataGridPremiumProcessedProps, "columns" | "isCellEditable" | "dataSource">) => Record<keyof import("@mui/x-data-grid").GridEventLookup, GridHistoryEventHandler<GridCellEditHistoryData> | GridHistoryEventHandler<GridRowEditHistoryData> | GridHistoryEventHandler<GridClipboardPasteHistoryData>>;