@mui/material 9.0.0-beta.0 → 9.0.0-beta.1

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 (138) hide show
  1. package/Accordion/Accordion.d.mts +1 -1
  2. package/Accordion/Accordion.d.ts +1 -1
  3. package/AccordionSummary/AccordionSummary.js +1 -0
  4. package/AccordionSummary/AccordionSummary.mjs +1 -0
  5. package/Backdrop/Backdrop.d.mts +1 -1
  6. package/Backdrop/Backdrop.d.ts +1 -1
  7. package/BottomNavigationAction/BottomNavigationAction.js +1 -0
  8. package/BottomNavigationAction/BottomNavigationAction.mjs +1 -0
  9. package/Breadcrumbs/BreadcrumbCollapsed.js +5 -1
  10. package/Breadcrumbs/BreadcrumbCollapsed.mjs +5 -1
  11. package/Button/Button.js +1 -0
  12. package/Button/Button.mjs +1 -0
  13. package/ButtonBase/ButtonBase.d.mts +5 -0
  14. package/ButtonBase/ButtonBase.d.ts +5 -0
  15. package/ButtonBase/ButtonBase.js +84 -85
  16. package/ButtonBase/ButtonBase.mjs +84 -85
  17. package/ButtonBase/useButtonBase.d.mts +91 -0
  18. package/ButtonBase/useButtonBase.d.ts +91 -0
  19. package/ButtonBase/useButtonBase.js +174 -0
  20. package/ButtonBase/useButtonBase.mjs +167 -0
  21. package/CHANGELOG.md +48 -0
  22. package/CardActionArea/CardActionArea.js +1 -0
  23. package/CardActionArea/CardActionArea.mjs +1 -0
  24. package/Chip/Chip.d.mts +7 -0
  25. package/Chip/Chip.d.ts +7 -0
  26. package/Chip/Chip.js +18 -1
  27. package/Chip/Chip.mjs +18 -1
  28. package/Dialog/Dialog.d.mts +8 -1
  29. package/Dialog/Dialog.d.ts +8 -1
  30. package/Dialog/Dialog.js +9 -1
  31. package/Dialog/Dialog.mjs +9 -1
  32. package/Divider/Divider.js +0 -8
  33. package/Divider/Divider.mjs +0 -8
  34. package/Drawer/Drawer.d.mts +1 -1
  35. package/Drawer/Drawer.d.ts +1 -1
  36. package/Fab/Fab.js +1 -0
  37. package/Fab/Fab.mjs +1 -0
  38. package/FilledInput/FilledInput.js +1 -1
  39. package/FilledInput/FilledInput.mjs +1 -1
  40. package/Grid/Grid.d.mts +8 -3
  41. package/Grid/Grid.d.ts +8 -3
  42. package/Grid/Grid.js +8 -3
  43. package/Grid/Grid.mjs +8 -3
  44. package/Grid/gridClasses.js +1 -1
  45. package/Grid/gridClasses.mjs +1 -1
  46. package/IconButton/IconButton.js +1 -0
  47. package/IconButton/IconButton.mjs +1 -0
  48. package/Input/Input.js +1 -1
  49. package/Input/Input.mjs +1 -1
  50. package/InputAdornment/inputAdornmentClasses.d.mts +2 -2
  51. package/InputAdornment/inputAdornmentClasses.d.ts +2 -2
  52. package/ListItemButton/ListItemButton.js +1 -0
  53. package/ListItemButton/ListItemButton.mjs +1 -0
  54. package/ListItemIcon/ListItemIcon.js +1 -1
  55. package/ListItemIcon/ListItemIcon.mjs +1 -1
  56. package/ListSubheader/ListSubheader.js +0 -3
  57. package/ListSubheader/ListSubheader.mjs +0 -3
  58. package/Menu/Menu.d.mts +1 -1
  59. package/Menu/Menu.d.ts +1 -1
  60. package/Menu/Menu.js +15 -32
  61. package/Menu/Menu.mjs +15 -32
  62. package/MenuItem/MenuItem.js +36 -26
  63. package/MenuItem/MenuItem.mjs +34 -26
  64. package/MenuList/MenuList.js +136 -101
  65. package/MenuList/MenuList.mjs +135 -100
  66. package/MenuList/MenuListContext.d.mts +11 -0
  67. package/MenuList/MenuListContext.d.ts +11 -0
  68. package/MenuList/MenuListContext.js +25 -0
  69. package/MenuList/MenuListContext.mjs +19 -0
  70. package/PaginationItem/PaginationItem.d.mts +5 -0
  71. package/PaginationItem/PaginationItem.d.ts +5 -0
  72. package/PaginationItem/PaginationItem.js +6 -0
  73. package/PaginationItem/PaginationItem.mjs +6 -0
  74. package/PigmentGrid/PigmentGrid.d.mts +1 -1
  75. package/PigmentGrid/PigmentGrid.d.ts +1 -1
  76. package/PigmentGrid/PigmentGrid.js +1 -1
  77. package/PigmentGrid/PigmentGrid.mjs +1 -1
  78. package/Popover/Popover.d.mts +1 -1
  79. package/Popover/Popover.d.ts +1 -1
  80. package/Popover/Popover.js +19 -7
  81. package/Popover/Popover.mjs +18 -6
  82. package/Snackbar/Snackbar.d.mts +1 -1
  83. package/Snackbar/Snackbar.d.ts +1 -1
  84. package/SpeedDial/SpeedDial.d.mts +1 -1
  85. package/SpeedDial/SpeedDial.d.ts +1 -1
  86. package/StepButton/StepButton.js +44 -14
  87. package/StepButton/StepButton.mjs +44 -14
  88. package/StepContent/StepContent.d.mts +1 -1
  89. package/StepContent/StepContent.d.ts +1 -1
  90. package/Stepper/Stepper.js +54 -22
  91. package/Stepper/Stepper.mjs +54 -22
  92. package/Stepper/StepperContext.d.mts +0 -5
  93. package/Stepper/StepperContext.d.ts +0 -5
  94. package/Stepper/StepperContext.js +1 -2
  95. package/Stepper/StepperContext.mjs +0 -1
  96. package/Tab/Tab.js +17 -1
  97. package/Tab/Tab.mjs +17 -1
  98. package/TabScrollButton/TabScrollButton.d.mts +1 -1
  99. package/TabScrollButton/TabScrollButton.d.ts +1 -1
  100. package/TabScrollButton/TabScrollButton.js +6 -2
  101. package/TabScrollButton/TabScrollButton.mjs +6 -2
  102. package/TableSortLabel/TableSortLabel.js +4 -1
  103. package/TableSortLabel/TableSortLabel.mjs +4 -1
  104. package/Tabs/Tabs.js +30 -21
  105. package/Tabs/Tabs.mjs +29 -20
  106. package/ToggleButton/ToggleButton.js +1 -0
  107. package/ToggleButton/ToggleButton.mjs +1 -0
  108. package/Tooltip/Tooltip.d.mts +1 -1
  109. package/Tooltip/Tooltip.d.ts +1 -1
  110. package/index.js +1 -1
  111. package/index.mjs +1 -1
  112. package/internal/SwitchBase.d.mts +2 -2
  113. package/internal/SwitchBase.d.ts +2 -2
  114. package/internal/SwitchBase.js +5 -1
  115. package/internal/SwitchBase.mjs +5 -1
  116. package/locale/psAF.js +1 -1
  117. package/locale/psAF.mjs +1 -1
  118. package/package.json +5 -5
  119. package/styles/createThemeWithVars.js +9 -9
  120. package/styles/createThemeWithVars.mjs +9 -9
  121. package/useAutocomplete/useAutocomplete.js +8 -0
  122. package/useAutocomplete/useAutocomplete.mjs +8 -0
  123. package/utils/focusWithVisible.js +24 -0
  124. package/utils/focusWithVisible.mjs +19 -0
  125. package/utils/index.d.mts +0 -1
  126. package/utils/index.d.ts +0 -1
  127. package/utils/index.js +0 -7
  128. package/utils/index.mjs +0 -1
  129. package/utils/useFocusableWhenDisabled.d.mts +30 -0
  130. package/utils/useFocusableWhenDisabled.d.ts +30 -0
  131. package/utils/useFocusableWhenDisabled.js +47 -0
  132. package/utils/useFocusableWhenDisabled.mjs +41 -0
  133. package/utils/useRovingTabIndex.d.mts +1 -2
  134. package/utils/useRovingTabIndex.d.ts +1 -2
  135. package/utils/useRovingTabIndex.js +25 -4
  136. package/utils/useRovingTabIndex.mjs +1 -2
  137. package/version/index.js +2 -2
  138. package/version/index.mjs +2 -2
