TabNavigator extra padding - react-native

How to style the TabNavigator Tab's height and padding? Im doing the following:
import Icon from "react-native-vector-icons/MaterialIcons";
const tabNav = TabNavigator({
TabItem1: {
screen: MainScreen,
navigationOptions: {
tabBarLabel:"Home",
tabBarIcon: ({ tintColor }) => <Icon name={"home"} size={20} color={tintColor} />
}
},
TabItem2: {
screen: MainScreen,
navigationOptions: {
tabBarLabel:"Home",
tabBarIcon: ({ tintColor }) => <Icon name={"home"} size={30} color={tintColor} />
}
},
TabItem3: {
screen: MainScreen,
navigationOptions: {
tabBarLabel:"Browse",
tabBarIcon: ({ tintColor }) => <Icon name={"home"} color={tintColor} />
}
}
}, {
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: '#222',
activeBackgroundColor :'yellow', //Doesn't work
showIcon: true,
tabStyle: {
padding: 0, margin:0, //Padding 0 here
},
iconStyle: {
width: 30,
height: 30,
padding:0 //Padding 0 here
},
}
});
How do I get rid of the padding between the icon and the label? I did padding:0 in iconStyle and also in tabStyle but no luck. I want no padding below the label too. How do I do that? Thanks.
Found the extra padding is caused by View:
How do i get rid of that?

Solved by setting:
tabBarOptions: {
labelStyle: {
margin: 0
},
}

Try just style under tabBarOptions
tabBarOptions: {
style: {
height: 45
}
}

Unfortunately plenty of layout settings are hardcoded in this lib (like padding: 12 for tab which comes by default from elsewhere).
The only option is to look in node_modules\react-navigation\lib\views\TabView\ files and adjust as needed to your requirements.
Right now I'm hacking those sourses to find a quick-n-dirty way to allow rectangular (x>y), not only square (x=y, as defaulted) tab icons.
Other option is to create your custom tabBar component as maintainers suggest

I just did it by looking at this page https://reactnavigation.org/docs/en/material-top-tab-navigator.html
my TabStack looks like this:
const tabBarOptions = {
labelStyle: {
fontSize: 12,
},
tabStyle: {
width: 100,
},
style: {
paddingTop: 50,
backgroundColor: 'red',
},
}
export const TabStack = createMaterialTopTabNavigator({
History: History,
Current: Current,
Settings: Settings,
}, {
tabBarOptions: tabBarOptions
});

If you are using SafeAreaView inside your screen, remove it from root and you will be fine

Ran into a similar problem today and came across this post. My issue however had a - paddingBottom: 30 - being applied to the tabBarStyle.
I did not want to overwrite the package files since it could either lead to unforeseen issues elsewhere or it will be overwritten in future updates.
I simply set the value to it's negative to bring the overall padding being applied to 0 - ie. paddingBottom: -30
Not sure if it'll help someone but it helped me.

This is the actual way how you style your tab navigator
const screenOptions = {
tabBarStyle:{
height:50,
},
tabBarItemStyle:{
margin:5,
}
};
<Tab.Navigator {...{ screenOptions }}>
//Tabs Here
</Tab.Navigator >

Related

How to add icons to MaterialTopTabNavigator

