|
10 | 10 | * governing permissions and limitations under the License.
|
11 | 11 | */
|
12 | 12 |
|
13 |
| -import {classNames, SlotProvider, useDOMRef, useIsMobileDevice} from '@react-spectrum/utils'; |
| 13 | +import {classNames, SlotProvider, unwrapDOMRef, useDOMRef, useIsMobileDevice} from '@react-spectrum/utils'; |
14 | 14 | import {DOMRef} from '@react-types/shared';
|
15 | 15 | import {MenuContext} from './context';
|
16 | 16 | import {Placement} from '@react-types/overlays';
|
17 | 17 | import {Popover, Tray} from '@react-spectrum/overlays';
|
18 |
| -import {PressResponder} from '@react-aria/interactions'; |
| 18 | +import {PressResponder, useInteractOutside} from '@react-aria/interactions'; |
19 | 19 | import React, {forwardRef, Fragment, useRef} from 'react';
|
20 | 20 | import {SpectrumMenuTriggerProps} from '@react-types/menu';
|
21 | 21 | import styles from '@adobe/spectrum-css-temp/components/menu/vars.css';
|
@@ -74,17 +74,29 @@ export const MenuTrigger = forwardRef(function MenuTrigger(props: SpectrumMenuTr
|
74 | 74 | state
|
75 | 75 | };
|
76 | 76 |
|
| 77 | + // Close when clicking outside the root menu when a submenu is open. |
| 78 | + let rootOverlayRef = useRef(null); |
| 79 | + let rootOverlayDomRef = unwrapDOMRef(rootOverlayRef); |
| 80 | + useInteractOutside({ |
| 81 | + ref: rootOverlayDomRef, |
| 82 | + onInteractOutside: () => { |
| 83 | + state?.close(); |
| 84 | + }, |
| 85 | + isDisabled: !state.isOpen || state.expandedKeysStack.length === 0 |
| 86 | + }); |
| 87 | + |
77 | 88 | // On small screen devices, the menu is rendered in a tray, otherwise a popover.
|
78 | 89 | let overlay;
|
79 | 90 | if (isMobile) {
|
80 | 91 | overlay = (
|
81 |
| - <Tray state={state} isFixedHeight> |
| 92 | + <Tray state={state} isFixedHeight ref={rootOverlayRef}> |
82 | 93 | {menu}
|
83 | 94 | </Tray>
|
84 | 95 | );
|
85 | 96 | } else {
|
86 | 97 | overlay = (
|
87 | 98 | <Popover
|
| 99 | + ref={rootOverlayRef} |
88 | 100 | UNSAFE_style={{clipPath: 'unset', overflow: 'visible', filter: 'unset', borderWidth: '0px'}}
|
89 | 101 | state={state}
|
90 | 102 | triggerRef={menuTriggerRef}
|
|
0 commit comments