createStackNavigator with submenu - react-native

How can I create a submenu in createStackNavigator?
I created my navigation as below:
const MainStackNavigator = createStackNavigator({
Home: {
screen: HomeScreen,
navigationOptions: {
headerTitle: 'iRent'
}
},
Company: {
screen: CompanyDetails,
navigationOptions: {
headerTitle: 'Company Details'
}
},
Snapshots: {
screen: PropSnapshot,
navigationOptions: {
headerTitle: 'Property Snapshots'
}
}
}, {
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Ionicons
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
});
const AppDrawerNavigator = createDrawerNavigator({
myApp: {
screen: MainStackNavigator
},
Home: {
screen: HomeScreen,
navigationOptions: {
drawerIcon: <FontAwesome name="home" size={20} />
}
},
Company: {
screen: CompanyDetails,
navigationOptions: {
drawerIcon: <FontAwesome name="building-o" size={20} />
}
},
Snapshots: {
screen: PropSnapshot,
navigationOptions: {
drawerIcon: <MaterialIcons name="data-usage" size={20} />
}
},
LogOut: {
screen: Login,
navigationOptions: {
title: 'Log Out',
drawerIcon: <Entypo name="log-out" size={20} />
}
}
});
const AppSwitchNavigator = createSwitchNavigator({
Login: { screen: Login },
ForgotPassword: { screen: ForgotPassword },
Main: { screen: AppDrawerNavigator }
});
const AppContainer = createAppContainer(AppSwitchNavigator);
It is working perfect, but how can I add submenus to the Company menu. I would like to have "Company Details", "Company Test" under the Company menu in the left menu bar. Is it possible to do using the createStackNavigator?
Thanks!

As far I understand, you need a dropdown menu which will contain your companies details when you click on company.
If you want this, then try to do with drawer navigation.
When you click on company a drawer will open between company and snapshot.
Rest navigate as you want.

Related

React Navigation with nested stack and drawer navigator

Am trying to develop an simple app, which has auth , drawer , and other stacks ! I am unable to nest each of these.
This is the flow :
--AuthStack
--SplashScreen
--Login
--FogotPassword
--DrawerStack
--DrawerStack
--MainAppStack
--Training
--etc
--MainAppStack
--Home
--screen2
--screen3
etc, For example After auth flow, my main screen would be drawer screen which is Home Screen from mainAppStack. Now, how can i navigate from home to screen2 and screen3 etc ?
I am not getting header, and i couldnt set header title. And while using hardware back its going to Home screen.
Please Guide !
And my navigator setup !
const AppStackNavigator = createStackNavigator({
Home: {
screen: Home,
navigationOptions: {
header: null
}
},
StoreList: {
screen: StoreList,
navigationOptions: {
header: null
}
},
EditSurvey: {
screen: EditSurvey,
navigationOptions: {
header: null
}
},
StoreSurvey: {
screen: StoreSurvey,
navigationOptions: {
header: null
}
},
Competition: {
screen: Competition,
navigationOptions: {
header: null
},
},
Display: {
screen: Display,
navigationOptions: {
header: null
},
},
SurveyCheckList: {
screen: SurveyCheckList,
navigationOptions: {
headerTransparent: true
}
},
});
const DrawerNavigator = createDrawerNavigator({
Dashboard: {
screen: AppStackNavigator,
navigationOptions: {
drawerLabel: "Home",
}
},
Training: {
screen: TrainingList,
navigationOptions: {
drawerLabel: "Training"
}
},
RoutePlan: {
screen: RouteCalendar,
navigationOptions: {
drawerLabel: "Route Plan"
}
}
},
{
contentOptions: {
activeTintColor: '#127CC1',
},
contentComponent: props => <DrawerComponent {...props}/>,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
navigationOptions : ({navigation}) => {
const { routeName } = navigation.state.routes[navigation.state.index];
const headerTitle = routeName;
return {
headerTitle,
headerLeft: (
<Icon name="md-menu" style={{ marginLeft: 10 }}
onPress={() => navigation.toggleDrawer()}
/>
)
}
}
}
);
const AuthStackNavigator = createStackNavigator(
{
SplashScreen: {
screen: SplashScreen,
navigationOptions: {
headerTransparent: true
}
},
LoginScreen: {
screen: Login,
navigationOptions: {
headerTransparent: true
}
},
Drawer: DrawerNavigator,
});

React Navigation: Is it possible to navigate to the same screen from different stackNavigators?

