@mui/x-data-grid 8.29.1 → 8.29.3

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 (44) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/components/columnsPanel/ColumnsPanelTrigger.js +2 -2
  3. package/components/columnsPanel/ColumnsPanelTrigger.mjs +2 -2
  4. package/components/containers/GridRootStyles.js +3 -2
  5. package/components/containers/GridRootStyles.mjs +3 -2
  6. package/components/filterPanel/FilterPanelTrigger.js +2 -2
  7. package/components/filterPanel/FilterPanelTrigger.mjs +2 -2
  8. package/components/panel/GridPanelContext.d.mts +9 -3
  9. package/components/panel/GridPanelContext.d.ts +9 -3
  10. package/components/panel/GridPanelContext.js +41 -7
  11. package/components/panel/GridPanelContext.mjs +40 -7
  12. package/components/panel/GridPreferencesPanel.js +4 -6
  13. package/components/panel/GridPreferencesPanel.mjs +4 -6
  14. package/components/toolbar/GridToolbarColumnsButton.js +2 -2
  15. package/components/toolbar/GridToolbarColumnsButton.mjs +2 -2
  16. package/components/toolbar/GridToolbarFilterButton.js +2 -2
  17. package/components/toolbar/GridToolbarFilterButton.mjs +2 -2
  18. package/components/toolbarV8/Toolbar.d.mts +1 -1
  19. package/components/toolbarV8/Toolbar.d.ts +1 -1
  20. package/components/toolbarV8/Toolbar.js +2 -125
  21. package/components/toolbarV8/Toolbar.mjs +2 -125
  22. package/components/toolbarV8/ToolbarButton.d.mts +1 -1
  23. package/components/toolbarV8/ToolbarButton.d.ts +1 -1
  24. package/components/toolbarV8/ToolbarButton.js +11 -50
  25. package/components/toolbarV8/ToolbarButton.mjs +11 -50
  26. package/components/virtualization/GridVirtualScrollbar.js +9 -53
  27. package/components/virtualization/GridVirtualScrollbar.mjs +9 -53
  28. package/components/virtualization/GridVirtualScroller.js +12 -0
  29. package/components/virtualization/GridVirtualScroller.mjs +12 -0
  30. package/hooks/features/columnResize/useGridColumnResize.js +56 -2
  31. package/hooks/features/columnResize/useGridColumnResize.mjs +57 -3
  32. package/hooks/features/rows/gridRowsUtils.js +1 -1
  33. package/hooks/features/rows/gridRowsUtils.mjs +1 -1
  34. package/index.js +1 -1
  35. package/index.mjs +1 -1
  36. package/package.json +3 -3
  37. package/components/toolbarV8/ToolbarContext.d.mts +0 -11
  38. package/components/toolbarV8/ToolbarContext.d.ts +0 -11
  39. package/components/toolbarV8/ToolbarContext.js +0 -19
  40. package/components/toolbarV8/ToolbarContext.mjs +0 -12
  41. package/components/toolbarV8/utils.d.mts +0 -5
  42. package/components/toolbarV8/utils.d.ts +0 -5
  43. package/components/toolbarV8/utils.js +0 -23
  44. package/components/toolbarV8/utils.mjs +0 -17
@@ -16,11 +16,10 @@ var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"
16
16
  var _clsx = _interopRequireDefault(require("clsx"));
17
17
  var _forwardRef = require("@mui/x-internals/forwardRef");
18
18
  var _useComponentRenderer = require("@mui/x-internals/useComponentRenderer");
19
+ var _ToolbarContext = require("@mui/x-internals/ToolbarContext");
19
20
  var _cssVariables = require("../../constants/cssVariables");
20
21
  var _gridClasses = require("../../constants/gridClasses");
21
- var _ToolbarContext = require("./ToolbarContext");
22
22
  var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
23
- var _utils = require("./utils");
24
23
  var _jsxRuntime = require("react/jsx-runtime");
25
24
  const _excluded = ["render", "className"];
