1 | 'use client';
|
2 |
|
3 | import * as React from 'react';
|
4 | import { isFragment } from 'react-is';
|
5 | import PropTypes from 'prop-types';
|
6 | import clsx from 'clsx';
|
7 | import composeClasses from '@mui/utils/composeClasses';
|
8 | import HTMLElementType from '@mui/utils/HTMLElementType';
|
9 | import { useRtl } from '@mui/system/RtlProvider';
|
10 | import useSlotProps from '@mui/utils/useSlotProps';
|
11 | import MenuList from "../MenuList/index.js";
|
12 | import Popover, { PopoverPaper } from "../Popover/index.js";
|
13 | import rootShouldForwardProp from "../styles/rootShouldForwardProp.js";
|
14 | import { styled } from "../zero-styled/index.js";
|
15 | import { useDefaultProps } from "../DefaultPropsProvider/index.js";
|
16 | import { getMenuUtilityClass } from "./menuClasses.js";
|
17 | import { jsx as _jsx } from "react/jsx-runtime";
|
18 | const RTL_ORIGIN = {
|
19 | vertical: 'top',
|
20 | horizontal: 'right'
|
21 | };
|
22 | const LTR_ORIGIN = {
|
23 | vertical: 'top',
|
24 | horizontal: 'left'
|
25 | };
|
26 | const useUtilityClasses = ownerState => {
|
27 | const {
|
28 | classes
|
29 | } = ownerState;
|
30 | const slots = {
|
31 | root: ['root'],
|
32 | paper: ['paper'],
|
33 | list: ['list']
|
34 | };
|
35 | return composeClasses(slots, getMenuUtilityClass, classes);
|
36 | };
|
37 | const MenuRoot = styled(Popover, {
|
38 | shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
|
39 | name: 'MuiMenu',
|
40 | slot: 'Root',
|
41 | overridesResolver: (props, styles) => styles.root
|
42 | })({});
|
43 | export const MenuPaper = styled(PopoverPaper, {
|
44 | name: 'MuiMenu',
|
45 | slot: 'Paper',
|
46 | overridesResolver: (props, styles) => styles.paper
|
47 | })({
|
48 |
|
49 |
|
50 |
|
51 | maxHeight: 'calc(100% - 96px)',
|
52 |
|
53 | WebkitOverflowScrolling: 'touch'
|
54 | });
|
55 | const MenuMenuList = styled(MenuList, {
|
56 | name: 'MuiMenu',
|
57 | slot: 'List',
|
58 | overridesResolver: (props, styles) => styles.list
|
59 | })({
|
60 |
|
61 | outline: 0
|
62 | });
|
63 | const Menu = React.forwardRef(function Menu(inProps, ref) {
|
64 | const props = useDefaultProps({
|
65 | props: inProps,
|
66 | name: 'MuiMenu'
|
67 | });
|
68 | const {
|
69 | autoFocus = true,
|
70 | children,
|
71 | className,
|
72 | disableAutoFocusItem = false,
|
73 | MenuListProps = {},
|
74 | onClose,
|
75 | open,
|
76 | PaperProps = {},
|
77 | PopoverClasses,
|
78 | transitionDuration = 'auto',
|
79 | TransitionProps: {
|
80 | onEntering,
|
81 | ...TransitionProps
|
82 | } = {},
|
83 | variant = 'selectedMenu',
|
84 | slots = {},
|
85 | slotProps = {},
|
86 | ...other
|
87 | } = props;
|
88 | const isRtl = useRtl();
|
89 | const ownerState = {
|
90 | ...props,
|
91 | autoFocus,
|
92 | disableAutoFocusItem,
|
93 | MenuListProps,
|
94 | onEntering,
|
95 | PaperProps,
|
96 | transitionDuration,
|
97 | TransitionProps,
|
98 | variant
|
99 | };
|
100 | const classes = useUtilityClasses(ownerState);
|
101 | const autoFocusItem = autoFocus && !disableAutoFocusItem && open;
|
102 | const menuListActionsRef = React.useRef(null);
|
103 | const handleEntering = (element, isAppearing) => {
|
104 | if (menuListActionsRef.current) {
|
105 | menuListActionsRef.current.adjustStyleForScrollbar(element, {
|
106 | direction: isRtl ? 'rtl' : 'ltr'
|
107 | });
|
108 | }
|
109 | if (onEntering) {
|
110 | onEntering(element, isAppearing);
|
111 | }
|
112 | };
|
113 | const handleListKeyDown = event => {
|
114 | if (event.key === 'Tab') {
|
115 | event.preventDefault();
|
116 | if (onClose) {
|
117 | onClose(event, 'tabKeyDown');
|
118 | }
|
119 | }
|
120 | };
|
121 |
|
122 | |
123 |
|
124 |
|
125 |
|
126 |
|
127 | let activeItemIndex = -1;
|
128 |
|
129 |
|
130 |
|
131 | React.Children.map(children, (child, index) => {
|
132 | if (! React.isValidElement(child)) {
|
133 | return;
|
134 | }
|
135 | if (process.env.NODE_ENV !== 'production') {
|
136 | if (isFragment(child)) {
|
137 | console.error(["MUI: The Menu component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
|
138 | }
|
139 | }
|
140 | if (!child.props.disabled) {
|
141 | if (variant === 'selectedMenu' && child.props.selected) {
|
142 | activeItemIndex = index;
|
143 | } else if (activeItemIndex === -1) {
|
144 | activeItemIndex = index;
|
145 | }
|
146 | }
|
147 | });
|
148 | const PaperSlot = slots.paper ?? MenuPaper;
|
149 | const paperExternalSlotProps = slotProps.paper ?? PaperProps;
|
150 | const rootSlotProps = useSlotProps({
|
151 | elementType: slots.root,
|
152 | externalSlotProps: slotProps.root,
|
153 | ownerState,
|
154 | className: [classes.root, className]
|
155 | });
|
156 | const paperSlotProps = useSlotProps({
|
157 | elementType: PaperSlot,
|
158 | externalSlotProps: paperExternalSlotProps,
|
159 | ownerState,
|
160 | className: classes.paper
|
161 | });
|
162 | return _jsx(MenuRoot, {
|
163 | onClose: onClose,
|
164 | anchorOrigin: {
|
165 | vertical: 'bottom',
|
166 | horizontal: isRtl ? 'right' : 'left'
|
167 | },
|
168 | transformOrigin: isRtl ? RTL_ORIGIN : LTR_ORIGIN,
|
169 | slots: {
|
170 | paper: PaperSlot,
|
171 | root: slots.root
|
172 | },
|
173 | slotProps: {
|
174 | root: rootSlotProps,
|
175 | paper: paperSlotProps
|
176 | },
|
177 | open: open,
|
178 | ref: ref,
|
179 | transitionDuration: transitionDuration,
|
180 | TransitionProps: {
|
181 | onEntering: handleEntering,
|
182 | ...TransitionProps
|
183 | },
|
184 | ownerState: ownerState,
|
185 | ...other,
|
186 | classes: PopoverClasses,
|
187 | children: _jsx(MenuMenuList, {
|
188 | onKeyDown: handleListKeyDown,
|
189 | actions: menuListActionsRef,
|
190 | autoFocus: autoFocus && (activeItemIndex === -1 || disableAutoFocusItem),
|
191 | autoFocusItem: autoFocusItem,
|
192 | variant: variant,
|
193 | ...MenuListProps,
|
194 | className: clsx(classes.list, MenuListProps.className),
|
195 | children: children
|
196 | })
|
197 | });
|
198 | });
|
199 | process.env.NODE_ENV !== "production" ? Menu.propTypes = {
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | |
205 |
|
206 |
|
207 |
|
208 | anchorEl: PropTypes .oneOfType([HTMLElementType, PropTypes.func]),
|
209 | |
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | autoFocus: PropTypes.bool,
|
217 | |
218 |
|
219 |
|
220 | children: PropTypes.node,
|
221 | |
222 |
|
223 |
|
224 | classes: PropTypes.object,
|
225 | |
226 |
|
227 |
|
228 | className: PropTypes.string,
|
229 | |
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 | disableAutoFocusItem: PropTypes.bool,
|
237 | |
238 |
|
239 |
|
240 |
|
241 | MenuListProps: PropTypes.object,
|
242 | |
243 |
|
244 |
|
245 |
|
246 |
|
247 |
|
248 | onClose: PropTypes.func,
|
249 | |
250 |
|
251 |
|
252 | open: PropTypes.bool.isRequired,
|
253 | |
254 |
|
255 |
|
256 | PaperProps: PropTypes.object,
|
257 | |
258 |
|
259 |
|
260 | PopoverClasses: PropTypes.object,
|
261 | |
262 |
|
263 |
|
264 |
|
265 | slotProps: PropTypes.shape({
|
266 | paper: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
267 | root: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
|
268 | }),
|
269 | |
270 |
|
271 |
|
272 |
|
273 | slots: PropTypes.shape({
|
274 | paper: PropTypes.elementType,
|
275 | root: PropTypes.elementType
|
276 | }),
|
277 | |
278 |
|
279 |
|
280 | sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
281 | |
282 |
|
283 |
|
284 |
|
285 | transitionDuration: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.shape({
|
286 | appear: PropTypes.number,
|
287 | enter: PropTypes.number,
|
288 | exit: PropTypes.number
|
289 | })]),
|
290 | |
291 |
|
292 |
|
293 |
|
294 |
|
295 | TransitionProps: PropTypes.object,
|
296 | |
297 |
|
298 |
|
299 |
|
300 | variant: PropTypes.oneOf(['menu', 'selectedMenu'])
|
301 | } : void 0;
|
302 | export default Menu; |
\ | No newline at end of file |