UNPKG

1.84 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import { useControllableReducer } from '../utils/useControllableReducer';
5import { DropdownActionTypes } from './useDropdown.types';
6import { dropdownReducer } from './dropdownReducer';
7
8/**
9 *
10 * Demos:
11 *
12 * - [Menu](https://mui.com/base-ui/react-menu/#hooks)
13 *
14 * API:
15 *
16 * - [useDropdown API](https://mui.com/base-ui/react-menu/hooks-api/#use-dropdown)
17 */
18export function useDropdown(parameters = {}) {
19 const {
20 defaultOpen,
21 onOpenChange,
22 open: openProp,
23 componentName = 'useDropdown'
24 } = parameters;
25 const [popupId, setPopupId] = React.useState('');
26 const [triggerElement, setTriggerElement] = React.useState(null);
27 const lastActionType = React.useRef(null);
28 const handleStateChange = React.useCallback((event, field, value, reason) => {
29 if (field === 'open') {
30 onOpenChange == null || onOpenChange(event, value);
31 }
32 lastActionType.current = reason;
33 }, [onOpenChange]);
34 const controlledProps = React.useMemo(() => openProp !== undefined ? {
35 open: openProp
36 } : {}, [openProp]);
37 const [state, dispatch] = useControllableReducer({
38 controlledProps,
39 initialState: defaultOpen ? {
40 open: true,
41 changeReason: null
42 } : {
43 open: false,
44 changeReason: null
45 },
46 onStateChange: handleStateChange,
47 reducer: dropdownReducer,
48 componentName
49 });
50 React.useEffect(() => {
51 if (!state.open && lastActionType.current !== null && lastActionType.current !== DropdownActionTypes.blur) {
52 triggerElement == null || triggerElement.focus();
53 }
54 }, [state.open, triggerElement]);
55 const contextValue = {
56 state,
57 dispatch,
58 popupId,
59 registerPopup: setPopupId,
60 registerTrigger: setTriggerElement,
61 triggerElement
62 };
63 return {
64 contextValue,
65 open: state.open
66 };
67}
\No newline at end of file