package/Menu/Menu.js CHANGED
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "__esModule", {
8
8
  });
9
9
  exports.default = exports.MenuPaper = void 0;
10
10
  var React = _interopRequireWildcard(require("react"));
11
- var _reactIs = require("react-is");
12
11
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
12
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
14
13
  var _HTMLElementType = _interopRequireDefault(require("@mui/utils/HTMLElementType"));
@@ -92,13 +91,17 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
92
91
  variant
93
92
  };
94
93
  const classes = useUtilityClasses(ownerState);
95
- const autoFocusItem = autoFocus && !disableAutoFocusItem && open;
94
+ const shouldManageInitialFocus = autoFocus && open; // `&& open` prevents a Menu with `keepMounted={true}` from accidentally stealing focus
95
+ const shouldAutoFocusActiveItem = shouldManageInitialFocus && !disableAutoFocusItem;
96
96
  const menuListActionsRef = React.useRef(null);
97
97
  const handleEntering = (element, _isAppearing) => {
98
98
  if (menuListActionsRef.current) {
99
99
  menuListActionsRef.current.adjustStyleForScrollbar(element, {
100
100
  direction: isRtl ? 'rtl' : 'ltr'
101
101
  });
102
+ if (shouldManageInitialFocus) {
103
+ menuListActionsRef.current.focusInitialTarget?.();
104
+ }
102
105
  }
103
106
  };
