How to adjust material top tabs width individually in react native - react-native

My goal is to copy WhatsApp UI. However, I am having trouble making the camera icon smaller while keeping the others flexed in the row direction. Below is code
<Tab.Navigator
screenOptions={{
tabBarPosition: 'top',
tabBarIndicatorStyle: {
backgroundColor: colors.text,
height: 4,
},
tabBarStyle: {
backgroundColor: colors.foreground,
},
tabBarContentContainerStyle: {
flexDirection: 'row',
flex: 1,
justifyContent: 'space-between',
// alignItems: 'center',
},
tabBarLabelStyle: {
fontWeight: '600',
},
tabBarActiveTintColor: colors.text,
tabBarInactiveTintColor: colors.secondaryText,
}}
initialRouteName="chats">
<Tab.Screen
name="Camera"
component={Camera}
options={{
tabBarIcon: ({ color }) => (
<AntDesign name="camera" size={24} color={color} />
),
tabBarLabel: () => null,
tabBarItemStyle: { width: 50 },
tabBarIconStyle: { width: 75 },
}}
/>
<Tab.Screen
name="Chats"
component={Chats}
/>
<Tab.Screen
name="Status"
component={Status}
/>
<Tab.Screen
name="Calls"
component={Calls}
/>
</Tab.Navigator>
After messing around with the width of tabBarItemStyle, I noticed that on click, it changes other tabs widths as well. In the documentation for tabBarItemStyle, it says it changes the individual styling, but it is not what I am experiencing. I get the following when I click the camera icon:
and when I click other tabs this:
I can't change the style of the tab individually, I tried lots of different variations. What am I missing? Thanks in advance.

Related

How to modify "selected tab" bottom border color on TopTabNavigator

I'm working on a react-native app using react-navigations createMaterialTopTabNavigator. I've read through the docs, but I cannot seem to find what props I need to modify to change the bottom border color of the active tab.
Does anyone have any advice?
FWIW here is my current Navigator code:
const TopTab = createMaterialTopTabNavigator()
function ProgressNavigator() {
const themes = useThemes()
return (
<TopTab.Navigator
screenOptions={{
tabBarStyle: {
backgroundColor: themes.lightBackground,
},
tabBarLabelStyle: {
paddingTop: 10,
fontSize: 14,
fontWeight: "bold",
},
tabBarActiveTintColor: themes.secondary.color,
tabBarInactiveTintColor: "#FFF",
}}
>
<TopTab.Screen name="Table" component={ProgressTable} />
<TopTab.Screen name="Chart" component={ProgressChart} />
</TopTab.Navigator>
)
}
Use tabBarIndicatorStyle to style an indicator. Below example sets label (and possible icon) and indicator to red.
<Tab.Navigator
screenOptions={{
tabBarIndicatorStyle: {
backgroundColor: 'red'
},
tabBarActiveTintColor: 'red',
}}>
...
</Tab.Navigator>

How to add an indicator under the active bottom tab?

