Skip to content

Commit 5c59005

Browse files
committed
polish tab bar glitch
1 parent 1535c86 commit 5c59005

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

src/libs/Navigation/AppNavigator/Navigators/TabNavigatorBar.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,25 @@ const ROUTE_TO_NAVIGATION_TAB: Record<string, ValueOf<typeof NAVIGATION_TABS>> =
2222
[NAVIGATORS.WORKSPACE_NAVIGATOR]: NAVIGATION_TABS.WORKSPACES,
2323
};
2424

25-
// Tab wrapper navigators — when `getFocusedLeafScreenName` bottoms out on one of these
26-
// (because the nested stack state hasn't hydrated yet), the user is landing on the tab root,
27-
// so treat it as "at root" to keep the tab bar visible during the transition.
25+
// Count as tab-root when they surface as the resolved leaf.
2826
const TAB_WRAPPER_NAVIGATORS = new Set<string>([
2927
NAVIGATORS.REPORTS_SPLIT_NAVIGATOR,
3028
NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR,
3129
NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR,
3230
NAVIGATORS.WORKSPACE_NAVIGATOR,
3331
]);
3432

33+
const isAtTabRootLevel = (name: string | undefined): boolean => !name || ROOT_TAB_SCREENS.has(name) || TAB_WRAPPER_NAVIGATORS.has(name);
34+
35+
// Deepest `screen` in a `{screen, params}` chain (e.g. WORKSPACE_NAV → WORKSPACE_SPLIT_NAV → WORKSPACE.INITIAL).
36+
const getPushTargetLeaf = (params: unknown): string | undefined => {
37+
const p = params as {screen?: unknown; params?: unknown} | undefined;
38+
if (typeof p?.screen !== 'string') {
39+
return undefined;
40+
}
41+
return getPushTargetLeaf(p.params) ?? p.screen;
42+
};
43+
3544
/**
3645
* Custom tab bar rendered by the BottomTabNavigator. Only receives `state` (not the
3746
* full BottomTabBarProps) to avoid `descriptors` thrashing memoization.
@@ -44,8 +53,8 @@ function TabNavigatorBar({state}: Pick<BottomTabBarProps, 'state'>) {
4453
const StyleUtils = useStyleUtils();
4554
const activeRoute = state.routes[state.index];
4655
const selectedTab = ROUTE_TO_NAVIGATION_TAB[activeRoute?.name ?? SCREENS.HOME] ?? NAVIGATION_TABS.HOME;
47-
const focusedScreen = getFocusedLeafScreenName(activeRoute?.state);
48-
const isAtRoot = !focusedScreen || ROOT_TAB_SCREENS.has(focusedScreen) || TAB_WRAPPER_NAVIGATORS.has(focusedScreen);
56+
// Check both leaves so wrapper hydration doesn't flash the tab bar on the push target (Android).
57+
const isAtRoot = isAtTabRootLevel(getFocusedLeafScreenName(activeRoute?.state)) && isAtTabRootLevel(getPushTargetLeaf(activeRoute?.params));
4958
// --- Narrow-only animation logic (hooks must run unconditionally per Rules of Hooks) ---
5059
// On native, screens also render the tab bar via bottomContent for swipe-back animations.
5160
// Delay showing this navigator's tab bar only when navigating back from a deeper screen

0 commit comments

Comments
 (0)