Skip to content

Commit 8bc9880

Browse files
committed
Don't close when dragging outside submenu
1 parent b776da9 commit 8bc9880

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

packages/@react-spectrum/menu/src/Menu.tsx

-10
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {mergeProps, useLayoutEffect, useSlotId, useSyncRef} from '@react-aria/ut
2424
import React, {ReactElement, useContext, useEffect, useRef, useState} from 'react';
2525
import {SpectrumMenuProps} from '@react-types/menu';
2626
import styles from '@adobe/spectrum-css-temp/components/menu/vars.css';
27-
import {useInteractOutside} from '@react-aria/interactions';
2827
import {useLocale, useLocalizedStringFormatter} from '@react-aria/i18n';
2928
import {useMenu} from '@react-aria/menu';
3029
import {useTreeState} from '@react-stately/tree';
@@ -70,15 +69,6 @@ export const Menu = React.forwardRef(function Menu<T extends object>(props: Spec
7069
let nextMenuLevel = state.collection.getItem(nextMenuLevelKey);
7170
hasOpenSubmenu = nextMenuLevel != null;
7271
}
73-
useInteractOutside({
74-
ref: domRef,
75-
onInteractOutside: (e) => {
76-
if (!popoverContainer?.contains(e.target as Node) && !trayContainerRef.current?.contains(e.target as Node)) {
77-
rootMenuTriggerState?.close();
78-
}
79-
},
80-
isDisabled: isSubmenu || !hasOpenSubmenu
81-
});
8272

8373
return (
8474
<MenuStateContext.Provider value={{popoverContainer, trayContainerRef, menu: domRef, submenu: submenuRef, rootMenuTriggerState, state}}>

packages/@react-spectrum/menu/src/MenuTrigger.tsx

+15-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {classNames, SlotProvider, useDOMRef, useIsMobileDevice} from '@react-spectrum/utils';
13+
import {classNames, SlotProvider, unwrapDOMRef, useDOMRef, useIsMobileDevice} from '@react-spectrum/utils';
1414
import {DOMRef} from '@react-types/shared';
1515
import {MenuContext} from './context';
1616
import {Placement} from '@react-types/overlays';
1717
import {Popover, Tray} from '@react-spectrum/overlays';
18-
import {PressResponder} from '@react-aria/interactions';
18+
import {PressResponder, useInteractOutside} from '@react-aria/interactions';
1919
import React, {forwardRef, Fragment, useRef} from 'react';
2020
import {SpectrumMenuTriggerProps} from '@react-types/menu';
2121
import styles from '@adobe/spectrum-css-temp/components/menu/vars.css';
@@ -74,17 +74,29 @@ export const MenuTrigger = forwardRef(function MenuTrigger(props: SpectrumMenuTr
7474
state
7575
};
7676

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+
7788
// On small screen devices, the menu is rendered in a tray, otherwise a popover.
7889
let overlay;
7990
if (isMobile) {
8091
overlay = (
81-
<Tray state={state} isFixedHeight>
92+
<Tray state={state} isFixedHeight ref={rootOverlayRef}>
8293
{menu}
8394
</Tray>
8495
);
8596
} else {
8697
overlay = (
8798
<Popover
99+
ref={rootOverlayRef}
88100
UNSAFE_style={{clipPath: 'unset', overflow: 'visible', filter: 'unset', borderWidth: '0px'}}
89101
state={state}
90102
triggerRef={menuTriggerRef}

0 commit comments

Comments
 (0)