@mui/x-data-grid 8.3.1 → 8.4.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 (68) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/DataGrid/DataGrid.js +1 -0
  3. package/components/GridApiContext.js +1 -3
  4. package/components/GridColumnUnsortedIcon.js +2 -1
  5. package/components/GridConfigurationContext.js +1 -3
  6. package/components/GridRow.js +1 -0
  7. package/components/cell/GridActionsCell.js +2 -1
  8. package/components/cell/GridBooleanCell.js +3 -1
  9. package/components/cell/GridEditBooleanCell.js +2 -1
  10. package/components/cell/GridEditDateCell.js +2 -1
  11. package/components/cell/GridEditInputCell.js +2 -1
  12. package/components/cell/GridEditSingleSelectCell.js +2 -1
  13. package/components/columnHeaders/ColumnHeaderMenuIcon.js +2 -1
  14. package/components/columnHeaders/GridColumnHeaderItem.js +1 -1
  15. package/components/columnHeaders/GridColumnHeaderSeparator.js +1 -0
  16. package/components/columnHeaders/GridColumnHeaderSortIcon.js +1 -0
  17. package/components/containers/GridRootStyles.js +1 -1
  18. package/components/panel/GridPanelContext.js +1 -0
  19. package/components/quickFilter/QuickFilterContext.js +1 -0
  20. package/components/toolbarV8/Toolbar.js +58 -32
  21. package/components/toolbarV8/ToolbarContext.js +1 -0
  22. package/components/toolbarV8/utils.d.ts +5 -0
  23. package/components/toolbarV8/utils.js +23 -0
  24. package/context/GridRootPropsContext.js +1 -3
  25. package/esm/DataGrid/DataGrid.js +1 -0
  26. package/esm/components/GridApiContext.js +1 -3
  27. package/esm/components/GridColumnUnsortedIcon.js +2 -1
  28. package/esm/components/GridConfigurationContext.js +1 -3
  29. package/esm/components/GridRow.js +1 -0
  30. package/esm/components/cell/GridActionsCell.js +2 -1
  31. package/esm/components/cell/GridBooleanCell.js +3 -1
  32. package/esm/components/cell/GridEditBooleanCell.js +2 -1
  33. package/esm/components/cell/GridEditDateCell.js +2 -1
  34. package/esm/components/cell/GridEditInputCell.js +2 -1
  35. package/esm/components/cell/GridEditSingleSelectCell.js +2 -1
  36. package/esm/components/columnHeaders/ColumnHeaderMenuIcon.js +2 -1
  37. package/esm/components/columnHeaders/GridColumnHeaderItem.js +1 -1
  38. package/esm/components/columnHeaders/GridColumnHeaderSeparator.js +1 -0
  39. package/esm/components/columnHeaders/GridColumnHeaderSortIcon.js +1 -0
  40. package/esm/components/containers/GridRootStyles.js +1 -1
  41. package/esm/components/panel/GridPanelContext.js +1 -0
  42. package/esm/components/quickFilter/QuickFilterContext.js +1 -0
  43. package/esm/components/toolbarV8/Toolbar.js +58 -32
  44. package/esm/components/toolbarV8/ToolbarContext.js +1 -0
  45. package/esm/components/toolbarV8/utils.d.ts +5 -0
  46. package/esm/components/toolbarV8/utils.js +17 -0
  47. package/esm/context/GridRootPropsContext.js +1 -3
  48. package/esm/hooks/features/columnHeaders/useGridColumnHeaders.js +3 -1
  49. package/esm/hooks/features/overlays/useGridOverlays.js +1 -0
  50. package/esm/hooks/features/pagination/useGridPaginationModel.js +1 -1
  51. package/esm/hooks/features/rowSelection/useGridRowSelection.js +1 -1
  52. package/esm/hooks/utils/useGridPrivateApiContext.js +1 -3
  53. package/esm/index.js +1 -1
  54. package/esm/locales/isIS.js +8 -8
  55. package/esm/material/variables.js +5 -0
  56. package/esm/models/events/gridEventLookup.d.ts +9 -0
  57. package/esm/utils/css/context.js +2 -1
  58. package/hooks/features/columnHeaders/useGridColumnHeaders.js +3 -1
  59. package/hooks/features/overlays/useGridOverlays.js +1 -0
  60. package/hooks/features/pagination/useGridPaginationModel.js +1 -1
  61. package/hooks/features/rowSelection/useGridRowSelection.js +1 -1
  62. package/hooks/utils/useGridPrivateApiContext.js +1 -3
  63. package/index.js +1 -1
  64. package/locales/isIS.js +8 -8
  65. package/material/variables.js +5 -0
  66. package/models/events/gridEventLookup.d.ts +9 -0
  67. package/package.json +2 -2
  68. package/utils/css/context.js +2 -1
