Skip to content

Commit 176a3b0

Browse files
authored
Merge pull request Expensify#65199 from Eskalifer1/fix/65151
fix:65151: Onyx Tab navigator error if per-diem is selected
2 parents 3905913 + daec4f4 commit 176a3b0

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

src/libs/Navigation/OnyxTabNavigator.tsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type {MaterialTopTabNavigationEventMap} from '@react-navigation/material-
22
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs';
33
import type {EventMapCore, NavigationState, ParamListBase, ScreenListeners} from '@react-navigation/native';
44
import {useRoute} from '@react-navigation/native';
5-
import React, {useCallback, useContext, useEffect, useRef, useState} from 'react';
5+
import React, {useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
66
import {useOnyx} from 'react-native-onyx';
77
import FocusTrapContainerElement from '@components/FocusTrap/FocusTrapContainerElement';
88
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
@@ -69,6 +69,24 @@ const TopTab = createMaterialTopTabNavigator<ParamListBase, string>();
6969
// This provider is placed in the OnyxTabNavigator component and the consumer is in the TabScreenWithFocusTrapWrapper component.
7070
const TabFocusTrapContext = React.createContext<(tabName: string, containerElement: HTMLElement | null) => void>(() => {});
7171

72+
const getTabNames = (children: React.ReactNode): string[] => {
73+
const result: string[] = [];
74+
75+
React.Children.forEach(children, (child) => {
76+
if (!React.isValidElement(child)) {
77+
return;
78+
}
79+
80+
const element = child as React.ReactElement<{name?: string}>;
81+
82+
if (typeof element.props.name === 'string') {
83+
result.push(element.props.name);
84+
}
85+
});
86+
87+
return result;
88+
};
89+
7290
// This takes all the same props as MaterialTopTabsNavigator: https://reactnavigation.org/docs/material-top-tab-navigator/#props,
7391
// except ID is now required, and it gets a `selectedTab` from Onyx
7492
// It also takes 2 more optional callbacks to manage the focus trap container elements of the tab bar and the active tab
@@ -94,6 +112,10 @@ function OnyxTabNavigator({
94112
const [focusTrapContainerElementMapping, setFocusTrapContainerElementMapping] = useState<Record<string, HTMLElement>>({});
95113
const [selectedTab, selectedTabResult] = useOnyx(`${ONYXKEYS.COLLECTION.SELECTED_TAB}${id}`, {canBeMissing: false});
96114

115+
const tabNames = useMemo(() => getTabNames(children), [children]);
116+
117+
const validInitialTab = selectedTab && tabNames.includes(selectedTab) ? selectedTab : defaultSelectedTab;
118+
97119
const LazyPlaceholder = useCallback(() => {
98120
return <FullScreenLoadingIndicator />;
99121
}, []);
@@ -146,7 +168,7 @@ function OnyxTabNavigator({
146168
/* eslint-disable-next-line react/jsx-props-no-spreading */
147169
{...rest}
148170
id={id}
149-
initialRouteName={selectedTab ?? defaultSelectedTab}
171+
initialRouteName={validInitialTab}
150172
backBehavior="initialRoute"
151173
keyboardDismissMode="none"
152174
tabBar={TabBarWithFocusTrapInclusion}

0 commit comments

Comments
 (0)