Search code examples
react-nativereact-navigationreact-native-drawer

React native - remove space between drawerIcon and item text on Drawer.Screen


I'm trying to adjust space between icon and text in drawer screen.

Here's an image to explain better.

Image showing space between icon and drawer item text

Here's my code

<Drawer.Navigator screenOptions={(navigation) => ({
        drawerItemStyle: {
           borderRadius: 0,
           width: '100%',
           marginLeft: 0
        }
      })}>
      <Drawer.Screen 
         name="HomeScreen" 
         component={HomeScreen} 
         options={{ 
            headerShown: true,  
            headerTransparent: true, 
            headerTitle: "", 
            title: 'Start Delivery',
            drawerIcon: (({focused}) => <Icon name="car" size={25} color={focused ? "#288df9" : "#777"} style={{padding:0, margin:0}} />)
         }} 
      />
</Drawer.Navigator>

Thanks


Solution

  • The default Drawer uses a DrawerItemList which is a list of DrawerItems. Looking at the source code, the view that wraps the label implements a marginLeft of 32. This is hardcoded and cannot be changed without using dirty tricks.

    Let us test this using the following example.

    function App() {
      return (
         <NavigationContainer>
          <Drawer.Navigator>
            <Drawer.Screen name="Home" component={Home} options={{drawerIcon: () => <View style={{height:20, width: 20, backgroundColor: "red"}} />}}  />
          </Drawer.Navigator>
        </NavigationContainer>
      );
    }
    

    The above uses a View as a dummy image with a red background. Here is the result.

    enter image description here

    Adding a marginRight of -32 to our icon removes the "gap" completely.

    function App() {
      return (
         <NavigationContainer>
          <Drawer.Navigator>
            <Drawer.Screen name="Home" component={Home} options={{drawerIcon: () => <View style={{height:20, width: 20, backgroundColor: "red", marginRight: -32}} />}}  />
          </Drawer.Navigator>
        </NavigationContainer>
      );
    }
    

    Here is the result.

    enter image description here

    This is not ideal since we have to do this for each icon, thus we could create a custom component and reuse it.

    const CustomIconComponent = ({focused, name}) => {
        return <View style={{marginRight: -32}}>
            <Icon name={name} size={25} color={focused ? "#288df9" : "#777"} />
        </View>
    }
    

    Then, use it for each screen.

    options={{ 
            
        ...
                title: 'Start Delivery',
                drawerIcon: (({focused}) => <CustomIconComponent focused={focused} />)
             }} 
    

    There is a second way. We could create a custom drawer. This would allow us to not use the DrawerItem component but a custom component with custom stylings.