I'm coding an app that uses react-navigation. My app has a bottom TabNavigator in which each tab consists of a stackNavigator, like so:
Routes.js:
const FirstStack = createStackNavigator({
First: {
screen: FirstScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const SecondStack = createStackNavigator({
Second: {
screen: SecondScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const ThirdStack = createStackNavigator({
Third: {
screen: ThirdScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const FourthStack = createStackNavigator({
Fourth: {
screen: FourthScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
const FifthStack = createStackNavigator({
Fifth: {
screen: FifthScreen,
navigationOptions: {
header: props => <AppToolbar />
}
}
});
export const AppStack = createBottomTabNavigator(
{
First: {
screen: FirstStack,
navigationOptions: {
title: "First",
tabBarLabel: "First",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-home" color={tintColor} size={24} />
)
}
},
Second: {
screen: SecondStack,
navigationOptions: {
title: "Second",
tabBarLabel: "Second",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-clock" color={tintColor} size={24} />
)
}
},
Third: {
screen: ThirdStack,
navigationOptions: {
title: "Third",
tabBarLabel: "Third",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-fitness" color={tintColor} size={24} />
)
}
},
Fourth: {
screen: FourthStack,
navigationOptions: {
title: "Fourth",
tabBarLabel: "Fourth",
tabBarIcon: ({ tintColor }) => (
<Icon
name="ios-cloud-download"
color={tintColor}
size={24}
/>
)
}
},
Fifth: {
screen: FifthStack,
navigationOptions: {
title: "Fifth",
tabBarLabel: "Fifth",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-person" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: "First",
order: ["First", "Second", "Third", "Fourth", "Fifth"],
tabBarOptions: {
activeTintColor: "white",
inactiveTintColor: "grey",
style: {
backgroundColor: "#121212",
borderTopColor: "#303030"
}
}
}
);
Each stackNavigator inside the tabs in the tabNavigator has its own header so that I can customize the header for each tab, but all headers have a button which should navigate to the profile screen (in this example its the contact icon).
AppToolbar.js:
const appToolbar = props => {
return (
<View style={styles.toolbar}>
<Text style={styles.toolbarTitle}>Title</Text>
<TouchableOpacity onPress={...}>
<Icon
name="ios-contact"
color="grey"
size={30}
style={{ padding: 0, margin: 0, marginRight: 10 }}
/>
</TouchableOpacity>
</View>
);
};
What I want to do is that by pressing the contact icon the app should navigate to the profile screen, what I don't know is if its possible to define like a global route thats accesible from everywhere, Or do I have to add the profile screen to all the stackNavigators so that it is accesible from every screen in every stack?
Thanks in advance!
Found the answer here https://stackoverflow.com/a/50701940/1276438
Use a stackNavigator with the profile stack and the tabNavigator as children, making the tabNavigator the default route.

How to force drawer to be over header with react navigation

I saw other answers regarding this issue but I can't find solution.
I want to show drawer always above app screen and above header. Instead drawer is always bellow header.
What am I doing wrong here:
const AppNavigation = createStackNavigator(
{
Main: { screen: Main, navigationOptions: {
title: "Main"
} },
Home: { screen: Home, navigationOptions: {
title: "Home"
} }
},
{
initialRouteName: "Main"
}
);
const DrawerNavigation = createDrawerNavigator(
{
Home: Home,
Main: Main
},
{
initialRouteName: "Main"
}
);
App = createStackNavigator({
drawer: {
screen: DrawerNavigation,
},
app: {
screen: AppNavigation
}
}, {
initialRouteName: 'drawer',
navigationOptions: ({navigation}) => ({
headerStyle: {backgroundColor: '#a9a9a9'},
title: 'Welcome!',
headerTintColor: 'white',
headerLeft: <Text onPress={() =>
navigation.dispatch(DrawerActions.toggleDrawer())}>Menu</Text>
})
});
export default () => (
<View style={{ flex: 1 }}>
<App />
</View>
Our app is similar to this. You can make the drawer be over the header with react-navigation if it is the <Root /> component of your app (the one you import into index.js). For example:
export const Root = DrawerNavigator({
Tabs: {
screen: Tabs,
title: 'Tabs'
},
STACK1: {
screen: STACK1,
title: 'STACK1',
},
STACK2: {
screen: STACK2,
title: 'STACK2',
},
});
That will give you something like this:

Functions are not valid as a React child (React-Native)

I can not wrap my head around and understand why am I given this warning, I am using two kinds of navigators ( tab navigator and stack navigator ), in App.js and I cannot seem to get them working correctly
App.js
export const Tabs = TabNavigator({
'FormScreen': {
screen: FormScreen,
navigationOptions: {
tabBarLabel: 'Contact Us',
tabBarIcon: ({ tintColor }) => <Icon name="ios-contact" type="entypo" size={28} color={tintColor} />
}
},
'ListScreen': {
screen: ListScreen,
navigationOptions: {
tabBarLabel: 'Contact List',
tabBarIcon: ({ tintColor }) => <Icon name="list" type="entypo" size={28} color={tintColor} />
}
}
});
export const NavigationScreen = () => {
return StackNavigator(
{
Tabs: {
screen: Tabs,
navigationOptions: {
gesturesEnabled: false
}
}
},
{
headerMode: "none",
mode: "modal"
}
);
};
export default class App extends React.Component {
render() {
return (
<NavigationScreen/>);
}
}

React native: createStackNavigator overlaps on the actual screen contents (Android)

I am creating a sample hotels listing application with following menus:
export const loggedInMenu = createMaterialBottomTabNavigator(
{
Hotels: {
screen: hotelDetailsScreen,
navigationOptions: {
tabBarLabel: "Hotels",
tabBarIcon: <Icon name="hotel" size={24} />
}
},
HotelsSearch: {
screen: HotelsSearch,
navigationOptions: {
tabBarLabel: "Search",
tabBarIcon: <Icon name="search" size={24} />
}
},
Favourites: {
screen: Favourites,
navigationOptions: {
tabBarLabel: "Hotels",
tabBarIcon: <Icon name="favorite" size={24} />
}
},
},
{
initialRouteName: 'Hotels'
}
);
export const hotelDetailsScreen = createStackNavigator(
{
Hotels: {screen: Hotels},
hotelDetails: {screen: hotelDetails},
},
{
initialRouteName: "Hotels",
headerLayoutPreset: "center",
navigationOptions: {
title: "Hotels",
headerTransparent: true,
headerStyle: {
backgroundColor: '#694fad'
}
}
}
);
The code works, however with one exception that the initial hotels screen header is overlapping the view data. Any help appreciated.
Check the below output:
Turns out that the docs was misleading (at least for me). I specified headerTransparent: true, which was Not needed as I just wanted to set the background color on the screen. I removed it and started working well.