104
107
  const handleListKeyDown = event => {
@@ -109,33 +112,6 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
109
112
  }
110
113
  }
111
114
  };
112
-
113
- /**
114
- * the index of the item should receive focus
115
- * in a `variant="selectedMenu"` it's the first `selected` item
116
- * otherwise it's the very first item.
117
- */
118
- let activeItemIndex = -1;
119
- // since we inject focus related props into children we have to do a lookahead
120
- // to check if there is a `selected` item. We're looking for the last `selected`
121
- // item and use the first valid item as a fallback
122
- React.Children.map(children, (child, index) => {
123
- if (! /*#__PURE__*/React.isValidElement(child)) {
124
- return;
125
- }
126
- if (process.env.NODE_ENV !== 'production') {
127
- if ((0, _reactIs.isFragment)(child)) {
128
- console.error(["MUI: The Menu component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
129
- }
130
- }
131
- if (!child.props.disabled) {
132
- if (variant === 'selectedMenu' && child.props.selected) {
133
- activeItemIndex = index;
134
- } else if (activeItemIndex === -1) {
135
- activeItemIndex = index;
136
- }
137
- }
138
- });
139
115
  const externalForwardedProps = {
140
116
  slots,
141
117
  slotProps
@@ -168,7 +144,14 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
168
144
  ownerState
169
145
  });
170
146
  const resolvedTransitionProps = typeof slotProps.transition === 'function' ? slotProps.transition(ownerState) : slotProps.transition;
171
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(MenuRoot, {
147
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(MenuRoot
148
+ // `disableAutoFocus={autoFocus}` is NOT a mistake
149
+ // - `autoFocus` means `Menu` will control focus and move it into `MenuList` or an active `MenuItem`
150
+ // - `disableAutoFocus` means disable `MenuRoot`s underlying `Popover`'s autoFocus handling
151
+ // This prevents `MenuList` and `Popover` from fighting each other to control focus.
152
+ // (This has nothing to do with DOM `autoFocus`)
153
+ , {
154
+ disableAutoFocus: autoFocus,
172
155
  onClose: onClose,
173
156
  anchorOrigin: {
174
157
  vertical: 'bottom',
@@ -201,8 +184,8 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
201
184
  classes: PopoverClasses,
202
185
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ListSlot, {
203
186
  actions: menuListActionsRef,
204
- autoFocus: autoFocus && (activeItemIndex === -1 || disableAutoFocusItem),
205
- autoFocusItem: autoFocusItem,
187
+ autoFocus: shouldManageInitialFocus,
188
+ autoFocusItem: shouldAutoFocusActiveItem,
206
189
  variant: variant,
207
190
  ...listSlotProps,
208
191
  children: children
package/Menu/Menu.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import * as React from 'react';
4
- import { isFragment } from 'react-is';
5
4
  import PropTypes from 'prop-types';
6
5
  import composeClasses from '@mui/utils/composeClasses';
7
6
  import HTMLElementType from '@mui/utils/HTMLElementType';
@@ -85,13 +84,17 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
85
84
  variant
86
85
  };
87
86
  const classes = useUtilityClasses(ownerState);
88
- const autoFocusItem = autoFocus && !disableAutoFocusItem && open;
87
+ const shouldManageInitialFocus = autoFocus && open; // `&& open` prevents a Menu with `keepMounted={true}` from accidentally stealing focus
88
+ const shouldAutoFocusActiveItem = shouldManageInitialFocus && !disableAutoFocusItem;
89
89
  const menuListActionsRef = React.useRef(null);
90
90
  const handleEntering = (element, _isAppearing) => {
91
91
  if (menuListActionsRef.current) {
92
92
  menuListActionsRef.current.adjustStyleForScrollbar(element, {
93
93
  direction: isRtl ? 'rtl' : 'ltr'
94
94
  });
95
+ if (shouldManageInitialFocus) {
96
+ menuListActionsRef.current.focusInitialTarget?.();
97
+ }
95
98
  }
96
99
  };
97
100
  const handleListKeyDown = event => {
@@ -102,33 +105,6 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
102
105
  }
103
106
  }
104
107
  };
105
-
106
- /**
107
- * the index of the item should receive focus
108
- * in a `variant="selectedMenu"` it's the first `selected` item
109
- * otherwise it's the very first item.
110
- */
111
- let activeItemIndex = -1;
112
- // since we inject focus related props into children we have to do a lookahead
113
- // to check if there is a `selected` item. We're looking for the last `selected`
114
- // item and use the first valid item as a fallback
115
- React.Children.map(children, (child, index) => {
116
- if (! /*#__PURE__*/React.isValidElement(child)) {
117
- return;
118
- }
119
- if (process.env.NODE_ENV !== 'production') {
120
- if (isFragment(child)) {
121
- console.error(["MUI: The Menu component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
122
- }
123
- }
124
- if (!child.props.disabled) {
125
- if (variant === 'selectedMenu' && child.props.selected) {
126
- activeItemIndex = index;
127
- } else if (activeItemIndex === -1) {
128
- activeItemIndex = index;
129
- }
130
- }
131
- });
132
108
  const externalForwardedProps = {
133
109
  slots,
134
110
  slotProps
@@ -161,7 +137,14 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
161
137
  ownerState
162
138
  });
163
139
  const resolvedTransitionProps = typeof slotProps.transition === 'function' ? slotProps.transition(ownerState) : slotProps.transition;
164
- return /*#__PURE__*/_jsx(MenuRoot, {
140
+ return /*#__PURE__*/_jsx(MenuRoot
141
+ // `disableAutoFocus={autoFocus}` is NOT a mistake
142
+ // - `autoFocus` means `Menu` will control focus and move it into `MenuList` or an active `MenuItem`
143
+ // - `disableAutoFocus` means disable `MenuRoot`s underlying `Popover`'s autoFocus handling
144
+ // This prevents `MenuList` and `Popover` from fighting each other to control focus.
145
+ // (This has nothing to do with DOM `autoFocus`)
146
+ , {
147
+ disableAutoFocus: autoFocus,
165
148
  onClose: onClose,
166
149
  anchorOrigin: {
167
150
  vertical: 'bottom',
@@ -194,8 +177,8 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(inProps, ref) {
194
177
  classes: PopoverClasses,
195
178
  children: /*#__PURE__*/_jsx(ListSlot, {
196
179
  actions: menuListActionsRef,
197
- autoFocus: autoFocus && (activeItemIndex === -1 || disableAutoFocusItem),
198
- autoFocusItem: autoFocusItem,
180
+ autoFocus: shouldManageInitialFocus,
181
+ autoFocusItem: shouldAutoFocusActiveItem,
199
182
  variant: variant,
200
183
  ...listSlotProps,
201
184
  children: children
@@ -18,30 +18,17 @@ var _DefaultPropsProvider = require("../DefaultPropsProvider");
18
18
  var _ListContext = _interopRequireDefault(require("../List/ListContext"));
19
19
  var _ButtonBase = _interopRequireDefault(require("../ButtonBase"));
20
20
  var _useEnhancedEffect = _interopRequireDefault(require("../utils/useEnhancedEffect"));
21
+ var _focusWithVisible = _interopRequireDefault(require("../utils/focusWithVisible"));
21
22
  var _useForkRef = _interopRequireDefault(require("../utils/useForkRef"));
23
+ var _useId = _interopRequireDefault(require("../utils/useId"));
24
+ var _useRovingTabIndex = require("../utils/useRovingTabIndex");
22
25
  var _Divider = require("../Divider");
23
26
  var _ListItemIcon = require("../ListItemIcon");
24
27
  var _ListItemText = require("../ListItemText");
28
+ var _MenuListContext = require("../MenuList/MenuListContext");
29
+ var _utils = require("../Select/utils");
25
30
  var _menuItemClasses = _interopRequireWildcard(require("./menuItemClasses"));
26
- var _Select = require("../Select");
27
31
  var _jsxRuntime = require("react/jsx-runtime");
28
- /**
29
- * If autoFocus is an object, it will attempt to call `element.focus()` with the options argument.
30
- * If the browser doesn't support the options argument, it will fall back to a simple `element.focus()` call.
31
- */function focusWithVisible(element, focusSource) {
32
- if (focusSource == null) {
33
- element.focus();
34
- return;
35
- }
36
- try {
37
- element.focus({
38
- focusVisible: focusSource === 'keyboard'
39
- });
40
- } catch (error) {
41
- // If the browser doesn't support the focus options argument, fall back to a simple focus call.
42
- element.focus();
43
- }
44
- }
45
32
  const overridesResolver = (props, styles) => {
46
33
  const {
47
34
  ownerState
@@ -177,7 +164,7 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
177
164
  name: 'MuiMenuItem'
178
165
  });
179
166
  const {
180
- autoFocus = false,
167
+ autoFocus: shouldAutoFocusOnMount = false,
181
168
  component = 'li',
182
169
  dense = false,
183
170
  divider = false,
@@ -188,23 +175,30 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
188
175
  className,
189
176
  ...other
190
177
  } = props;
191
- const focusSource = (0, _Select.useSelectFocusSource)();
178
+ const focusSource = (0, _utils.useSelectFocusSource)();
192
179
  const context = React.useContext(_ListContext.default);
193
180
  const childContext = React.useMemo(() => ({
194
181
  dense: dense || context.dense || false,
195
182
  disableGutters
196
183
  }), [context.dense, dense, disableGutters]);
184
+ const menuListContext = (0, _MenuListContext.useMenuListContext)();
185
+ const rovingItemId = (0, _useId.default)();
186
+ // Escape hatch via ButtonBase for when an anchored <Menu> is opened with a pointer
187
+ // interaction on a trigger, the item should receive DOM focus but without focus visible
188
+ // styling. Current API does not allow a reliable `openInteractionType` for anchored menus.
189
+ const suppressFocusVisible = menuListContext.suppressInitialFocusVisible;
190
+ const itemsFocusableWhenDisabled = menuListContext.itemsFocusableWhenDisabled;
197
191
  const menuItemRef = React.useRef(null);
198
192
  (0, _useEnhancedEffect.default)(() => {
199
- if (autoFocus) {
193
+ if (shouldAutoFocusOnMount) {
200
194
  if (menuItemRef.current) {
201
- focusWithVisible(menuItemRef.current, focusSource);
195
+ (0, _focusWithVisible.default)(menuItemRef.current, focusSource);
202
196
  } else if (process.env.NODE_ENV !== 'production') {
203
197
  console.error('MUI: Unable to set focus to a MenuItem whose component has not been rendered.');
204
198
  }
205
199
  }
206
200
  // eslint-disable-next-line react-hooks/exhaustive-deps
207
- }, [autoFocus]);
201
+ }, [shouldAutoFocusOnMount]);
208
202
  const ownerState = {
209
203
  ...props,
210
204
  dense: childContext.dense,
@@ -212,10 +206,23 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
212
206
  disableGutters
213
207
  };
214
208
  const classes = useUtilityClasses(props);
215
- const handleRef = (0, _useForkRef.default)(menuItemRef, ref);
209
+ const rovingItemProps = (0, _useRovingTabIndex.useRovingTabIndexItem)({
210
+ id: rovingItemId,
211
+ ref,
212
+ disabled: props.disabled,
213
+ focusableWhenDisabled: itemsFocusableWhenDisabled,
214
+ selected: props.selected
215
+ });
216
+ const handleRef = (0, _useForkRef.default)(menuItemRef, rovingItemProps.ref);
216
217
  let tabIndex;
217
- if (!props.disabled) {
218
- tabIndex = tabIndexProp !== undefined ? tabIndexProp : -1;
218
+ if (tabIndexProp !== undefined) {
219
+ tabIndex = tabIndexProp;
220
+ } else if (menuListContext.variant === 'selectedMenu') {
221
+ tabIndex = rovingItemProps.tabIndex;
222
+ } else if (!props.disabled || itemsFocusableWhenDisabled) {
223
+ // In `menu` variant, registration still drives arrow-key navigation even
224
+ // though each item keeps `tabIndex={-1}`.
225
+ tabIndex = -1;
219
226
  }
220
227
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ListContext.default.Provider, {
221
228
  value: childContext,
@@ -224,6 +231,9 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
224
231
  role: role,
225
232
  tabIndex: tabIndex,
226
233
  component: component,
234
+ internalNativeButton: false,
235
+ focusableWhenDisabled: itemsFocusableWhenDisabled,
236
+ suppressFocusVisible: suppressFocusVisible,
227
237
  focusVisibleClassName: (0, _clsx.default)(classes.focusVisible, focusVisibleClassName),
228
238
  className: (0, _clsx.default)(classes.root, className),
229
239
  ...other,
@@ -11,32 +11,17 @@ import { useDefaultProps } from "../DefaultPropsProvider/index.mjs";
11
11
  import ListContext from "../List/ListContext.mjs";
12
12
  import ButtonBase from "../ButtonBase/index.mjs";
13
13
  import useEnhancedEffect from "../utils/useEnhancedEffect.mjs";
14
+ import focusWithVisible from "../utils/focusWithVisible.mjs";
14
15
  import useForkRef from "../utils/useForkRef.mjs";
16
+ import useId from "../utils/useId.mjs";
17
+ import { useRovingTabIndexItem } from "../utils/useRovingTabIndex.mjs";
15
18
  import { dividerClasses } from "../Divider/index.mjs";
16
19
  import { listItemIconClasses } from "../ListItemIcon/index.mjs";
17
20
  import { listItemTextClasses } from "../ListItemText/index.mjs";
21
+ import { useMenuListContext } from "../MenuList/MenuListContext.mjs";
22
+ import { useSelectFocusSource } from "../Select/utils/index.mjs";
18
23
  import menuItemClasses, { getMenuItemUtilityClass } from "./menuItemClasses.mjs";
19
- import { useSelectFocusSource } from "../Select/index.mjs";
20
-
21
- /**
22
- * If autoFocus is an object, it will attempt to call `element.focus()` with the options argument.
23
- * If the browser doesn't support the options argument, it will fall back to a simple `element.focus()` call.
24
- */
25
24
  import { jsx as _jsx } from "react/jsx-runtime";
26
- function focusWithVisible(element, focusSource) {
27
- if (focusSource == null) {
28
- element.focus();
29
- return;
30
- }
31
- try {
32
- element.focus({
33
- focusVisible: focusSource === 'keyboard'
34
- });
35
- } catch (error) {
36
- // If the browser doesn't support the focus options argument, fall back to a simple focus call.
37
- element.focus();
38
- }
39
- }
40
25
  export const overridesResolver = (props, styles) => {
41
26
  const {
42
27
  ownerState
@@ -171,7 +156,7 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
171
156
  name: 'MuiMenuItem'
172
157
  });
173
158
  const {
174
- autoFocus = false,
159
+ autoFocus: shouldAutoFocusOnMount = false,
175
160
  component = 'li',
176
161
  dense = false,
177
162
  divider = false,
@@ -188,9 +173,16 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
188
173
  dense: dense || context.dense || false,
189
174
  disableGutters
190
175
  }), [context.dense, dense, disableGutters]);
176
+ const menuListContext = useMenuListContext();
177
+ const rovingItemId = useId();
178
+ // Escape hatch via ButtonBase for when an anchored <Menu> is opened with a pointer
179
+ // interaction on a trigger, the item should receive DOM focus but without focus visible
180
+ // styling. Current API does not allow a reliable `openInteractionType` for anchored menus.
181
+ const suppressFocusVisible = menuListContext.suppressInitialFocusVisible;
182
+ const itemsFocusableWhenDisabled = menuListContext.itemsFocusableWhenDisabled;
191
183
  const menuItemRef = React.useRef(null);
192
184
  useEnhancedEffect(() => {
193
- if (autoFocus) {
185
+ if (shouldAutoFocusOnMount) {
194
186
  if (menuItemRef.current) {
195
187
  focusWithVisible(menuItemRef.current, focusSource);
196
188
  } else if (process.env.NODE_ENV !== 'production') {
@@ -198,7 +190,7 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
198
190
  }
199
191
  }
200
192
  // eslint-disable-next-line react-hooks/exhaustive-deps
201
- }, [autoFocus]);
193
+ }, [shouldAutoFocusOnMount]);
202
194
  const ownerState = {
203
195
  ...props,
204
196
  dense: childContext.dense,
@@ -206,10 +198,23 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
206
198
  disableGutters
207
199
  };
208
200
  const classes = useUtilityClasses(props);
209
- const handleRef = useForkRef(menuItemRef, ref);
201
+ const rovingItemProps = useRovingTabIndexItem({
202
+ id: rovingItemId,
203
+ ref,
204
+ disabled: props.disabled,
205
+ focusableWhenDisabled: itemsFocusableWhenDisabled,
206
+ selected: props.selected
207
+ });
208
+ const handleRef = useForkRef(menuItemRef, rovingItemProps.ref);
210
209
  let tabIndex;
211
- if (!props.disabled) {
212
- tabIndex = tabIndexProp !== undefined ? tabIndexProp : -1;
210
+ if (tabIndexProp !== undefined) {
211
+ tabIndex = tabIndexProp;
212
+ } else if (menuListContext.variant === 'selectedMenu') {
213
+ tabIndex = rovingItemProps.tabIndex;
214
+ } else if (!props.disabled || itemsFocusableWhenDisabled) {
215
+ // In `menu` variant, registration still drives arrow-key navigation even
216
+ // though each item keeps `tabIndex={-1}`.
217
+ tabIndex = -1;
213
218
  }
214
219
  return /*#__PURE__*/_jsx(ListContext.Provider, {
215
220
  value: childContext,
@@ -218,6 +223,9 @@ const MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
218
223
  role: role,
219
224
  tabIndex: tabIndex,
220
225
  component: component,
226
+ internalNativeButton: false,
227
+ focusableWhenDisabled: itemsFocusableWhenDisabled,
228
+ suppressFocusVisible: suppressFocusVisible,
221
229
  focusVisibleClassName: clsx(classes.focusVisible, focusVisibleClassName),
222
230
  className: clsx(classes.root, className),
223
231
  ...other,