React Navigation - opening a modal from the tab bar - reactjs

Using React Navigation (6), I've got bottom tabs set up as my main navigator:
export function TabNavigator() {
const getColor = ({ focused, color }) => (focused ? palette.blue : color)
return (
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen
name="home"
component={HomeScreen}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="home-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="favourites"
component={FavouritesScreen}
options={{
tabBarLabel: "Favourites",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="heart-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="about"
component={AboutYouScreen}
options={{
tabBarLabel: "About you",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="person-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="bottomchat"
component={ChatNavigator}
options={{
tabBarLabel: "Check-in",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="chatbubble-ellipses-outline" color={getColor(rest)} size={size} />
),
}}
/>
</Tab.Navigator>
)
}
With the last tab (the ChatNavigator), I want the screen it opens to be a full screen modal, hiding the bottom tab bar (the user can exit out if it via a back button at the top).
Is this possible?

As I was writing this question I found an answer which actually worked for me on this blog post
The solution:
Create the full screen modal in your parent stack
Pass in a mock component to the tab screen (this will never get called)
Add a listener to the tab component that prevents default and then navigates to the page of your choice
So for me:
const ChatBase = () => <View style={{ flex: 1, backgroundColor: "red" }} />
export function TabNavigator() {
const getColor = ({ focused, color }) => (focused ? palette.blue : color)
return (
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen
name="home"
component={HomeScreen}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="home-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="favourites"
component={FavouritesScreen}
options={{
tabBarLabel: "Favourites",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="heart-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="about"
component={AboutYouScreen}
options={{
tabBarLabel: "About you",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="person-outline" color={getColor(rest)} size={size} />
),
}}
/>
<Tab.Screen
name="bottomchat"
/* Pass in a blank component as the base (this never gets shown) */
component={ChatBase}
options={{
tabBarLabel: "Check-in",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="chatbubble-ellipses-outline" color={getColor(rest)} size={size} />
),
}}
listeners={({ navigation }) => ({
tabPress: (e) => {
e.preventDefault()
navigation.navigate("chat")
},
})}
/>
</Tab.Navigator>
)
}
In my root stack navigator, I've got a screen called chat that gets called:
export function MainNavigator() {
return (
<Stack.Navigator
screenOptions={{
cardStyle: { backgroundColor: "transparent" },
headerShown: false,
}}
>
<Stack.Screen name="main" component={TabNavigator} />
<Stack.Screen name="chat" component={ChatScreen} />
</Stack.Navigator>
)
}

Use listener/tabPress props with navigator, but navigator from TabNavigator component
export function TabNavigator( { navigation } ) { // <-- use this navitagor
.........
.........
<Tab.Screen
name="bottomchat"
component={ AnyComponent } // <-- ignored
options={{
tabBarLabel: "Check-in",
tabBarIcon: ({ size, ...rest }) => (
<Ionicons name="chatbubble-ellipses-outline" color={getColor(rest)} size={size} />
),
}}
listeners={() => ({
tabPress: (e) => {
e.preventDefault()
navigation.navigate("ChatComponent") // <-- Here you put the name where the chat component is declared
},
})}
/>
</Tab.Navigator>
)
}

Related

How can I remove the rounded shape around my selected tab text?

I just start learning React Native, and I added my bottom nav using Material Bottom Tabs.
My only issue is this purple circle around my icon when selected. I checked the docs looking for this default setting but couldn't find it.
Here is my code:
const Tab = createMaterialBottomTabNavigator();
const App = () => {
const [loaded] = useFonts({
InterBold: require("./assets/fonts/Inter-Bold.ttf"),
InterSemiBold: require("./assets/fonts/Inter-SemiBold.ttf"),
InterMedium: require("./assets/fonts/Inter-Medium.ttf"),
InterRegular: require("./assets/fonts/Inter-Regular.ttf"),
InterLight: require("./assets/fonts/Inter-Light.ttf"),
});
if (!loaded) return null;
return (
<NavigationContainer theme={theme}>
<Tab.Navigator initialRouteName="Menu principal"
activeColor="#f0edf6"
inactiveColor="white"
barStyle={{ backgroundColor: 'black' }}
>
<Tab.Screen name="Menu principal" component={Home}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Collections" component={Collections}
options={{
tabBarLabel: 'Collections',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="cards" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Associations" component={Associations}
options={{
tabBarLabel: 'Associations',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="account-group" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Classement" component={Classement}
options={{
tabBarLabel: 'Classement',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="trophy" color={color} size={26} />
),
}}
/>
<Tab.Screen name="News" component={News}
options={{
tabBarLabel: 'News',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="newspaper" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
Here is the solution I found. You have to npm install react-native-paper, import, and use it.
To use react-native-paper to change the little circle tab buttons, wrap <Tab.Navigator>...</Tab.Navigator> with <PaperProvider theme={theme}> as shown below.
Finally, create a const theme like I did, and change the secondaryContainer to whatever color you want.
P.S. make sure to change your import names as shown to not conflict with the Provider for redux.
import {
MD3LightTheme as DefaultTheme,
Provider as PaperProvider,
} from "react-native-paper";
const Tab = createMaterialBottomTabNavigator();
const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
secondaryContainer: "red",
},
};
const App = () => {
return (
<NavigationContainer>
<PaperProvider theme={theme}>
<Tab.Navigator initialRouteName="Menu principal"
activeColor="#f0edf6"
inactiveColor="white"
barStyle={{ backgroundColor: 'black' }}
>
// rest of your code
</Tab.Navigator>
</PaperProvider>
</NavigationContainer>
)
}

react-native: how can I do a navigation somewhere in a modal

I have this in app.js
<NavigationContainer>
<TabNav.Navigator initialRouteName='home'>
<TabNav.Screen name='home' component={Map} options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="map-search-outline" color={color} size={30} style={style.iconStyle} />
),
tabBarLabel: (null)
}} />
<TabNav.Screen name='user' component={User} options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="card-account-details-outline" color={color} size={30} style={style.iconStyle} />
),
tabBarLabel: (null)
}} />
<TabNav.Screen name='settings' component={Settings} options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="set-square" color={color} size={30} style={style.iconStyle} />
),
tabBarLabel: (null)
}} />
</TabNav.Navigator>
</NavigationContainer>
In the component Map with the MapView there is markers showing modals with informations.
How can I go into new form screens component edit and report from that modal ?
Navigation stack doesn't work from there, or I am missing something ?
You can simply do it by passing props.
<Component navigation={this.props.navigation} />
Inside Component
this.props.navigation.navigate('NextScreen')

