react-native-paper icon indicating copy to clipboard operation
react-native-paper copied to clipboard

Bottom Tab with expo-router 3

Open silencer07 opened this issue 1 year ago • 3 comments

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

silencer07 avatar Mar 19 '24 07:03 silencer07

Found out the above does not work because it removes the header of the containing root stack!

silencer07 avatar Mar 19 '24 08:03 silencer07

@silencer07 Did you find a workaround?

Shadic78 avatar Aug 06 '24 16:08 Shadic78

@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>
  );

silencer07 avatar Aug 08 '24 23:08 silencer07