feat:migrate to standard navigation shared adapter - #581
oleksandrzavarzin-callstack wants to merge 16 commits into
Conversation
Match the naming of @bottom-tabs/react-navigation, and trim the changeset down to the release-note facts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| '@bottom-tabs/react-navigation': patch | ||
| --- | ||
|
|
||
| Drop the `color` dependency in favour of React Native's `processColor`. `color` is ESM-only, so consumers had to extend `transformIgnorePatterns` before Jest would run at all |
There was a problem hiding this comment.
Why do we need to drop this dependency? I'm concerned we might get regressions
| { | ||
| "name": "@bottom-tabs/standard-navigation", | ||
| "version": "1.4.0", | ||
| "description": "Framework-agnostic native bottom tabs navigator built on the standard-navigation contract", |
There was a problem hiding this comment.
| "description": "Framework-agnostic native bottom tabs navigator built on the standard-navigation contract", | |
| "description": "Framework-agnostic native bottom tabs navigator", |
| import type { StandardNavigator } from 'standard-navigation'; | ||
|
|
||
| import { nativeBottomTabsNavigator } from '../index'; | ||
| import type { | ||
| NativeBottomTabNavigationOptions, | ||
| NativeBottomTabsEventMap, | ||
| NativeBottomTabsNavigatorProps, | ||
| } from '../types'; | ||
|
|
||
| jest.mock('react-native-bottom-tabs', () => ({ | ||
| __esModule: true, | ||
| default: () => null, | ||
| })); | ||
|
|
||
| const conformsToTheContract: StandardNavigator< | ||
| NativeBottomTabNavigationOptions, | ||
| NativeBottomTabsEventMap, | ||
| NativeBottomTabsNavigatorProps | ||
| > = nativeBottomTabsNavigator; | ||
|
|
||
| it('declares a navigator matching the published standard-navigation contract', () => { | ||
| expect(conformsToTheContract.type).toBe('standard'); | ||
| expect(conformsToTheContract.version).toBe(1); | ||
| expect(typeof conformsToTheContract.NavigatorContent).toBe('function'); | ||
| }); |
There was a problem hiding this comment.
I think we can remove this whole test
|
I have two requested changes before approving:
|
What
Expo SDK 56 dropped Expo Router's dependency on
@react-navigation/*in favour of a vendored fork.@bottom-tabs/react-navigationimports the real thing, so on SDK 56+ two copies of React Navigation load and their contexts stop lining up.This moves the tab view into a new framework-agnostic package,
@bottom-tabs/standard-navigation, built on thestandard-navigationcontract. One implementation, two adapters:@bottom-tabs/standard-navigationunstable_createStandardRouterNavigator@bottom-tabs/react-navigationwithLayoutContext@bottom-tabs/react-navigation's public API is unchanged - same exports, same types, same theme-derived tint defaults. It becomes a thin adapter over the shared view.Notable
colordependency for React Native'sprocessColor.coloris ESM-only, so every consumer who writes tests had to patchtransformIgnorePatternsbefore Jest would run at all.@react-navigation/nativestays at>=7. An earlier revision raised it to>=7.3.0, which brokenpm installoutright for SDK 52-55 apps locked below that - and nothing on that path needs 7.3.NativeBottomTabsContentcarries its event map and navigator props on phantom type-only properties. Without them an integrator loses every navigator prop at the call site:tabBarActiveTintColorand friends become type errors.unstable_createStandardRouterNavigatoris marked unstable by Expo and may change between minors. We deliberately don't call it ourselves, so a break stays in app code.tabBarreceives{ state, descriptors, actions, emitter }rather than anavigationobject, so@react-navigation/bottom-tabs'BottomTabBarcan't be used there. The React Navigation path is unaffected.How to test
apps/expo-router-testruns one assertion suite against both adapters under a real Expo Router tree, with a console spy that fails on any warning or error.Verified on an app scaffolded from
create-expo-app --template default@sdk-57(Expo 57, React Native 0.86.3, React 19.2.3):@react-navigation/*is absent fromnode_modulesentirely, so there's no second copy to line up - everything resolves through Expo Router's vendored fork.The SDK 52-55 path was checked separately: the documented
withLayoutContextrecipe typechecks clean against a realexpo-router@55install, at both 7.1.33 and 7.3.0.Screenshots