diff --git a/src/libs/Navigation/OnyxTabNavigator.tsx b/src/libs/Navigation/OnyxTabNavigator.tsx index a1d9d1786dd2..5c5bbe201ab4 100644 --- a/src/libs/Navigation/OnyxTabNavigator.tsx +++ b/src/libs/Navigation/OnyxTabNavigator.tsx @@ -3,8 +3,7 @@ import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs import type {EventMapCore, NavigationState, ScreenListeners} from '@react-navigation/native'; import {useRoute} from '@react-navigation/native'; import React, {useCallback, useContext, useEffect, useState} from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import FocusTrapContainerElement from '@components/FocusTrap/FocusTrapContainerElement'; import type {TabSelectorProps} from '@components/TabSelector/TabSelector'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -13,40 +12,36 @@ import Tab from '@userActions/Tab'; import ONYXKEYS from '@src/ONYXKEYS'; import type {SelectedTabRequest} from '@src/types/onyx'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; +import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; import {defaultScreenOptions} from './OnyxTabNavigatorConfig'; -type OnyxTabNavigatorOnyxProps = { - selectedTab: OnyxEntry; -}; - -type OnyxTabNavigatorProps = OnyxTabNavigatorOnyxProps & - ChildrenProps & { - /** ID of the tab component to be saved in onyx */ - id: string; +type OnyxTabNavigatorProps = ChildrenProps & { + /** ID of the tab component to be saved in onyx */ + id: string; - /** Name of the selected tab */ - selectedTab?: SelectedTabRequest; + /** Name of the selected tab */ + defaultSelectedTab?: SelectedTabRequest; - /** A function triggered when a tab has been selected */ - onTabSelected?: (newIouType: IOURequestType) => void; + /** A function triggered when a tab has been selected */ + onTabSelected?: (newIouType: IOURequestType) => void; - tabBar: (props: TabSelectorProps) => React.ReactNode; + tabBar: (props: TabSelectorProps) => React.ReactNode; - screenListeners?: ScreenListeners; + screenListeners?: ScreenListeners; - /** Callback to register the focus trap container elements of the current active tab. - * Use this in the parent component to get the focus trap container element of the active tab, - * then pass it to the ScreenWrapper so that only focusable elements of the active tab are included in the focus trap - * Check the `IOURequestStartPage.tsx` and `NewChatSelectorPage.tsx` components for example usage - */ - onActiveTabFocusTrapContainerElementChanged?: (containerElement: HTMLElement | null) => void; + /** Callback to register the focus trap container elements of the current active tab. + * Use this in the parent component to get the focus trap container element of the active tab, + * then pass it to the ScreenWrapper so that only focusable elements of the active tab are included in the focus trap + * Check the `IOURequestStartPage.tsx` and `NewChatSelectorPage.tsx` components for example usage + */ + onActiveTabFocusTrapContainerElementChanged?: (containerElement: HTMLElement | null) => void; - /** Callback to register the focus trap container elements of the tab bar. - * This callback is useful when the custom-rendered tab bar is supporting the focus trap container element registration (which is the case of `TabSelector.tsx` component). - * Together, with the `onActiveTabFocusTrapContainerElementChanged` callback, we can manage the focus trap of the tab navigator in the parent component. - */ - onTabBarFocusTrapContainerElementChanged?: (containerElement: HTMLElement | null) => void; - }; + /** Callback to register the focus trap container elements of the tab bar. + * This callback is useful when the custom-rendered tab bar is supporting the focus trap container element registration (which is the case of `TabSelector.tsx` component). + * Together, with the `onActiveTabFocusTrapContainerElementChanged` callback, we can manage the focus trap of the tab navigator in the parent component. + */ + onTabBarFocusTrapContainerElementChanged?: (containerElement: HTMLElement | null) => void; +}; // eslint-disable-next-line rulesdir/no-inline-named-export const TopTab = createMaterialTopTabNavigator(); @@ -60,7 +55,7 @@ const TabFocusTrapContext = React.createContext<(tabName: string, containerEleme // It also takes 2 more optional callbacks to manage the focus trap container elements of the tab bar and the active tab function OnyxTabNavigator({ id, - selectedTab, + defaultSelectedTab, tabBar: TabBar, children, onTabBarFocusTrapContainerElementChanged, @@ -71,6 +66,7 @@ function OnyxTabNavigator({ }: OnyxTabNavigatorProps) { // Mapping of tab name to focus trap container element const [focusTrapContainerElementMapping, setFocusTrapContainerElementMapping] = useState>({}); + const [selectedTab, selectedTabResult] = useOnyx(`${ONYXKEYS.COLLECTION.SELECTED_TAB}${id}`); // This callback is used to register the focus trap container element of each avaiable tab screen const setTabFocusTrapContainerElement = useCallback((tabName: string, containerElement: HTMLElement | null) => { @@ -107,13 +103,17 @@ function OnyxTabNavigator({ onActiveTabFocusTrapContainerElementChanged?.(selectedTab ? focusTrapContainerElementMapping[selectedTab] : null); }, [selectedTab, focusTrapContainerElementMapping, onActiveTabFocusTrapContainerElementChanged]); + if (isLoadingOnyxValue(selectedTabResult)) { + return null; + } + return ( ({ - selectedTab: { - key: ({id}) => `${ONYXKEYS.COLLECTION.SELECTED_TAB}${id}`, - }, -})(OnyxTabNavigator); +export default OnyxTabNavigator; export {TabScreenWithFocusTrapWrapper, TopTab}; diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index dd5f4676eb6b..eac30b8839d2 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -134,6 +134,7 @@ function IOURequestStartPage({ {iouType !== CONST.IOU.TYPE.SEND && iouType !== CONST.IOU.TYPE.PAY && iouType !== CONST.IOU.TYPE.INVOICE ? (