1 | 'use client';
|
2 |
|
3 | import * as React from 'react';
|
4 | import { useControllableReducer } from '../utils/useControllableReducer';
|
5 | import { DropdownActionTypes } from './useDropdown.types';
|
6 | import { dropdownReducer } from './dropdownReducer';
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | export 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?.(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?.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 |