@mui/x-data-grid-pro 6.3.1 → 6.5.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 (133) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/DataGridPro/DataGridPro.js +25 -1
  3. package/DataGridPro/useDataGridProComponent.js +5 -3
  4. package/DataGridPro/useDataGridProProps.js +7 -13
  5. package/components/GridColumnHeaders.js +15 -1
  6. package/components/GridDetailPanel.js +1 -1
  7. package/components/headerFiltering/GridHeaderFilterAdornment.d.ts +14 -0
  8. package/components/headerFiltering/GridHeaderFilterAdornment.js +99 -0
  9. package/components/headerFiltering/GridHeaderFilterCell.d.ts +20 -0
  10. package/components/headerFiltering/GridHeaderFilterCell.js +224 -0
  11. package/components/headerFiltering/GridHeaderFilterClearButton.d.ts +6 -0
  12. package/components/headerFiltering/GridHeaderFilterClearButton.js +25 -0
  13. package/components/headerFiltering/GridHeaderFilterMenu.d.ts +14 -0
  14. package/components/headerFiltering/GridHeaderFilterMenu.js +69 -0
  15. package/components/headerFiltering/constants.d.ts +3 -0
  16. package/components/headerFiltering/constants.js +30 -0
  17. package/components/headerFiltering/index.d.ts +2 -0
  18. package/components/headerFiltering/index.js +2 -0
  19. package/components/index.d.ts +1 -0
  20. package/components/index.js +2 -1
  21. package/constants/dataGridProDefaultSlotsComponents.js +5 -1
  22. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +21 -0
  23. package/hooks/features/columnHeaders/useGridColumnHeaders.js +111 -0
  24. package/hooks/features/columnResize/useGridColumnResize.js +12 -1
  25. package/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +1 -0
  26. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -0
  27. package/index.js +1 -1
  28. package/internals/index.d.ts +1 -0
  29. package/internals/index.js +4 -0
  30. package/legacy/DataGridPro/DataGridPro.js +25 -1
  31. package/legacy/DataGridPro/useDataGridProComponent.js +5 -3
  32. package/legacy/DataGridPro/useDataGridProProps.js +10 -9
  33. package/legacy/components/GridColumnHeaders.js +15 -1
  34. package/legacy/components/GridDetailPanel.js +1 -1
  35. package/legacy/components/headerFiltering/GridHeaderFilterAdornment.js +97 -0
  36. package/legacy/components/headerFiltering/GridHeaderFilterCell.js +230 -0
  37. package/legacy/components/headerFiltering/GridHeaderFilterClearButton.js +24 -0
  38. package/legacy/components/headerFiltering/GridHeaderFilterMenu.js +68 -0
  39. package/legacy/components/headerFiltering/constants.js +30 -0
  40. package/legacy/components/headerFiltering/index.js +2 -0
  41. package/legacy/components/index.js +2 -1
  42. package/legacy/constants/dataGridProDefaultSlotsComponents.js +5 -1
  43. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +120 -0
  44. package/legacy/hooks/features/columnResize/useGridColumnResize.js +12 -1
  45. package/legacy/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +1 -0
  46. package/legacy/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -0
  47. package/legacy/index.js +1 -1
  48. package/legacy/internals/index.js +4 -0
  49. package/legacy/material/icons.js +4 -1
  50. package/legacy/material/index.js +3 -2
  51. package/legacy/models/gridProSlotProps.js +1 -0
  52. package/legacy/utils/releaseInfo.js +1 -1
  53. package/legacy/utils/tree/createRowTree.js +1 -0
  54. package/legacy/utils/tree/insertDataRowInTree.js +4 -0
  55. package/legacy/utils/tree/removeDataRowFromTree.js +1 -0
  56. package/legacy/utils/tree/updateRowTree.js +2 -0
  57. package/legacy/utils/tree/utils.js +20 -12
  58. package/material/icons.d.ts +3 -0
  59. package/material/icons.js +4 -1
  60. package/material/index.d.ts +1 -0
  61. package/material/index.js +3 -2
  62. package/models/dataGridProProps.d.ts +16 -1
  63. package/models/gridProIconSlotsComponent.d.ts +5 -0
  64. package/models/gridProSlotProps.d.ts +9 -0
  65. package/models/gridProSlotProps.js +1 -0
  66. package/models/gridProSlotsComponent.d.ts +13 -2
  67. package/modern/DataGridPro/DataGridPro.js +25 -1
  68. package/modern/DataGridPro/useDataGridProComponent.js +5 -3
  69. package/modern/DataGridPro/useDataGridProProps.js +7 -13
  70. package/modern/components/GridColumnHeaders.js +15 -1
  71. package/modern/components/GridDetailPanel.js +1 -1
  72. package/modern/components/headerFiltering/GridHeaderFilterAdornment.js +98 -0
  73. package/modern/components/headerFiltering/GridHeaderFilterCell.js +222 -0
  74. package/modern/components/headerFiltering/GridHeaderFilterClearButton.js +24 -0
  75. package/modern/components/headerFiltering/GridHeaderFilterMenu.js +68 -0
  76. package/modern/components/headerFiltering/constants.js +30 -0
  77. package/modern/components/headerFiltering/index.js +2 -0
  78. package/modern/components/index.js +2 -1
  79. package/modern/constants/dataGridProDefaultSlotsComponents.js +5 -1
  80. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +110 -0
  81. package/modern/hooks/features/columnResize/useGridColumnResize.js +11 -0
  82. package/modern/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +1 -0
  83. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -0
  84. package/modern/index.js +1 -1
  85. package/modern/internals/index.js +4 -0
  86. package/modern/material/icons.js +4 -1
  87. package/modern/material/index.js +3 -2
  88. package/modern/models/gridProSlotProps.js +1 -0
  89. package/modern/utils/releaseInfo.js +1 -1
  90. package/modern/utils/tree/createRowTree.js +1 -0
  91. package/modern/utils/tree/insertDataRowInTree.js +4 -0
  92. package/modern/utils/tree/removeDataRowFromTree.js +1 -0
  93. package/modern/utils/tree/updateRowTree.js +2 -0
  94. package/modern/utils/tree/utils.js +19 -13
  95. package/node/DataGridPro/DataGridPro.js +25 -1
  96. package/node/DataGridPro/useDataGridProComponent.js +4 -2
  97. package/node/DataGridPro/useDataGridProProps.js +6 -12
  98. package/node/components/GridColumnHeaders.js +15 -1
  99. package/node/components/GridDetailPanel.js +2 -2
  100. package/node/components/headerFiltering/GridHeaderFilterAdornment.js +105 -0
  101. package/node/components/headerFiltering/GridHeaderFilterCell.js +230 -0
  102. package/node/components/headerFiltering/GridHeaderFilterClearButton.js +32 -0
  103. package/node/components/headerFiltering/GridHeaderFilterMenu.js +75 -0
  104. package/node/components/headerFiltering/constants.js +37 -0
  105. package/node/components/headerFiltering/index.js +27 -0
  106. package/node/components/index.js +11 -0
  107. package/node/constants/dataGridProDefaultSlotsComponents.js +5 -1
  108. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +120 -0
  109. package/node/hooks/features/columnResize/useGridColumnResize.js +11 -0
  110. package/node/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +1 -0
  111. package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -0
  112. package/node/index.js +1 -1
  113. package/node/internals/index.js +8 -0
  114. package/node/material/icons.js +6 -2
  115. package/node/material/index.js +2 -1
  116. package/node/models/gridProSlotProps.js +5 -0
  117. package/node/utils/releaseInfo.js +1 -1
  118. package/node/utils/tree/createRowTree.js +1 -0
  119. package/node/utils/tree/insertDataRowInTree.js +4 -0
  120. package/node/utils/tree/removeDataRowFromTree.js +1 -0
  121. package/node/utils/tree/updateRowTree.js +2 -0
  122. package/node/utils/tree/utils.js +19 -13
  123. package/package.json +2 -2
  124. package/typeOverloads/modules.d.ts +13 -1
  125. package/utils/releaseInfo.js +1 -1
  126. package/utils/tree/createRowTree.d.ts +2 -0
  127. package/utils/tree/createRowTree.js +1 -0
  128. package/utils/tree/insertDataRowInTree.d.ts +5 -1
  129. package/utils/tree/insertDataRowInTree.js +4 -0
  130. package/utils/tree/removeDataRowFromTree.js +1 -0
  131. package/utils/tree/updateRowTree.js +2 -0
  132. package/utils/tree/utils.d.ts +4 -2
  133. package/utils/tree/utils.js +19 -13
