How to add drawerIcon inside options in React Native - react-native

Here is my code:
<Drawer.Screen
name="Home"
component={StackNavigator}
options={({route}) => {
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Billing';
if (sideMenuDisabledScreens.includes(routeName))
return {swipeEnabled: false};
}}
/>
I am implementing drawer navigator in my application and I want to add icon for drawer item home. Inside options I have added route to disable drawer for particular screens. After adding the route disable code I am not able to mention icons for drawerIcon. How can I do this?

i get your point, you can have both properties just like this
options={({route}) => {
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Billing';
if (sideMenuDisabledScreens.includes(routeName))
return {swipeEnabled: false};
},
{
drawerIcon: // add your comp here,
title:" THIS is possible",
}
}
Hope ite helps. feel free for doubts

Add drawerIcon property like the following:
drawerIcon: ({ tintColor }) => (
<Image
source={require('./chats-icon.png')}
style={[{ tintColor: tintColor }]}
/>
),

Related

Nested Navigation Stack does not find navigator

I am want to add a secondary Navigation so that a subset of screens have access to providers, as opposed to the whole stack being wrapped by providers they do not need access to. However, I think there is something wrong with my nested setup because I get an error when clicking a button that would navigate to the substack:
ERROR The action 'NAVIGATE' with payload {"name":"VehicleDetailInspections","params":{"vehicleId":27541}} was not handled by any navigator.
Do you have a screen named 'VehicleDetailInspections'?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.
The link to this only shows tabs & drawers, which we do not have.
My setup is:
HOMESTACK
const HomeStack = createNativeStackNavigator<HomeStackParams>();
export function HomeNavigator(): JSX.Element {
const styles = useInspectionStyles();
return (
<VehicleDataProvider>
<HomeStack.Navigator
screenOptions={{
headerStyle: styles.headerStyles,
headerBackVisible: false,
headerTitle: '',
headerLeft: () => <GoBack />,
}}
>
<HomeStack.Group
screenOptions={{
headerShadowVisible: false,
headerStyle: [styles.headerStyles],
}}
>
<HomeStack.Screen
name={VEHICLE_DETAIL}
component={VEHICLE_DETAIL.component}
/>
</HomeStack.Group>
/*
// I have tried both of these options:
<HomeStack.Group>
{() => <InspectionNavigator />}
</HomeStack.Group>
// or
<HomeStack.Screen
name={'InspectionSubStack'}
component={InspectionNavigator}
/>
*/
</HomeStack.Navigator>
</VehicleDataProvider>
);
}
In the above HomeStack, in the VEHICLE_DETAIL screen, there is a button which when clicked navigates to VEHICLE_DETAIL_INSPECTIONS which is part of the InspectionStack below.
const navigation = useNavigation<NavigationProp<InspectionStackParams>>();
...
onPress={() =>
navigation.navigate('VEHICLE_DETAIL_INSPECTIONS', {
vehicleId: vehicle.id,
})
}
INSPECTION substack:
const InspectionStack = createNativeStackNavigator<InspectionStackParams>();
export function InspectionNavigator(): JSX.Element {
const styles = useInspectionStyles();
return (
<InspectionsDataProvider>
<InspectionProgresssProvider>
<InspectionStack.Navigator
screenOptions={{
headerStyle: styles.headerStyles,
headerBackVisible: false,
headerTitle: '',
headerLeft: () => <GoBack />,
}}
>
<InspectionStack.Screen
name={VEHICLE_DETAIL_INSPECTIONS}
component={
VEHICLE_DETAIL_INSPECTIONS.component
}
/>
<InspectionStack.Screen
name={VEHICLE_INSPECTIONS_SECTION].name}
component={
VEHICLE_INSPECTIONS_SECTION.component
}
/>
<InspectionStack.Screen
name={VEHICLE_INSPECTIONS_STEP}
component={VEHICLE_INSPECTIONS_STEP.component}
/>
</InspectionStack.Navigator>
</InspectionProgresssProvider>
</InspectionsDataProvider>
);
}
What do I need to do to get the InspectionNavigator to be found by the navigate() from HomeStack?

React-Native: tabLongPress event listener on react-navigation bottom tabs

I'm using #react-navigation/material-bottom-tabs and it works great!
How can I add the listener for the long press event on tab icons?
<Tab.Navigator ...>
<Tab.Screen
...
options={{
tabBarIcon: ({ focused, color }) => (
<FontAwesomeIcon
icon={icon}
color={color}
size={24}
/>
),
}}
listeners={{
tabPress: () => console.log('tabPress')
}}
/>
</Tab.Navigator>
I tried the following ways to resolve this issue but none works.
Wrap FontAwesomeIcon with gesture handler
Add tabLongPress listener
First of all prevent default behavior
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
// Do something manually
});
return unsubscribe;
}, [navigation]);

React Navigation Tab.Screen set Component as name

What i want to do is the following when using the react navigation package.
The docs allow the following:
<Tab.Screen name="name" component={FeedScreen} />
what i want to achieve is this:
<Tab.Screen name={<NameMarkdown />} component={FeedScreen} />
because i want to render markdown as the name of a tab in my application.
is there a way to solve the problem?
The name prop only accepts the string name of the screen you can't pass the component into a name prop.
To give customize the style of your tab you can use it like this
<Tab.Navigator
screenOptions={tabScreenOptions}
tabBarOptions={tabBarOptions}
>
<Tab.Screen name="name" component={FeedScreen} />
tabBarOptions = {
showLabel: false,
style: styles.tabContainer,
tabStyle: styles.tabStyle,
};
tabScreenOptions = props => {
const { route } = props;
return {
tabBarIcon: ({ focused }) => <TabIcon {...{ route, focused }} />,
};
};
const TabIcon = ({ focused, route }) => (
// Here you can use your own component according to your need
<Image
source={Images.tabs[route.name]}
style={{ tintColor: focused ? Colors.primary : Colors.white214 }}
/>
);
Hope this helps you out.

