UNPKG

2.66 kBJavaScriptView Raw
1'use client';
2
3import _extends from "@babel/runtime/helpers/esm/extends";
4import * as React from 'react';
5import { unstable_useForkRef as useForkRef } from '@mui/utils';
6import { DropdownContext } from '../useDropdown/DropdownContext';
7import { DropdownActionTypes } from '../useDropdown/useDropdown.types';
8import { useButton } from '../useButton/useButton';
9import { combineHooksSlotProps } from '../utils/combineHooksSlotProps';
10import { extractEventHandlers } from '../utils';
11
12/**
13 *
14 * Demos:
15 *
16 * - [Menu](https://mui.com/base-ui/react-menu/#hooks)
17 *
18 * API:
19 *
20 * - [useMenuButton API](https://mui.com/base-ui/react-menu/hooks-api/#use-menu-button)
21 */
22export function useMenuButton(parameters = {}) {
23 const {
24 disabled = false,
25 focusableWhenDisabled,
26 rootRef: externalRef
27 } = parameters;
28 const menuContext = React.useContext(DropdownContext);
29 if (menuContext === null) {
30 throw new Error('useMenuButton: no menu context available.');
31 }
32 const {
33 state,
34 dispatch,
35 registerTrigger,
36 popupId
37 } = menuContext;
38 const {
39 getRootProps: getButtonRootProps,
40 rootRef: buttonRootRef,
41 active
42 } = useButton({
43 disabled,
44 focusableWhenDisabled,
45 rootRef: externalRef
46 });
47 const handleRef = useForkRef(buttonRootRef, registerTrigger);
48 const createHandleClick = otherHandlers => event => {
49 otherHandlers.onClick?.(event);
50 if (event.defaultMuiPrevented) {
51 return;
52 }
53 dispatch({
54 type: DropdownActionTypes.toggle,
55 event
56 });
57 };
58 const createHandleKeyDown = otherHandlers => event => {
59 otherHandlers.onKeyDown?.(event);
60 if (event.defaultMuiPrevented) {
61 return;
62 }
63 if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
64 event.preventDefault();
65 dispatch({
66 type: DropdownActionTypes.open,
67 event
68 });
69 }
70 };
71 const getOwnRootProps = (otherHandlers = {}) => ({
72 onClick: createHandleClick(otherHandlers),
73 onKeyDown: createHandleKeyDown(otherHandlers)
74 });
75 const getRootProps = (externalProps = {}) => {
76 const externalEventHandlers = extractEventHandlers(externalProps);
77 const getCombinedProps = combineHooksSlotProps(getOwnRootProps, getButtonRootProps);
78 return _extends({
79 'aria-haspopup': 'menu',
80 'aria-expanded': state.open,
81 'aria-controls': popupId
82 }, externalProps, externalEventHandlers, getCombinedProps(externalEventHandlers), {
83 tabIndex: 0,
84 // this is needed to make the button focused after click in Safari
85 ref: handleRef
86 });
87 };
88 return {
89 active,
90 getRootProps,
91 open: state.open,
92 rootRef: handleRef
93 };
94}
\No newline at end of file