@mui/x-data-grid 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.
- package/CHANGELOG.md +84 -0
- package/components/cell/GridActionsCell.d.ts +22 -2
- package/components/cell/GridActionsCell.js +15 -5
- package/components/toolbar/GridToolbar.d.ts +5 -0
- package/components/toolbar/GridToolbar.js +5 -0
- package/components/toolbarV8/GridToolbar.d.ts +1 -1
- package/components/toolbarV8/GridToolbar.js +26 -24
- package/constants/localeTextConstants.js +3 -0
- package/esm/components/cell/GridActionsCell.d.ts +22 -2
- package/esm/components/cell/GridActionsCell.js +15 -5
- package/esm/components/toolbar/GridToolbar.d.ts +5 -0
- package/esm/components/toolbar/GridToolbar.js +5 -0
- package/esm/components/toolbarV8/GridToolbar.d.ts +1 -1
- package/esm/components/toolbarV8/GridToolbar.js +26 -24
- package/esm/constants/localeTextConstants.js +3 -0
- package/esm/hooks/core/useGridProps.js +5 -3
- package/esm/hooks/features/focus/useGridFocus.js +26 -2
- package/esm/hooks/features/scroll/useGridScroll.js +3 -3
- package/esm/index.js +1 -1
- package/esm/internals/index.d.ts +1 -1
- package/esm/internals/index.js +1 -1
- package/esm/locales/arSD.js +3 -0
- package/esm/locales/beBY.js +3 -0
- package/esm/locales/bgBG.js +3 -0
- package/esm/locales/bnBD.js +3 -0
- package/esm/locales/caES.js +3 -0
- package/esm/locales/csCZ.js +3 -0
- package/esm/locales/daDK.js +3 -0
- package/esm/locales/deDE.js +3 -0
- package/esm/locales/elGR.js +3 -0
- package/esm/locales/esES.js +3 -0
- package/esm/locales/faIR.js +3 -0
- package/esm/locales/fiFI.js +3 -0
- package/esm/locales/frFR.js +3 -0
- package/esm/locales/heIL.js +3 -0
- package/esm/locales/hrHR.js +3 -0
- package/esm/locales/huHU.js +3 -0
- package/esm/locales/hyAM.js +3 -0
- package/esm/locales/idID.js +3 -0
- package/esm/locales/isIS.js +3 -0
- package/esm/locales/itIT.js +3 -0
- package/esm/locales/jaJP.js +3 -0
- package/esm/locales/koKR.js +3 -0
- package/esm/locales/nbNO.js +3 -0
- package/esm/locales/nlNL.js +3 -0
- package/esm/locales/nnNO.js +3 -0
- package/esm/locales/plPL.js +3 -0
- package/esm/locales/ptBR.js +3 -0
- package/esm/locales/ptPT.js +3 -0
- package/esm/locales/roRO.js +3 -0
- package/esm/locales/ruRU.js +3 -0
- package/esm/locales/skSK.js +3 -0
- package/esm/locales/svSE.js +3 -0
- package/esm/locales/trTR.js +3 -0
- package/esm/locales/ukUA.js +3 -0
- package/esm/locales/urPK.js +3 -0
- package/esm/locales/viVN.js +3 -0
- package/esm/locales/zhCN.js +3 -0
- package/esm/locales/zhHK.js +3 -0
- package/esm/locales/zhTW.js +3 -0
- package/esm/material/icons/index.d.ts +2 -0
- package/esm/material/icons/index.js +6 -0
- package/esm/material/index.js +3 -1
- package/esm/models/api/gridLocaleTextApi.d.ts +2 -0
- package/esm/models/gridIconSlotsComponent.d.ts +10 -0
- package/esm/models/gridStateCommunity.d.ts +1 -1
- package/esm/utils/keyboardUtils.d.ts +3 -1
- package/esm/utils/keyboardUtils.js +6 -0
- package/hooks/core/useGridProps.js +5 -3
- package/hooks/features/focus/useGridFocus.js +25 -1
- package/hooks/features/scroll/useGridScroll.js +3 -3
- package/index.js +1 -1
- package/internals/index.d.ts +1 -1
- package/internals/index.js +14 -0
- package/locales/arSD.js +3 -0
- package/locales/beBY.js +3 -0
- package/locales/bgBG.js +3 -0
- package/locales/bnBD.js +3 -0
- package/locales/caES.js +3 -0
- package/locales/csCZ.js +3 -0
- package/locales/daDK.js +3 -0
- package/locales/deDE.js +3 -0
- package/locales/elGR.js +3 -0
- package/locales/esES.js +3 -0
- package/locales/faIR.js +3 -0
- package/locales/fiFI.js +3 -0
- package/locales/frFR.js +3 -0
- package/locales/heIL.js +3 -0
- package/locales/hrHR.js +3 -0
- package/locales/huHU.js +3 -0
- package/locales/hyAM.js +3 -0
- package/locales/idID.js +3 -0
- package/locales/isIS.js +3 -0
- package/locales/itIT.js +3 -0
- package/locales/jaJP.js +3 -0
- package/locales/koKR.js +3 -0
- package/locales/nbNO.js +3 -0
- package/locales/nlNL.js +3 -0
- package/locales/nnNO.js +3 -0
- package/locales/plPL.js +3 -0
- package/locales/ptBR.js +3 -0
- package/locales/ptPT.js +3 -0
- package/locales/roRO.js +3 -0
- package/locales/ruRU.js +3 -0
- package/locales/skSK.js +3 -0
- package/locales/svSE.js +3 -0
- package/locales/trTR.js +3 -0
- package/locales/ukUA.js +3 -0
- package/locales/urPK.js +3 -0
- package/locales/viVN.js +3 -0
- package/locales/zhCN.js +3 -0
- package/locales/zhHK.js +3 -0
- package/locales/zhTW.js +3 -0
- package/material/icons/index.d.ts +2 -0
- package/material/icons/index.js +7 -1
- package/material/index.js +2 -0
- package/models/api/gridLocaleTextApi.d.ts +2 -0
- package/models/gridIconSlotsComponent.d.ts +10 -0
- package/models/gridStateCommunity.d.ts +1 -1
- package/package.json +3 -3
- package/utils/keyboardUtils.d.ts +3 -1
- package/utils/keyboardUtils.js +8 -0
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` [](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` [](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` [](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` [](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` [](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` [](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 -->
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { GridRowParams } from "../../models/params/gridRowParams.js";
|
|
2
3
|
import { GridRenderCellParams } from "../../models/params/gridCellParams.js";
|
|
3
4
|
import { GridMenuProps } from "../menu/GridMenu.js";
|
|
4
|
-
|
|
5
|
+
import { GridValidRowModel, GridTreeNodeWithRender } from "../../models/gridRows.js";
|
|
6
|
+
interface GridActionsCellProps<R extends GridValidRowModel = any, V = any, F = V, N extends GridTreeNodeWithRender = GridTreeNodeWithRender> extends Omit<GridRenderCellParams<R, V, F, N>, 'api'> {
|
|
5
7
|
api?: GridRenderCellParams['api'];
|
|
6
8
|
position?: GridMenuProps['position'];
|
|
7
9
|
children: React.ReactNode;
|
|
@@ -12,8 +14,26 @@ interface GridActionsCellProps extends Omit<GridRenderCellParams, 'api'> {
|
|
|
12
14
|
* @default false
|
|
13
15
|
*/
|
|
14
16
|
suppressChildrenValidation?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Callback to fire before the menu gets opened.
|
|
19
|
+
* Use this callback to prevent the menu from opening.
|
|
20
|
+
*
|
|
21
|
+
* @param {GridRowParams<R>} params Row parameters.
|
|
22
|
+
* @param {React.MouseEvent<HTMLElement>} event The event triggering this callback.
|
|
23
|
+
* @returns {boolean} if the menu should be opened.
|
|
24
|
+
*/
|
|
25
|
+
onMenuOpen?: (params: GridRowParams<R>, event: React.MouseEvent<HTMLElement>) => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Callback to fire before the menu gets closed.
|
|
28
|
+
* Use this callback to prevent the menu from closing.
|
|
29
|
+
*
|
|
30
|
+
* @param {GridRowParams<R>} params Row parameters.
|
|
31
|
+
* @param {React.MouseEvent<HTMLElement> | React.KeyboardEvent | MouseEvent | TouchEvent | undefined} event The event triggering this callback.
|
|
32
|
+
* @returns {boolean} if the menu should be closed.
|
|
33
|
+
*/
|
|
34
|
+
onMenuClose?: (params: GridRowParams<R>, event: React.MouseEvent<HTMLElement> | React.KeyboardEvent | MouseEvent | TouchEvent | undefined) => boolean;
|
|
15
35
|
}
|
|
16
|
-
declare function GridActionsCell(props: GridActionsCellProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
declare function GridActionsCell<R extends GridValidRowModel = any, V = any, F = V, N extends GridTreeNodeWithRender = GridTreeNodeWithRender>(props: GridActionsCellProps<R, V, F, N>): import("react/jsx-runtime").JSX.Element;
|
|
17
37
|
declare namespace GridActionsCell {
|
|
18
38
|
var propTypes: any;
|
|
19
39
|
}
|
|
@@ -21,13 +21,16 @@ var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
|
|
|
21
21
|
var _useGridApiContext = require("../../hooks/utils/useGridApiContext");
|
|
22
22
|
var _GridActionsCellItem = require("./GridActionsCellItem");
|
|
23
23
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
24
|
-
const _excluded = ["api", "colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "children", "suppressChildrenValidation"];
|
|
24
|
+
const _excluded = ["api", "colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "onMenuOpen", "onMenuClose", "children", "suppressChildrenValidation"];
|
|
25
25
|
const hasActions = colDef => typeof colDef.getActions === 'function';
|
|
26
26
|
function GridActionsCell(props) {
|
|
27
27
|
const {
|
|
28
|
+
id,
|
|
28
29
|
hasFocus,
|
|
29
30
|
tabIndex,
|
|
30
31
|
position = 'bottom-end',
|
|
32
|
+
onMenuOpen,
|
|
33
|
+
onMenuClose,
|
|
31
34
|
children,
|
|
32
35
|
suppressChildrenValidation
|
|
33
36
|
} = props,
|
|
@@ -43,6 +46,7 @@ function GridActionsCell(props) {
|
|
|
43
46
|
const menuId = (0, _useId.default)();
|
|
44
47
|
const buttonId = (0, _useId.default)();
|
|
45
48
|
const rootProps = (0, _useGridRootProps.useGridRootProps)();
|
|
49
|
+
const rowParams = apiRef.current.getRowParams(id);
|
|
46
50
|
const actions = [];
|
|
47
51
|
React.Children.forEach(children, child => {
|
|
48
52
|
// Unwrap React.Fragment
|
|
@@ -101,21 +105,27 @@ If this is intentional, you can suppress this warning by passing the \`suppressC
|
|
|
101
105
|
setFocusedButtonIndex(numberOfButtons - 1);
|
|
102
106
|
}
|
|
103
107
|
}, [focusedButtonIndex, numberOfButtons]);
|
|
104
|
-
const showMenu =
|
|
108
|
+
const showMenu = event => {
|
|
109
|
+
if (onMenuOpen && !onMenuOpen(rowParams, event)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
105
112
|
setOpen(true);
|
|
106
113
|
setFocusedButtonIndex(numberOfButtons - 1);
|
|
107
114
|
ignoreCallToFocus.current = true;
|
|
108
115
|
};
|
|
109
|
-
const hideMenu =
|
|
116
|
+
const hideMenu = event => {
|
|
117
|
+
if (onMenuClose && !onMenuClose(rowParams, event)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
110
120
|
setOpen(false);
|
|
111
121
|
};
|
|
112
122
|
const toggleMenu = event => {
|
|
113
123
|
event.stopPropagation();
|
|
114
124
|
event.preventDefault();
|
|
115
125
|
if (open) {
|
|
116
|
-
hideMenu();
|
|
126
|
+
hideMenu(event);
|
|
117
127
|
} else {
|
|
118
|
-
showMenu();
|
|
128
|
+
showMenu(event);
|
|
119
129
|
}
|
|
120
130
|
};
|
|
121
131
|
const handleTouchRippleRef = index => instance => {
|
|
@@ -2,6 +2,11 @@ import { GridToolbarContainerProps } from "../containers/GridToolbarContainer.js
|
|
|
2
2
|
import { GridToolbarExportProps } from "./GridToolbarExport.js";
|
|
3
3
|
import { GridToolbarQuickFilterProps } from "./GridToolbarQuickFilter.js";
|
|
4
4
|
export interface GridToolbarProps extends GridToolbarContainerProps, GridToolbarExportProps {
|
|
5
|
+
/**
|
|
6
|
+
* Show the history controls (undo/redo buttons).
|
|
7
|
+
* @default true
|
|
8
|
+
*/
|
|
9
|
+
showHistoryControls?: boolean;
|
|
5
10
|
/**
|
|
6
11
|
* Show the quick filter component.
|
|
7
12
|
* @default true
|
|
@@ -74,6 +74,11 @@ process.env.NODE_ENV !== "production" ? GridToolbar.propTypes = {
|
|
|
74
74
|
quickFilterParser: _propTypes.default.func,
|
|
75
75
|
slotProps: _propTypes.default.object
|
|
76
76
|
}),
|
|
77
|
+
/**
|
|
78
|
+
* Show the history controls (undo/redo buttons).
|
|
79
|
+
* @default true
|
|
80
|
+
*/
|
|
81
|
+
showHistoryControls: _propTypes.default.bool,
|
|
77
82
|
/**
|
|
78
83
|
* Show the quick filter component.
|
|
79
84
|
* @default true
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { GridSlotProps } from "../../models/gridSlotsComponentsProps.js";
|
|
3
3
|
interface GridToolbarInternalProps {
|
|
4
|
-
|
|
4
|
+
mainControls?: React.ReactNode;
|
|
5
5
|
additionalExportMenuItems?: (onMenuItemClick: () => void) => React.ReactNode;
|
|
6
6
|
}
|
|
7
7
|
export type GridToolbarProps = GridSlotProps['toolbar'] & GridToolbarInternalProps;
|
|
@@ -31,7 +31,7 @@ var _gridClasses = require("../../constants/gridClasses");
|
|
|
31
31
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
32
32
|
const _excluded = ["className"],
|
|
33
33
|
_excluded2 = ["className"],
|
|
34
|
-
_excluded3 = ["showQuickFilter", "quickFilterProps", "csvOptions", "printOptions", "
|
|
34
|
+
_excluded3 = ["showQuickFilter", "quickFilterProps", "csvOptions", "printOptions", "mainControls", "additionalExportMenuItems"];
|
|
35
35
|
const useUtilityClasses = ownerState => {
|
|
36
36
|
const {
|
|
37
37
|
classes
|
|
@@ -93,7 +93,7 @@ function GridToolbar(props) {
|
|
|
93
93
|
quickFilterProps,
|
|
94
94
|
csvOptions,
|
|
95
95
|
printOptions,
|
|
96
|
-
|
|
96
|
+
mainControls,
|
|
97
97
|
additionalExportMenuItems
|
|
98
98
|
} = props,
|
|
99
99
|
other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded3);
|
|
@@ -108,30 +108,32 @@ function GridToolbar(props) {
|
|
|
108
108
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Toolbar.Toolbar, (0, _extends2.default)({}, other, {
|
|
109
109
|
children: [rootProps.label && /*#__PURE__*/(0, _jsxRuntime.jsx)(GridToolbarLabel, {
|
|
110
110
|
children: rootProps.label
|
|
111
|
-
}),
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
}), mainControls || /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
|
|
112
|
+
children: [!rootProps.disableColumnSelector && /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
|
|
113
|
+
title: apiRef.current.getLocaleText('toolbarColumns'),
|
|
114
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_columnsPanel.ColumnsPanelTrigger, {
|
|
115
|
+
render: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ToolbarButton.ToolbarButton, {}),
|
|
116
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.columnSelectorIcon, {
|
|
117
|
+
fontSize: "small"
|
|
118
|
+
})
|
|
117
119
|
})
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
}), !rootProps.disableColumnFilter && /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
|
|
121
|
+
title: apiRef.current.getLocaleText('toolbarFilters'),
|
|
122
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_filterPanel.FilterPanelTrigger, {
|
|
123
|
+
render: (triggerProps, state) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_ToolbarButton.ToolbarButton, (0, _extends2.default)({}, triggerProps, {
|
|
124
|
+
color: state.filterCount > 0 ? 'primary' : 'default',
|
|
125
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseBadge, {
|
|
126
|
+
badgeContent: state.filterCount,
|
|
127
|
+
color: "primary",
|
|
128
|
+
variant: "dot",
|
|
129
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.openFilterButtonIcon, {
|
|
130
|
+
fontSize: "small"
|
|
131
|
+
})
|
|
130
132
|
})
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
}),
|
|
133
|
+
}))
|
|
134
|
+
})
|
|
135
|
+
})]
|
|
136
|
+
}), showExportMenu && (!rootProps.disableColumnFilter || !rootProps.disableColumnSelector) && /*#__PURE__*/(0, _jsxRuntime.jsx)(GridToolbarDivider, {}), showExportMenu && /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
|
|
135
137
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseTooltip, {
|
|
136
138
|
title: apiRef.current.getLocaleText('toolbarExport'),
|
|
137
139
|
disableInteractive: exportMenuOpen,
|
|
@@ -17,6 +17,9 @@ const GRID_DEFAULT_LOCALE_TEXT = exports.GRID_DEFAULT_LOCALE_TEXT = {
|
|
|
17
17
|
toolbarDensityCompact: 'Compact',
|
|
18
18
|
toolbarDensityStandard: 'Standard',
|
|
19
19
|
toolbarDensityComfortable: 'Comfortable',
|
|
20
|
+
// Undo/redo toolbar button text
|
|
21
|
+
toolbarUndo: 'Undo',
|
|
22
|
+
toolbarRedo: 'Redo',
|
|
20
23
|
// Columns selector toolbar button text
|
|
21
24
|
toolbarColumns: 'Columns',
|
|
22
25
|
toolbarColumnsLabel: 'Select columns',
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { GridRowParams } from "../../models/params/gridRowParams.js";
|
|
2
3
|
import { GridRenderCellParams } from "../../models/params/gridCellParams.js";
|
|
3
4
|
import { GridMenuProps } from "../menu/GridMenu.js";
|
|
4
|
-
|
|
5
|
+
import { GridValidRowModel, GridTreeNodeWithRender } from "../../models/gridRows.js";
|
|
6
|
+
interface GridActionsCellProps<R extends GridValidRowModel = any, V = any, F = V, N extends GridTreeNodeWithRender = GridTreeNodeWithRender> extends Omit<GridRenderCellParams<R, V, F, N>, 'api'> {
|
|
5
7
|
api?: GridRenderCellParams['api'];
|
|
6
8
|
position?: GridMenuProps['position'];
|
|
7
9
|
children: React.ReactNode;
|
|
@@ -12,8 +14,26 @@ interface GridActionsCellProps extends Omit<GridRenderCellParams, 'api'> {
|
|
|
12
14
|
* @default false
|
|
13
15
|
*/
|
|
14
16
|
suppressChildrenValidation?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Callback to fire before the menu gets opened.
|
|
19
|
+
* Use this callback to prevent the menu from opening.
|
|
20
|
+
*
|
|
21
|
+
* @param {GridRowParams<R>} params Row parameters.
|
|
22
|
+
* @param {React.MouseEvent<HTMLElement>} event The event triggering this callback.
|
|
23
|
+
* @returns {boolean} if the menu should be opened.
|
|
24
|
+
*/
|
|
25
|
+
onMenuOpen?: (params: GridRowParams<R>, event: React.MouseEvent<HTMLElement>) => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Callback to fire before the menu gets closed.
|
|
28
|
+
* Use this callback to prevent the menu from closing.
|
|
29
|
+
*
|
|
30
|
+
* @param {GridRowParams<R>} params Row parameters.
|
|
31
|
+
* @param {React.MouseEvent<HTMLElement> | React.KeyboardEvent | MouseEvent | TouchEvent | undefined} event The event triggering this callback.
|
|
32
|
+
* @returns {boolean} if the menu should be closed.
|
|
33
|
+
*/
|
|
34
|
+
onMenuClose?: (params: GridRowParams<R>, event: React.MouseEvent<HTMLElement> | React.KeyboardEvent | MouseEvent | TouchEvent | undefined) => boolean;
|
|
15
35
|
}
|
|
16
|
-
declare function GridActionsCell(props: GridActionsCellProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
declare function GridActionsCell<R extends GridValidRowModel = any, V = any, F = V, N extends GridTreeNodeWithRender = GridTreeNodeWithRender>(props: GridActionsCellProps<R, V, F, N>): import("react/jsx-runtime").JSX.Element;
|
|
17
37
|
declare namespace GridActionsCell {
|
|
18
38
|
var propTypes: any;
|
|
19
39
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
4
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
5
|
-
const _excluded = ["api", "colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "children", "suppressChildrenValidation"];
|
|
5
|
+
const _excluded = ["api", "colDef", "id", "hasFocus", "isEditable", "field", "value", "formattedValue", "row", "rowNode", "cellMode", "tabIndex", "position", "onMenuOpen", "onMenuClose", "children", "suppressChildrenValidation"];
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { useRtl } from '@mui/system/RtlProvider';
|
|
@@ -17,9 +17,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
17
17
|
const hasActions = colDef => typeof colDef.getActions === 'function';
|
|
18
18
|
function GridActionsCell(props) {
|
|
19
19
|
const {
|
|
20
|
+
id,
|
|
20
21
|
hasFocus,
|
|
21
22
|
tabIndex,
|
|
22
23
|
position = 'bottom-end',
|
|
24
|
+
onMenuOpen,
|
|
25
|
+
onMenuClose,
|
|
23
26
|
children,
|
|
24
27
|
suppressChildrenValidation
|
|
25
28
|
} = props,
|
|
@@ -35,6 +38,7 @@ function GridActionsCell(props) {
|
|
|
35
38
|
const menuId = useId();
|
|
36
39
|
const buttonId = useId();
|
|
37
40
|
const rootProps = useGridRootProps();
|
|
41
|
+
const rowParams = apiRef.current.getRowParams(id);
|
|
38
42
|
const actions = [];
|
|
39
43
|
React.Children.forEach(children, child => {
|
|
40
44
|
// Unwrap React.Fragment
|
|
@@ -93,21 +97,27 @@ If this is intentional, you can suppress this warning by passing the \`suppressC
|
|
|
93
97
|
setFocusedButtonIndex(numberOfButtons - 1);
|
|
94
98
|
}
|
|
95
99
|
}, [focusedButtonIndex, numberOfButtons]);
|
|
96
|
-
const showMenu =
|
|
100
|
+
const showMenu = event => {
|
|
101
|
+
if (onMenuOpen && !onMenuOpen(rowParams, event)) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
97
104
|
setOpen(true);
|
|
98
105
|
setFocusedButtonIndex(numberOfButtons - 1);
|
|
99
106
|
ignoreCallToFocus.current = true;
|
|
100
107
|
};
|
|
101
|
-
const hideMenu =
|
|
108
|
+
const hideMenu = event => {
|
|
109
|
+
if (onMenuClose && !onMenuClose(rowParams, event)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
102
112
|
setOpen(false);
|
|
103
113
|
};
|
|
104
114
|
const toggleMenu = event => {
|
|
105
115
|
event.stopPropagation();
|
|
106
116
|
event.preventDefault();
|
|
107
117
|
if (open) {
|
|
108
|
-
hideMenu();
|
|
118
|
+
hideMenu(event);
|
|
109
119
|
} else {
|
|
110
|
-
showMenu();
|
|
120
|
+
showMenu(event);
|
|
111
121
|
}
|
|
112
122
|
};
|
|
113
123
|
const handleTouchRippleRef = index => instance => {
|
|
@@ -2,6 +2,11 @@ import { GridToolbarContainerProps } from "../containers/GridToolbarContainer.js
|
|
|
2
2
|
import { GridToolbarExportProps } from "./GridToolbarExport.js";
|
|
3
3
|
import { GridToolbarQuickFilterProps } from "./GridToolbarQuickFilter.js";
|
|
4
4
|
export interface GridToolbarProps extends GridToolbarContainerProps, GridToolbarExportProps {
|
|
5
|
+
/**
|
|
6
|
+
* Show the history controls (undo/redo buttons).
|
|
7
|
+
* @default true
|
|
8
|
+
*/
|
|
9
|
+
showHistoryControls?: boolean;
|
|
5
10
|
/**
|
|
6
11
|
* Show the quick filter component.
|
|
7
12
|
* @default true
|
|
@@ -68,6 +68,11 @@ process.env.NODE_ENV !== "production" ? GridToolbar.propTypes = {
|
|
|
68
68
|
quickFilterParser: PropTypes.func,
|
|
69
69
|
slotProps: PropTypes.object
|
|
70
70
|
}),
|
|
71
|
+
/**
|
|
72
|
+
* Show the history controls (undo/redo buttons).
|
|
73
|
+
* @default true
|
|
74
|
+
*/
|
|
75
|
+
showHistoryControls: PropTypes.bool,
|
|
71
76
|
/**
|
|
72
77
|
* Show the quick filter component.
|
|
73
78
|
* @default true
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { GridSlotProps } from "../../models/gridSlotsComponentsProps.js";
|
|
3
3
|
interface GridToolbarInternalProps {
|
|
4
|
-
|
|
4
|
+
mainControls?: React.ReactNode;
|
|
5
5
|
additionalExportMenuItems?: (onMenuItemClick: () => void) => React.ReactNode;
|
|
6
6
|
}
|
|
7
7
|
export type GridToolbarProps = GridSlotProps['toolbar'] & GridToolbarInternalProps;
|
|
@@ -4,7 +4,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
4
4
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
5
5
|
const _excluded = ["className"],
|
|
6
6
|
_excluded2 = ["className"],
|
|
7
|
-
_excluded3 = ["showQuickFilter", "quickFilterProps", "csvOptions", "printOptions", "
|
|
7
|
+
_excluded3 = ["showQuickFilter", "quickFilterProps", "csvOptions", "printOptions", "mainControls", "additionalExportMenuItems"];
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
10
|
import useId from '@mui/utils/useId';
|
|
@@ -84,7 +84,7 @@ function GridToolbar(props) {
|
|
|
84
84
|
quickFilterProps,
|
|
85
85
|
csvOptions,
|
|
86
86
|
printOptions,
|
|
87
|
-
|
|
87
|
+
mainControls,
|
|
88
88
|
additionalExportMenuItems
|
|
89
89
|
} = props,
|
|
90
90
|
other = _objectWithoutPropertiesLoose(props, _excluded3);
|
|
@@ -99,30 +99,32 @@ function GridToolbar(props) {
|
|
|
99
99
|
return /*#__PURE__*/_jsxs(Toolbar, _extends({}, other, {
|
|
100
100
|
children: [rootProps.label && /*#__PURE__*/_jsx(GridToolbarLabel, {
|
|
101
101
|
children: rootProps.label
|
|
102
|
-
}),
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
}), mainControls || /*#__PURE__*/_jsxs(React.Fragment, {
|
|
103
|
+
children: [!rootProps.disableColumnSelector && /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
|
|
104
|
+
title: apiRef.current.getLocaleText('toolbarColumns'),
|
|
105
|
+
children: /*#__PURE__*/_jsx(ColumnsPanelTrigger, {
|
|
106
|
+
render: /*#__PURE__*/_jsx(ToolbarButton, {}),
|
|
107
|
+
children: /*#__PURE__*/_jsx(rootProps.slots.columnSelectorIcon, {
|
|
108
|
+
fontSize: "small"
|
|
109
|
+
})
|
|
108
110
|
})
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
111
|
+
}), !rootProps.disableColumnFilter && /*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
|
|
112
|
+
title: apiRef.current.getLocaleText('toolbarFilters'),
|
|
113
|
+
children: /*#__PURE__*/_jsx(FilterPanelTrigger, {
|
|
114
|
+
render: (triggerProps, state) => /*#__PURE__*/_jsx(ToolbarButton, _extends({}, triggerProps, {
|
|
115
|
+
color: state.filterCount > 0 ? 'primary' : 'default',
|
|
116
|
+
children: /*#__PURE__*/_jsx(rootProps.slots.baseBadge, {
|
|
117
|
+
badgeContent: state.filterCount,
|
|
118
|
+
color: "primary",
|
|
119
|
+
variant: "dot",
|
|
120
|
+
children: /*#__PURE__*/_jsx(rootProps.slots.openFilterButtonIcon, {
|
|
121
|
+
fontSize: "small"
|
|
122
|
+
})
|
|
121
123
|
})
|
|
122
|
-
})
|
|
123
|
-
})
|
|
124
|
-
})
|
|
125
|
-
}),
|
|
124
|
+
}))
|
|
125
|
+
})
|
|
126
|
+
})]
|
|
127
|
+
}), showExportMenu && (!rootProps.disableColumnFilter || !rootProps.disableColumnSelector) && /*#__PURE__*/_jsx(GridToolbarDivider, {}), showExportMenu && /*#__PURE__*/_jsxs(React.Fragment, {
|
|
126
128
|
children: [/*#__PURE__*/_jsx(rootProps.slots.baseTooltip, {
|
|
127
129
|
title: apiRef.current.getLocaleText('toolbarExport'),
|
|
128
130
|
disableInteractive: exportMenuOpen,
|
|
@@ -11,6 +11,9 @@ export const GRID_DEFAULT_LOCALE_TEXT = {
|
|
|
11
11
|
toolbarDensityCompact: 'Compact',
|
|
12
12
|
toolbarDensityStandard: 'Standard',
|
|
13
13
|
toolbarDensityComfortable: 'Comfortable',
|
|
14
|
+
// Undo/redo toolbar button text
|
|
15
|
+
toolbarUndo: 'Undo',
|
|
16
|
+
toolbarRedo: 'Redo',
|
|
14
17
|
// Columns selector toolbar button text
|
|
15
18
|
toolbarColumns: 'Columns',
|
|
16
19
|
toolbarColumnsLabel: 'Select columns',
|
|
@@ -8,7 +8,8 @@ export const propsStateInitializer = (state, props) => {
|
|
|
8
8
|
listView: props.listView,
|
|
9
9
|
getRowId: props.getRowId,
|
|
10
10
|
isCellEditable: props.isCellEditable,
|
|
11
|
-
isRowSelectable: props.isRowSelectable
|
|
11
|
+
isRowSelectable: props.isRowSelectable,
|
|
12
|
+
dataSource: props.dataSource
|
|
12
13
|
}
|
|
13
14
|
});
|
|
14
15
|
};
|
|
@@ -24,8 +25,9 @@ export const useGridProps = (apiRef, props) => {
|
|
|
24
25
|
listView: props.listView,
|
|
25
26
|
getRowId: props.getRowId,
|
|
26
27
|
isCellEditable: props.isCellEditable,
|
|
27
|
-
isRowSelectable: props.isRowSelectable
|
|
28
|
+
isRowSelectable: props.isRowSelectable,
|
|
29
|
+
dataSource: props.dataSource
|
|
28
30
|
}
|
|
29
31
|
}));
|
|
30
|
-
}, [apiRef, props.listView, props.getRowId, props.isCellEditable, props.isRowSelectable]);
|
|
32
|
+
}, [apiRef, props.listView, props.getRowId, props.isCellEditable, props.isRowSelectable, props.dataSource]);
|
|
31
33
|
};
|
|
@@ -9,8 +9,9 @@ import { gridClasses } from "../../../constants/gridClasses.js";
|
|
|
9
9
|
import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
|
|
10
10
|
import { useGridLogger } from "../../utils/useGridLogger.js";
|
|
11
11
|
import { useGridEvent } from "../../utils/useGridEvent.js";
|
|
12
|
-
import { isNavigationKey } from "../../../utils/keyboardUtils.js";
|
|
12
|
+
import { isNavigationKey, isPasteShortcut } from "../../../utils/keyboardUtils.js";
|
|
13
13
|
import { gridFocusCellSelector, gridFocusColumnGroupHeaderSelector } from "./gridFocusStateSelector.js";
|
|
14
|
+
import { doesSupportPreventScroll } from "../../../utils/doesSupportPreventScroll.js";
|
|
14
15
|
import { gridVisibleColumnDefinitionsSelector } from "../columns/gridColumnsSelector.js";
|
|
15
16
|
import { getVisibleRows } from "../../utils/useGridVisibleRows.js";
|
|
16
17
|
import { clamp } from "../../../utils/utils.js";
|
|
@@ -50,6 +51,29 @@ export const useGridFocus = (apiRef, props) => {
|
|
|
50
51
|
const setCellFocus = React.useCallback((id, field) => {
|
|
51
52
|
const focusedCell = gridFocusCellSelector(apiRef);
|
|
52
53
|
if (focusedCell?.id === id && focusedCell?.field === field) {
|
|
54
|
+
/**
|
|
55
|
+
* Check if the state matches the actual DOM focus. They can get out of sync after `updateRows()` remounts the cell.
|
|
56
|
+
*/
|
|
57
|
+
if (apiRef.current.getCellMode(id, field) !== 'view') {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const cellElement = apiRef.current.getCellElement(id, field);
|
|
61
|
+
if (!cellElement) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const doc = ownerDocument(apiRef.current.rootElementRef.current);
|
|
65
|
+
if (cellElement.contains(doc.activeElement)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (doesSupportPreventScroll()) {
|
|
69
|
+
cellElement.focus({
|
|
70
|
+
preventScroll: true
|
|
71
|
+
});
|
|
72
|
+
} else {
|
|
73
|
+
const scrollPosition = apiRef.current.getScrollPosition();
|
|
74
|
+
cellElement.focus();
|
|
75
|
+
apiRef.current.scroll(scrollPosition);
|
|
76
|
+
}
|
|
53
77
|
return;
|
|
54
78
|
}
|
|
55
79
|
apiRef.current.setState(state => {
|
|
@@ -224,7 +248,7 @@ export const useGridFocus = (apiRef, props) => {
|
|
|
224
248
|
apiRef.current.setCellFocus(id, field);
|
|
225
249
|
}, [apiRef]);
|
|
226
250
|
const handleCellKeyDown = React.useCallback((params, event) => {
|
|
227
|
-
if (event.key === 'Enter' || event.key === 'Tab' || event.key === 'Shift' || isNavigationKey(event.key)) {
|
|
251
|
+
if (isPasteShortcut(event) || event.key === 'Enter' || event.key === 'Tab' || event.key === 'Shift' || isNavigationKey(event.key)) {
|
|
228
252
|
return;
|
|
229
253
|
}
|
|
230
254
|
apiRef.current.setCellFocus(params.id, params.field);
|
|
@@ -56,7 +56,7 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
56
56
|
}
|
|
57
57
|
logger.debug(`Scrolling to cell at row ${params.rowIndex}, col: ${params.colIndex} `);
|
|
58
58
|
let scrollCoordinates = {};
|
|
59
|
-
if (params.colIndex !== undefined) {
|
|
59
|
+
if (params.colIndex !== undefined && visibleColumns[params.colIndex]) {
|
|
60
60
|
const columnPositions = gridColumnPositionsSelector(apiRef);
|
|
61
61
|
let cellWidth;
|
|
62
62
|
if (typeof params.rowIndex !== 'undefined') {
|
|
@@ -73,7 +73,7 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
73
73
|
// When using RTL, `scrollLeft` becomes negative, so we must ensure that we only compare values.
|
|
74
74
|
scrollCoordinates.left = scrollIntoView({
|
|
75
75
|
containerSize: dimensions.viewportOuterSize.width,
|
|
76
|
-
scrollPosition: Math.abs(virtualScrollerRef.current
|
|
76
|
+
scrollPosition: Math.abs(virtualScrollerRef.current?.scrollLeft ?? 0),
|
|
77
77
|
elementSize: cellWidth,
|
|
78
78
|
elementOffset: columnPositions[params.colIndex]
|
|
79
79
|
});
|
|
@@ -86,7 +86,7 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
86
86
|
const targetOffsetHeight = rowsMeta.positions[elementIndex + 1] ? rowsMeta.positions[elementIndex + 1] - rowsMeta.positions[elementIndex] : rowsMeta.currentPageTotalHeight - rowsMeta.positions[elementIndex];
|
|
87
87
|
scrollCoordinates.top = scrollIntoView({
|
|
88
88
|
containerSize: dimensions.viewportInnerSize.height,
|
|
89
|
-
scrollPosition: virtualScrollerRef.current
|
|
89
|
+
scrollPosition: virtualScrollerRef.current?.scrollTop ?? 0,
|
|
90
90
|
elementSize: targetOffsetHeight,
|
|
91
91
|
elementOffset: rowsMeta.positions[elementIndex]
|
|
92
92
|
});
|
package/esm/index.js
CHANGED