@@ -657,7 +657,7 @@ export const GridRootStyles = styled('div', {
657
657
  borderTop: 'none'
658
658
  }
659
659
  },
660
- [`&.${c['root--disableUserSelection']} .${c.cell}`]: {
660
+ [`&.${c['root--disableUserSelection']}`]: {
661
661
  userSelect: 'none'
662
662
  },
663
663
  [`& .${c['row--dynamicHeight']} > .${c.cell}`]: {
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  export const GridPanelContext = /*#__PURE__*/React.createContext(undefined);
4
+ if (process.env.NODE_ENV !== "production") GridPanelContext.displayName = "GridPanelContext";
4
5
  export function useGridPanelContext() {
5
6
  const context = React.useContext(GridPanelContext);
6
7
  if (context === undefined) {
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  export const QuickFilterContext = /*#__PURE__*/React.createContext(undefined);
3
+ if (process.env.NODE_ENV !== "production") QuickFilterContext.displayName = "QuickFilterContext";
3
4
  export function useQuickFilterContext() {
4
5
  const context = React.useContext(QuickFilterContext);
5
6
  if (context === undefined) {
@@ -12,6 +12,7 @@ import { getDataGridUtilityClass } from "../../constants/gridClasses.js";
12
12
  import { useGridComponentRenderer } from "../../hooks/utils/useGridComponentRenderer.js";
13
13
  import { ToolbarContext } from "./ToolbarContext.js";
14
14
  import { useGridRootProps } from "../../hooks/utils/useGridRootProps.js";
15
+ import { sortByDocumentPosition } from "./utils.js";
15
16
  import { jsx as _jsx } from "react/jsx-runtime";
16
17
  const useUtilityClasses = ownerState => {
17
18
  const {
@@ -59,21 +60,11 @@ const Toolbar = forwardRef(function Toolbar(props, ref) {
59
60
  const classes = useUtilityClasses(rootProps);
60
61
  const [focusableItemId, setFocusableItemId] = React.useState(null);
61
62
  const [items, setItems] = React.useState([]);
62
- const registerItem = React.useCallback((id, itemRef) => {
63
- setItems(prevItems => [...prevItems, {
64
- id,
65
- ref: itemRef
66
- }]);
67
- }, []);
68
- const unregisterItem = React.useCallback(id => {
69
- setItems(prevItems => prevItems.filter(i => i.id !== id));
70
- if (focusableItemId === id) {
71
- setFocusableItemId(null);
72
- }
73
- }, [focusableItemId]);
63
+ const getSortedItems = React.useCallback(() => items.sort(sortByDocumentPosition), [items]);
74
64
  const findEnabledItem = React.useCallback((startIndex, step, wrap = true) => {
75
65
  let index = startIndex;
76
- const itemCount = items.length;
66
+ const sortedItems = getSortedItems();
67
+ const itemCount = sortedItems.length;
77
68
 
78
69
  // Look for enabled items in the specified direction
79
70
  for (let i = 0; i < itemCount; i += 1) {
@@ -93,53 +84,93 @@ const Toolbar = forwardRef(function Toolbar(props, ref) {
93
84
  }
94
85
 
95
86
  // Return if we found an enabled item
96
- if (!items[index].ref.current?.disabled && items[index].ref.current?.ariaDisabled !== 'true') {
87
+ if (!sortedItems[index].ref.current?.disabled && sortedItems[index].ref.current?.ariaDisabled !== 'true') {
97
88
  return index;
98
89
  }
99
90
  }
100
91
 
101
92
  // If we've checked all items and found none enabled
102
93
  return -1;
103
- }, [items]);
94
+ }, [getSortedItems]);
95
+ const registerItem = React.useCallback((id, itemRef) => {
96
+ setItems(prevItems => [...prevItems, {
97
+ id,
98
+ ref: itemRef
99
+ }]);
100
+ }, []);
101
+ const unregisterItem = React.useCallback(id => {
102
+ setItems(prevItems => prevItems.filter(i => i.id !== id));
103
+ }, []);
104
104
  const onItemKeyDown = React.useCallback(event => {
105
105
  if (!focusableItemId) {
106
106
  return;
107
107
  }
108
- const currentIndex = items.findIndex(item => item.id === focusableItemId);
108
+ const sortedItems = getSortedItems();
109
+ const focusableItemIndex = sortedItems.findIndex(item => item.id === focusableItemId);
109
110
  let newIndex = -1;
110
111
  if (event.key === 'ArrowRight') {
111
112
  event.preventDefault();
112
- newIndex = findEnabledItem(currentIndex, 1);
113
+ newIndex = findEnabledItem(focusableItemIndex, 1);
113
114
  } else if (event.key === 'ArrowLeft') {
114
115
  event.preventDefault();
115
- newIndex = findEnabledItem(currentIndex, -1);
116
+ newIndex = findEnabledItem(focusableItemIndex, -1);
116
117
  } else if (event.key === 'Home') {
117
118
  event.preventDefault();
118
119
  newIndex = findEnabledItem(-1, 1, false);
119
120
  } else if (event.key === 'End') {
120
121
  event.preventDefault();
121
- newIndex = findEnabledItem(items.length, -1, false);
122
+ newIndex = findEnabledItem(sortedItems.length, -1, false);
122
123
  }
123
- if (newIndex >= 0 && newIndex < items.length) {
124
- const item = items[newIndex];
124
+
125
+ // TODO: Check why this is necessary
126
+ if (newIndex >= 0 && newIndex < sortedItems.length) {
127
+ const item = sortedItems[newIndex];
125
128
  setFocusableItemId(item.id);
126
129
  item.ref.current?.focus();
127
130
  }
128
- }, [items, focusableItemId, findEnabledItem]);
131
+ }, [getSortedItems, focusableItemId, findEnabledItem]);
129
132
  const onItemFocus = React.useCallback(id => {
130
133
  if (focusableItemId !== id) {
131
134
  setFocusableItemId(id);
132
135
  }
133
- }, [focusableItemId]);
136
+ }, [focusableItemId, setFocusableItemId]);
134
137
  const onItemDisabled = React.useCallback(id => {
135
- const currentIndex = items.findIndex(item => item.id === id);
138
+ const sortedItems = getSortedItems();
139
+ const currentIndex = sortedItems.findIndex(item => item.id === id);
136
140
  const newIndex = findEnabledItem(currentIndex, 1);
137
- if (newIndex >= 0 && newIndex < items.length) {
138
- const item = items[newIndex];
141
+ if (newIndex >= 0 && newIndex < sortedItems.length) {
142
+ const item = sortedItems[newIndex];
139
143
  setFocusableItemId(item.id);
140
144
  item.ref.current?.focus();
141
145
  }
142
- }, [items, findEnabledItem]);
146
+ }, [getSortedItems, findEnabledItem]);
147
+ React.useEffect(() => {
148
+ const sortedItems = getSortedItems();
149
+ if (sortedItems.length > 0) {
150
+ // Set initial focusable item
151
+ if (!focusableItemId) {
152
+ setFocusableItemId(sortedItems[0].id);
153
+ return;
154
+ }
155
+ const focusableItemIndex = sortedItems.findIndex(item => item.id === focusableItemId);
156
+ if (!sortedItems[focusableItemIndex]) {
157
+ // Last item has been removed from the items array
158
+ const item = sortedItems[sortedItems.length - 1];
159
+ if (item) {
160
+ setFocusableItemId(item.id);
161
+ item.ref.current?.focus();
162
+ }
163
+ } else if (focusableItemIndex === -1) {
164
+ // Focused item has been removed from the items array
165
+ const item = sortedItems[focusableItemIndex];
166
+ if (item) {
167
+ setFocusableItemId(item.id);
168
+ item.ref.current?.focus();
169
+ }
170
+ }
171
+ }
172
+ // eslint-disable-next-line react-hooks/exhaustive-deps
173
+ }, [getSortedItems, findEnabledItem]);
143
174
  const contextValue = React.useMemo(() => ({
144
175
  focusableItemId,
145
176
  registerItem,
@@ -156,11 +187,6 @@ const Toolbar = forwardRef(function Toolbar(props, ref) {
156
187
  }, other, {
157
188
  ref
158
189
  }));
159
- React.useEffect(() => {
160
- if (items.length > 0) {
161
- setFocusableItemId(items[0].id);
162
- }
163
- }, [items]);
164
190
  return /*#__PURE__*/_jsx(ToolbarContext.Provider, {
165
191
  value: contextValue,
166
192
  children: element
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  export const ToolbarContext = /*#__PURE__*/React.createContext(undefined);
3
+ if (process.env.NODE_ENV !== "production") ToolbarContext.displayName = "ToolbarContext";
3
4
  export function useToolbarContext() {
4
5
  const context = React.useContext(ToolbarContext);
5
6
  if (context === undefined) {
@@ -0,0 +1,5 @@
1
+ export declare function sortByDocumentPosition(a: {
2
+ ref: React.RefObject<HTMLButtonElement | null>;
3
+ }, b: {
4
+ ref: React.RefObject<HTMLButtonElement | null>;
5
+ }): 0 | 1 | -1;
@@ -0,0 +1,17 @@
1
+ /* eslint-disable no-bitwise */
2
+ export function sortByDocumentPosition(a, b) {
3
+ if (!a.ref.current || !b.ref.current) {
4
+ return 0;
5
+ }
6
+ const position = a.ref.current.compareDocumentPosition(b.ref.current);
7
+ if (!position) {
8
+ return 0;
9
+ }
10
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
11
+ return -1;
12
+ }
13
+ if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) {
14
+ return 1;
15
+ }
16
+ return 0;
17
+ }
@@ -2,7 +2,5 @@
2
2
 
3
3
  import * as React from 'react';
4
4
  const GridRootPropsContext = /*#__PURE__*/React.createContext(undefined);
5
- if (process.env.NODE_ENV !== 'production') {
6
- GridRootPropsContext.displayName = 'GridRootPropsContext';
7
- }
5
+ if (process.env.NODE_ENV !== "production") GridRootPropsContext.displayName = "GridRootPropsContext";
8
6
  export { GridRootPropsContext };
@@ -75,7 +75,7 @@ export const useGridColumnHeaders = props => {
75
75
  useGridEvent(apiRef, 'columnResizeStart', handleColumnResizeStart);
76
76
  useGridEvent(apiRef, 'columnResizeStop', handleColumnResizeStop);
77
77
  useGridEvent(apiRef, 'columnHeaderDragStart', handleColumnReorderStart);
78
- useGridEvent(apiRef, 'columnHeaderDragEnd', handleColumnReorderStop);
78
+ useGridEvent(apiRef, 'columnHeaderDragEndNative', handleColumnReorderStop);
79
79
 
80
80
  // Helper for computation common between getColumnHeaders and getColumnGroupHeaders
81
81
  const getColumnsToRender = params => {
@@ -113,6 +113,7 @@ export const useGridColumnHeaders = props => {
113
113
  })]
114
114
  });
115
115
  };
116
+ if (process.env.NODE_ENV !== "production") getFillers.displayName = "getFillers";
116
117
  const getColumnHeaders = (params, other = {}) => {
117
118
  const {
118
119
  renderedColumns,
@@ -181,6 +182,7 @@ export const useGridColumnHeaders = props => {
181
182
  })]
182
183
  });
183
184
  };
185
+ if (process.env.NODE_ENV !== "production") getColumnHeadersRow.displayName = "getColumnHeadersRow";
184
186
  const getColumnGroupHeaders = ({
185
187
  depth,
186
188
  params
@@ -61,6 +61,7 @@ export const useGridOverlays = () => {
61
61
  children: /*#__PURE__*/_jsx(Overlay, _extends({}, overlayProps))
62
62
  }));
63
63
  };
64
+ if (process.env.NODE_ENV !== "production") getOverlay.displayName = "getOverlay";
64
65
  return {
65
66
  getOverlay,
66
67
  overlaysProps
@@ -138,7 +138,7 @@ export const useGridPaginationModel = (apiRef, props) => {
138
138
  return;
139
139
  }
140
140
  const dimensions = apiRef.current.getRootDimensions();
141
- const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
141
+ const maximumPageSizeWithoutScrollBar = Math.max(1, Math.floor(dimensions.viewportInnerSize.height / rowHeight));
142
142
  apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
143
143
  }, [apiRef, props.autoPageSize, rowHeight]);
144
144
  const handleRowCountChange = React.useCallback(newRowCount => {
@@ -427,7 +427,7 @@ export const useGridRowSelection = (apiRef, props) => {
427
427
  const toggleAllRows = React.useCallback(value => {
428
428
  const filterModel = gridFilterModelSelector(apiRef);
429
429
  const quickFilterModel = gridQuickFilterValuesSelector(apiRef);
430
- const hasFilters = filterModel.items.length > 0 || (quickFilterModel?.length || 0) > 0;
430
+ const hasFilters = filterModel.items.length > 0 || quickFilterModel?.some(val => val.length);
431
431
  if (!props.isRowSelectable && !props.checkboxSelectionVisibleOnly && applyAutoSelection && !hasFilters) {
432
432
  apiRef.current.setRowSelectionModel({
433
433
  type: value ? 'exclude' : 'include',
@@ -1,8 +1,6 @@
1
1
  import * as React from 'react';
2
2
  export const GridPrivateApiContext = /*#__PURE__*/React.createContext(undefined);
3
- if (process.env.NODE_ENV !== 'production') {
4
- GridPrivateApiContext.displayName = 'GridPrivateApiContext';
5
- }
3
+ if (process.env.NODE_ENV !== "production") GridPrivateApiContext.displayName = "GridPrivateApiContext";
6
4
  export function useGridPrivateApiContext() {
7
5
  const privateApiRef = React.useContext(GridPrivateApiContext);
8
6
  if (privateApiRef === undefined) {
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v8.3.1
2
+ * @mui/x-data-grid v8.4.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -58,11 +58,11 @@ const isISGrid = {
58
58
  filterPanelInputPlaceholder: 'Síu gildi',
59
59
  // Filter operators text
60
60
  filterOperatorContains: 'inniheldur',
61
- // filterOperatorDoesNotContain: 'does not contain',
61
+ filterOperatorDoesNotContain: 'inniheldur ekki',
62
62
  filterOperatorEquals: 'jafnt og',
63
- // filterOperatorDoesNotEqual: 'does not equal',
64
- filterOperatorStartsWith: 'byrjar með',
65
- filterOperatorEndsWith: 'endar með',
63
+ filterOperatorDoesNotEqual: 'ekki jafnt og',
64
+ filterOperatorStartsWith: 'byrjar á',
65
+ filterOperatorEndsWith: 'endar á',
66
66
  filterOperatorIs: 'er líka með',
67
67
  filterOperatorNot: 'er ekki líka með',
68
68
  filterOperatorAfter: 'eftir',
@@ -80,11 +80,11 @@ const isISGrid = {
80
80
  'filterOperator<=': '<=',
81
81
  // Header filter operators text
82
82
  headerFilterOperatorContains: 'Inniheldur',
83
- // headerFilterOperatorDoesNotContain: 'Does not contain',
83
+ headerFilterOperatorDoesNotContain: 'Inniheldur ekki',
84
84
  headerFilterOperatorEquals: 'Jafnt og',
85
- // headerFilterOperatorDoesNotEqual: 'Does not equal',
86
- headerFilterOperatorStartsWith: 'Byrjar með',
87
- headerFilterOperatorEndsWith: 'Endar með',
85
+ headerFilterOperatorDoesNotEqual: 'Ekki jafnt og',
86
+ headerFilterOperatorStartsWith: 'Byrjar á',
87
+ headerFilterOperatorEndsWith: 'Endar á',
88
88
  headerFilterOperatorIs: 'Er jafnt og',
89
89
  headerFilterOperatorNot: 'Er ekki jafnt og',
90
90
  headerFilterOperatorAfter: 'Eftir',
@@ -93,5 +93,10 @@ function removeOpacity(color) {
93
93
  return setOpacity(color, 1);
94
94
  }
95
95
  function formatFont(font) {
96
+ // Accounts for disabled typography variants
97
+ // See: https://github.com/mui/mui-x/issues/17812
98
+ if (!font) {
99
+ return undefined;
100
+ }
96
101
  return `${font.fontWeight} ${font.fontSize} / ${font.lineHeight} ${font.fontFamily}`;
97
102
  }
@@ -195,6 +195,15 @@ export interface GridColumnHeaderEventLookup {
195
195
  params: GridColumnHeaderParams;
196
196
  event: React.DragEvent<HTMLElement>;
197
197
  };
198
+ /**
199
+ * Fired when the dragging of a column header ends.
200
+ * Same as `columnHeaderDragEnd`, but also fires when the DOM element is unmounted.
201
+ * @ignore - do not document.
202
+ */
203
+ columnHeaderDragEndNative: {
204
+ params: GridColumnHeaderParams;
205
+ event: DragEvent;
206
+ };
198
207
  /**
199
208
  * Fired when a `dblclick` DOM event happens in the column header separator.
200
209
  * @ignore - do not document.
@@ -9,6 +9,7 @@ const CSSVariablesContext = /*#__PURE__*/React.createContext({
9
9
  href: "/unset"
10
10
  })
11
11
  });
12
+ if (process.env.NODE_ENV !== "production") CSSVariablesContext.displayName = "CSSVariablesContext";
12
13
  export function useCSSVariablesClass() {
13
14
  return React.useContext(CSSVariablesContext).className;
14
15
  }
@@ -49,7 +50,7 @@ export function GridCSSVariablesContext(props) {
49
50
  function variablesToString(variables) {
50
51
  let output = '';
51
52
  for (const key in variables) {
52
- if (Object.hasOwn(variables, key)) {
53
+ if (Object.hasOwn(variables, key) && variables[key] !== undefined) {
53
54
  output += `${key}:${variables[key]};`;
54
55
  }
55
56
  }
@@ -83,7 +83,7 @@ const useGridColumnHeaders = props => {
83
83
  (0, _useGridEvent.useGridEvent)(apiRef, 'columnResizeStart', handleColumnResizeStart);
84
84
  (0, _useGridEvent.useGridEvent)(apiRef, 'columnResizeStop', handleColumnResizeStop);
85
85
  (0, _useGridEvent.useGridEvent)(apiRef, 'columnHeaderDragStart', handleColumnReorderStart);
86
- (0, _useGridEvent.useGridEvent)(apiRef, 'columnHeaderDragEnd', handleColumnReorderStop);
86
+ (0, _useGridEvent.useGridEvent)(apiRef, 'columnHeaderDragEndNative', handleColumnReorderStop);
87
87
 
88
88
  // Helper for computation common between getColumnHeaders and getColumnGroupHeaders
89
89
  const getColumnsToRender = params => {
@@ -121,6 +121,7 @@ const useGridColumnHeaders = props => {
121
121
  })]
122
122
  });
123
123
  };
124
+ if (process.env.NODE_ENV !== "production") getFillers.displayName = "getFillers";
124
125
  const getColumnHeaders = (params, other = {}) => {
125
126
  const {
126
127
  renderedColumns,
@@ -189,6 +190,7 @@ const useGridColumnHeaders = props => {
189
190
  })]
190
191
  });
191
192
  };
193
+ if (process.env.NODE_ENV !== "production") getColumnHeadersRow.displayName = "getColumnHeadersRow";
192
194
  const getColumnGroupHeaders = ({
193
195
  depth,
194
196
  params
@@ -68,6 +68,7 @@ const useGridOverlays = () => {
68
68
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Overlay, (0, _extends2.default)({}, overlayProps))
69
69
  }));
70
70
  };
71
+ if (process.env.NODE_ENV !== "production") getOverlay.displayName = "getOverlay";
71
72
  return {
72
73
  getOverlay,
73
74
  overlaysProps
@@ -147,7 +147,7 @@ const useGridPaginationModel = (apiRef, props) => {
147
147
  return;
148
148
  }
149
149
  const dimensions = apiRef.current.getRootDimensions();
150
- const maximumPageSizeWithoutScrollBar = Math.floor(dimensions.viewportInnerSize.height / rowHeight);
150
+ const maximumPageSizeWithoutScrollBar = Math.max(1, Math.floor(dimensions.viewportInnerSize.height / rowHeight));
151
151
  apiRef.current.setPageSize(maximumPageSizeWithoutScrollBar);
152
152
  }, [apiRef, props.autoPageSize, rowHeight]);
153
153
  const handleRowCountChange = React.useCallback(newRowCount => {
@@ -436,7 +436,7 @@ const useGridRowSelection = (apiRef, props) => {
436
436
  const toggleAllRows = React.useCallback(value => {
437
437
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
438
438
  const quickFilterModel = (0, _gridFilterSelector.gridQuickFilterValuesSelector)(apiRef);
439
- const hasFilters = filterModel.items.length > 0 || (quickFilterModel?.length || 0) > 0;
439
+ const hasFilters = filterModel.items.length > 0 || quickFilterModel?.some(val => val.length);
440
440
  if (!props.isRowSelectable && !props.checkboxSelectionVisibleOnly && applyAutoSelection && !hasFilters) {
441
441
  apiRef.current.setRowSelectionModel({
442
442
  type: value ? 'exclude' : 'include',
@@ -8,9 +8,7 @@ exports.GridPrivateApiContext = void 0;
8
8
  exports.useGridPrivateApiContext = useGridPrivateApiContext;
9
9
  var React = _interopRequireWildcard(require("react"));
10
10
  const GridPrivateApiContext = exports.GridPrivateApiContext = /*#__PURE__*/React.createContext(undefined);
11
- if (process.env.NODE_ENV !== 'production') {
12
- GridPrivateApiContext.displayName = 'GridPrivateApiContext';
13
- }
11
+ if (process.env.NODE_ENV !== "production") GridPrivateApiContext.displayName = "GridPrivateApiContext";
14
12
  function useGridPrivateApiContext() {
15
13
  const privateApiRef = React.useContext(GridPrivateApiContext);
16
14
  if (privateApiRef === undefined) {
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v8.3.1
2
+ * @mui/x-data-grid v8.4.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
package/locales/isIS.js CHANGED
@@ -64,11 +64,11 @@ const isISGrid = {
64
64
  filterPanelInputPlaceholder: 'Síu gildi',
65
65
  // Filter operators text
66
66
  filterOperatorContains: 'inniheldur',
67
- // filterOperatorDoesNotContain: 'does not contain',
67
+ filterOperatorDoesNotContain: 'inniheldur ekki',
68
68
  filterOperatorEquals: 'jafnt og',
69
- // filterOperatorDoesNotEqual: 'does not equal',
70
- filterOperatorStartsWith: 'byrjar með',
71
- filterOperatorEndsWith: 'endar með',
69
+ filterOperatorDoesNotEqual: 'ekki jafnt og',
70
+ filterOperatorStartsWith: 'byrjar á',
71
+ filterOperatorEndsWith: 'endar á',
72
72
  filterOperatorIs: 'er líka með',
73
73
  filterOperatorNot: 'er ekki líka með',
74
74
  filterOperatorAfter: 'eftir',
@@ -86,11 +86,11 @@ const isISGrid = {
86
86
  'filterOperator<=': '<=',
87
87
  // Header filter operators text
88
88
  headerFilterOperatorContains: 'Inniheldur',
89
- // headerFilterOperatorDoesNotContain: 'Does not contain',
89
+ headerFilterOperatorDoesNotContain: 'Inniheldur ekki',
90
90
  headerFilterOperatorEquals: 'Jafnt og',
91
- // headerFilterOperatorDoesNotEqual: 'Does not equal',
92
- headerFilterOperatorStartsWith: 'Byrjar með',
93
- headerFilterOperatorEndsWith: 'Endar með',
91
+ headerFilterOperatorDoesNotEqual: 'Ekki jafnt og',
92
+ headerFilterOperatorStartsWith: 'Byrjar á',
93
+ headerFilterOperatorEndsWith: 'Endar á',
94
94
  headerFilterOperatorIs: 'Er jafnt og',
95
95
  headerFilterOperatorNot: 'Er ekki jafnt og',
96
96
  headerFilterOperatorAfter: 'Eftir',
@@ -99,5 +99,10 @@ function removeOpacity(color) {
99
99
  return setOpacity(color, 1);
100
100
  }
101
101
  function formatFont(font) {
102
+ // Accounts for disabled typography variants
103
+ // See: https://github.com/mui/mui-x/issues/17812
104
+ if (!font) {
105
+ return undefined;
106
+ }
102
107
  return `${font.fontWeight} ${font.fontSize} / ${font.lineHeight} ${font.fontFamily}`;
103
108
  }
@@ -195,6 +195,15 @@ export interface GridColumnHeaderEventLookup {
195
195
  params: GridColumnHeaderParams;
196
196
  event: React.DragEvent<HTMLElement>;
197
197
  };
198
+ /**
199
+ * Fired when the dragging of a column header ends.
200
+ * Same as `columnHeaderDragEnd`, but also fires when the DOM element is unmounted.
201
+ * @ignore - do not document.
202
+ */
203
+ columnHeaderDragEndNative: {
204
+ params: GridColumnHeaderParams;
205
+ event: DragEvent;
206
+ };
198
207
  /**
199
208
  * Fired when a `dblclick` DOM event happens in the column header separator.
200
209
  * @ignore - do not document.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid",
3
- "version": "8.3.1",
3
+ "version": "8.4.0",
4
4
  "author": "MUI Team",
5
5
  "description": "The Community plan edition of the MUI X Data Grid components.",
6
6
  "main": "./index.js",
@@ -45,7 +45,7 @@
45
45
  "prop-types": "^15.8.1",
46
46
  "reselect": "^5.1.1",
47
47
  "use-sync-external-store": "^1.5.0",
48
- "@mui/x-internals": "8.3.1"
48
+ "@mui/x-internals": "8.4.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@emotion/react": "^11.9.0",
@@ -19,6 +19,7 @@ const CSSVariablesContext = /*#__PURE__*/React.createContext({
19
19
  href: "/unset"
20
20
  })
21
21
  });
22
+ if (process.env.NODE_ENV !== "production") CSSVariablesContext.displayName = "CSSVariablesContext";
22
23
  function useCSSVariablesClass() {
23
24
  return React.useContext(CSSVariablesContext).className;
24
25
  }
@@ -59,7 +60,7 @@ function GridCSSVariablesContext(props) {
59
60
  function variablesToString(variables) {
60
61
  let output = '';
61
62
  for (const key in variables) {
62
- if (Object.hasOwn(variables, key)) {
63
+ if (Object.hasOwn(variables, key) && variables[key] !== undefined) {
63
64
  output += `${key}:${variables[key]};`;
64
65
  }
65
66
  }