I need to add an indicator for the active tab I tried to add a borderBottom with tabStyle but we can't check focused with that.
Using react-navigation v5 and createBottomTabNavigator for bottom tabs.
Here's my code:
<BottomTab.Navigator
tabBarOptions={{
activeTintColor: colors.brown,
labelPosition: 'below-icon',
}}>
<BottomTab.Screen
name="Home"
component={HomeTabNav}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({focused}) => {
return focused ? (
<HomeSelectedIcon height={ms(24)} width={ms(24)} />
) : (
<HomeIcon height={ms(24)} width={ms(24)} />
);
},
}}
/>
...
</BottomTab.Navigator>
);
};
Thanks in advance!
I figured it out myself by making a custom tabbar icon if someone needs to achieve this using the bottom-tab bar only.
Here's the code.
<BottomTab.Navigator
tabBarOptions={{
activeTintColor: colors.brown,
showLabel: false,
tabStyle: styles.tabStyle,
style: styles.tabContainerStyle,
}}>
<BottomTab.Screen
name="Home"
component={HomeTabNav}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({focused}) => {
return focused ? (
<View style={styles.labelFocusedContainer}>
<HomeSelectedIcon height={24} width={24} />
<Text style={styles.labelFocusedStyle}>Home</Text>
</View>
) : (
<View style={styles.labelContainer}>
<HomeIcon height={24} width={24} />
<Text style={styles.labelStyle}>Home</Text>
</View>
);
},
}}
/>
...
</BottomTab.Navigator>
const styles = StyleSheet.create({
labelContainer: {
alignItems: 'center',
width: '100%',
},
labelFocusedContainer: {
alignItems: 'center',
width: '100%',
borderBottomWidth: 3,
borderBottomColor: colors.brown,
},
labelFocusedStyle: {
textAlign: 'center',
marginVertical: 8,
color: colors.brown,
backgroundColor: 'transparent',
fontSize: 10,
},
labelStyle: {
textAlign: 'center',
marginVertical: 8,
color: colors.veryDarkgray,
backgroundColor: 'transparent',
fontSize: 10,
},
});
But the best and easy way to do this is by using createMaterialTopTabNavigator and using these props.
tabBarPosition="bottom"
tabBarOptions={{
showIcon: true,
pressOpacity: 1,
iconStyle: styles.iconStyle,
showLabel: true,
activeTintColor: colors.brown,
indicatorStyle: {
borderWidth: 2,
borderColor: colors.brown,
},
This does not seem to be possible / easily achievable with bottom-tabs, but you could use the material version - #react-navigation/material-top-tabs and configure it to match your needs, specifically using tabBarPosition="bottom" and tabBarOptions={{ indicatorStyle: { backgroundColor } }}.
You can check more options in the docs: https://reactnavigation.org/docs/material-top-tab-navigator/#tabbaroptions
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
const Tabs = createMaterialTopTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tabs.Navigator tabBarPosition="bottom" tabBarOptions={{ indicatorStyle: { backgroundColor: 'red' } }}>
<Tabs.Screen name="screen 1" component={View} />
<Tabs.Screen name="screen 2" component={View} />
</Tabs.Navigator>
</NavigationContainer>
);
}
The best answer would be to use the tabBarButton prop to override and add your own custom styles to the container of the tab button.
https://reactnavigation.org/docs/bottom-tab-navigator#tabbarbutton
const CustomTabButton = (props) => (
<Pressable
{...props}
style={
props.accessibilityState.selected
? [props.style, styles.activeTab]
: props.style
}
/>
)
styles.activeTab is the custom style you want to add, be careful to spread the props.style to get the default styles from the library like width, padding, height etc
props.accessibilityState.selected will add styles according to condition if you want styles for all the tabs you can remove the condition.
Inside screeenOptions prop on navigator or the option props of each screen.
tabBarButton: CustomTabButton
Using material top tab is not a good solution because it does not support well with a keyboard. But bottom tabs do work well with the keyboard.

Change the color of top navigation bar in react-native

I am new to react-native and I am working on developing a login application. The functionalities work completely fine. I want to change the color of the Navigation header(as shown in picture) from white to some other color. I looked but couldn't find a way to do the same. Can anyone guide me to correct pointer to achieve the same.
Here is the stackNavigation code that I am using :
const Login = createStackNavigator();
const LoginStack = () => {
return (
<Login.Navigator
initialRouteName="Welcome"
headerMode="float"
screenOptions={() => ({
headerTintColor: AppStyles.colorSet.mainBackgroundColor,
headerTitleStyle: styles.headerTitleStyle,
headerRight: () => <View />,
cardStyle: { backgroundColor: '#275362', }
})}
>
<Login.Screen name="Login" component={LoginScreen} />
<Login.Screen
options={{ headerShown: false }}
name="Welcome"
component={WelcomeScreen}
/>
</Login.Navigator>
);
};
const styles = StyleSheet.create({
headerTitleStyle: {
fontWeight: 'bold',
textAlign: 'center',
alignSelf: 'center',
color: 'red',
flex: 1,
},
});
If you want to change the header's background color for all the screens in your navigator:
<Login.Navigator
initialRouteName="Welcome"
headerMode="float"
screenOptions={{
headerStyle: {
backgroundColor: 'blue',
}
}}
>
If you only want to change the header's background color of your login screen:
<Login.Screen
name="Login"
component={LoginScreen}
options={{
headerStyle: {
backgroundColor: 'red',
}
}}
/>

How to horizontally center TopTabNavigator in React Native?

