UNPKG

10.5 kBJavaScriptView Raw
1import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
2import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
3import _extends from "@babel/runtime/helpers/esm/extends";
4import * as React from 'react';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import { unstable_composeClasses as composeClasses } from '@mui/base';
8import { alpha } from '@mui/system';
9import styled, { rootShouldForwardProp } from '../styles/styled';
10import useThemeProps from '../styles/useThemeProps';
11import ListContext from '../List/ListContext';
12import ButtonBase from '../ButtonBase';
13import useEnhancedEffect from '../utils/useEnhancedEffect';
14import useForkRef from '../utils/useForkRef';
15import { dividerClasses } from '../Divider';
16import { listItemIconClasses } from '../ListItemIcon';
17import { listItemTextClasses } from '../ListItemText';
18import menuItemClasses, { getMenuItemUtilityClass } from './menuItemClasses';
19import { jsx as _jsx } from "react/jsx-runtime";
20export var overridesResolver = function overridesResolver(props, styles) {
21 var ownerState = props.ownerState;
22 return [styles.root, ownerState.dense && styles.dense, ownerState.divider && styles.divider, !ownerState.disableGutters && styles.gutters];
23};
24
25var useUtilityClasses = function useUtilityClasses(ownerState) {
26 var disabled = ownerState.disabled,
27 dense = ownerState.dense,
28 divider = ownerState.divider,
29 disableGutters = ownerState.disableGutters,
30 selected = ownerState.selected,
31 classes = ownerState.classes;
32 var slots = {
33 root: ['root', dense && 'dense', disabled && 'disabled', !disableGutters && 'gutters', divider && 'divider', selected && 'selected']
34 };
35 var composedClasses = composeClasses(slots, getMenuItemUtilityClass, classes);
36 return _extends({}, classes, composedClasses);
37};
38
39var MenuItemRoot = styled(ButtonBase, {
40 shouldForwardProp: function shouldForwardProp(prop) {
41 return rootShouldForwardProp(prop) || prop === 'classes';
42 },
43 name: 'MuiMenuItem',
44 slot: 'Root',
45 overridesResolver: overridesResolver
46})(function (_ref) {
47 var _extends2;
48
49 var theme = _ref.theme,
50 ownerState = _ref.ownerState;
51 return _extends({}, theme.typography.body1, {
52 display: 'flex',
53 justifyContent: 'flex-start',
54 alignItems: 'center',
55 position: 'relative',
56 textDecoration: 'none',
57 minHeight: 48,
58 paddingTop: 6,
59 paddingBottom: 6,
60 boxSizing: 'border-box',
61 whiteSpace: 'nowrap'
62 }, !ownerState.disableGutters && {
63 paddingLeft: 16,
64 paddingRight: 16
65 }, ownerState.divider && {
66 borderBottom: "1px solid ".concat((theme.vars || theme).palette.divider),
67 backgroundClip: 'padding-box'
68 }, (_extends2 = {
69 '&:hover': {
70 textDecoration: 'none',
71 backgroundColor: (theme.vars || theme).palette.action.hover,
72 // Reset on touch devices, it doesn't add specificity
73 '@media (hover: none)': {
74 backgroundColor: 'transparent'
75 }
76 }
77 }, _defineProperty(_extends2, "&.".concat(menuItemClasses.selected), _defineProperty({
78 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / ").concat(theme.vars.palette.action.selectedOpacity, ")") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity)
79 }, "&.".concat(menuItemClasses.focusVisible), {
80 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / calc(").concat(theme.vars.palette.action.selectedOpacity, " + ").concat(theme.vars.palette.action.focusOpacity, "))") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity)
81 })), _defineProperty(_extends2, "&.".concat(menuItemClasses.selected, ":hover"), {
82 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / calc(").concat(theme.vars.palette.action.selectedOpacity, " + ").concat(theme.vars.palette.action.hoverOpacity, "))") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
83 // Reset on touch devices, it doesn't add specificity
84 '@media (hover: none)': {
85 backgroundColor: theme.vars ? "rgba(".concat(theme.vars.palette.primary.mainChannel, " / ").concat(theme.vars.palette.action.selectedOpacity, ")") : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity)
86 }
87 }), _defineProperty(_extends2, "&.".concat(menuItemClasses.focusVisible), {
88 backgroundColor: (theme.vars || theme).palette.action.focus
89 }), _defineProperty(_extends2, "&.".concat(menuItemClasses.disabled), {
90 opacity: (theme.vars || theme).palette.action.disabledOpacity
91 }), _defineProperty(_extends2, "& + .".concat(dividerClasses.root), {
92 marginTop: theme.spacing(1),
93 marginBottom: theme.spacing(1)
94 }), _defineProperty(_extends2, "& + .".concat(dividerClasses.inset), {
95 marginLeft: 52
96 }), _defineProperty(_extends2, "& .".concat(listItemTextClasses.root), {
97 marginTop: 0,
98 marginBottom: 0
99 }), _defineProperty(_extends2, "& .".concat(listItemTextClasses.inset), {
100 paddingLeft: 36
101 }), _defineProperty(_extends2, "& .".concat(listItemIconClasses.root), {
102 minWidth: 36
103 }), _extends2), !ownerState.dense && _defineProperty({}, theme.breakpoints.up('sm'), {
104 minHeight: 'auto'
105 }), ownerState.dense && _extends({
106 minHeight: 32,
107 // https://material.io/components/menus#specs > Dense
108 paddingTop: 4,
109 paddingBottom: 4
110 }, theme.typography.body2, _defineProperty({}, "& .".concat(listItemIconClasses.root, " svg"), {
111 fontSize: '1.25rem'
112 })));
113});
114var MenuItem = /*#__PURE__*/React.forwardRef(function MenuItem(inProps, ref) {
115 var props = useThemeProps({
116 props: inProps,
117 name: 'MuiMenuItem'
118 });
119
120 var _props$autoFocus = props.autoFocus,
121 autoFocus = _props$autoFocus === void 0 ? false : _props$autoFocus,
122 _props$component = props.component,
123 component = _props$component === void 0 ? 'li' : _props$component,
124 _props$dense = props.dense,
125 dense = _props$dense === void 0 ? false : _props$dense,
126 _props$divider = props.divider,
127 divider = _props$divider === void 0 ? false : _props$divider,
128 _props$disableGutters = props.disableGutters,
129 disableGutters = _props$disableGutters === void 0 ? false : _props$disableGutters,
130 focusVisibleClassName = props.focusVisibleClassName,
131 _props$role = props.role,
132 role = _props$role === void 0 ? 'menuitem' : _props$role,
133 tabIndexProp = props.tabIndex,
134 other = _objectWithoutProperties(props, ["autoFocus", "component", "dense", "divider", "disableGutters", "focusVisibleClassName", "role", "tabIndex"]);
135
136 var context = React.useContext(ListContext);
137 var childContext = {
138 dense: dense || context.dense || false,
139 disableGutters: disableGutters
140 };
141 var menuItemRef = React.useRef(null);
142 useEnhancedEffect(function () {
143 if (autoFocus) {
144 if (menuItemRef.current) {
145 menuItemRef.current.focus();
146 } else if (process.env.NODE_ENV !== 'production') {
147 console.error('MUI: Unable to set focus to a MenuItem whose component has not been rendered.');
148 }
149 }
150 }, [autoFocus]);
151
152 var ownerState = _extends({}, props, {
153 dense: childContext.dense,
154 divider: divider,
155 disableGutters: disableGutters
156 });
157
158 var classes = useUtilityClasses(props);
159 var handleRef = useForkRef(menuItemRef, ref);
160 var tabIndex;
161
162 if (!props.disabled) {
163 tabIndex = tabIndexProp !== undefined ? tabIndexProp : -1;
164 }
165
166 return /*#__PURE__*/_jsx(ListContext.Provider, {
167 value: childContext,
168 children: /*#__PURE__*/_jsx(MenuItemRoot, _extends({
169 ref: handleRef,
170 role: role,
171 tabIndex: tabIndex,
172 component: component,
173 focusVisibleClassName: clsx(classes.focusVisible, focusVisibleClassName)
174 }, other, {
175 ownerState: ownerState,
176 classes: classes
177 }))
178 });
179});
180process.env.NODE_ENV !== "production" ? MenuItem.propTypes
181/* remove-proptypes */
182= {
183 // ----------------------------- Warning --------------------------------
184 // | These PropTypes are generated from the TypeScript type definitions |
185 // | To update them edit the d.ts file and run "yarn proptypes" |
186 // ----------------------------------------------------------------------
187
188 /**
189 * If `true`, the list item is focused during the first mount.
190 * Focus will also be triggered if the value changes from false to true.
191 * @default false
192 */
193 autoFocus: PropTypes.bool,
194
195 /**
196 * The content of the component.
197 */
198 children: PropTypes.node,
199
200 /**
201 * Override or extend the styles applied to the component.
202 */
203 classes: PropTypes.object,
204
205 /**
206 * The component used for the root node.
207 * Either a string to use a HTML element or a component.
208 */
209 component: PropTypes.elementType,
210
211 /**
212 * If `true`, compact vertical padding designed for keyboard and mouse input is used.
213 * The prop defaults to the value inherited from the parent Menu component.
214 * @default false
215 */
216 dense: PropTypes.bool,
217
218 /**
219 * @ignore
220 */
221 disabled: PropTypes.bool,
222
223 /**
224 * If `true`, the left and right padding is removed.
225 * @default false
226 */
227 disableGutters: PropTypes.bool,
228
229 /**
230 * If `true`, a 1px light border is added to the bottom of the menu item.
231 * @default false
232 */
233 divider: PropTypes.bool,
234
235 /**
236 * This prop can help identify which element has keyboard focus.
237 * The class name will be applied when the element gains the focus through keyboard interaction.
238 * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo).
239 * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/HEAD/explainer.md).
240 * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `focus-visible` class to other components
241 * if needed.
242 */
243 focusVisibleClassName: PropTypes.string,
244
245 /**
246 * @ignore
247 */
248 role: PropTypes
249 /* @typescript-to-proptypes-ignore */
250 .string,
251
252 /**
253 * @ignore
254 */
255 selected: PropTypes.bool,
256
257 /**
258 * The system prop that allows defining system overrides as well as additional CSS styles.
259 */
260 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
261
262 /**
263 * @default 0
264 */
265 tabIndex: PropTypes.number
266} : void 0;
267export default MenuItem;
\No newline at end of file