Bottom Tab with expo-router 3
Scouring from net I was able to have expo-router use react-native-paper bottom tabs. However screenOptions and tabBarIcon is having error in typescript.
import {
createMaterialBottomTabNavigator,
MaterialBottomTabNavigationOptions,
MaterialBottomTabNavigationEventMap,
} from "react-native-paper/react-navigation";
import { TabNavigationState, ParamListBase } from "@react-navigation/native";
import { withLayoutContext } from "expo-router";
import {
BottomTabNavigationEventMap,
BottomTabNavigationOptions,
} from "@react-navigation/bottom-tabs";
const BottomTabNavigator = createMaterialBottomTabNavigator().Navigator;
export const MaterialBottomTabs = withLayoutContext<
MaterialBottomTabNavigationOptions | BottomTabNavigationOptions,
typeof BottomTabNavigator,
TabNavigationState<ParamListBase>,
MaterialBottomTabNavigationEventMap | BottomTabNavigationEventMap
>(BottomTabNavigator);
What is the proper way of integrating expo-router to react-native-paper's bottom tab without having to resolve to using any on screenOptions and manually typing the tabBarIcon option
Found out the above does not work because it removes the header of the containing root stack!
@silencer07 Did you find a workaround?
@Shadic78 unfortunately no. I just used the expo tab for my pet project.
If you can call this a workaround basically I did this: https://callstack.github.io/react-native-paper/docs/guides/theming-with-react-navigation/
import {
DarkTheme as NavigationDarkTheme,
DefaultTheme as NavigationDefaultTheme,
} from "@react-navigation/native";
import merge from "deepmerge";
import {
adaptNavigationTheme,
MD3DarkTheme,
MD3LightTheme,
MD3Theme,
} from "react-native-paper";
import { NavigationTheme } from "react-native-paper/lib/typescript/types";
const { LightTheme, DarkTheme } = adaptNavigationTheme({
reactNavigationLight: NavigationDefaultTheme,
reactNavigationDark: NavigationDarkTheme,
});
// ..ommitted for brevity
const colors = {...}
const rnPaperLightTheme = { ...MD3LightTheme };
rnPaperLightTheme.colors.onSurface = colors.textColor;
rnPaperLightTheme.colors.onPrimary = "black";
rnPaperLightTheme.colors.onSurfaceVariant = "#475569";
rnPaperLightTheme.colors.surfaceVariant = colors.bgColor;
const navigationLightTheme = { ...LightTheme };
navigationLightTheme.colors.background = colors.bgColor; // bg of the content child
navigationLightTheme.colors.card = colors.bgColor; // header and tab colors
navigationLightTheme.colors.primary = colors.textColor; // active tab color
navigationLightTheme.colors.text = colors.textColor; // header text
export const CombinedDefaultTheme: MD3Theme & NavigationTheme = merge(
rnPaperLightTheme,
navigationLightTheme,
);
export const CombinedDarkTheme: MD3Theme & NavigationTheme = merge(
MD3DarkTheme,
DarkTheme,
);
Then on your root _layout.tsx
return (
<PaperProvider theme={CombinedDefaultTheme}>
<ThemeProvider value={CombinedDefaultTheme}>
<GestureHandlerRootView style={{ flex: 1 }}>
<Slot /> // or you can use the old-school react navigation way. haven't tried it
</GestureHandlerRootView>
</ThemeProvider>
</PaperProvider>
);