@mui/x-data-grid 8.22.1 → 8.23.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 (54) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/colDef/gridBooleanColDef.js +0 -1
  3. package/colDef/gridDateOperators.js +6 -6
  4. package/components/cell/GridBooleanCell.js +9 -1
  5. package/components/cell/GridFooterCell.d.ts +9 -0
  6. package/components/cell/GridFooterCell.js +54 -0
  7. package/components/containers/GridRootStyles.js +4 -0
  8. package/esm/colDef/gridBooleanColDef.js +0 -1
  9. package/esm/colDef/gridDateOperators.js +6 -6
  10. package/esm/components/cell/GridBooleanCell.js +9 -1
  11. package/esm/components/cell/GridFooterCell.d.ts +9 -0
  12. package/esm/components/cell/GridFooterCell.js +48 -0
  13. package/esm/components/containers/GridRootStyles.js +4 -0
  14. package/esm/hooks/features/columnResize/gridColumnResizeApi.d.ts +7 -0
  15. package/esm/hooks/features/columnResize/gridColumnResizeApi.js +1 -0
  16. package/esm/hooks/features/columnResize/useGridColumnResize.js +13 -1
  17. package/esm/hooks/features/columns/gridColumnsUtils.js +1 -4
  18. package/esm/hooks/features/dataSource/useGridDataSourceBase.d.ts +3 -3
  19. package/esm/hooks/features/editing/useGridCellEditing.js +1 -0
  20. package/esm/hooks/features/pagination/gridPaginationSelector.js +3 -0
  21. package/esm/hooks/features/rowSelection/useGridRowSelection.js +17 -15
  22. package/esm/hooks/features/rowSelection/utils.js +2 -2
  23. package/esm/index.js +1 -1
  24. package/esm/internals/index.d.ts +2 -0
  25. package/esm/internals/index.js +1 -0
  26. package/esm/locales/ptPT.d.ts +2 -1
  27. package/esm/locales/ptPT.js +114 -125
  28. package/esm/models/gridAggregation.d.ts +18 -0
  29. package/esm/models/gridAggregation.js +1 -0
  30. package/esm/utils/domUtils.d.ts +1 -0
  31. package/esm/utils/domUtils.js +4 -0
  32. package/esm/utils/utils.d.ts +1 -1
  33. package/esm/utils/utils.js +2 -2
  34. package/hooks/features/columnResize/gridColumnResizeApi.d.ts +7 -0
  35. package/hooks/features/columnResize/gridColumnResizeApi.js +1 -0
  36. package/hooks/features/columnResize/useGridColumnResize.js +12 -0
  37. package/hooks/features/columns/gridColumnsUtils.js +1 -4
  38. package/hooks/features/dataSource/useGridDataSourceBase.d.ts +3 -3
  39. package/hooks/features/editing/useGridCellEditing.js +1 -0
  40. package/hooks/features/pagination/gridPaginationSelector.js +3 -0
  41. package/hooks/features/rowSelection/useGridRowSelection.js +17 -15
  42. package/hooks/features/rowSelection/utils.js +2 -2
  43. package/index.js +1 -1
  44. package/internals/index.d.ts +2 -0
  45. package/internals/index.js +8 -0
  46. package/locales/ptPT.d.ts +2 -1
  47. package/locales/ptPT.js +114 -125
  48. package/models/gridAggregation.d.ts +18 -0
  49. package/models/gridAggregation.js +5 -0
  50. package/package.json +3 -3
  51. package/utils/domUtils.d.ts +1 -0
  52. package/utils/domUtils.js +5 -0
  53. package/utils/utils.d.ts +1 -1
  54. package/utils/utils.js +2 -2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,107 @@
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.23.0
9
+
10
+ _Dec 23, 2025_
11
+
12
+ We'd like to extend a big thank you to the 12 contributors who made this release possible. Here are some highlights ✨:
13
+
14
+ - 🧮 Support Data Grid `size`, `size(true)`, and `size(false)` [aggregations for `'boolean'` column type](https://mui.com/x/react-data-grid/aggregation/#usage-with-row-grouping)
15
+ - 🔎 Allow zooming a heatmap
16
+
17
+ Special thanks go out to these community members for their valuable contributions:
18
+ @henkerik, @sai6855
19
+
20
+ The following team members contributed to this release:
21
+ @alelthomas, @alexfauquette, @arminmeh, @bernardobelchior, @brijeshb42, @flaviendelangle, @JCQuintas, @mapache-salvaje, @MBilalShafi, @siriwatknp
22
+
23
+ ### Data Grid
24
+
25
+ #### `@mui/x-data-grid@8.23.0`
26
+
27
+ - [DataGrid] Fix columns state and columns prop sync issue (#20703) @arminmeh
28
+ - [DataGrid] Fix filter datetime with seconds (#20557) @siriwatknp
29
+ - [DataGrid] Add new `includeHeaderFilters` flag to include header filters when autosizing columns (#20510) @siriwatknp
30
+ - [DataGrid] Prevent default on `Enter` key down when starting editing (#20751) @siriwatknp
31
+ - [l10n] Improve Portuguese from Portugal (pt-PT) locale (#20722) @Copilot
32
+
33
+ #### `@mui/x-data-grid-pro@8.23.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
34
+
35
+ Same changes as in `@mui/x-data-grid@8.23.0`, plus:
36
+
37
+ - [DataGridPro] Fix crash on rows change in tree data with pagination (#20215) @Copilot
38
+
39
+ #### `@mui/x-data-grid-premium@8.23.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
40
+
41
+ Same changes as in `@mui/x-data-grid-pro@8.23.0`, plus:
42
+
43
+ - [DataGridPremium] Add aggregation for `'boolean'` column type (#20683) @arminmeh
44
+ - [DataGridPremium] Fix strategy value computation with row grouping (#20725) @MBilalShafi
45
+ - [DataGridPremium] Handle `isRowSelectable()` checks for the rows missing due to `keepNonExistentRowsSelected` (#20668) @arminmeh
46
+
47
+ ### Date and Time Pickers
48
+
49
+ #### `@mui/x-date-pickers@8.23.0`
50
+
51
+ Internal changes.
52
+
53
+ #### `@mui/x-date-pickers-pro@8.23.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
54
+
55
+ Same changes as in `@mui/x-date-pickers@8.23.0`.
56
+
57
+ ### Charts
58
+
59
+ #### `@mui/x-charts@8.23.0`
60
+
61
+ - [charts] Custom stack functions implementation (#20679) @JCQuintas
62
+ - [charts] Extract keyboard focus navigation to the series config (#20693) @alexfauquette
63
+ - [charts] Fix demo not wrapping in mobile (#20713) @JCQuintas
64
+ - [charts] Fix missing dependencies in `x-charts-vendor` (#20685) @henkerik
65
+ - [charts] Remove webkit test differences (#20707) @JCQuintas
66
+
67
+ #### `@mui/x-charts-pro@8.23.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
68
+
69
+ Same changes as in `@mui/x-charts@8.23.0`, plus:
70
+
71
+ - [charts-pro] Allow registering preview plots from higher tier packages (#20716) @bernardobelchior
72
+ - [charts-pro] Fix erroneous behavior when adding/removing pointers from zoom&pan gestures (#20698) @JCQuintas
73
+ - [charts-pro] Move heatmap highlight handling to plot component (#20701) @bernardobelchior
74
+ - [charts-pro] Add zoom to heatmap (#20708) @bernardobelchior
75
+
76
+ #### `@mui/x-charts-premium@8.23.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
77
+
78
+ Same changes as in `@mui/x-charts-pro@8.23.0`.
79
+
80
+ ### Tree View
81
+
82
+ #### `@mui/x-tree-view@8.23.0`
83
+
84
+ - [tree view] Add new APIs to disable selection feature for tree view item (#20666) @siriwatknp
85
+
86
+ #### `@mui/x-tree-view-pro@8.23.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
87
+
88
+ Same changes as in `@mui/x-tree-view@8.23.0`.
89
+
90
+ ### Codemod
91
+
92
+ #### `@mui/x-codemod@8.23.0`
93
+
94
+ Internal changes.
95
+
96
+ ### Docs
97
+
98
+ - [docs] Clarify feature availability and relationship between Community and Pro/Premium docs (#20714) @mapache-salvaje
99
+ - [docs] Copyedit Tree View docs and apply new component style rules (DX-19) (#20652) @mapache-salvaje
100
+ - [docs] Fix `ColumnPinningDynamicRowHeight` demo (#20750) @sai6855
101
+ - [docs] Clean up Charts docs sidebar (DX-97) (#20700) @alelthomas
102
+ - [docs] Fix tick labels not being shown on a demo (#20718) @sai6855
103
+
104
+ ### Core
105
+
106
+ - [code-infra] Bump prettier to 3.7.4 (#20709) @JCQuintas
107
+ - [code-infra] Fix contributor generation logic in changelog script (#20705) @brijeshb42
108
+
8
109
  ## 8.22.1
9
110
 
10
111
  _Dec 17, 2025_
@@ -42,7 +42,6 @@ const GRID_BOOLEAN_COL_DEF = exports.GRID_BOOLEAN_COL_DEF = (0, _extends2.defaul
42
42
  filterOperators: (0, _gridBooleanOperators.getGridBooleanOperators)(),
43
43
  getApplyQuickFilterFn: () => null,
44
44
  // @ts-ignore
45
- aggregable: false,
46
45
  chartable: false,
47
46
  // @ts-ignore
48
47
  pastedValueParser: value => stringToBoolean(value)
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getGridDateOperators = void 0;
7
7
  var _GridFilterInputDate = require("../components/panel/filterPanel/GridFilterInputDate");
8
- function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
8
+ function buildApplyFilterFn(filterItem, compareFn, showTime, keepRawComparison) {
9
9
  if (!filterItem.value) {
10
10
  return null;
11
11
  }
@@ -27,7 +27,7 @@ function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
27
27
  if (!value) {
28
28
  return false;
29
29
  }
30
- if (keepHours) {
30
+ if (keepRawComparison) {
31
31
  return compareFn(value.getTime(), time);
32
32
  }
33
33
 
@@ -62,7 +62,7 @@ const getGridDateOperators = showTime => [{
62
62
  }, {
63
63
  value: 'after',
64
64
  getApplyFilterFn: filterItem => {
65
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 > value2, showTime);
65
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 > value2, showTime, showTime);
66
66
  },
67
67
  InputComponent: _GridFilterInputDate.GridFilterInputDate,
68
68
  InputComponentProps: {
@@ -71,7 +71,7 @@ const getGridDateOperators = showTime => [{
71
71
  }, {
72
72
  value: 'onOrAfter',
73
73
  getApplyFilterFn: filterItem => {
74
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 >= value2, showTime);
74
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 >= value2, showTime, showTime);
75
75
  },
76
76
  InputComponent: _GridFilterInputDate.GridFilterInputDate,
77
77
  InputComponentProps: {
@@ -80,7 +80,7 @@ const getGridDateOperators = showTime => [{
80
80
  }, {
81
81
  value: 'before',
82
82
  getApplyFilterFn: filterItem => {
83
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 < value2, showTime, !showTime);
83
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 < value2, showTime, true);
84
84
  },
85
85
  InputComponent: _GridFilterInputDate.GridFilterInputDate,
86
86
  InputComponentProps: {
@@ -89,7 +89,7 @@ const getGridDateOperators = showTime => [{
89
89
  }, {
90
90
  value: 'onOrBefore',
91
91
  getApplyFilterFn: filterItem => {
92
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 <= value2, showTime);
92
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 <= value2, showTime, showTime);
93
93
  },
94
94
  InputComponent: _GridFilterInputDate.GridFilterInputDate,
95
95
  InputComponentProps: {
@@ -18,6 +18,7 @@ var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
18
18
  var _useGridApiContext = require("../../hooks/utils/useGridApiContext");
19
19
  var _gridRowsUtils = require("../../hooks/features/rows/gridRowsUtils");
20
20
  var _constants = require("../../internals/constants");
21
+ var _GridFooterCell = require("./GridFooterCell");
21
22
  var _jsxRuntime = require("react/jsx-runtime");
22
23
  const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "hasFocus", "tabIndex", "hideDescendantCount"];
23
24
  const useUtilityClasses = ownerState => {
@@ -116,7 +117,14 @@ const GridBooleanCell = exports.GridBooleanCell = /*#__PURE__*/React.memo(GridBo
116
117
  if (process.env.NODE_ENV !== "production") GridBooleanCell.displayName = "GridBooleanCell";
117
118
  const renderBooleanCell = params => {
118
119
  if (params.field !== _constants.GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD && (0, _gridRowsUtils.isAutogeneratedRowNode)(params.rowNode)) {
119
- return '';
120
+ const aggregationMetaData = params.aggregation;
121
+ if (!aggregationMetaData) {
122
+ return '';
123
+ }
124
+ if (aggregationMetaData.position === 'footer') {
125
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridFooterCell.GridFooterCell, (0, _extends2.default)({}, params));
126
+ }
127
+ return params.formattedValue;
120
128
  }
121
129
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridBooleanCell, (0, _extends2.default)({}, params));
122
130
  };
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import { SxProps, Theme } from '@mui/material/styles';
3
+ import type { GridRenderCellParams } from "../../models/params/gridCellParams.js";
4
+ interface GridFooterCellProps extends GridRenderCellParams {
5
+ sx?: SxProps<Theme>;
6
+ }
7
+ declare function GridFooterCellRaw(props: GridFooterCellProps): import("react/jsx-runtime").JSX.Element;
8
+ declare const GridFooterCell: React.MemoExoticComponent<typeof GridFooterCellRaw>;
9
+ export { GridFooterCell };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.GridFooterCell = void 0;
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
+ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
12
+ var React = _interopRequireWildcard(require("react"));
13
+ var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
14
+ var _styles = require("@mui/material/styles");
15
+ var _cssVariables = require("../../constants/cssVariables");
16
+ var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
17
+ var _gridClasses = require("../../constants/gridClasses");
18
+ var _jsxRuntime = require("react/jsx-runtime");
19
+ const _excluded = ["formattedValue", "colDef", "cellMode", "row", "api", "id", "value", "rowNode", "field", "hasFocus", "tabIndex", "isEditable"];
20
+ const GridFooterCellRoot = (0, _styles.styled)('div', {
21
+ name: 'MuiDataGrid',
22
+ slot: 'FooterCell'
23
+ })({
24
+ fontWeight: _cssVariables.vars.typography.fontWeight.medium,
25
+ color: _cssVariables.vars.colors.foreground.accent
26
+ });
27
+ const useUtilityClasses = ownerState => {
28
+ const {
29
+ classes
30
+ } = ownerState;
31
+ const slots = {
32
+ root: ['footerCell']
33
+ };
34
+ return (0, _composeClasses.default)(slots, _gridClasses.getDataGridUtilityClass, classes);
35
+ };
36
+ function GridFooterCellRaw(props) {
37
+ const {
38
+ formattedValue
39
+ } = props,
40
+ other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
41
+ const rootProps = (0, _useGridRootProps.useGridRootProps)();
42
+ const ownerState = {
43
+ classes: rootProps.classes
44
+ };
45
+ const classes = useUtilityClasses(ownerState);
46
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridFooterCellRoot, (0, _extends2.default)({
47
+ ownerState: ownerState,
48
+ className: classes.root
49
+ }, other, {
50
+ children: formattedValue
51
+ }));
52
+ }
53
+ const GridFooterCell = exports.GridFooterCell = /*#__PURE__*/React.memo(GridFooterCellRaw);
54
+ if (process.env.NODE_ENV !== "production") GridFooterCell.displayName = "GridFooterCell";
@@ -357,6 +357,10 @@ const GridRootStyles = exports.GridRootStyles = (0, _styles.styled)('div', {
357
357
  },
358
358
  [`& .${_gridClasses.gridClasses.treeDataGroupingCell}`]: {
359
359
  width: 'unset'
360
+ },
361
+ [`& .${_gridClasses.gridClasses['columnHeader--filter']}`]: {
362
+ flex: 'none !important',
363
+ width: 'unset !important'
360
364
  }
361
365
  },
362
366
  [`&.${_gridClasses.gridClasses.withSidePanel}`]: {
@@ -35,7 +35,6 @@ export const GRID_BOOLEAN_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
35
35
  filterOperators: getGridBooleanOperators(),
36
36
  getApplyQuickFilterFn: () => null,
37
37
  // @ts-ignore
38
- aggregable: false,
39
38
  chartable: false,
40
39
  // @ts-ignore
41
40
  pastedValueParser: value => stringToBoolean(value)
@@ -1,5 +1,5 @@
1
1
  import { GridFilterInputDate } from "../components/panel/filterPanel/GridFilterInputDate.js";
2
- function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
2
+ function buildApplyFilterFn(filterItem, compareFn, showTime, keepRawComparison) {
3
3
  if (!filterItem.value) {
4
4
  return null;
5
5
  }
@@ -21,7 +21,7 @@ function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
21
21
  if (!value) {
22
22
  return false;
23
23
  }
24
- if (keepHours) {
24
+ if (keepRawComparison) {
25
25
  return compareFn(value.getTime(), time);
26
26
  }
27
27
 
@@ -56,7 +56,7 @@ export const getGridDateOperators = showTime => [{
56
56
  }, {
57
57
  value: 'after',
58
58
  getApplyFilterFn: filterItem => {
59
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 > value2, showTime);
59
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 > value2, showTime, showTime);
60
60
  },
61
61
  InputComponent: GridFilterInputDate,
62
62
  InputComponentProps: {
@@ -65,7 +65,7 @@ export const getGridDateOperators = showTime => [{
65
65
  }, {
66
66
  value: 'onOrAfter',
67
67
  getApplyFilterFn: filterItem => {
68
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 >= value2, showTime);
68
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 >= value2, showTime, showTime);
69
69
  },
70
70
  InputComponent: GridFilterInputDate,
71
71
  InputComponentProps: {
@@ -74,7 +74,7 @@ export const getGridDateOperators = showTime => [{
74
74
  }, {
75
75
  value: 'before',
76
76
  getApplyFilterFn: filterItem => {
77
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 < value2, showTime, !showTime);
77
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 < value2, showTime, true);
78
78
  },
79
79
  InputComponent: GridFilterInputDate,
80
80
  InputComponentProps: {
@@ -83,7 +83,7 @@ export const getGridDateOperators = showTime => [{
83
83
  }, {
84
84
  value: 'onOrBefore',
85
85
  getApplyFilterFn: filterItem => {
86
- return buildApplyFilterFn(filterItem, (value1, value2) => value1 <= value2, showTime);
86
+ return buildApplyFilterFn(filterItem, (value1, value2) => value1 <= value2, showTime, showTime);
87
87
  },
88
88
  InputComponent: GridFilterInputDate,
89
89
  InputComponentProps: {
@@ -11,6 +11,7 @@ import { useGridRootProps } from "../../hooks/utils/useGridRootProps.js";
11
11
  import { useGridApiContext } from "../../hooks/utils/useGridApiContext.js";
12
12
  import { isAutogeneratedRowNode } from "../../hooks/features/rows/gridRowsUtils.js";
13
13
  import { GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD } from "../../internals/constants.js";
14
+ import { GridFooterCell } from "./GridFooterCell.js";
14
15
  import { jsx as _jsx } from "react/jsx-runtime";
15
16
  const useUtilityClasses = ownerState => {
16
17
  const {
@@ -109,7 +110,14 @@ if (process.env.NODE_ENV !== "production") GridBooleanCell.displayName = "GridBo
109
110
  export { GridBooleanCell };
110
111
  export const renderBooleanCell = params => {
111
112
  if (params.field !== GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD && isAutogeneratedRowNode(params.rowNode)) {
112
- return '';
113
+ const aggregationMetaData = params.aggregation;
114
+ if (!aggregationMetaData) {
115
+ return '';
116
+ }
117
+ if (aggregationMetaData.position === 'footer') {
118
+ return /*#__PURE__*/_jsx(GridFooterCell, _extends({}, params));
119
+ }
120
+ return params.formattedValue;
113
121
  }
114
122
  return /*#__PURE__*/_jsx(GridBooleanCell, _extends({}, params));
115
123
  };
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import { SxProps, Theme } from '@mui/material/styles';
3
+ import type { GridRenderCellParams } from "../../models/params/gridCellParams.js";
4
+ interface GridFooterCellProps extends GridRenderCellParams {
5
+ sx?: SxProps<Theme>;
6
+ }
7
+ declare function GridFooterCellRaw(props: GridFooterCellProps): import("react/jsx-runtime").JSX.Element;
8
+ declare const GridFooterCell: React.MemoExoticComponent<typeof GridFooterCellRaw>;
9
+ export { GridFooterCell };
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+
3
+ import _extends from "@babel/runtime/helpers/esm/extends";
4
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
+ const _excluded = ["formattedValue", "colDef", "cellMode", "row", "api", "id", "value", "rowNode", "field", "hasFocus", "tabIndex", "isEditable"];
6
+ import * as React from 'react';
7
+ import composeClasses from '@mui/utils/composeClasses';
8
+ import { styled } from '@mui/material/styles';
9
+ import { vars } from "../../constants/cssVariables.js";
10
+ import { useGridRootProps } from "../../hooks/utils/useGridRootProps.js";
11
+ import { getDataGridUtilityClass } from "../../constants/gridClasses.js";
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ const GridFooterCellRoot = styled('div', {
14
+ name: 'MuiDataGrid',
15
+ slot: 'FooterCell'
16
+ })({
17
+ fontWeight: vars.typography.fontWeight.medium,
18
+ color: vars.colors.foreground.accent
19
+ });
20
+ const useUtilityClasses = ownerState => {
21
+ const {
22
+ classes
23
+ } = ownerState;
24
+ const slots = {
25
+ root: ['footerCell']
26
+ };
27
+ return composeClasses(slots, getDataGridUtilityClass, classes);
28
+ };
29
+ function GridFooterCellRaw(props) {
30
+ const {
31
+ formattedValue
32
+ } = props,
33
+ other = _objectWithoutPropertiesLoose(props, _excluded);
34
+ const rootProps = useGridRootProps();
35
+ const ownerState = {
36
+ classes: rootProps.classes
37
+ };
38
+ const classes = useUtilityClasses(ownerState);
39
+ return /*#__PURE__*/_jsx(GridFooterCellRoot, _extends({
40
+ ownerState: ownerState,
41
+ className: classes.root
42
+ }, other, {
43
+ children: formattedValue
44
+ }));
45
+ }
46
+ const GridFooterCell = /*#__PURE__*/React.memo(GridFooterCellRaw);
47
+ if (process.env.NODE_ENV !== "production") GridFooterCell.displayName = "GridFooterCell";
48
+ export { GridFooterCell };
@@ -351,6 +351,10 @@ export const GridRootStyles = styled('div', {
351
351
  },
352
352
  [`& .${c.treeDataGroupingCell}`]: {
353
353
  width: 'unset'
354
+ },
355
+ [`& .${c['columnHeader--filter']}`]: {
356
+ flex: 'none !important',
357
+ width: 'unset !important'
354
358
  }
355
359
  },
356
360
  [`&.${c.withSidePanel}`]: {
@@ -1,6 +1,7 @@
1
1
  import type { GridColDef } from "../../../models/colDef/gridColDef.js";
2
2
  export declare const DEFAULT_GRID_AUTOSIZE_OPTIONS: {
3
3
  includeHeaders: boolean;
4
+ includeHeaderFilters: boolean;
4
5
  includeOutliers: boolean;
5
6
  outliersFactor: number;
6
7
  expand: boolean;
@@ -16,6 +17,12 @@ export type GridAutosizeOptions = {
16
17
  * @default false
17
18
  */
18
19
  includeHeaders?: boolean;
20
+ /**
21
+ * If true, include header filter widths in the calculation.
22
+ * Only applies when header filters are enabled.
23
+ * @default false
24
+ */
25
+ includeHeaderFilters?: boolean;
19
26
  /**
20
27
  * If true, width outliers will be ignored.
21
28
  * @default false
@@ -1,5 +1,6 @@
1
1
  export const DEFAULT_GRID_AUTOSIZE_OPTIONS = {
2
2
  includeHeaders: true,
3
+ includeHeaderFilters: false,
3
4
  includeOutliers: false,
4
5
  outliersFactor: 1.5,
5
6
  expand: false,
@@ -6,7 +6,7 @@ import useEventCallback from '@mui/utils/useEventCallback';
6
6
  import ownerDocument from '@mui/utils/ownerDocument';
7
7
  import useLazyRef from '@mui/utils/useLazyRef';
8
8
  import { useRtl } from '@mui/system/RtlProvider';
9
- import { findGridCellElementsFromCol, findGridElement, findLeftPinnedCellsAfterCol, findRightPinnedCellsBeforeCol, getFieldFromHeaderElem, findHeaderElementFromField, getFieldsFromGroupHeaderElem, findGroupHeaderElementsFromField, findGridHeader, findGridCells, findParentElementFromClassName, findLeftPinnedHeadersAfterCol, findRightPinnedHeadersBeforeCol, escapeOperandAttributeSelector } from "../../../utils/domUtils.js";
9
+ import { findGridCellElementsFromCol, findGridElement, findLeftPinnedCellsAfterCol, findRightPinnedCellsBeforeCol, getFieldFromHeaderElem, findHeaderElementFromField, getFieldsFromGroupHeaderElem, findGroupHeaderElementsFromField, findGridHeader, findGridHeaderFilter, findGridCells, findParentElementFromClassName, findLeftPinnedHeadersAfterCol, findRightPinnedHeadersBeforeCol, escapeOperandAttributeSelector } from "../../../utils/domUtils.js";
10
10
  import { DEFAULT_GRID_AUTOSIZE_OPTIONS } from "./gridColumnResizeApi.js";
11
11
  import { gridClasses } from "../../../constants/gridClasses.js";
12
12
  import { useGridEvent, useGridApiMethod, useGridEventPriority, useGridLogger, useGridNativeEventListener, useGridSelector, useOnMount } from "../../utils/index.js";
@@ -17,6 +17,7 @@ import { useTimeout } from "../../utils/useTimeout.js";
17
17
  import { GridPinnedColumnPosition } from "../columns/gridColumnsInterfaces.js";
18
18
  import { gridColumnsStateSelector } from "../columns/index.js";
19
19
  import { gridDimensionsSelector } from "../dimensions/index.js";
20
+ import { gridHeaderFilteringEnabledSelector } from "../headerFiltering/index.js";
20
21
  import { gridResizingColumnFieldSelector } from "./columnResizeSelector.js";
21
22
  function trackFinger(event, currentTouchId) {
22
23
  if (currentTouchId !== undefined && event.changedTouches) {
@@ -134,6 +135,7 @@ function extractColumnWidths(apiRef, options, columns) {
134
135
  const widthByField = {};
135
136
  const root = apiRef.current.rootElementRef.current;
136
137
  root.classList.add(gridClasses.autosizing);
138
+ const includeHeaderFilters = options.includeHeaderFilters && gridHeaderFilteringEnabledSelector(apiRef);
137
139
  columns.forEach(column => {
138
140
  const cells = findGridCells(apiRef.current, column.field);
139
141
  const widths = cells.map(cell => {
@@ -164,6 +166,16 @@ function extractColumnWidths(apiRef, options, columns) {
164
166
  filteredWidths.push(width);
165
167
  }
166
168
  }
169
+ if (includeHeaderFilters) {
170
+ const headerFilter = findGridHeaderFilter(apiRef.current, column.field);
171
+ if (headerFilter) {
172
+ const style = window.getComputedStyle(headerFilter, null);
173
+ const paddingWidth = parseInt(style.paddingLeft, 10) + parseInt(style.paddingRight, 10);
174
+ const contentWidth = headerFilter.scrollWidth;
175
+ const width = contentWidth + paddingWidth;
176
+ filteredWidths.push(width);
177
+ }
178
+ }
167
179
  const hasColumnMin = column.minWidth !== -Infinity && column.minWidth !== undefined;
168
180
  const hasColumnMax = column.maxWidth !== Infinity && column.maxWidth !== undefined;
169
181
  const min = hasColumnMin ? column.minWidth : 0;
@@ -236,8 +236,7 @@ export const createColumnsState = ({
236
236
  const currentState = gridColumnsStateSelector(apiRef);
237
237
  columnsState = {
238
238
  orderedFields: keepOnlyColumnsToUpsert ? [] : [...currentState.orderedFields],
239
- lookup: _extends({}, currentState.lookup),
240
- // Will be cleaned later if keepOnlyColumnsToUpsert=true
239
+ lookup: keepOnlyColumnsToUpsert ? {} : _extends({}, currentState.lookup),
241
240
  columnVisibilityModel,
242
241
  initialColumnVisibilityModel: updateInitialVisibilityModel ? columnVisibilityModel : currentState.initialColumnVisibilityModel
243
242
  };
@@ -250,12 +249,10 @@ export const createColumnsState = ({
250
249
  }
251
250
  }
252
251
  }
253
- const columnsToUpsertLookup = {};
254
252
  columnsToUpsert.forEach(newColumn => {
255
253
  const {
256
254
  field
257
255
  } = newColumn;
258
- columnsToUpsertLookup[field] = true;
259
256
  columnsToKeep[field] = true;
260
257
  let existingState = columnsState.lookup[field];
261
258
  if (existingState == null) {
@@ -21,8 +21,8 @@ export declare const useGridDataSourceBase: <Api extends GridPrivateApiCommunity
21
21
  cache: GridDataSourceCache;
22
22
  events: {
23
23
  strategyAvailabilityChange: GridEventListener<"strategyAvailabilityChange">;
24
- sortModelChange: (params: unknown) => void;
25
- filterModelChange: (params: unknown) => void;
26
- paginationModelChange: (params: unknown) => void;
24
+ sortModelChange: (...params: unknown[]) => void;
25
+ filterModelChange: (...params: unknown[]) => void;
26
+ paginationModelChange: (...params: unknown[]) => void;
27
27
  };
28
28
  };
@@ -107,6 +107,7 @@ export const useGridCellEditing = (apiRef, props) => {
107
107
  reason = GridCellEditStartReasons.pasteKeyDown;
108
108
  } else if (event.key === 'Enter') {
109
109
  reason = GridCellEditStartReasons.enterKeyDown;
110
+ event.preventDefault();
110
111
  } else if (event.key === 'Backspace' || event.key === 'Delete') {
111
112
  reason = GridCellEditStartReasons.deleteKeyDown;
112
113
  }
@@ -60,6 +60,9 @@ export const gridPaginationRowRangeSelector = createSelectorMemoized(gridPaginat
60
60
  if (!clientSidePaginationEnabled) {
61
61
  return null;
62
62
  }
63
+ if (!visibleSortedRowEntries || visibleSortedRowEntries.length === 0) {
64
+ return null;
65
+ }
63
66
  const visibleTopLevelRowCount = visibleSortedTopLevelRowEntries.length;
64
67
  const topLevelFirstRowIndex = Math.min(paginationModel.pageSize * paginationModel.page, visibleTopLevelRowCount - 1);
65
68
  const topLevelLastRowIndex = paginationModel.pageSize === ALL_RESULTS_PAGE_VALUE ? visibleTopLevelRowCount - 1 : Math.min(topLevelFirstRowIndex + paginationModel.pageSize - 1, visibleTopLevelRowCount - 1);
@@ -20,6 +20,7 @@ import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from "../../../internals/constants.js"
20
20
  import { gridClasses } from "../../../constants/gridClasses.js";
21
21
  import { isEventTargetInPortal } from "../../../utils/domUtils.js";
22
22
  import { isMultipleRowSelectionEnabled, findRowsToSelect, findRowsToDeselect } from "./utils.js";
23
+ import { runIf } from "../../../utils/utils.js";
23
24
  import { createRowSelectionManager } from "../../../models/gridRowSelectionManager.js";
24
25
  import { gridPaginatedVisibleSortedGridRowIdsSelector } from "../pagination/index.js";
25
26
  const emptyModel = {
@@ -38,11 +39,6 @@ export const rowSelectionStateInitializer = (state, props) => _extends({}, state
38
39
  */
39
40
  export const useGridRowSelection = (apiRef, props) => {
40
41
  const logger = useGridLogger(apiRef, 'useGridSelection');
41
- const runIfRowSelectionIsEnabled = React.useCallback(callback => (...args) => {
42
- if (props.rowSelection) {
43
- callback(...args);
44
- }
45
- }, [props.rowSelection]);
46
42
  const isNestedData = useGridSelector(apiRef, gridRowMaximumTreeDepthSelector) > 1;
47
43
  const applyAutoSelection = props.signature !== GridSignature.DataGrid && (props.rowSelectionPropagation?.parents || props.rowSelectionPropagation?.descendants) && isNestedData;
48
44
  const propRowSelectionModel = React.useMemo(() => {
@@ -121,6 +117,12 @@ export const useGridRowSelection = (apiRef, props) => {
121
117
  if (props.rowSelection === false) {
122
118
  return false;
123
119
  }
120
+
121
+ // If `keepNonExistentRowsSelected` is true, we might run in a case where row selectability is checked for a row that does not exist.
122
+ // Since that row was previously selected (otherwise it would not be checked at this point), we return true.
123
+ if (props.keepNonExistentRowsSelected && !apiRef.current.getRow(id)) {
124
+ return true;
125
+ }
124
126
  if (propIsRowSelectable && !propIsRowSelectable(apiRef.current.getRowParams(id))) {
125
127
  return false;
126
128
  }
@@ -129,7 +131,7 @@ export const useGridRowSelection = (apiRef, props) => {
129
131
  return false;
130
132
  }
131
133
  return true;
132
- }, [apiRef, props.rowSelection, propIsRowSelectable]);
134
+ }, [apiRef, props.rowSelection, props.keepNonExistentRowsSelected, propIsRowSelectable]);
133
135
  const getSelectedRows = React.useCallback(() => gridRowSelectionIdsSelector(apiRef), [apiRef]);
134
136
  const selectRow = React.useCallback((id, isSelected = true, resetSelection = false) => {
135
137
  if (!apiRef.current.isRowSelectable(id)) {
@@ -303,7 +305,7 @@ export const useGridRowSelection = (apiRef, props) => {
303
305
  * EVENTS
304
306
  */
305
307
  const isFirstRender = React.useRef(true);
306
- const removeOutdatedSelection = React.useCallback((sortModelUpdated = false) => {
308
+ const removeOutdatedSelection = React.useCallback(() => {
307
309
  if (isFirstRender.current) {
308
310
  return;
309
311
  }
@@ -357,7 +359,7 @@ export const useGridRowSelection = (apiRef, props) => {
357
359
  const shouldReapplyPropagation = isNestedData && props.rowSelectionPropagation?.parents && (newSelectionModel.ids.size > 0 ||
358
360
  // In case of exclude selection, newSelectionModel.ids.size === 0 means all rows are selected
359
361
  newSelectionModel.type === 'exclude');
360
- if (hasChanged || shouldReapplyPropagation && !sortModelUpdated) {
362
+ if (hasChanged || shouldReapplyPropagation) {
361
363
  if (shouldReapplyPropagation) {
362
364
  if (newSelectionModel.type === 'exclude') {
363
365
  const unfilteredSelectedRowIds = getRowsToBeSelected();
@@ -540,12 +542,12 @@ export const useGridRowSelection = (apiRef, props) => {
540
542
  }
541
543
  apiRef.current.setRowSelectionModel(propRowSelectionModel);
542
544
  });
543
- useGridEvent(apiRef, 'filteredRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection()));
544
- useGridEvent(apiRef, 'rowClick', runIfRowSelectionIsEnabled(handleRowClick));
545
- useGridEvent(apiRef, 'rowSelectionCheckboxChange', runIfRowSelectionIsEnabled(handleRowSelectionCheckboxChange));
545
+ useGridEvent(apiRef, 'filteredRowsSet', runIf(props.rowSelection, removeOutdatedSelection));
546
+ useGridEvent(apiRef, 'rowClick', runIf(props.rowSelection, handleRowClick));
547
+ useGridEvent(apiRef, 'rowSelectionCheckboxChange', runIf(props.rowSelection, handleRowSelectionCheckboxChange));
546
548
  useGridEvent(apiRef, 'headerSelectionCheckboxChange', handleHeaderSelectionCheckboxChange);
547
- useGridEvent(apiRef, 'cellMouseDown', runIfRowSelectionIsEnabled(preventSelectionOnShift));
548
- useGridEvent(apiRef, 'cellKeyDown', runIfRowSelectionIsEnabled(handleCellKeyDown));
549
+ useGridEvent(apiRef, 'cellMouseDown', runIf(props.rowSelection, preventSelectionOnShift));
550
+ useGridEvent(apiRef, 'cellKeyDown', runIf(props.rowSelection, handleCellKeyDown));
549
551
 
550
552
  /*
551
553
  * EFFECTS
@@ -588,8 +590,8 @@ export const useGridRowSelection = (apiRef, props) => {
588
590
  }
589
591
  }, [apiRef, canHaveMultipleSelection, checkboxSelection, isStateControlled, props.rowSelection]);
590
592
  React.useEffect(() => {
591
- runIfRowSelectionIsEnabled(removeOutdatedSelection);
592
- }, [removeOutdatedSelection, runIfRowSelectionIsEnabled]);
593
+ runIf(props.rowSelection, removeOutdatedSelection);
594
+ }, [props.rowSelection, removeOutdatedSelection]);
593
595
  React.useEffect(() => {
594
596
  if (isFirstRender.current) {
595
597
  isFirstRender.current = false;