26
25
  const useUtilityClasses = ownerState => {
@@ -67,127 +66,6 @@ const Toolbar = exports.Toolbar = (0, _forwardRef.forwardRef)(function Toolbar(p
67
66
  other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
68
67
  const rootProps = (0, _useGridRootProps.useGridRootProps)();
69
68
  const classes = useUtilityClasses(rootProps);
70
- const [focusableItemId, setFocusableItemId] = React.useState(null);
71
- const [items, setItems] = React.useState([]);
72
- const getSortedItems = React.useCallback(() => items.sort(_utils.sortByDocumentPosition), [items]);
73
- const findEnabledItem = React.useCallback((startIndex, step, wrap = true) => {
74
- let index = startIndex;
75
- const sortedItems = getSortedItems();
76
- const itemCount = sortedItems.length;
77
-
78
- // Look for enabled items in the specified direction
79
- for (let i = 0; i < itemCount; i += 1) {
80
- index += step;
81
-
82
- // Handle wrapping around the ends
83
- if (index >= itemCount) {
84
- if (!wrap) {
85
- return -1;
86
- }
87
- index = 0;
88
- } else if (index < 0) {
89
- if (!wrap) {
90
- return -1;
91
- }
92
- index = itemCount - 1;
93
- }
94
-
95
- // Return if we found an enabled item
96
- if (!sortedItems[index].ref.current?.disabled && sortedItems[index].ref.current?.ariaDisabled !== 'true') {
97
- return index;
98
- }
99
- }
100
-
101
- // If we've checked all items and found none enabled
102
- return -1;
103
- }, [getSortedItems]);
104
- const registerItem = React.useCallback((id, itemRef) => {
105
- setItems(prevItems => [...prevItems, {
106
- id,
107
- ref: itemRef
108
- }]);
109
- }, []);
110
- const unregisterItem = React.useCallback(id => {
111
- setItems(prevItems => prevItems.filter(i => i.id !== id));
112
- }, []);
113
- const onItemKeyDown = React.useCallback(event => {
114
- if (!focusableItemId) {
115
- return;
116
- }
117
- const sortedItems = getSortedItems();
118
- const focusableItemIndex = sortedItems.findIndex(item => item.id === focusableItemId);
119
- let newIndex = -1;
120
- if (event.key === 'ArrowRight') {
121
- event.preventDefault();
122
- newIndex = findEnabledItem(focusableItemIndex, 1);
123
- } else if (event.key === 'ArrowLeft') {
124
- event.preventDefault();
125
- newIndex = findEnabledItem(focusableItemIndex, -1);
126
- } else if (event.key === 'Home') {
127
- event.preventDefault();
128
- newIndex = findEnabledItem(-1, 1, false);
129
- } else if (event.key === 'End') {
130
- event.preventDefault();
131
- newIndex = findEnabledItem(sortedItems.length, -1, false);
132
- }
133
-
134
- // TODO: Check why this is necessary
135
- if (newIndex >= 0 && newIndex < sortedItems.length) {
136
- const item = sortedItems[newIndex];
137
- setFocusableItemId(item.id);
138
- item.ref.current?.focus();
139
- }
140
- }, [getSortedItems, focusableItemId, findEnabledItem]);
141
- const onItemFocus = React.useCallback(id => {
142
- if (focusableItemId !== id) {
143
- setFocusableItemId(id);
144
- }
145
- }, [focusableItemId, setFocusableItemId]);
146
- const onItemDisabled = React.useCallback(id => {
147
- const sortedItems = getSortedItems();
148
- const currentIndex = sortedItems.findIndex(item => item.id === id);
149
- const newIndex = findEnabledItem(currentIndex, 1);
150
- if (newIndex >= 0 && newIndex < sortedItems.length) {
151
- const item = sortedItems[newIndex];
152
- setFocusableItemId(item.id);
153
- item.ref.current?.focus();
154
- }
155
- }, [getSortedItems, findEnabledItem]);
156
- React.useEffect(() => {
157
- const sortedItems = getSortedItems();
158
- if (sortedItems.length > 0) {
159
- // Set initial focusable item
160
- if (!focusableItemId) {
161
- setFocusableItemId(sortedItems[0].id);
162
- return;
163
- }
164
- const focusableItemIndex = sortedItems.findIndex(item => item.id === focusableItemId);
165
- if (!sortedItems[focusableItemIndex]) {
166
- // Last item has been removed from the items array
167
- const item = sortedItems[sortedItems.length - 1];
168
- if (item) {
169
- setFocusableItemId(item.id);
170
- item.ref.current?.focus();
171
- }
172
- } else if (focusableItemIndex === -1) {
173
- // Focused item has been removed from the items array
174
- const item = sortedItems[focusableItemIndex];
175
- if (item) {
176
- setFocusableItemId(item.id);
177
- item.ref.current?.focus();
178
- }
179
- }
180
- }
181
- // eslint-disable-next-line react-hooks/exhaustive-deps
182
- }, [getSortedItems, findEnabledItem]);
183
- const contextValue = React.useMemo(() => ({
184
- focusableItemId,
185
- registerItem,
186
- unregisterItem,
187
- onItemKeyDown,
188
- onItemFocus,
189
- onItemDisabled
190
- }), [focusableItemId, registerItem, unregisterItem, onItemKeyDown, onItemFocus, onItemDisabled]);
191
69
  const element = (0, _useComponentRenderer.useComponentRenderer)(ToolbarRoot, render, (0, _extends2.default)({
192
70
  role: 'toolbar',
193
71
  'aria-orientation': 'horizontal',
@@ -196,8 +74,7 @@ const Toolbar = exports.Toolbar = (0, _forwardRef.forwardRef)(function Toolbar(p
196
74
  }, other, {
197
75
  ref
198
76
  }));
199
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ToolbarContext.ToolbarContext.Provider, {
200
- value: contextValue,
77
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ToolbarContext.ToolbarContextProvider, {
201
78
  children: element
202
79
  });
203
80
  });
@@ -10,11 +10,10 @@ import composeClasses from '@mui/utils/composeClasses';
10
10
  import clsx from 'clsx';
11
11
  import { forwardRef } from '@mui/x-internals/forwardRef';
12
12
  import { useComponentRenderer } from '@mui/x-internals/useComponentRenderer';
13
+ import { ToolbarContextProvider } from '@mui/x-internals/ToolbarContext';
13
14
  import { vars } from "../../constants/cssVariables.mjs";
14
15
  import { getDataGridUtilityClass } from "../../constants/gridClasses.mjs";
15
- import { ToolbarContext } from "./ToolbarContext.mjs";
16
16
  import { useGridRootProps } from "../../hooks/utils/useGridRootProps.mjs";
17
- import { sortByDocumentPosition } from "./utils.mjs";
18
17
  import { jsx as _jsx } from "react/jsx-runtime";
19
18
  const useUtilityClasses = ownerState => {
20
19
  const {
@@ -60,127 +59,6 @@ const Toolbar = forwardRef(function Toolbar(props, ref) {
60
59
  other = _objectWithoutPropertiesLoose(props, _excluded);
61
60
  const rootProps = useGridRootProps();
62
61
  const classes = useUtilityClasses(rootProps);
63
- const [focusableItemId, setFocusableItemId] = React.useState(null);
64
- const [items, setItems] = React.useState([]);
65
- const getSortedItems = React.useCallback(() => items.sort(sortByDocumentPosition), [items]);
66
- const findEnabledItem = React.useCallback((startIndex, step, wrap = true) => {
67
- let index = startIndex;
68
- const sortedItems = getSortedItems();
69
- const itemCount = sortedItems.length;
70
-
71
- // Look for enabled items in the specified direction
72
- for (let i = 0; i < itemCount; i += 1) {
73
- index += step;
74
-
75
- // Handle wrapping around the ends
76
- if (index >= itemCount) {
77
- if (!wrap) {
78
- return -1;
79
- }
80
- index = 0;
81
- } else if (index < 0) {
82
- if (!wrap) {
83
- return -1;
84
- }
85
- index = itemCount - 1;
86
- }
87
-
88
- // Return if we found an enabled item
89
- if (!sortedItems[index].ref.current?.disabled && sortedItems[index].ref.current?.ariaDisabled !== 'true') {
90
- return index;
91
- }
92
- }
93
-
94
- // If we've checked all items and found none enabled
95
- return -1;
96
- }, [getSortedItems]);
97
- const registerItem = React.useCallback((id, itemRef) => {
98
- setItems(prevItems => [...prevItems, {
99
- id,
100
- ref: itemRef
101
- }]);
102
- }, []);
103
- const unregisterItem = React.useCallback(id => {
104
- setItems(prevItems => prevItems.filter(i => i.id !== id));
105
- }, []);
106
- const onItemKeyDown = React.useCallback(event => {
107
- if (!focusableItemId) {
108
- return;
109
- }
110
- const sortedItems = getSortedItems();
111
- const focusableItemIndex = sortedItems.findIndex(item => item.id === focusableItemId);
112
- let newIndex = -1;
113
- if (event.key === 'ArrowRight') {
114
- event.preventDefault();
115
- newIndex = findEnabledItem(focusableItemIndex, 1);
116
- } else if (event.key === 'ArrowLeft') {
117
- event.preventDefault();
118
- newIndex = findEnabledItem(focusableItemIndex, -1);
119
- } else if (event.key === 'Home') {
120
- event.preventDefault();
121
- newIndex = findEnabledItem(-1, 1, false);
122
- } else if (event.key === 'End') {
123
- event.preventDefault();
124
- newIndex = findEnabledItem(sortedItems.length, -1, false);
125
- }
126
-
127
- // TODO: Check why this is necessary
128
- if (newIndex >= 0 && newIndex < sortedItems.length) {
129
- const item = sortedItems[newIndex];
130
- setFocusableItemId(item.id);
131
- item.ref.current?.focus();
132
- }
133
- }, [getSortedItems, focusableItemId, findEnabledItem]);
134
- const onItemFocus = React.useCallback(id => {
135
- if (focusableItemId !== id) {
136
- setFocusableItemId(id);
137
- }
138
- }, [focusableItemId, setFocusableItemId]);
139
- const onItemDisabled = React.useCallback(id => {
140
- const sortedItems = getSortedItems();
141
- const currentIndex = sortedItems.findIndex(item => item.id === id);
142
- const newIndex = findEnabledItem(currentIndex, 1);
143
- if (newIndex >= 0 && newIndex < sortedItems.length) {
144
- const item = sortedItems[newIndex];
145
- setFocusableItemId(item.id);
146
- item.ref.current?.focus();
147
- }
148
- }, [getSortedItems, findEnabledItem]);
149
- React.useEffect(() => {
150
- const sortedItems = getSortedItems();
151
- if (sortedItems.length > 0) {
152
- // Set initial focusable item
153
- if (!focusableItemId) {
154
- setFocusableItemId(sortedItems[0].id);
155
- return;
156
- }
157
- const focusableItemIndex = sortedItems.findIndex(item => item.id === focusableItemId);
158
- if (!sortedItems[focusableItemIndex]) {
159
- // Last item has been removed from the items array
160
- const item = sortedItems[sortedItems.length - 1];
161
- if (item) {
162
- setFocusableItemId(item.id);
163
- item.ref.current?.focus();
164
- }
165
- } else if (focusableItemIndex === -1) {
166
- // Focused item has been removed from the items array
167
- const item = sortedItems[focusableItemIndex];
168
- if (item) {
169
- setFocusableItemId(item.id);
170
- item.ref.current?.focus();
171
- }
172
- }
173
- }
174
- // eslint-disable-next-line react-hooks/exhaustive-deps
175
- }, [getSortedItems, findEnabledItem]);
176
- const contextValue = React.useMemo(() => ({
177
- focusableItemId,
178
- registerItem,
179
- unregisterItem,
180
- onItemKeyDown,
181
- onItemFocus,
182
- onItemDisabled
183
- }), [focusableItemId, registerItem, unregisterItem, onItemKeyDown, onItemFocus, onItemDisabled]);
184
62
  const element = useComponentRenderer(ToolbarRoot, render, _extends({
185
63
  role: 'toolbar',
186
64
  'aria-orientation': 'horizontal',
@@ -189,8 +67,7 @@ const Toolbar = forwardRef(function Toolbar(props, ref) {
189
67
  }, other, {
190
68
  ref
191
69
  }));
192
- return /*#__PURE__*/_jsx(ToolbarContext.Provider, {
193
- value: contextValue,
70
+ return /*#__PURE__*/_jsx(ToolbarContextProvider, {
194
71
  children: element
195
72
  });
196
73
  });
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { type RenderProp } from '@mui/x-internals/useComponentRenderer';
2
+ import type { RenderProp } from '@mui/x-internals/useComponentRenderer';
3
3
  import type { GridSlotProps } from "../../models/index.mjs";
4
4
  export type ToolbarButtonProps = GridSlotProps['baseIconButton'] & {
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { type RenderProp } from '@mui/x-internals/useComponentRenderer';
2
+ import type { RenderProp } from '@mui/x-internals/useComponentRenderer';
3
3
  import type { GridSlotProps } from "../../models/index.js";
4
4
  export type ToolbarButtonProps = GridSlotProps['baseIconButton'] & {
5
5
  /**
@@ -12,13 +12,13 @@ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runt
12
12
  var React = _interopRequireWildcard(require("react"));
13
13
  var _propTypes = _interopRequireDefault(require("prop-types"));
14
14
  var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
15
- var _useId = _interopRequireDefault(require("@mui/utils/useId"));
16
15
  var _forwardRef = require("@mui/x-internals/forwardRef");
17
16
  var _useComponentRenderer = require("@mui/x-internals/useComponentRenderer");
17
+ var _ToolbarContext = require("@mui/x-internals/ToolbarContext");
18
18
  var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
19
- var _ToolbarContext = require("./ToolbarContext");
20
19
  var _jsxRuntime = require("react/jsx-runtime");
21
- const _excluded = ["render", "onKeyDown", "onFocus", "disabled", "aria-disabled"];
20
+ const _excluded = ["render", "onKeyDown", "onFocus", "onBlur", "disabled", "aria-disabled"],
21
+ _excluded2 = ["tabIndex"];
22
22
  /**
23
23
  * A button for performing actions from the toolbar.
24
24
  * It renders the `baseIconButton` slot.
@@ -33,59 +33,20 @@ const _excluded = ["render", "onKeyDown", "onFocus", "disabled", "aria-disabled"
33
33
  */
34
34
  const ToolbarButton = exports.ToolbarButton = (0, _forwardRef.forwardRef)(function ToolbarButton(props, ref) {
35
35
  const {
36
- render,
37
- onKeyDown,
38
- onFocus,
39
- disabled,
40
- 'aria-disabled': ariaDisabled
36
+ render
41
37
  } = props,
42
38
  other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
43
- const id = (0, _useId.default)();
44
39
  const rootProps = (0, _useGridRootProps.useGridRootProps)();
45
40
  const buttonRef = React.useRef(null);
46
41
  const handleRef = (0, _useForkRef.default)(buttonRef, ref);
47
- const {
48
- focusableItemId,
49
- registerItem,
50
- unregisterItem,
51
- onItemKeyDown,
52
- onItemFocus,
53
- onItemDisabled
54
- } = (0, _ToolbarContext.useToolbarContext)();
55
- const handleKeyDown = event => {
56
- onItemKeyDown(event);
57
- onKeyDown?.(event);
58
- };
59
- const handleFocus = event => {
60
- onItemFocus(id);
61
- onFocus?.(event);
62
- };
63
- React.useEffect(() => {
64
- registerItem(id, buttonRef);
65
- return () => unregisterItem(id);
66
- // eslint-disable-next-line react-hooks/exhaustive-deps
67
- }, []);
68
- const previousDisabled = React.useRef(disabled);
69
- React.useEffect(() => {
70
- if (previousDisabled.current !== disabled && disabled === true) {
71
- onItemDisabled(id, disabled);
72
- }
73
- previousDisabled.current = disabled;
74
- }, [disabled, id, onItemDisabled]);
75
- const previousAriaDisabled = React.useRef(ariaDisabled);
76
- React.useEffect(() => {
77
- if (previousAriaDisabled.current !== ariaDisabled && ariaDisabled === true) {
78
- onItemDisabled(id, true);
79
- }
80
- previousAriaDisabled.current = ariaDisabled;
81
- }, [ariaDisabled, id, onItemDisabled]);
42
+ const _useRegisterToolbarBu = (0, _ToolbarContext.useRegisterToolbarButton)(props, buttonRef),
43
+ {
44
+ tabIndex
45
+ } = _useRegisterToolbarBu,
46
+ toolbarButtonProps = (0, _objectWithoutPropertiesLoose2.default)(_useRegisterToolbarBu, _excluded2);
82
47
  const element = (0, _useComponentRenderer.useComponentRenderer)(rootProps.slots.baseIconButton, render, (0, _extends2.default)({}, rootProps.slotProps?.baseIconButton, {
83
- tabIndex: focusableItemId === id ? 0 : -1
84
- }, other, {
85
- disabled,
86
- 'aria-disabled': ariaDisabled,
87
- onKeyDown: handleKeyDown,
88
- onFocus: handleFocus,
48
+ tabIndex
49
+ }, other, toolbarButtonProps, {
89
50
  ref: handleRef
90
51
  }));
91
52
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(React.Fragment, {
@@ -2,15 +2,15 @@
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
- const _excluded = ["render", "onKeyDown", "onFocus", "disabled", "aria-disabled"];
5
+ const _excluded = ["render", "onKeyDown", "onFocus", "onBlur", "disabled", "aria-disabled"],
6
+ _excluded2 = ["tabIndex"];
6
7
  import * as React from 'react';
7
8
  import PropTypes from 'prop-types';
8
9
  import useForkRef from '@mui/utils/useForkRef';
9
- import useId from '@mui/utils/useId';
10
10
  import { forwardRef } from '@mui/x-internals/forwardRef';
11
11
  import { useComponentRenderer } from '@mui/x-internals/useComponentRenderer';
12
+ import { useRegisterToolbarButton } from '@mui/x-internals/ToolbarContext';
12
13
  import { useGridRootProps } from "../../hooks/utils/useGridRootProps.mjs";
13
- import { useToolbarContext } from "./ToolbarContext.mjs";
14
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
15
  /**
16
16
  * A button for performing actions from the toolbar.
@@ -26,59 +26,20 @@ import { jsx as _jsx } from "react/jsx-runtime";
26
26
  */
27
27
  const ToolbarButton = forwardRef(function ToolbarButton(props, ref) {
28
28
  const {
29
- render,
30
- onKeyDown,
31
- onFocus,
32
- disabled,
33
- 'aria-disabled': ariaDisabled
29
+ render
34
30
  } = props,
35
31
  other = _objectWithoutPropertiesLoose(props, _excluded);
36
- const id = useId();
37
32
  const rootProps = useGridRootProps();
38
33
  const buttonRef = React.useRef(null);
39
34
  const handleRef = useForkRef(buttonRef, ref);
40
- const {
41
- focusableItemId,
42
- registerItem,
43
- unregisterItem,
44
- onItemKeyDown,
45
- onItemFocus,
46
- onItemDisabled
47
- } = useToolbarContext();
48
- const handleKeyDown = event => {
49
- onItemKeyDown(event);
50
- onKeyDown?.(event);
51
- };
52
- const handleFocus = event => {
53
- onItemFocus(id);
54
- onFocus?.(event);
55
- };
56
- React.useEffect(() => {
57
- registerItem(id, buttonRef);
58
- return () => unregisterItem(id);
59
- // eslint-disable-next-line react-hooks/exhaustive-deps
60
- }, []);
61
- const previousDisabled = React.useRef(disabled);
62
- React.useEffect(() => {
63
- if (previousDisabled.current !== disabled && disabled === true) {
64
- onItemDisabled(id, disabled);
65
- }
66
- previousDisabled.current = disabled;
67
- }, [disabled, id, onItemDisabled]);
68
- const previousAriaDisabled = React.useRef(ariaDisabled);
69
- React.useEffect(() => {
70
- if (previousAriaDisabled.current !== ariaDisabled && ariaDisabled === true) {
71
- onItemDisabled(id, true);
72
- }
73
- previousAriaDisabled.current = ariaDisabled;
74
- }, [ariaDisabled, id, onItemDisabled]);
35
+ const _useRegisterToolbarBu = useRegisterToolbarButton(props, buttonRef),
36
+ {
37
+ tabIndex
38
+ } = _useRegisterToolbarBu,
39
+ toolbarButtonProps = _objectWithoutPropertiesLoose(_useRegisterToolbarBu, _excluded2);
75
40
  const element = useComponentRenderer(rootProps.slots.baseIconButton, render, _extends({}, rootProps.slotProps?.baseIconButton, {
76
- tabIndex: focusableItemId === id ? 0 : -1
77
- }, other, {
78
- disabled,
79
- 'aria-disabled': ariaDisabled,
80
- onKeyDown: handleKeyDown,
81
- onFocus: handleFocus,
41
+ tabIndex
42
+ }, other, toolbarButtonProps, {
82
43
  ref: handleRef
83
44
  }));
84
45
  return /*#__PURE__*/_jsx(React.Fragment, {
@@ -9,11 +9,9 @@ Object.defineProperty(exports, "__esModule", {
9
9
  exports.scrollbarSizeCssExpression = exports.ScrollbarCorner = exports.GridVirtualScrollbar = void 0;
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
  var _styles = require("@mui/material/styles");
12
- var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
13
- var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
14
12
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
15
13
  var _forwardRef = require("@mui/x-internals/forwardRef");
16
- var _useOnMount = require("../../hooks/utils/useOnMount");
14
+ var _platform = require("@mui/x-internals/platform");
17
15
  var _useGridPrivateApiContext = require("../../hooks/utils/useGridPrivateApiContext");
18
16
  var _hooks = require("../../hooks");
19
17
  var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
@@ -45,7 +43,13 @@ const Scrollbar = (0, _styles.styled)('div', {
45
43
  '&:hover': {
46
44
  zIndex: 70
47
45
  },
48
- '--size': scrollbarSizeCssExpression
46
+ '--size': scrollbarSizeCssExpression,
47
+ // [iOS-scrollbar-swap]
48
+ // On iOS, native scrollbars of the `GridVirtualScroller` are shown instead,
49
+ // so hide these to avoid a duplicate thumb.
50
+ [_platform.iOSMediaQuery]: {
51
+ display: 'none'
52
+ }
49
53
  });
50
54
  const ScrollbarVertical = (0, _styles.styled)(Scrollbar, {
51
55
  slot: 'internal'
@@ -91,64 +95,16 @@ const ScrollbarCorner = exports.ScrollbarCorner = (0, _styles.styled)(Scrollbar,
91
95
  const GridVirtualScrollbar = exports.GridVirtualScrollbar = (0, _forwardRef.forwardRef)(function GridVirtualScrollbar(props, ref) {
92
96
  const apiRef = (0, _useGridPrivateApiContext.useGridPrivateApiContext)();
93
97
  const rootProps = (0, _useGridRootProps.useGridRootProps)();
94
- const isLocked = React.useRef(false);
95
- const lastPosition = React.useRef(0);
96
- const scrollbarRef = React.useRef(null);
97
98
  const classes = useUtilityClasses(rootProps, props.position);
98
99
  const dimensions = (0, _hooks.useGridSelector)(apiRef, _hooks.gridDimensionsSelector);
99
100
  const propertyDimension = props.position === 'vertical' ? 'height' : 'width';
100
- const propertyScroll = props.position === 'vertical' ? 'scrollTop' : 'scrollLeft';
101
- const propertyScrollPosition = props.position === 'vertical' ? 'top' : 'left';
102
101
  const scrollbarInnerSize = props.position === 'horizontal' ? dimensions.minimumSize.width : dimensions.minimumSize.height - dimensions.headersTotalHeight;
103
- const onScrollerScroll = (0, _useEventCallback.default)(() => {
104
- const scrollbar = scrollbarRef.current;
105
- const scrollPosition = props.scrollPosition.current;
106
- if (!scrollbar) {
107
- return;
108
- }
109
- if (scrollPosition[propertyScrollPosition] === lastPosition.current) {
110
- return;
111
- }
112
- lastPosition.current = scrollPosition[propertyScrollPosition];
113
- if (isLocked.current) {
114
- isLocked.current = false;
115
- return;
116
- }
117
- isLocked.current = true;
118
- scrollbar[propertyScroll] = props.scrollPosition.current[propertyScrollPosition];
119
- });
120
- const onScrollbarScroll = (0, _useEventCallback.default)(() => {
121
- const scroller = apiRef.current.virtualScrollerRef.current;
122
- const scrollbar = scrollbarRef.current;
123
- if (!scrollbar) {
124
- return;
125
- }
126
- if (isLocked.current) {
127
- isLocked.current = false;
128
- return;
129
- }
130
- isLocked.current = true;
131
- scroller[propertyScroll] = scrollbar[propertyScroll];
132
- });
133
- (0, _useOnMount.useOnMount)(() => {
134
- const scroller = apiRef.current.virtualScrollerRef.current;
135
- const scrollbar = scrollbarRef.current;
136
- const options = {
137
- passive: true
138
- };
139
- scroller.addEventListener('scroll', onScrollerScroll, options);
140
- scrollbar.addEventListener('scroll', onScrollbarScroll, options);
141
- return () => {
142
- scroller.removeEventListener('scroll', onScrollerScroll, options);
143
- scrollbar.removeEventListener('scroll', onScrollbarScroll, options);
144
- };
145
- });
146
102
  const Container = props.position === 'vertical' ? ScrollbarVertical : ScrollbarHorizontal;
147
103
  const scrollbarInnerStyle = React.useMemo(() => ({
148
104
  [propertyDimension]: `${scrollbarInnerSize}px`
149
105
  }), [propertyDimension, scrollbarInnerSize]);
150
106
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Container, {
151
- ref: (0, _useForkRef.default)(ref, scrollbarRef),
107
+ ref: ref,
152
108
  className: classes.root,
153
109
  tabIndex: -1,
154
110
  "aria-hidden": "true"
@@ -2,11 +2,9 @@
2
2
 
3
3
  import * as React from 'react';
4
4
  import { styled } from '@mui/material/styles';
5
- import useEventCallback from '@mui/utils/useEventCallback';
6
- import useForkRef from '@mui/utils/useForkRef';
7
5
  import composeClasses from '@mui/utils/composeClasses';
8
6
  import { forwardRef } from '@mui/x-internals/forwardRef';
9
- import { useOnMount } from "../../hooks/utils/useOnMount.mjs";
7
+ import { iOSMediaQuery } from '@mui/x-internals/platform';
10
8
  import { useGridPrivateApiContext } from "../../hooks/utils/useGridPrivateApiContext.mjs";
11
9
  import { gridDimensionsSelector, useGridSelector } from "../../hooks/index.mjs";
12
10
  import { useGridRootProps } from "../../hooks/utils/useGridRootProps.mjs";
@@ -38,7 +36,13 @@ const Scrollbar = styled('div', {
38
36
  '&:hover': {
39
37
  zIndex: 70
40
38
  },
41
- '--size': scrollbarSizeCssExpression
39
+ '--size': scrollbarSizeCssExpression,
40
+ // [iOS-scrollbar-swap]
41
+ // On iOS, native scrollbars of the `GridVirtualScroller` are shown instead,
42
+ // so hide these to avoid a duplicate thumb.
43
+ [iOSMediaQuery]: {
44
+ display: 'none'
45
+ }
42
46
  });
43
47
  const ScrollbarVertical = styled(Scrollbar, {
44
48
  slot: 'internal'
@@ -84,64 +88,16 @@ export const ScrollbarCorner = styled(Scrollbar, {
84
88
  const GridVirtualScrollbar = forwardRef(function GridVirtualScrollbar(props, ref) {
85
89
  const apiRef = useGridPrivateApiContext();
86
90
  const rootProps = useGridRootProps();
87
- const isLocked = React.useRef(false);
88
- const lastPosition = React.useRef(0);
89
- const scrollbarRef = React.useRef(null);
90
91
  const classes = useUtilityClasses(rootProps, props.position);
91
92
  const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
92
93
  const propertyDimension = props.position === 'vertical' ? 'height' : 'width';
93
- const propertyScroll = props.position === 'vertical' ? 'scrollTop' : 'scrollLeft';
94
- const propertyScrollPosition = props.position === 'vertical' ? 'top' : 'left';
95
94
  const scrollbarInnerSize = props.position === 'horizontal' ? dimensions.minimumSize.width : dimensions.minimumSize.height - dimensions.headersTotalHeight;
96
- const onScrollerScroll = useEventCallback(() => {
97
- const scrollbar = scrollbarRef.current;
98
- const scrollPosition = props.scrollPosition.current;
99
- if (!scrollbar) {
100
- return;
101
- }
102
- if (scrollPosition[propertyScrollPosition] === lastPosition.current) {
103
- return;
104
- }
105
- lastPosition.current = scrollPosition[propertyScrollPosition];
106
- if (isLocked.current) {
107
- isLocked.current = false;
108
- return;
109
- }
110
- isLocked.current = true;
111
- scrollbar[propertyScroll] = props.scrollPosition.current[propertyScrollPosition];
112
- });
113
- const onScrollbarScroll = useEventCallback(() => {
114
- const scroller = apiRef.current.virtualScrollerRef.current;
115
- const scrollbar = scrollbarRef.current;
116
- if (!scrollbar) {
117
- return;
118
- }
119
- if (isLocked.current) {
120
- isLocked.current = false;
121
- return;
122
- }
123
- isLocked.current = true;
124
- scroller[propertyScroll] = scrollbar[propertyScroll];
125
- });
126
- useOnMount(() => {
127
- const scroller = apiRef.current.virtualScrollerRef.current;
128
- const scrollbar = scrollbarRef.current;
129
- const options = {
130
- passive: true
131
- };
132
- scroller.addEventListener('scroll', onScrollerScroll, options);
133
- scrollbar.addEventListener('scroll', onScrollbarScroll, options);
134
- return () => {
135
- scroller.removeEventListener('scroll', onScrollerScroll, options);
136
- scrollbar.removeEventListener('scroll', onScrollbarScroll, options);
137
- };
138
- });
139
95
  const Container = props.position === 'vertical' ? ScrollbarVertical : ScrollbarHorizontal;
140
96
  const scrollbarInnerStyle = React.useMemo(() => ({
141
97
  [propertyDimension]: `${scrollbarInnerSize}px`
142
98
  }), [propertyDimension, scrollbarInnerSize]);
143
99
  return /*#__PURE__*/_jsx(Container, {
144
- ref: useForkRef(ref, scrollbarRef),
100
+ ref: ref,
145
101
  className: classes.root,
146
102
  tabIndex: -1,
147
103
  "aria-hidden": "true"