React Navigation V5 does not receive focused parameter when using custom bottomTab component

I am currently trying to implement a custom tabBar design into my react native app which is using React Navigation 5 as the navigation library. Everything is working correctly, except that my tabBarIcons don't receive any props, so i cannot determine whether i have to show the active or inactive tabIcon. Whenever i use a default tabbar i do receive the props, so there must be something wrong in my custom tabbar. I did follow the docs though, and only find the instruction to emit the 'tabPress' event. I do however think that i should emit more events to get the correct focused prop. I have set up the navigator like this:
const Tabs = createBottomTabNavigator();
export default () => (
<Tabs.Navigator tabBar={TabBarComponent} initialRouteName="Home">
<Tabs.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ focused }) => {
// The props here are {}, so focused is undefined.
const icon = focused
? require('images/iconOverviewRed.png')
: require('images/iconOverviewGrey.png');
return <Image source={icon} />;
},
}}
/>
<Tabs.Screen
name="Overview"
component={OverviewScreen}
options={{
tabBarIcon: props => {
console.log(props);
return <Image source={require('images/logoRed.png')} />;
},
}}
/>
<Tabs.Screen
name="Account"
component={AccountScreen}
options={{
tabBarIcon: ({ focused }) => {
const icon = focused
? require('images/iconAccountRed.png')
: require('images/iconAccountGrey.png');
return <Image source={icon} resizeMethod="resize" />;
},
}}
/>
</Tabs.Navigator>
);
And this is my custom tabBar compnent:
const TabBar = ({ navigation, state, descriptors }: any) => {
return (
<View style={styles.container}>
{state.routes.map((route: any) => {
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!event.defaultPrevented) {
navigation.dispatch({
...TabActions.jumpTo(route.name),
target: state.key,
});
}
};
return (
<TabIcon
key={route.key}
Icon={descriptors[route.key].options.tabBarIcon}
onPress={onPress}
isBig={route.name === 'Home'}
/>
);
})}
</View>
);
};
const TabIcon = ({ onPress, Icon, key, isBig }: any) => {
return (
<TouchableWithoutFeedback key={key} onPress={onPress}>
<View style={isBig ? styles.bigTab : styles.defaultTab} key={key}>
<Icon />
</View>
</TouchableWithoutFeedback>
);
};
Thanks in advance.
descriptors[route.key].options just gives you the options as you have specified them. If you log the value of descriptors[route.key].options.tabBarIcon, you'll see that it prints the function that you have specified.
In your custom tab bar, it's upto you to use the option as you need. Since it's a function here, you'll have to call it and pass desired arguments.
descriptors[route.key].options.tabBarIcon({ focused: state.index === index })
This also means that you fully control the option. You can put whatever type you'd like, function, a require statement directly etc. and then use that. You also don't have to call it tabBarIcon, you can call it whatever you want.

React native drawer (for iOS & Android) disable/drawerLock mode not working

I am new in React native development,I have completed drawer functionality using following tutorial and github example:-
Drawer Git hub link
Drawer Tutorial link
So,According to above link Drawer component has one disable parameter which is helpful to lock drawer.
In my case,I have:-
Login Page :- So I am trying to lock the drawer when user is not logged into system.
Home Page :- So when ever user logged in successfully,I have open this page and unlock my drawer.
Added render() method for reference:-
render() {
<Drawer
ref={(ref) => this._drawer = ref}
disabled={!this.state.drawerEnabled}
type="overlay"
content={<Menu navigate={(route) => {
this._navigator.push(navigationHelper(route));
this._drawer.close()
}}/>}
tapToClose={true}
openDrawerOffset={0.2}
panCloseMask={0.2}
closedDrawerOffset={-3}
styles={{
drawer: {shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3},
main: {paddingLeft: 3}
}}
tweenHandler={(ratio) => ({
main: { opacity:(2-ratio)/2 }
})}>
<Navigator
ref={(ref) => this._navigator = ref}
configureScene={(route) => Navigator.SceneConfigs.FloatFromLeft}
initialRoute={{
id: 'Login',
title: 'Login',
index: 0
}}
renderScene={(route, navigator) => this._renderScene(route, navigator)}
navigationBar={
<Navigator.NavigationBar
style={styles.navBar}
routeMapper={NavigationBarRouteMapper} />
}
/>
</Drawer>
);
}
So,My problem is:-
disabled parameter is not working.I have tried with `setState()' function also but the result is same.
Please suggest me other drawer examples/tutorials which works in above case.
I think React Navigation library is best option. Which is fully customizable and supported both Android and IOS. You should use Drawer Navigator, can get documentation here.
Here I am adding code sample, that How I am locked/unlocked the drawer.
Here StackApp will be your Stack Navigator which contain all the
drawer pages.
StackApp.navigationOptions = ({ navigation }) => {
let drawerLockMode = 'unlocked';
if (navigation.state.index > 0) {
drawerLockMode = 'locked-closed'; //For child page it will lock drawer
}
return {
drawerLockMode
};
};
const DrawerStack = createDrawerNavigator({
StackHome: {screen: StackApp},
// Auth: {screen: AuthScreen},
}
,{
drawerWidth:width*0.8,
contentComponent: (props) =>
<ScrollView>
<Menu {...props}/>
</ScrollView>
});
check react native documentation and find 'drawerLockMode'