callstackincubator/react-native-bottom-tabs

☂ TabView Configuration

Closed this issue · 19 comments

The goal of this umbrella issue is to implement missing configuration options for TabView:

  • barTintColor - Background color of the tab bar (@shubhamguptadream11) #55
  • activeTintColor - Color of the active tab icon and label. (Handled in #42)
  • inactiveTintColor - Color of the inactive tab icon and label. (Handled in #42)
  • translucent - (iOS) A Boolean value that indicates whether the tab bar is translucent (@shubhamguptadream11)
  • rippleColor (Android) - Color of ripple effect (@sarthak-d11) #56
  • activeIndicatorColor (Android) - Color of tab indicator (@shubhamguptadream11)

just an idea, but we could use the NavigationContainer theme (from @react-navigation/native package) as a default value for a couple of those props

https://developer.apple.com/documentation/uikit/uitabbar/3750912-scrolledgeappearance
on iOS the new default seems that the tabbar is transparent until content scrolls below the tabbar.
WIP PR: #22

Working on tint color
WIP PR: #42

I am looking into barTintColor.

I checked JS bottom tabs there we have tabBarActiveBackgroundColor & tabBarInactiveBackgroundColor as props for background color of tabs. I am going to implement something similar for Native Bottom Tabs as well.

Is this okay @okwasniewski

Hey @shubhamguptadream11 great to have you as a contributor! 👍🏻

There is an open PR #42 adding tint colors should be merged soon so I think you can work on something different.

@okwasniewski Is tintColor and barTintColor same?

Ah no, its not! Sorry 😅

Go ahead 👍🏻

I want to look into unselectedTintColor. Is this okay @okwasniewski

Hey @sarthak-d11 I updated the issue description looks like unselectedTintColor is handled in #42 you can pick something else 👍🏻

In that case, Can I look into rippleColor? @okwasniewski

In that case, Can I look into rippleColor? @okwasniewski

Sure! I'll assign you

Current Behavior in JS Bottom Tabs Related to Background Color of Tabs

Prop Names:

  • tabBarActiveBackgroundColor
  • tabBarInactiveBackgroundColor

To illustrate the behavior, let’s consider the following code:

<Tab.Navigator 
  screenOptions={{ 
    headerShown: false, 
    tabBarActiveBackgroundColor: 'red', 
    tabBarInactiveBackgroundColor: 'green' 
  }}
>
  <Tab.Screen 
    name="Article" 
    component={Article} 
    options={{
      tabBarActiveBackgroundColor: 'blue',
      tabBarInactiveBackgroundColor: 'skyblue'
    }}
  />
  <Tab.Screen 
    name="Albums" 
    component={Albums} 
    options={{
      tabBarActiveBackgroundColor: 'orange',
      tabBarInactiveBackgroundColor: 'red'
    }}
  />
  <Tab.Screen name="Contacts" component={Contacts} />
  <Tab.Screen name="Chat" component={Chat} />
</Tab.Navigator>

Initial Setup:

  • The default Navigator level provides an active background color of 'red' and an inactive background color of 'green'.
  • The Article tab has specific colors: 'blue' (active) and 'skyblue' (inactive).
  • The Albums tab has 'orange' (active) and 'red' (inactive).
  • The Contacts and Chat tabs do not specify background colors.

Behavior at Initial Mount:

  • The Article tab is active:
    • Active background color: 'blue' (specified at the tab level).
    • Inactive tabs adopt 'skyblue' as the background color since the inactive color of the selected tab (Article) is applied to all inactive tabs.

Behavior on Switching to Albums:

  • The Albums tab becomes active:
    • Active background color: 'orange' (specified at the tab level).
    • Inactive tabs (now Article, Contacts, and Chat) change to 'red', the inactive color of the selected tab (Albums).

Behavior on Switching to Contacts:

  • The Contacts tab becomes active:
    • Active background color: 'red' (from Navigator, since no specific color is set for Contacts).
    • Inactive tabs adopt the color 'green' from the Navigator-level settings.

Summary:

  • If active and inactive colors are specified at the tab level, these settings take precedence for the selected tab and all inactive tabs.
  • If no tab-specific settings are found, the colors are taken from the Navigator level settings.
  • If not specified at either level, default settings are applied.

Note:
In every case, the inactive color for all tabs is the same. It is either taken from the options of the currently selected tab or from the Navigator options. However, it is not set individually for each inactive tab.

Attaching video for reference:
video_2.webm

@okwasniewski
What do you think should we go with implementing this behaviour in Native bottom tabs or just apply tabBarActiveBackgroundColor and tabBarInActiveBackgroundColor at Navigator level?

@shubhamguptadream11

Thanks for outlining how it works on JS tabs!

A while ago there was Native Tab Bar implementation inside of RN Core (https://github.com/facebook/react-native/blob/v0.56.0/React/Views/RCTTabBar.m)

It supported barTintColor which was the color of the tab bar background.

I'm not sure if setting the color of individual items makes sense for the native tab bar I think for custom scenarios users should pick JS Tab Bar.

My idea with this prop was to change the tab bar background at the navigator level (which in this case doesn't need to be divided into active and inActive). Let me know what you think, maybe there is a use case to change colors per tab but I don't think native components support it anyways.

@okwasniewski
Yeah, I agree—setting individual item colors for the native tab bar doesn’t really make sense.

I also checked iOS implementation there we have barTintColor or UITabBarAppearance().backgroundColor which basically set the backgroundColor of tabBar irrespective of active or inactive tabs.

I am going with this approach in both platform

@okwasniewski
Can you explain translucent and activeIndicatorColor a bit in detail.

This is what I understood.

translucent (iOS)

  • Meaning: This property is a Boolean value (either true or false) that determines whether the tab bar should be translucent on iOS devices. And this ideally should be available at Navigator level.

Doubt: How will it override already applied barTintColor?

activeIndicatorColor(Android):
Doubt: Is this background color of active tab? If yes, should it be at individual tab level or it will be at navigator level?

@shubhamguptadream11

  • Meaning: This property is a Boolean value (either true or false) that determines whether the tab bar should be translucent on iOS devices. And this ideally should be available at Navigator level.

Yes! This was also available in RN Core before: https://github.com/facebook/react-native/blob/v0.56.0/React/Views/RCTTabBar.m

Doubt: How will it override already applied barTintColor?

Im guessing It won't have any effect because if you set the background of the tab bar its not translucent anymore.

activeIndicatorColor(Android):
Doubt: Is this background color of active tab? If yes, should it be at individual tab level or it will be at navigator level?

For Material Design 3 there is an active indicator, there is an API setItemActiveIndicatorColor which can be used for it.

This involves double checking how it works with #42

Reference: https://developer.android.com/reference/com/google/android/material/navigation/NavigationBarView#setItemActiveIndicatorColor(android.content.res.ColorStateList)

Got it.

@okwasniewski Can you assign translucent and barStyle property on me?

Since activeIndicatorColor is somewhat depedent over #42 will pick this after if available.

Hey @shubhamguptadream11

I moved dissapear on scroll to a separate issue so we are only missing activeIndicatorColor for Android.

With this implemented we will be able to have fully custom colored TabView!

CleanShot 2024-10-27 at 13 36 09@2x

FYI, it's itemActiveIndicatorColor property of Android's BottomNavigationView. Should I assign you to the last feature?

Yeah sure!!
You can assign this to me. I will be happy to help here as well.