How do I apply external/global style to a react-navigation bottom tab

I tried to apply a global style to a bottom tab navigation in react-native but it can't accept it in the screenOptions prop. But it works fine when I use normal inline styling. Please help
export default function CustomBottomTab() {
return (
<Tab.Navigator
screenOptions={{
tabBarStyle: {styles.customTab} //underlines the dot as an error
}}
>
<Tab.Screen
name='Landing'
component={HomeScreen}
options={{
tabBarIcon: (props) => <AntDesign name='home' size={20} {...props} />,
}}
/>
<Tab.Screen
name='Notifications'
component={NotifScreen}
options={{
tabBarIcon: (props) => (
<FontAwesome5 name='bell' size={20} {...props} />
),
}}
/>
<Tab.Screen
name='Wishlist'
component={WishScreen}
options={{
tabBarIcon: (props) => (
<Ionicons name='bookmarks-outline' size={20} {...props} />
),
}}
/>
<Tab.Screen
name='Messages'
component={MessagesScreen}
options={{
tabBarIcon: (props) => (
<FontAwesome5 name='comment' size={20} {...props} />
),
}}
/>
</Tab.Navigator>
);
}
Remove {} from around {styles.customTab}. It's not valid JavaScript syntax.
It needs to be:
tabBarStyle: styles.customTab

React Navigation change backgroundColor below tabBar

I am using React Navigations tabBar with my React Native project, and I don't know how to change the background color of my bottom tab bar properly. I used Expo to make my app and I have also edited app.json to have the correct backgroundColor, yet nothing changes. Here is my code:
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
screenOptions={{
tabBarActiveTintColor: "#E40066",
tabBarInactiveTintColor: "#fff",
tabBarActiveBackgroundColor: "#171717",
tabBarInactiveBackgroundColor: "#171717",
headerShown: false,
tabBarStyle: {
borderWidth: 1,
},
style: {
backgroundColor: "#171717",
},
}}
>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="glass-cocktail"
color={color}
size={size}
/>
),
}}
/>
<Tab.Screen
name="Search"
component={Search}
options={{
tabBarLabel: "Search",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="magnify" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Saved"
component={Saved}
options={{
tabBarLabel: "Saved",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="heart" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}
export default function App() {
const navTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: "#171717",
},
};
return (
<NavigationContainer theme={navTheme}>
<MyTabs style={{ backgroundColor: "#171717" }}></MyTabs>
</NavigationContainer>
);
}
Yet my tabBar looks like this, I want it to be #171717, not white... Thank you in advance
The solution was to make a theme to change the background color:
export default function App() {
const navTheme = {
colors: {
background: "#171717"
}
};
return (
<NavigationContainer theme={navTheme}>
<MyTabs style={{ backgroundColor: "#171717" }}></MyTabs>
</NavigationContainer>
);
}
You can use this
<Tab.Navigator
tabBarOptions={{
style: {
backgroundColor:'#171717 '
}
}}>
{Screens}
</Tab.Navigator>

How can i customize react navigation v5 material bottom navigator?

I was trying to customize my material bottom navigation tab but there is not enough resource on the internet as far as i searched. Can you help me with this problem?
Here is my current bottom navigation tab:
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs';
interface IAppTabsProps extends IAppStackNavigationProps<'AppTabs'> {}
const Tabs = createMaterialBottomTabNavigator<AppTabsParamList>();
const AppTabs: React.FC<IAppTabsProps> = () => {
return (
<Tabs.Navigator labeled keyboardHidesNavigationBar initialRouteName="Home" shifting sceneAnimationEnabled>
<Tabs.Screen
name="Home"
component={Home}
options={{
tabBarIcon: ({ focused, ...props }) => (
<Ionicons name={focused ? 'home' : 'home-outline'} size={24} {...props} />
),
tabBarBadge: true,
tabBarLabel: 'Home',
}}
/>
<Tabs.Screen
name="Profile"
component={Profile}
options={{
tabBarIcon: props => <Ionicons name="ios-person" size={24} {...props} />,
tabBarLabel: 'Profile',
}}
/>
<Tabs.Screen
name="Notifications"
component={Notifications}
options={{
tabBarIcon: ({ focused, ...props }) => (
<FontistoIcons name={focused ? 'bell-alt' : 'bell'} size={24} {...props} />
),
tabBarLabel: 'Notifications',
tabBarBadge: 4,
}}
/>
<Tabs.Screen
name="Preferences"
component={Preferences}
options={{
tabBarIcon: props => <SimpleLineIcons name="settings" size={24} {...props} />,
tabBarLabel: 'Preferences',
}}
/>
</Tabs.Navigator>
);
};

Resources