@@ -0,0 +1,222 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["colIndex", "height", "hasFocus", "headerFilterComponent", "filterOperators", "width", "headerClassName", "colDef", "item", "headerFilterMenuRef", "InputComponentProps", "showClearIcon"];
4
+ import * as React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import clsx from 'clsx';
7
+ import { unstable_useForkRef as useForkRef, unstable_composeClasses as composeClasses, unstable_capitalize as capitalize } from '@mui/utils';
8
+ import { gridVisibleColumnFieldsSelector, getDataGridUtilityClass } from '@mui/x-data-grid';
9
+ import { useGridPrivateApiContext, unstable_gridHeaderFilteringEditFieldSelector, unstable_gridHeaderFilteringMenuSelector, isNavigationKey } from '@mui/x-data-grid/internals';
10
+ import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
11
+ import { GridHeaderFilterAdornment } from './GridHeaderFilterAdornment';
12
+ import { GridHeaderFilterClearButton } from './GridHeaderFilterClearButton';
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ import { jsxs as _jsxs } from "react/jsx-runtime";
15
+ const useUtilityClasses = ownerState => {
16
+ const {
17
+ colDef,
18
+ classes,
19
+ showColumnVerticalBorder
20
+ } = ownerState;
21
+ const slots = {
22
+ root: ['columnHeader', colDef.headerAlign === 'left' && 'columnHeader--alignLeft', colDef.headerAlign === 'center' && 'columnHeader--alignCenter', colDef.headerAlign === 'right' && 'columnHeader--alignRight', 'withBorderColor', showColumnVerticalBorder && 'columnHeader--withRightBorder']
23
+ };
24
+ return composeClasses(slots, getDataGridUtilityClass, classes);
25
+ };
26
+ const GridHeaderFilterCell = /*#__PURE__*/React.forwardRef((props, ref) => {
27
+ const {
28
+ colIndex,
29
+ height,
30
+ hasFocus,
31
+ headerFilterComponent,
32
+ filterOperators,
33
+ width,
34
+ headerClassName,
35
+ colDef,
36
+ item,
37
+ headerFilterMenuRef,
38
+ InputComponentProps,
39
+ showClearIcon = true
40
+ } = props,
41
+ other = _objectWithoutPropertiesLoose(props, _excluded);
42
+ const apiRef = useGridPrivateApiContext();
43
+ const columnFields = gridVisibleColumnFieldsSelector(apiRef);
44
+ const rootProps = useGridRootProps();
45
+ const cellRef = React.useRef(null);
46
+ const handleRef = useForkRef(ref, cellRef);
47
+ const inputRef = React.useRef(null);
48
+ const buttonRef = React.useRef(null);
49
+ const isEditing = unstable_gridHeaderFilteringEditFieldSelector(apiRef) === colDef.field;
50
+ const isMenuOpen = unstable_gridHeaderFilteringMenuSelector(apiRef) === colDef.field;
51
+ const currentOperator = filterOperators[0];
52
+ const InputComponent = colDef.filterable ? currentOperator.InputComponent : null;
53
+ const applyFilterChanges = React.useCallback(updatedItem => {
54
+ if (item.value && !updatedItem.value) {
55
+ apiRef.current.deleteFilterItem(updatedItem);
56
+ return;
57
+ }
58
+ apiRef.current.upsertFilterItem(updatedItem);
59
+ }, [apiRef, item]);
60
+ const clearFilterItem = React.useCallback(() => {
61
+ apiRef.current.deleteFilterItem(item);
62
+ }, [apiRef, item]);
63
+ React.useLayoutEffect(() => {
64
+ if (hasFocus && !isMenuOpen) {
65
+ let focusableElement = cellRef.current.querySelector('[tabindex="0"]');
66
+ if (isEditing && InputComponent) {
67
+ focusableElement = inputRef.current;
68
+ }
69
+ const elementToFocus = focusableElement || cellRef.current;
70
+ elementToFocus?.focus();
71
+ apiRef.current.columnHeadersContainerElementRef.current.scrollLeft = 0;
72
+ }
73
+ }, [InputComponent, apiRef, hasFocus, isEditing, isMenuOpen]);
74
+ const onKeyDown = React.useCallback(event => {
75
+ if (isMenuOpen || isNavigationKey(event.key)) {
76
+ return;
77
+ }
78
+ switch (event.key) {
79
+ case 'Escape':
80
+ if (isEditing) {
81
+ apiRef.current.stopHeaderFilterEditMode();
82
+ }
83
+ break;
84
+ case 'Enter':
85
+ if (isEditing) {
86
+ apiRef.current.stopHeaderFilterEditMode();
87
+ break;
88
+ }
89
+ if (event.metaKey || event.ctrlKey) {
90
+ headerFilterMenuRef.current = buttonRef.current;
91
+ apiRef.current.showHeaderFilterMenu(colDef.field);
92
+ break;
93
+ }
94
+ apiRef.current.startHeaderFilterEditMode(colDef.field);
95
+ break;
96
+ case 'Tab':
97
+ {
98
+ if (isEditing) {
99
+ const fieldToFocus = columnFields[colIndex + (event.shiftKey ? -1 : 1)] ?? null;
100
+ if (fieldToFocus) {
101
+ apiRef.current.startHeaderFilterEditMode(fieldToFocus);
102
+ apiRef.current.setColumnHeaderFilterFocus(fieldToFocus, event);
103
+ }
104
+ }
105
+ break;
106
+ }
107
+ default:
108
+ if (isEditing || event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {
109
+ break;
110
+ }
111
+ apiRef.current.startHeaderFilterEditMode(colDef.field);
112
+ break;
113
+ }
114
+ }, [apiRef, colDef.field, colIndex, columnFields, headerFilterMenuRef, isEditing, isMenuOpen]);
115
+ const publish = React.useCallback((eventName, propHandler) => event => {
116
+ apiRef.current.publishEvent(eventName, apiRef.current.getColumnHeaderParams(colDef.field), event);
117
+ if (propHandler) {
118
+ propHandler(event);
119
+ }
120
+ }, [apiRef, colDef.field]);
121
+ const onMouseDown = React.useCallback(event => {
122
+ if (!hasFocus) {
123
+ if (inputRef.current) {
124
+ inputRef.current.focus();
125
+ }
126
+ apiRef.current.setColumnHeaderFilterFocus(colDef.field, event);
127
+ }
128
+ }, [apiRef, colDef.field, hasFocus]);
129
+ const mouseEventsHandlers = React.useMemo(() => ({
130
+ onKeyDown: publish('headerFilterKeyDown', onKeyDown),
131
+ onClick: publish('headerFilterClick'),
132
+ onMouseDown: publish('headerFilterMouseDown', onMouseDown)
133
+ }), [onMouseDown, onKeyDown, publish]);
134
+ const ownerState = _extends({}, rootProps, {
135
+ colDef
136
+ });
137
+ const classes = useUtilityClasses(ownerState);
138
+ const isNoInputOperator = filterOperators?.find(({
139
+ value
140
+ }) => item.operator === value)?.requiresFilterValue === false;
141
+ const isApplied = Boolean(item?.value) || isNoInputOperator;
142
+ const label = currentOperator.headerLabel ?? apiRef.current.getLocaleText(`headerFilterOperator${capitalize(item.operator)}`);
143
+ const isFilterActive = isApplied || hasFocus;
144
+ return /*#__PURE__*/_jsxs("div", _extends({
145
+ className: clsx(classes.root, headerClassName),
146
+ ref: handleRef,
147
+ style: {
148
+ height,
149
+ width,
150
+ minWidth: width,
151
+ maxWidth: width
152
+ },
153
+ role: "columnheader",
154
+ "aria-colindex": colIndex + 1,
155
+ "aria-label": headerFilterComponent == null ? colDef.headerName ?? colDef.field : undefined
156
+ }, other, mouseEventsHandlers, {
157
+ children: [headerFilterComponent, InputComponent && headerFilterComponent === undefined ? /*#__PURE__*/_jsx(InputComponent, _extends({
158
+ apiRef: apiRef,
159
+ item: item,
160
+ inputRef: inputRef,
161
+ applyValue: applyFilterChanges,
162
+ onFocus: () => apiRef.current.startHeaderFilterEditMode(colDef.field),
163
+ onBlur: () => apiRef.current.stopHeaderFilterEditMode(),
164
+ placeholder: apiRef.current.getLocaleText('columnMenuFilter'),
165
+ label: isFilterActive ? capitalize(label) : ' ',
166
+ isFilterActive: isFilterActive,
167
+ headerFilterMenu: /*#__PURE__*/_jsx(GridHeaderFilterAdornment, {
168
+ operators: filterOperators,
169
+ item: item,
170
+ field: colDef.field,
171
+ applyFilterChanges: applyFilterChanges,
172
+ headerFilterMenuRef: headerFilterMenuRef,
173
+ buttonRef: buttonRef
174
+ }),
175
+ clearButton: showClearIcon && isApplied ? /*#__PURE__*/_jsx(GridHeaderFilterClearButton, {
176
+ onClick: clearFilterItem
177
+ }) : null,
178
+ disabled: isNoInputOperator,
179
+ tabIndex: -1
180
+ }, currentOperator?.InputComponentProps, InputComponentProps)) : null]
181
+ }));
182
+ });
183
+ process.env.NODE_ENV !== "production" ? GridHeaderFilterCell.propTypes = {
184
+ // ----------------------------- Warning --------------------------------
185
+ // | These PropTypes are generated from the TypeScript type definitions |
186
+ // | To update them edit the TypeScript types and run "yarn proptypes" |
187
+ // ----------------------------------------------------------------------
188
+ colDef: PropTypes.object.isRequired,
189
+ colIndex: PropTypes.number.isRequired,
190
+ filterOperators: PropTypes.arrayOf(PropTypes.shape({
191
+ getApplyFilterFn: PropTypes.func.isRequired,
192
+ getValueAsString: PropTypes.func,
193
+ headerLabel: PropTypes.string,
194
+ InputComponent: PropTypes.elementType,
195
+ InputComponentProps: PropTypes.object,
196
+ label: PropTypes.string,
197
+ requiresFilterValue: PropTypes.bool,
198
+ value: PropTypes.string.isRequired
199
+ })),
200
+ hasFocus: PropTypes.bool,
201
+ /**
202
+ * Class name that will be added in the column header cell.
203
+ */
204
+ headerClassName: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
205
+ headerFilterComponent: PropTypes.node,
206
+ headerFilterMenuRef: PropTypes.shape({
207
+ current: PropTypes.object
208
+ }).isRequired,
209
+ height: PropTypes.number.isRequired,
210
+ InputComponentProps: PropTypes.object,
211
+ item: PropTypes.shape({
212
+ field: PropTypes.string.isRequired,
213
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
214
+ operator: PropTypes.string.isRequired,
215
+ value: PropTypes.any
216
+ }).isRequired,
217
+ showClearIcon: PropTypes.bool,
218
+ sortIndex: PropTypes.number,
219
+ tabIndex: PropTypes.oneOf([-1, 0]).isRequired,
220
+ width: PropTypes.number.isRequired
221
+ } : void 0;
222
+ export { GridHeaderFilterCell };
@@ -0,0 +1,24 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ const sx = {
6
+ padding: '2px'
7
+ };
8
+ function GridHeaderFilterClearButton({
9
+ onClick
10
+ }) {
11
+ const rootProps = useGridRootProps();
12
+ return /*#__PURE__*/_jsx(rootProps.slots.baseIconButton, _extends({
13
+ tabIndex: -1,
14
+ "aria-label": "Clear filter",
15
+ size: "small",
16
+ onClick: onClick,
17
+ sx: sx
18
+ }, rootProps.slotProps?.baseIconButton, {
19
+ children: /*#__PURE__*/_jsx(rootProps.slots.headerFilterClearIcon, {
20
+ fontSize: "inherit"
21
+ })
22
+ }));
23
+ }
24
+ export { GridHeaderFilterClearButton };
@@ -0,0 +1,68 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import MenuList from '@mui/material/MenuList';
4
+ import MenuItem from '@mui/material/MenuItem';
5
+ import ListItemIcon from '@mui/material/ListItemIcon';
6
+ import ListItemText from '@mui/material/ListItemText';
7
+ import { unstable_capitalize as capitalize } from '@mui/utils';
8
+ import { useGridApiContext, GridMenu } from '@mui/x-data-grid';
9
+ import { OPERATOR_SYMBOL_MAPPING } from './constants';
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ import { jsxs as _jsxs } from "react/jsx-runtime";
12
+ function GridHeaderFilterMenu({
13
+ open,
14
+ field,
15
+ targetRef,
16
+ applyFilterChanges,
17
+ operators,
18
+ item,
19
+ id,
20
+ labelledBy
21
+ }) {
22
+ const apiRef = useGridApiContext();
23
+ const hideMenu = React.useCallback(() => {
24
+ apiRef.current.hideHeaderFilterMenu();
25
+ }, [apiRef]);
26
+ const handleListKeyDown = React.useCallback(event => {
27
+ if (event.key === 'Tab') {
28
+ event.preventDefault();
29
+ }
30
+ if (event.key === 'Escape' || event.key === 'Tab') {
31
+ hideMenu();
32
+ }
33
+ }, [hideMenu]);
34
+ if (!targetRef.current) {
35
+ return null;
36
+ }
37
+ return /*#__PURE__*/_jsx(GridMenu, {
38
+ placement: "bottom-start",
39
+ open: open,
40
+ target: targetRef.current,
41
+ onClickAway: hideMenu,
42
+ onExited: hideMenu,
43
+ children: /*#__PURE__*/_jsx(MenuList, {
44
+ "aria-labelledby": labelledBy,
45
+ id: id,
46
+ onKeyDown: handleListKeyDown,
47
+ children: operators.map((op, i) => {
48
+ const label = op?.headerLabel ?? apiRef.current.getLocaleText(`headerFilterOperator${capitalize(op.value)}`);
49
+ return /*#__PURE__*/_jsxs(MenuItem, {
50
+ onClick: () => {
51
+ applyFilterChanges(_extends({}, item, {
52
+ operator: op.value
53
+ }));
54
+ hideMenu();
55
+ },
56
+ autoFocus: i === 0 ? open : false,
57
+ selected: op.value === item.operator,
58
+ children: [/*#__PURE__*/_jsx(ListItemIcon, {
59
+ children: OPERATOR_SYMBOL_MAPPING[op.value]
60
+ }), /*#__PURE__*/_jsx(ListItemText, {
61
+ children: label
62
+ })]
63
+ }, `${field}-${op.value}`);
64
+ })
65
+ })
66
+ });
67
+ }
68
+ export { GridHeaderFilterMenu };
@@ -0,0 +1,30 @@
1
+ export const OPERATOR_SYMBOL_MAPPING = {
2
+ contains: '∋',
3
+ equals: '=',
4
+ '=': '=',
5
+ '!=': '≠',
6
+ '>': '>',
7
+ '>=': '≥',
8
+ '<': '<',
9
+ '<=': '≤',
10
+ startsWith: '⊃',
11
+ endsWith: '⊂',
12
+ is: '=',
13
+ not: '≠',
14
+ isNot: '≠',
15
+ isEmpty: '∅',
16
+ isNotEmpty: '∉',
17
+ isIn: '∈',
18
+ isNotIn: '∉',
19
+ isLessThan: '<',
20
+ isLessThanOrEqual: '≤',
21
+ isGreaterThan: '>',
22
+ isGreaterThanOrEqual: '≥',
23
+ isBetween: '∈',
24
+ isNotBetween: '∉',
25
+ isAnyOf: '∈',
26
+ after: '>',
27
+ onOrAfter: '≥',
28
+ before: '<',
29
+ onOrBefore: '≤'
30
+ };
@@ -0,0 +1,2 @@
1
+ export * from './GridHeaderFilterAdornment';
2
+ export * from './GridHeaderFilterCell';
@@ -2,4 +2,5 @@
2
2
  export * from './GridTreeDataGroupingCell';
3
3
  export * from './GridColumnMenuPinningItem';
4
4
  export * from './GridDetailPanelToggleCell';
5
- export * from '../material/icons';
5
+ export * from '../material/icons';
6
+ export * from './headerFiltering';
@@ -2,8 +2,12 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { DATA_GRID_DEFAULT_SLOTS_COMPONENTS } from '@mui/x-data-grid/internals';
3
3
  import { GridProColumnMenu } from '../components/GridProColumnMenu';
4
4
  import { GridColumnHeaders } from '../components/GridColumnHeaders';
5
+ import { GridHeaderFilterMenu } from '../components/headerFiltering/GridHeaderFilterMenu';
6
+ import { GridHeaderFilterCell } from '../components/headerFiltering/GridHeaderFilterCell';
5
7
  import materialSlots from '../material';
6
8
  export const DATA_GRID_PRO_DEFAULT_SLOTS_COMPONENTS = _extends({}, DATA_GRID_DEFAULT_SLOTS_COMPONENTS, materialSlots, {
7
9
  ColumnMenu: GridProColumnMenu,
8
- ColumnHeaders: GridColumnHeaders
10
+ ColumnHeaders: GridColumnHeaders,
11
+ HeaderFilterCell: GridHeaderFilterCell,
12
+ HeaderFilterMenu: GridHeaderFilterMenu
9
13
  });
@@ -0,0 +1,110 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["getColumnsToRender", "getRootProps"];
4
+ import * as React from 'react';
5
+ import { unstable_gridFocusColumnHeaderFilterSelector, useGridSelector, gridFilterModelSelector, unstable_gridTabIndexColumnHeaderFilterSelector } from '@mui/x-data-grid';
6
+ import { styled } from '@mui/system';
7
+ import { useGridColumnHeaders as useGridColumnHeadersCommunity, getTotalHeaderHeight, useGridPrivateApiContext, getGridFilter } from '@mui/x-data-grid/internals';
8
+ import { useGridRootProps } from '../../utils/useGridRootProps';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ const GridHeaderFilterRow = styled('div', {
11
+ name: 'MuiDataGrid',
12
+ slot: 'HeaderFilterRow',
13
+ overridesResolver: (props, styles) => styles.headerFilterRow
14
+ })(() => ({
15
+ display: 'flex',
16
+ borderTop: '1px solid rgba(224, 224, 224, 1)'
17
+ }));
18
+ export const useGridColumnHeaders = props => {
19
+ const apiRef = useGridPrivateApiContext();
20
+ const {
21
+ headerGroupingMaxDepth,
22
+ hasOtherElementInTabSequence
23
+ } = props;
24
+ const columnHeaderFilterTabIndexState = useGridSelector(apiRef, unstable_gridTabIndexColumnHeaderFilterSelector);
25
+ const _useGridColumnHeaders = useGridColumnHeadersCommunity(_extends({}, props, {
26
+ hasOtherElementInTabSequence: hasOtherElementInTabSequence || columnHeaderFilterTabIndexState !== null
27
+ })),
28
+ {
29
+ getColumnsToRender,
30
+ getRootProps
31
+ } = _useGridColumnHeaders,
32
+ otherProps = _objectWithoutPropertiesLoose(_useGridColumnHeaders, _excluded);
33
+ const headerFiltersRef = React.useRef(null);
34
+ apiRef.current.register('private', {
35
+ headerFiltersElementRef: headerFiltersRef
36
+ });
37
+ const headerFilterMenuRef = React.useRef(null);
38
+ const rootProps = useGridRootProps();
39
+ const disableHeaderFiltering = !rootProps.unstable_headerFilters;
40
+ const headerHeight = Math.floor(rootProps.columnHeaderHeight * props.densityFactor);
41
+ const filterModel = useGridSelector(apiRef, gridFilterModelSelector);
42
+ const totalHeaderHeight = getTotalHeaderHeight(apiRef, rootProps.columnHeaderHeight) + (disableHeaderFiltering ? 0 : headerHeight);
43
+ const columnHeaderFilterFocus = useGridSelector(apiRef, unstable_gridFocusColumnHeaderFilterSelector);
44
+ const getColumnFilters = (params, other = {}) => {
45
+ if (disableHeaderFiltering) {
46
+ return null;
47
+ }
48
+ const columnsToRender = getColumnsToRender(params);
49
+ if (columnsToRender == null) {
50
+ return null;
51
+ }
52
+ const {
53
+ renderedColumns,
54
+ firstColumnToRender
55
+ } = columnsToRender;
56
+ const filters = [];
57
+ for (let i = 0; i < renderedColumns.length; i += 1) {
58
+ const colDef = renderedColumns[i];
59
+ const columnIndex = firstColumnToRender + i;
60
+ const hasFocus = columnHeaderFilterFocus?.field === colDef.field;
61
+ const isFirstColumn = columnIndex === 0;
62
+ const tabIndexField = columnHeaderFilterTabIndexState?.field;
63
+ const tabIndex = tabIndexField === colDef.field || isFirstColumn && !props.hasOtherElementInTabSequence ? 0 : -1;
64
+ let headerFilterComponent;
65
+ if (colDef.renderHeaderFilter) {
66
+ headerFilterComponent = colDef.renderHeaderFilter(apiRef.current.getColumnHeaderParams(colDef.field));
67
+ }
68
+ const headerClassName = typeof colDef.headerClassName === 'function' ? colDef.headerClassName({
69
+ field: colDef.field,
70
+ colDef
71
+ }) : colDef.headerClassName;
72
+
73
+ // TODO: Support for `isAnyOf` operator
74
+ const filterOperators = colDef.filterOperators?.filter(operator => operator.value !== 'isAnyOf') ?? [];
75
+ const item = filterModel?.items.find(it => it.field === colDef.field && it.operator !== 'isAnyOf') ?? getGridFilter(colDef);
76
+ filters.push( /*#__PURE__*/_jsx(rootProps.slots.headerFilterCell, _extends({
77
+ colIndex: columnIndex,
78
+ height: headerHeight,
79
+ width: colDef.computedWidth,
80
+ colDef: colDef,
81
+ hasFocus: hasFocus,
82
+ tabIndex: tabIndex,
83
+ headerFilterMenuRef: headerFilterMenuRef,
84
+ headerFilterComponent: headerFilterComponent,
85
+ headerClassName: headerClassName,
86
+ filterOperators: filterOperators,
87
+ "data-field": colDef.field,
88
+ item: item
89
+ }, rootProps.slotProps?.headerFilterCell, other), `${colDef.field}-filter`));
90
+ }
91
+ return /*#__PURE__*/_jsx(GridHeaderFilterRow, {
92
+ ref: headerFiltersRef,
93
+ ownerState: rootProps,
94
+ role: "row",
95
+ "aria-rowindex": headerGroupingMaxDepth + 2,
96
+ children: filters
97
+ });
98
+ };
99
+ const rootStyle = {
100
+ minHeight: totalHeaderHeight,
101
+ maxHeight: totalHeaderHeight,
102
+ lineHeight: `${headerHeight}px`
103
+ };
104
+ return _extends({}, otherProps, {
105
+ getColumnFilters,
106
+ getRootProps: disableHeaderFiltering ? getRootProps : (other = {}) => _extends({
107
+ style: rootStyle
108
+ }, other)
109
+ });
110
+ };
@@ -87,6 +87,7 @@ export const useGridColumnResize = (apiRef, props) => {
87
87
  const logger = useGridLogger(apiRef, 'useGridColumnResize');
88
88
  const colDefRef = React.useRef();
89
89
  const colElementRef = React.useRef();
90
+ const headerFilterElementRef = React.useRef();
90
91
  const colGroupingElementRef = React.useRef();
91
92
  const colCellElementsRef = React.useRef();
92
93
  const theme = useTheme();
@@ -108,6 +109,12 @@ export const useGridColumnResize = (apiRef, props) => {
108
109
  colElementRef.current.style.width = `${newWidth}px`;
109
110
  colElementRef.current.style.minWidth = `${newWidth}px`;
110
111
  colElementRef.current.style.maxWidth = `${newWidth}px`;
112
+ const headerFilterElement = headerFilterElementRef.current;
113
+ if (headerFilterElement) {
114
+ headerFilterElement.style.width = `${newWidth}px`;
115
+ headerFilterElement.style.minWidth = `${newWidth}px`;
116
+ headerFilterElement.style.maxWidth = `${newWidth}px`;
117
+ }
111
118
  [...colCellElementsRef.current, ...colGroupingElementRef.current].forEach(element => {
112
119
  const div = element;
113
120
  let finalWidth;
@@ -177,6 +184,10 @@ export const useGridColumnResize = (apiRef, props) => {
177
184
  }, event);
178
185
  colDefRef.current = colDef;
179
186
  colElementRef.current = apiRef.current.columnHeadersContainerElementRef?.current.querySelector(`[data-field="${colDef.field}"]`);
187
+ const headerFilterRowElement = apiRef.current.headerFiltersElementRef?.current;
188
+ if (headerFilterRowElement) {
189
+ headerFilterElementRef.current = headerFilterRowElement.querySelector(`[data-field="${colDef.field}"]`);
190
+ }
180
191
  colGroupingElementRef.current = findGroupHeaderElementsFromField(apiRef.current.columnHeadersContainerElementRef?.current, colDef.field);
181
192
  colCellElementsRef.current = findGridCellElementsFromCol(colElementRef.current, apiRef.current);
182
193
  const doc = ownerDocument(apiRef.current.rootElementRef.current);
@@ -26,6 +26,7 @@ export function addPinnedRow({
26
26
  isAutoGenerated
27
27
  };
28
28
  insertNodeInTree({
29
+ previousTree: null,
29
30
  node,
30
31
  tree,
31
32
  treeDepths
@@ -77,6 +77,7 @@ export const useGridTreeDataPreProcessors = (privateApiRef, props) => {
77
77
  };
78
78
  if (params.updates.type === 'full') {
79
79
  return createRowTree({
80
+ previousTree: params.previousTree,
80
81
  nodes: params.updates.rows.map(getRowTreeBuilderNode),
81
82
  defaultGroupingExpansionDepth: props.defaultGroupingExpansionDepth,
82
83
  isGroupExpandedByDefault: props.isGroupExpandedByDefault,
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-pro v6.3.1
2
+ * @mui/x-data-grid-pro v6.5.0
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -1,7 +1,11 @@
1
+ // eslint-disable-next-line import/export
1
2
  export * from '@mui/x-data-grid/internals';
2
3
  export { DataGridProVirtualScroller } from '../components/DataGridProVirtualScroller';
3
4
  export { GridColumnHeaders } from '../components/GridColumnHeaders';
4
5
  export { DATA_GRID_PRO_DEFAULT_SLOTS_COMPONENTS } from '../constants/dataGridProDefaultSlotsComponents';
6
+
7
+ // eslint-disable-next-line import/export
8
+ export { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';
5
9
  export { useGridColumnResize, columnResizeStateInitializer } from '../hooks/features/columnResize/useGridColumnResize';
6
10
  export { useGridColumnPinning, columnPinningStateInitializer } from '../hooks/features/columnPinning/useGridColumnPinning';
7
11
  export { useGridColumnPinningPreProcessors } from '../hooks/features/columnPinning/useGridColumnPinningPreProcessors';
@@ -14,4 +14,7 @@ export const GridPushPinLeftIcon = createSvgIcon( /*#__PURE__*/_jsx("g", {
14
14
  d: "M16,9V4l1,0c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H7C6.45,2,6,2.45,6,3v0 c0,0.55,0.45,1,1,1l1,0v5c0,1.66-1.34,3-3,3h0v2h5.97v7l1,1l1-1v-7H19v-2h0C17.34,12,16,10.66,16,9z",
15
15
  fillRule: "evenodd"
16
16
  })
17
- }), 'PushPinLeft');
17
+ }), 'PushPinLeft');
18
+ export const GridHighlightOffIcon = createSvgIcon( /*#__PURE__*/_jsx("path", {
19
+ d: "M14.59 8L12 10.59 9.41 8 8 9.41 10.59 12 8 14.59 9.41 16 12 13.41 14.59 16 16 14.59 13.41 12 16 9.41 14.59 8zM12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"
20
+ }), 'HighlightOff');
@@ -1,8 +1,9 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import { GridPushPinRightIcon, GridPushPinLeftIcon } from './icons';
2
+ import { GridPushPinRightIcon, GridPushPinLeftIcon, GridHighlightOffIcon } from './icons';
3
3
  const iconSlots = {
4
4
  ColumnMenuPinRightIcon: GridPushPinRightIcon,
5
- ColumnMenuPinLeftIcon: GridPushPinLeftIcon
5
+ ColumnMenuPinLeftIcon: GridPushPinLeftIcon,
6
+ HeaderFilterClearIcon: GridHighlightOffIcon
6
7
  };
7
8
  const materialSlots = _extends({}, iconSlots);
8
9
  export default materialSlots;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTY4MzIzNzYwMDAwMA==";
3
+ const releaseInfo = "MTY4NDQ0MzYwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat
@@ -15,6 +15,7 @@ export const createRowTree = params => {
15
15
  dataRowIds.push(node.id);
16
16
  insertDataRowInTree({
17
17
  tree,
18
+ previousTree: params.previousTree,
18
19
  id: node.id,
19
20
  path: node.path,
20
21
  onDuplicatePath: params.onDuplicatePath,
@@ -10,6 +10,7 @@ export const insertDataRowInTree = ({
10
10
  id,
11
11
  path,
12
12
  updatedGroupsManager,
13
+ previousTree,
13
14
  tree,
14
15
  treeDepths,
15
16
  onDuplicatePath,
@@ -42,6 +43,7 @@ export const insertDataRowInTree = ({
42
43
  updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
43
44
  insertNodeInTree({
44
45
  node: leafNode,
46
+ previousTree,
45
47
  tree,
46
48
  treeDepths
47
49
  });
@@ -55,6 +57,7 @@ export const insertDataRowInTree = ({
55
57
  updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
56
58
  updateGroupNodeIdAndAutoGenerated({
57
59
  tree,
60
+ previousTree,
58
61
  treeDepths,
59
62
  node: existingNodeWithPartialPath,
60
63
  updatedNode: {
@@ -94,6 +97,7 @@ export const insertDataRowInTree = ({
94
97
  defaultGroupingExpansionDepth,
95
98
  isGroupExpandedByDefault
96
99
  }),
100
+ previousTree,
97
101
  tree,
98
102
  treeDepths
99
103
  });
@@ -48,6 +48,7 @@ const replaceDataGroupWithAutoGeneratedGroup = ({
48
48
  updatedGroupsManager?.addAction(node.parent, 'removeChildren');
49
49
  updatedGroupsManager?.addAction(node.parent, 'insertChildren');
50
50
  updateGroupNodeIdAndAutoGenerated({
51
+ previousTree: null,
51
52
  tree,
52
53
  treeDepths,
53
54
  node,
@@ -14,6 +14,7 @@ export const updateRowTree = params => {
14
14
  path
15
15
  } = params.nodes.inserted[i];
16
16
  insertDataRowInTree({
17
+ previousTree: params.previousTree,
17
18
  tree,
18
19
  treeDepths,
19
20
  updatedGroupsManager,
@@ -51,6 +52,7 @@ export const updateRowTree = params => {
51
52
  id
52
53
  });
53
54
  insertDataRowInTree({
55
+ previousTree: params.previousTree,
54
56
  tree,
55
57
  treeDepths,
56
58
  updatedGroupsManager,