I have an app in React Native v3. I have MaterialTopTabNavigator with text. It's working fine. But I need to add icons above text of tabs.
https://pasteboard.co/IuTpjGz.png
I have tried this (CommonIcon is my element, but I have also tried Icon from react-native-elements), but it's not working and VScode says ''CommonIcon' refers to a value, but is being used as a type here.'
When I run it in emulator, I got SyntaxError.
HomeScreen:{
screen:HomeScreen,
navigationOptions: {
tabBarLabel:"Home",
tabBarIcon: ({ tintColor }) => (
<CommonIcon name="ios-bookmarks" size={20}/>
)
},
},
...
tabBarOptions: {
showIcon: true
},
So my question is, how to createMaterialTopTabNavigator in React Native 3 with both labels and icons?
My colleague figured it out.
You should not put navigationOptions to the createMaterialTopTabNavigator. They belong to the page you want to go. In that page, you can specify options for it.
Main Page and Tab Navigator
export const IndraMainPage = createMaterialTopTabNavigator(
{
MarketTab: MarketPage,
TradesTab: TradesPage,
OrdersTab: OrdersPage,
EventsTab: EventsPage,
ReportsTab: ReportsPage,
},
{
order: ['ReportsTab', 'TradesTab', 'MarketTab', 'OrdersTab', 'EventsTab'],
initialRouteName: 'MarketTab',
tabBarPosition: 'bottom',
backBehavior: 'none',
lazy: true,
swipeEnabled: true,
tabBarOptions: {
upperCaseLabel: false,
activeTintColor: COLOR_PRIMARY,
inactiveTintColor: COLOR_TEXT,
showIcon: false,
tabStyle: {height: 55, flexDirection: 'column', padding: 0, paddingTop: 10},
style: {
backgroundColor: 'rgb(250,250,250)',
},
indicatorStyle: {backgroundColor: 'transparent'},
},
},
);
and then the specific page
export default class EventsPage extends Component<EventsPageProps, EventsPageState> {
static navigationOptions = {
tabBarVisible: true,
tabBarLabel: ({tintColor}: TabBarLabelProps) => (
<CenteredColumn>
<CommonIcon name="calendar" size={20} color={tintColor ? tintColor : COLOR_TEXT} />
<CommonText xs style={{color: tintColor ? tintColor : COLOR_TEXT}}>
Events Tab
</CommonText>
</CenteredColumn>
),
};
...

React Navigation MaterialTopTabNavigator - indicator did not follow custom tab bar width

I tried to customise the width of the tab bar. I managed to successfully do so, but the indicator is still consuming the whole width of the screen. Any idea on how to change the indicator width to follow the tab width? I know I can fully customise the tab bar, but is there any other way?
This is the current behaviour.
This is my configurations
const PersonalInfoTabs = createMaterialTopTabNavigator(
{
PersonalData: {
screen: PersonalData,
navigationOptions: {
title: 'A'
}
},
AccountSet: {
screen: AccountSet,
navigationOptions: {
title: 'B'
}
},
ModifyPassword: {
screen: ModifyPassword,
navigationOptions: {
title: 'C'
}
}
},
{
tabBarOptions: {
activeTintColor: 'black',
inactiveTintColor: 'black',
style: {
backgroundColor: 'yellow',
width: 300
}
}
}
);
From the documentation for React Navigation for React-Native, it looks like you also have to set the style for the tabs in the tabStyle field:
{
tabBarOptions: {
activeTintColor: 'black',
inactiveTintColor: 'black',
style: {
backgroundColor: 'yellow',
width: 300
},
tabStyle: {
width: 100
}
}
}
Thanks to #ValdaXD to point out the 100 width.
<Tab.Navigator
screenOptions={{
tabBarLabelStyle: { fontSize: 12 },
tabBarItemStyle: { width: 100 },
tabBarStyle: { backgroundColor: 'powderblue' },
}}
>
{/* ... */}
</Tab.Navigator>
tabBarItemStyle did the trick for me

How can I conditionally set tabs in createBottomTabNavigator?

I have a static data file (json) that stores information like facebook page link. If the facebook page link is empty, I do NOT want the Follow Us tab to show. The facebook page link is stored in businessDataJSON.facebook. Is there a way to only show the Follow Us Tab if businessDataJSON.facebook is not empty (empty string)? This is my App.js:
const ListStack = createStackNavigator(
{
ListCategories: ListCategoriesScreen,
ListCategoryItems: ListCategoryItemsScreen
},
{
initialRouteName: "ListCategories",
defaultNavigationOptions: {
headerStyle: {
backgroundColor: businessDataJSON.theme.navigationBarBackground
},
headerTintColor: businessDataJSON.theme.navigationBarTint,
headerTitleStyle: {
fontWeight: "bold"
}
}
}
);
const FollowUsStack = createStackNavigator(
{
FollowUs: FollowUsScreen
},
{
initialRouteName: "FollowUs",
defaultNavigationOptions: {
headerStyle: {
backgroundColor: businessDataJSON.theme.navigationBarBackground
},
headerTintColor: businessDataJSON.theme.navigationBarTint,
headerTitleStyle: {
fontWeight: "bold"
}
}
}
);
export default createAppContainer(
createBottomTabNavigator(
{
ListTab: {
screen: ListStack,
navigationOptions: {
title: businessDataJSON.theme.tabBarListTitle,
tabBarIcon: ({ tintColor }) => (
<Icon
name={businessDataJSON.theme.tabBarListIcon}
size={17}
color={tintColor}
/>
)
}
},
FollowUsStack: {
screen: FollowUsStack,
navigationOptions: {
title: "Follow Us",
tabBarIcon: ({ tintColor }) => (
<Icon name="users" size={17} color={tintColor} />
)
}
}
},
{
tabBarOptions: {
activeTintColor: businessDataJSON.theme.tabBarIconActive,
inactiveTintColor: businessDataJSON.theme.tabBarIconInactive,
style: {
elevation: 8,
...Platform.select({
ios: { paddingTop: 4, paddingBottom: 4 },
android: {
borderTopWidth: 0,
paddingTop: 6,
paddingBottom: 6
}
})
}
}
}
)
);
Yes but you would need to make the creation of the tabs dinamic wich leads to the navigation prop to be lost and make a nightmare to use it without redux. The simple approach that i can see is to use a root createSwitchNavigator with a loading screen/start screen and the tabs as the 2nd screen. in the loading screen you check if there is your facebook page, and navigate to them accordingly. this example is for auth, but it works in your case . trust me, the navigation props is a nightmare to manage.

How to Style React-Navigation tab navigator with a mobx variable

I think I've just been staring at this too long, and now my brain doesn't work. I have mobx stores, one of which houses a basic theme color value. I want to pass this into my react-navigation tab background color, but I can't figure out how to do it. We are using Typescript, and that might be part of what is confusing me, because every time I try to inject my store, I get a bunch of errors.
Anyway, if someone could help me figure out how to either inject my store properly, or to pass a prop to my createMaterialTopTabNavigator function, I would greatly appreciate it.
Here is my top tab navigator code:
export const SignedInWithGroup = createMaterialTopTabNavigator(
{
Home: {
screen: MeetingStack,
navigationOptions: {
tabBarLabel: 'Advocacy Day',
tabBarIcon: <Ionicons name="md-home" size={24} />,
},
},
Legislators: {
screen: Legislators,
navigationOptions: {
tabBarLabel: 'Legislators',
tabBarIcon: <Ionicons name="ios-people" size={24} />,
},
},
Messages: {
screen: Messages,
navigationOptions: {
tabBarLabel: 'Messages',
tabBarIcon: <Ionicons name="ios-chatboxes" size={24} />,
},
},
Directory: {
screen: DirectoryStack,
navigationOptions: {
tabBarLabel: 'Directory',
tabBarIcon: <MaterialIcons name="contacts" size={24} />,
},
},
More: {
screen: MoreStack,
navigationOptions: {
tabBarLabel: 'More',
tabBarIcon: <MaterialIcons name="more" size={24} />,
},
},
},
{
tabBarPosition: 'bottom',
tabBarOptions: {
showIcon: true,
style: {
paddingTop: Platform.OS === 'android' ? 0 : 0,
backgroundColor: "#CCBE00", //Replace with theme color
},
tabStyle: {
padding: 0,
},
labelStyle: {
marginTop: Platform.OS === 'ios' ? 8 : 0,
marginBottom: Platform.OS === 'ios' ? 20 : 10,
marginLeft: 15,
fontSize: 7,
color: 'white',
},
},
}
);
export const createRootNavigator = (props:any, signedIn = false) => {
console.log("Props");
console.log(props);
return createSwitchNavigator(
{ SignedInWithGroup: { screen: SignedInWithGroup }, SignedOut },
{ initialRouteName: signedIn ? 'SignedInWithGroup' : 'SignedOut' }
);
};
and here is what is in my app.js:
const Layout = createRootNavigator(signedIn);
return (
<Provider {...stores}>
<Layout />
</Provider>
);
Solution
Use your custom tabbar from MaterialTopTabBar.
Install the react-navigation-tabs module. Because, react-navigation's TabNaviagtion is from react-navigation-tabs. (srcs)
$ yarn install react-navigation-tabs
or
$ npm install react-navigation-tabs --save
Make your custom tabbar component observing store(MobX) for the tabBarComponent option . I do not write code related in MobX or Redux.
import React, { Component } from 'react';
import { MaterialTopTabBar } from 'react-navigation-tabs';
// create a component
class TabBar extends Component {
  render() {
    return (
      <MaterialTopTabBar
        {...this.props}
        style={{ backgroundColor: 'green' }} // Replace with theme color. You should use observing variable from MobX or Redux.
      />
    );
  }
}
//make this component available to the app
export default TabBar;
Apply your custom tabbar in createMaterialTopTabNavigator.
const TabNavigation = createMaterialTopTabNavigator(
  {
    Home: HomeScreen,
    Login: HomeScreen,
    Register: HomeScreen,
  },
  {
    tabBarComponent: (props) => { // Use your custom tabbar here.
return (
<TabBar
{...props}
/>
);
},
tabBarPosition: 'bottom',
tabBarOptions: {
showIcon: true,
style: {
paddingTop: Platform.OS === 'android' ? 0 : 0,
},
tabStyle: {
padding: 0,
},
labelStyle: {
marginTop: Platform.OS === 'ios' ? 8 : 0,
marginBottom: Platform.OS === 'ios' ? 20 : 10,
marginLeft: 15,
fontSize: 7,
color: 'white',
},
},
}
);
Why?
As I wrote, react-navigation-tabs is used as TabNavigation basically in react-navigation And you can use custom view through tabBarComponent option when you createTabNavigator
There are some mudules you can use.
Navigators
createBottomTabNavigator
createMaterialTopTabNavigator
Views
BottomTabBar
MaterialTopTabBar (You used this view)
Utils
createTabNavigator
Thus, extending component or making your custom tabbar from BottomTabBar or MaterialTopTabBar can be one of the easily solutions.

Custom View as background for StackNavigator

I need use one image below stack navigator or something like this.
Into StackNavigator I can set backgroundColor, opacity (view style) etc. But no possibility to set one background image or custom view component. Also if set to each screen its not good for screen translation.
I was try to wrap like this:
<ImageBackground>
<MyStackNavigator/>
</ImageBackground/>
No results.
Can you help me? +1 for any try
I found a solution
Navigator:
const AuthStackNavigator = StackNavigator({
LANDING: {
screen: LandingScreen
},
SIGN_IN: {
screen: SignInScreen
},
{
mode: 'card',
cardStyle: { backgroundColor: 'transparent' },
transitionConfig: () => ({
containerStyle: {
backgroundColor: 'transparent',
}
}),
initialRouteName: 'LANDING',
}
);
Render:
render() {
return <ImageBackground
style={{
width: null,
height: null,
backgroundColor: 'transparent',
flex: 1,
}}
source={landing_background}
>
<AuthStackNavigator
ref='navigator'
/>
</ImageBackground>
}