I've been struggling to apply the proper styling so that my Top Tab Navigator is horizontally centered on the screen. I've tried applying AlignItems: center to the different style props but that does not seem to work. Any tips?
Here is the documentation I have been following: https://reactnavigation.org/docs/material-top-tab-navigator/
import React from "react";
import { createMaterialTopTabNavigator } from "#react-navigation/material-top-tabs";
import Creators from "../../screens/Creators/Creators";
import Feed from "../../screens/Feed/Feed";
import Profile from "../../screens/Profile/Profile";
const Tab = createMaterialTopTabNavigator();
function TabNav() {
return (
<Tab.Navigator
tabBarOptions={{
labelStyle: {
fontSize: 12,
color: "white",
},
tabStyle: {
width: 100,
height: 40,
marginTop: 50,
},
indicatorStyle: {
backgroundColor: "white",
},
style: {
backgroundColor: "#03182d",
},
}}
>
<Tab.Screen name="Creators" component={Creators} />
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
);
}
export default TabNav;
remove tabStyle and it will work perfectly like this
<Tab.Navigator
tabBarOptions={{
labelStyle: {
fontSize: 12,
color: "white",
},
//remove this
//tabStyle: {
// width: 100,
// height: 40,
// marginTop: 50,
},
indicatorStyle: {
backgroundColor: "white",
},
style: {
backgroundColor: "#03182d",
},
}}
>
<Tab.Screen name="Creators" component={Creators} />
<Tab.Screen name="Feed" component={Feed} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
or remove only width as it is smudging your tabs

How to handle the SafeArea's background color with Bottom Tab Navigation?

Current Behavior
Hi everyone,
I want to set the background color for the Bottom Tab. So I did as below.
<Tab.Navigator
tabBarOptions={{
activeTintColor: '#FF0000',
activeBackgroundColor: '#FFFFFF',
inactiveBackgroundColor: '#FF0000',
inactiveTintColor: '#FFFFFF'
}}>
<Tab.Screen
name="Home"
component={HomeScreen}
/>
<Tab.Screen
name="Account"
component={AccountScreen}
/>
</Tab.Navigator>
The problem is the SafeArea has a white background
Expected Behavior
What I expect is
So could you tell me how to solve this issue in React Navigation version 5 please?
Thank you!
Your Environment
iOS
react-native: 0.61.5
#react-navigation/native: ^5.0.5
#react-navigation/bottom-tabs: ^5.0.5
I just set backgroundColor
<Tab.Navigator
initialRouteName="Stack_Main"
tabBarOptions={{
style: {
backgroundColor: "#FF0000",
},
}}
>
screenOptions={({route}) => ({
tabBarStyle: {backgroundColor: '#436332', borderTopColor: '#23321A'},
tabBarLabelStyle: {
fontWeight: '600',
fontSize: 12,
},
tabBarActiveTintColor: '#f1c522',
tabBarInactiveTintColor: '#f4f1de',
tabBarActiveBackgroundColor: '#436332',
tabBarInactiveBackgroundColor: '#436332',
})}
I found a option (I don't like but it work) in this answer: How do you make the react-native react-navigation tab bar transparent
<Tab.Navigator
tabBarOptions={{
showLabel: false,
activeTintColor: theme.primary,
inactiveTintColor: theme.tintInactiveTabBar,
style: {
backgroundColor: theme.backgroundTabBar,
position: 'absolute',
left: 0,
bottom: 0,
right: 0,
borderTopRightRadius: 10,
borderTopLeftRadius: 10,
},
}}>...</Tab.Navigator>
Put position: absolute and bottom, left and right attributes. It works for me.
#react-navigation^v6.x you need to add tabBarStyle: { backgroundColor: 'red'} in the screenOptions prop.
For example:
<Tab.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#141E30',
},
headerTintColor: '#BBC8D6',
headerBackTitleVisible: false,
headerTitleStyle: {color: '#BBC8D6'},
tabBarShowLabel: false,
tabBarStyle: {
backgroundColor: '#141E30',
},
}}>
<Tab.Screen
options={{
tabBarIcon: () => (
<Icon
name="th-list"
size={25}
color="#BBC8D6"
style={{paddingVertical: 10}}
/>
),
title: 'ToDos',
// tabBarBadge: 3,
}}
name={HOME}
component={HomeScreen}
/>
<Tab.Screen
options={{
tabBarIcon: () => (
<Icon
name="image"
size={25}
color="#BBC8D6"
style={{paddingVertical: 10}}
/>
),
title: 'Floor Plan',
}}
name={FLOOR_PLAN}
component={FloorPlanScreen}
/>
<Tab.Screen
options={{
tabBarIcon: () => (
<Icon
name="user-circle-o"
size={25}
color="#BBC8D6"
style={{paddingVertical: 10}}
/>
),
title: 'Profile',
}}
name={PROFILE}
component={ProfileScreen}
/>
</Tab.Navigator>