UNPKG

3.4 kBJavaScriptView Raw
1'use client';
2
3import _extends from "@babel/runtime/helpers/esm/extends";
4import * as React from 'react';
5import { unstable_useId as useId, unstable_useForkRef as useForkRef } from '@mui/utils';
6import { useButton } from '../useButton';
7import { useListItem } from '../useList';
8import { DropdownActionTypes } from '../useDropdown';
9import { DropdownContext } from '../useDropdown/DropdownContext';
10import { combineHooksSlotProps } from '../utils/combineHooksSlotProps';
11import { useCompoundItem } from '../useCompound';
12import { extractEventHandlers } from '../utils/extractEventHandlers';
13function idGenerator(existingKeys) {
14 return `menu-item-${existingKeys.size}`;
15}
16const FALLBACK_MENU_CONTEXT = {
17 dispatch: () => {},
18 popupId: '',
19 registerPopup: () => {},
20 registerTrigger: () => {},
21 state: {
22 open: true,
23 changeReason: null
24 },
25 triggerElement: null
26};
27
28/**
29 *
30 * Demos:
31 *
32 * - [Menu](https://mui.com/base-ui/react-menu/#hooks)
33 *
34 * API:
35 *
36 * - [useMenuItem API](https://mui.com/base-ui/react-menu/hooks-api/#use-menu-item)
37 */
38export function useMenuItem(params) {
39 const {
40 disabled = false,
41 id: idParam,
42 rootRef: externalRef,
43 label,
44 disableFocusOnHover = false
45 } = params;
46 const id = useId(idParam);
47 const itemRef = React.useRef(null);
48 const itemMetadata = React.useMemo(() => ({
49 disabled,
50 id: id ?? '',
51 label,
52 ref: itemRef
53 }), [disabled, id, label]);
54 const {
55 dispatch
56 } = React.useContext(DropdownContext) ?? FALLBACK_MENU_CONTEXT;
57 const {
58 getRootProps: getListRootProps,
59 highlighted
60 } = useListItem({
61 item: id,
62 handlePointerOverEvents: !disableFocusOnHover
63 });
64 const {
65 index,
66 totalItemCount
67 } = useCompoundItem(id ?? idGenerator, itemMetadata);
68 const {
69 getRootProps: getButtonProps,
70 focusVisible,
71 rootRef: buttonRefHandler
72 } = useButton({
73 disabled,
74 focusableWhenDisabled: true
75 });
76 const handleRef = useForkRef(buttonRefHandler, externalRef, itemRef);
77 React.useDebugValue({
78 id,
79 highlighted,
80 disabled,
81 label
82 });
83 const createHandleClick = otherHandlers => event => {
84 otherHandlers.onClick?.(event);
85 if (event.defaultMuiPrevented) {
86 return;
87 }
88 dispatch({
89 type: DropdownActionTypes.close,
90 event
91 });
92 };
93 const getOwnHandlers = (otherHandlers = {}) => _extends({}, otherHandlers, {
94 onClick: createHandleClick(otherHandlers)
95 });
96 function getRootProps(externalProps = {}) {
97 const externalEventHandlers = extractEventHandlers(externalProps);
98 const getCombinedRootProps = combineHooksSlotProps(getOwnHandlers, combineHooksSlotProps(getButtonProps, getListRootProps));
99 return _extends({}, externalProps, externalEventHandlers, getCombinedRootProps(externalEventHandlers), {
100 id,
101 ref: handleRef,
102 role: 'menuitem'
103 });
104 }
105
106 // If `id` is undefined (during SSR in React < 18), we fall back to rendering a simplified menu item
107 // which does not have access to infortmation about its position or highlighted state.
108 if (id === undefined) {
109 return {
110 getRootProps,
111 disabled: false,
112 focusVisible,
113 highlighted: false,
114 index: -1,
115 totalItemCount: 0,
116 rootRef: handleRef
117 };
118 }
119 return {
120 getRootProps,
121 disabled,
122 focusVisible,
123 highlighted,
124 index,
125 totalItemCount,
126 rootRef: handleRef
127 };
128}
\No newline at end of file