diff --git a/src/components/FocusTrap/FocusTrapForModal/index.web.tsx b/src/components/FocusTrap/FocusTrapForModal/index.web.tsx index be5da8c49a78..00dcedd32aa2 100644 --- a/src/components/FocusTrap/FocusTrapForModal/index.web.tsx +++ b/src/components/FocusTrap/FocusTrapForModal/index.web.tsx @@ -1,6 +1,7 @@ import FocusTrap from 'focus-trap-react'; import React from 'react'; import sharedTrapStack from '@components/FocusTrap/sharedTrapStack'; +import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; import type FocusTrapForModalProps from './FocusTrapForModalProps'; function FocusTrapForModal({children, active}: FocusTrapForModalProps) { @@ -12,6 +13,12 @@ function FocusTrapForModal({children, active}: FocusTrapForModalProps) { clickOutsideDeactivates: true, initialFocus: false, fallbackFocus: document.body, + setReturnFocus: (element) => { + if (ReportActionComposeFocusManager.isFocused()) { + return false; + } + return element; + }, }} > {children} diff --git a/src/libs/Navigation/isReportOpenInRHP.ts b/src/libs/Navigation/isReportOpenInRHP.ts new file mode 100644 index 000000000000..51e8a95bb66b --- /dev/null +++ b/src/libs/Navigation/isReportOpenInRHP.ts @@ -0,0 +1,17 @@ +import type {NavigationState} from '@react-navigation/native'; +import NAVIGATORS from '@src/NAVIGATORS'; +import SCREENS from '@src/SCREENS'; + +const isReportOpenInRHP = (state: NavigationState | undefined): boolean => { + const lastRoute = state?.routes?.at(-1); + if (!lastRoute) { + return false; + } + const params = lastRoute.params; + if (params && 'screen' in params && typeof params.screen === 'string' && params.screen === SCREENS.RIGHT_MODAL.SEARCH_REPORT) { + return true; + } + return !!(lastRoute.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR && lastRoute.state?.routes?.some((route) => route?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT)); +}; + +export default isReportOpenInRHP; diff --git a/src/libs/Navigation/linkTo/index.ts b/src/libs/Navigation/linkTo/index.ts index 3c4608d6b5de..bb0a8a233046 100644 --- a/src/libs/Navigation/linkTo/index.ts +++ b/src/libs/Navigation/linkTo/index.ts @@ -3,6 +3,7 @@ import type {NavigationContainerRef, NavigationState, PartialState} from '@react import {findFocusedRoute} from '@react-navigation/native'; import {omitBy} from 'lodash'; import getIsNarrowLayout from '@libs/getIsNarrowLayout'; +import isReportOpenInRHP from '@libs/Navigation/isReportOpenInRHP'; import extractPolicyIDsFromState from '@libs/Navigation/linkingConfig/extractPolicyIDsFromState'; import isCentralPaneName from '@libs/NavigationUtils'; import shallowCompare from '@libs/ObjectUtils'; @@ -68,7 +69,7 @@ export default function linkTo(navigation: NavigationContainerRef route?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT); + const isReportInRhpOpened = isReportOpenInRHP(rootState); // If action type is different than NAVIGATE we can't change it to the PUSH safely if (action?.type === CONST.NAVIGATION.ACTION_TYPE.NAVIGATE) { diff --git a/src/libs/ReportActionComposeFocusManager.ts b/src/libs/ReportActionComposeFocusManager.ts index 0765f5f0ba75..2dfa81d89a20 100644 --- a/src/libs/ReportActionComposeFocusManager.ts +++ b/src/libs/ReportActionComposeFocusManager.ts @@ -1,8 +1,10 @@ import React from 'react'; import type {MutableRefObject} from 'react'; import type {TextInput} from 'react-native'; -import ROUTES from '@src/ROUTES'; -import Navigation from './Navigation/Navigation'; +import SCREENS from '@src/SCREENS'; +import getTopmostRouteName from './Navigation/getTopmostRouteName'; +import isReportOpenInRHP from './Navigation/isReportOpenInRHP'; +import navigationRef from './Navigation/navigationRef'; type FocusCallback = (shouldFocusForNonBlurInputOnTapOutside?: boolean) => void; @@ -31,8 +33,9 @@ function onComposerFocus(callback: FocusCallback | null, isMainComposer = false) * Request focus on the ReportActionComposer */ function focus(shouldFocusForNonBlurInputOnTapOutside?: boolean) { - /** Do not trigger the refocusing when the active route is not the report route, */ - if (!Navigation.isActiveRoute(ROUTES.REPORT_WITH_ID.getRoute(Navigation.getTopmostReportId() ?? '-1'))) { + /** Do not trigger the refocusing when the active route is not the report screen */ + const navigationState = navigationRef.getState(); + if (!navigationState || (!isReportOpenInRHP(navigationState) && getTopmostRouteName(navigationState) !== SCREENS.REPORT)) { return; } diff --git a/tests/perf-test/SidebarLinks.perf-test.tsx b/tests/perf-test/SidebarLinks.perf-test.tsx index 4caa22d062d4..0bd2e83f4e72 100644 --- a/tests/perf-test/SidebarLinks.perf-test.tsx +++ b/tests/perf-test/SidebarLinks.perf-test.tsx @@ -20,6 +20,11 @@ jest.mock('../../src/libs/Navigation/Navigation', () => ({ isNavigationReady: jest.fn(() => Promise.resolve()), isDisplayedInModal: jest.fn(() => false), })); +jest.mock('../../src/libs/Navigation/navigationRef', () => ({ + getState: () => ({ + routes: [], + }), +})); jest.mock('@components/Icon/Expensicons'); jest.mock('@react-navigation/native');