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

feat: new method `getBottomTabHeight` added to BottomNavigationBar

Open Santhosh-Umapathi opened this issue 1 year ago • 2 comments
trafficstars

Motivation

Our app requires a feature "Scroll to show/hide BottomTabs" same as LinkedIn Bottom Tabs feature. Implementing this feature was not a problem, however to achieve this animation, we need the Height of the BottomTabs.

This height is retrieved from useBottomTabBarHeight();. But it does not calculate the height correctly on Android when we use Custom tabBar with createBottomTabNavigator from '@react-navigation/bottom-tabs'

Goal

To get the correct height of the rendered Bottom tabs when its using react-native-paper

Related issue

Currently, the BottomNavigationBar does not provide a way to get the height of the rendered BottomNavigationBar.

When using the useBottomTabBarHeight() it gives the height of the default bottom tabs from @react-navigation/bottom-tabs

Test plan

Please note that the zustand global store was used to store this bottom tab height, but can easily replicate with local state as well.

Example usage

const AndroidCustomTabBarWrapper = (props: BottomTabBarProps) => (
  <AndroidCustomTabBar {...props} />
);

const AndroidCustomTabBar = ({
  navigation,
  state,
  descriptors,
  insets,
}: BottomTabBarProps) => {
  const {actions} = useStore();

  const descriptor = descriptors[state.routes[state.index].key];

  // Get the options from the descriptor
  const {tabBarStyle} = descriptor.options;

  return (
    <Animated.View style={[tabBarStyle as AnimatedStyle<ViewStyle>]}>
      <BottomNavigation.Bar
        activeIndicatorStyle={styles.activeIndicatorStyle}
        inactiveColor={colors.grey[800]}
        style={styles.barStyle}
        navigationState={state}
        safeAreaInsets={insets}
        getBottomTabHeight={actions.setBottomTabHeight} // Patch - Set the height of the bottom tab bar
        onTabPress={({route, preventDefault}) => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
            canPreventDefault: true,
          });

          if (event.defaultPrevented) {
            preventDefault();
          } else {
            navigation.dispatch({
              ...CommonActions.navigate(route.name, route.params),
              target: state.key,
            });
          }
        }}
        renderIcon={({route, focused, color}) => {
          const {options} = descriptors[route.key];
          if (options.tabBarIcon) {
            return options.tabBarIcon({focused, color, size: spacings[24]});
          }

          return null;
        }}
        getLabelText={({route}) => {
          const {options} = descriptors[route.key];
          const label =
            options.tabBarLabel !== undefined
              ? options.tabBarLabel
              : options.title !== undefined
                ? options.title
                : undefined;

          return typeof label === 'string' ? label : undefined;
        }}
      />
    </Animated.View>
  );
};

export const BottomTabs = () => {
  return (
    <Tab.Navigator tabBar={AndroidCustomTabBarWrapper}>
      <Tab.Screen
        name={'Home'}
        component={()=><></>}
      />

    </Tab.Navigator>
  );
};

Santhosh-Umapathi avatar May 15 '24 14:05 Santhosh-Umapathi

Hey @Santhosh-Umapathi, thank you for your pull request 🤗. The documentation from this branch can be viewed here.

callstack-bot avatar May 15 '24 14:05 callstack-bot

Hi @gedu , Could you kindly look into this PR.

Santhosh-Umapathi avatar Jul 23 '24 06:07 Santhosh-Umapathi