diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 7fc5013f58a0..2b8d25d5d639 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -80,7 +80,7 @@ function BaseModal( isVisibleRef.current = isVisible; let removeOnCloseListener: () => void; if (isVisible) { - Modal.willAlertModalBecomeVisible(true); + Modal.willAlertModalBecomeVisible(true, type === CONST.MODAL.MODAL_TYPE.POPOVER || type === CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED); // To handle closing any modal already visible when this modal is mounted, i.e. PopoverReportActionContextMenu removeOnCloseListener = Modal.setCloseModal(onClose); } @@ -91,7 +91,7 @@ function BaseModal( } removeOnCloseListener(); }; - }, [isVisible, wasVisible, onClose]); + }, [isVisible, wasVisible, onClose, type]); useEffect( () => () => { diff --git a/src/components/PopoverWithoutOverlay/index.tsx b/src/components/PopoverWithoutOverlay/index.tsx index a87e1f1f0412..d163f47c7241 100644 --- a/src/components/PopoverWithoutOverlay/index.tsx +++ b/src/components/PopoverWithoutOverlay/index.tsx @@ -59,7 +59,7 @@ function PopoverWithoutOverlay( close(anchorRef); Modal.onModalDidClose(); } - Modal.willAlertModalBecomeVisible(isVisible); + Modal.willAlertModalBecomeVisible(isVisible, true); return () => { if (!removeOnClose) { diff --git a/src/components/ThreeDotsMenu/index.tsx b/src/components/ThreeDotsMenu/index.tsx index 5de074afff75..464c72b8581f 100644 --- a/src/components/ThreeDotsMenu/index.tsx +++ b/src/components/ThreeDotsMenu/index.tsx @@ -1,6 +1,8 @@ -import React, {useRef, useState} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import type {PopoverMenuItem} from '@components/PopoverMenu'; @@ -13,11 +15,18 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as Browser from '@libs/Browser'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; +import ONYXKEYS from '@src/ONYXKEYS'; import type {AnchorPosition} from '@src/styles'; +import type {Modal} from '@src/types/onyx'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; import type IconAsset from '@src/types/utils/IconAsset'; -type ThreeDotsMenuProps = { +type ThreeDotsMenuOnyxProps = { + /** Details about any modals being used */ + modal: OnyxEntry; +}; + +type ThreeDotsMenuProps = ThreeDotsMenuOnyxProps & { /** Tooltip for the popup icon */ iconTooltip?: TranslationPaths; @@ -67,12 +76,14 @@ function ThreeDotsMenu({ shouldOverlay = false, shouldSetModalVisibility = true, disabled = false, + modal = {}, }: ThreeDotsMenuProps) { const theme = useTheme(); const styles = useThemeStyles(); const [isPopupMenuVisible, setPopupMenuVisible] = useState(false); const buttonRef = useRef(null); const {translate} = useLocalize(); + const isBehindModal = modal?.willAlertModalBecomeVisible && !modal?.isPopover && !shouldOverlay; const showPopoverMenu = () => { setPopupMenuVisible(true); @@ -82,6 +93,13 @@ function ThreeDotsMenu({ setPopupMenuVisible(false); }; + useEffect(() => { + if (!isBehindModal || !isPopupMenuVisible) { + return; + } + hidePopoverMenu(); + }, [isBehindModal, isPopupMenuVisible]); + return ( <> @@ -120,7 +138,7 @@ function ThreeDotsMenu({ ({ + modal: { + key: ONYXKEYS.MODAL, + }, +})(ThreeDotsMenu); diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index 71ba850e721f..6351d0165544 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -72,9 +72,10 @@ function setModalVisibility(isVisible: boolean) { /** * Allows other parts of app to know that an alert modal is about to open. * This will trigger as soon as a modal is opened but not yet visible while animation is running. + * isPopover indicates that the next open modal is popover or bottom docked */ -function willAlertModalBecomeVisible(isVisible: boolean) { - Onyx.merge(ONYXKEYS.MODAL, {willAlertModalBecomeVisible: isVisible}); +function willAlertModalBecomeVisible(isVisible: boolean, isPopover = false) { + Onyx.merge(ONYXKEYS.MODAL, {willAlertModalBecomeVisible: isVisible, isPopover}); } export {setCloseModal, close, onModalDidClose, setModalVisibility, willAlertModalBecomeVisible, closeTop}; diff --git a/src/types/onyx/Modal.ts b/src/types/onyx/Modal.ts index 126b56d4c504..1a38864f30d6 100644 --- a/src/types/onyx/Modal.ts +++ b/src/types/onyx/Modal.ts @@ -4,6 +4,8 @@ type Modal = { /** Indicates if there is a modal currently visible or not */ isVisible?: boolean; + + isPopover?: boolean; }; export default Modal;