Drawer Improvement, Let define a route key to open/close multiple dra… (#1803)

* Drawer Improvement, Let define a route key to open/close multiple drawer with no side effects

* fix lint issues

* fix flow issues
This commit is contained in:
Flo
2017-11-29 16:01:35 +01:00
parent 3fee1bdeb9
commit 8462821dd7
4 changed files with 124 additions and 18 deletions

View File

@@ -19,6 +19,7 @@ import Banner from './Banner';
import CustomTabs from './CustomTabs';
import CustomTransitioner from './CustomTransitioner';
import Drawer from './Drawer';
import MultipleDrawer from './MultipleDrawer';
import TabsInDrawer from './TabsInDrawer';
import ModalStack from './ModalStack';
import StacksInTabs from './StacksInTabs';
@@ -43,6 +44,11 @@ const ExampleRoutes = {
description: 'Android-style drawer navigation',
screen: Drawer,
},
MultipleDrawer: {
name: 'Multiple Drawer Example',
description: 'Add any drawer you need',
screen: MultipleDrawer,
},
TabsInDrawer: {
name: 'Drawer + Tabs Example',
description: 'A drawer combined with tabs',

View File

@@ -0,0 +1,80 @@
/**
* @flow
*/
import React from 'react';
import { Button, Platform, ScrollView, StyleSheet } from 'react-native';
import { DrawerNavigator } from 'react-navigation';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import SampleText from './SampleText';
const MyNavScreen = ({ navigation, banner }) => (
<ScrollView style={styles.container}>
<SampleText>{banner}</SampleText>
<Button
onPress={() => navigation.navigate('DrawerOpen')}
title="Open drawer"
/>
<Button onPress={() => navigation.goBack(null)} title="Go back" />
</ScrollView>
);
const InboxScreen = ({ navigation }) => (
<MyNavScreen banner={'Inbox Screen'} navigation={navigation} />
);
InboxScreen.navigationOptions = {
drawerLabel: 'Inbox',
drawerIcon: ({ tintColor }) => (
<MaterialIcons
name="move-to-inbox"
size={24}
style={{ color: tintColor }}
/>
),
};
const DraftsScreen = ({ navigation }) => (
<MyNavScreen banner={'Drafts Screen'} navigation={navigation} />
);
DraftsScreen.navigationOptions = {
drawerLabel: 'Drafts',
drawerIcon: ({ tintColor }) => (
<MaterialIcons name="drafts" size={24} style={{ color: tintColor }} />
),
};
const DrawerExample = DrawerNavigator(
{
Inbox: {
path: '/',
screen: InboxScreen,
},
Drafts: {
path: '/sent',
screen: DraftsScreen,
},
},
{
initialRouteName: 'Drafts',
contentOptions: {
activeTintColor: '#e91e63',
},
}
);
const MainDrawerExample = DrawerNavigator({
Drafts: {
screen: DrawerExample,
},
}, {
drawerOpenRoute: 'FooDrawerOpen',
drawerCloseRoute: 'FooDrawerClose',
});
const styles = StyleSheet.create({
container: {
marginTop: Platform.OS === 'ios' ? 20 : 0,
},
});
export default MainDrawerExample;

View File

@@ -70,7 +70,11 @@ const DefaultDrawerConfig = {
const DrawerNavigator = (
routeConfigs: NavigationRouteConfigMap,
config: DrawerNavigatorConfig = {}
config: DrawerNavigatorConfig = {
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
}
) => {
const mergedConfig = { ...DefaultDrawerConfig, ...config };
const {
@@ -82,6 +86,9 @@ const DrawerNavigator = (
drawerPosition,
useNativeAnimations,
drawerBackgroundColor,
drawerOpenRoute,
drawerCloseRoute,
drawerToggleRoute,
...tabsConfig
} = mergedConfig;
@@ -89,7 +96,7 @@ const DrawerNavigator = (
const drawerRouter = TabRouter(
{
DrawerClose: {
[drawerCloseRoute]: {
screen: createNavigator(
contentRouter,
routeConfigs,
@@ -99,15 +106,15 @@ const DrawerNavigator = (
<DrawerScreen {...props} />
)),
},
DrawerOpen: {
[drawerOpenRoute]: {
screen: () => null,
},
DrawerToggle: {
[drawerToggleRoute]: {
screen: () => null,
},
},
{
initialRouteName: 'DrawerClose',
initialRouteName: drawerCloseRoute,
}
);
@@ -126,6 +133,9 @@ const DrawerNavigator = (
contentComponent={contentComponent}
contentOptions={contentOptions}
drawerPosition={drawerPosition}
drawerOpenRoute={drawerOpenRoute}
drawerCloseRoute={drawerCloseRoute}
drawerToggleRoute={drawerToggleRoute}
/>
));

View File

@@ -33,6 +33,9 @@ export type DrawerViewConfig = {
drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open',
drawerWidth?: number | (() => number),
drawerPosition?: 'left' | 'right',
drawerOpenRoute: string,
drawerCloseRoute: string,
drawerToggleRoute: string,
contentComponent?: React.ComponentType<*>,
contentOptions?: {},
style?: ViewStyleProp,
@@ -81,14 +84,19 @@ export default class DrawerView extends React.PureComponent<
if (
this.props.navigation.state.index !== nextProps.navigation.state.index
) {
const {
drawerOpenRoute,
drawerCloseRoute,
drawerToggleRoute,
} = this.props;
const { routes, index } = nextProps.navigation.state;
if (routes[index].routeName === 'DrawerOpen') {
if (routes[index].routeName === drawerOpenRoute) {
this._drawer.openDrawer();
} else if (routes[index].routeName === 'DrawerToggle') {
} else if (routes[index].routeName === drawerToggleRoute) {
if (this._drawer.state.drawerShown) {
this.props.navigation.navigate('DrawerClose');
this.props.navigation.navigate(drawerCloseRoute);
} else {
this.props.navigation.navigate('DrawerOpen');
this.props.navigation.navigate(drawerOpenRoute);
}
} else {
this._drawer.closeDrawer();
@@ -100,27 +108,28 @@ export default class DrawerView extends React.PureComponent<
_screenNavigationProp: NavigationScreenProp<NavigationStateRoute>;
_handleDrawerOpen = () => {
const { navigation } = this.props;
const { navigation, drawerOpenRoute } = this.props;
const { routes, index } = navigation.state;
if (routes[index].routeName !== 'DrawerOpen') {
this.props.navigation.navigate('DrawerOpen');
if (routes[index].routeName !== drawerOpenRoute) {
this.props.navigation.navigate(drawerOpenRoute);
}
};
_handleDrawerClose = () => {
const { navigation } = this.props;
const { navigation, drawerCloseRoute } = this.props;
const { routes, index } = navigation.state;
if (routes[index].routeName !== 'DrawerClose') {
this.props.navigation.navigate('DrawerClose');
if (routes[index].routeName !== drawerCloseRoute) {
this.props.navigation.navigate(drawerCloseRoute);
}
};
_updateScreenNavigation = (
navigation: NavigationScreenProp<NavigationState>
) => {
const { drawerCloseRoute } = this.props;
// $FlowFixMe there's no way type the specific shape of the nav state
const navigationState: NavigationStateRoute = navigation.state.routes.find(
(route: *) => route.routeName === 'DrawerClose'
(route: *) => route.routeName === drawerCloseRoute
);
if (
this._screenNavigationProp &&
@@ -146,8 +155,9 @@ export default class DrawerView extends React.PureComponent<
};
_getNavigationState = (navigation: NavigationScreenProp<NavigationState>) => {
const { drawerCloseRoute } = this.props;
const navigationState = navigation.state.routes.find(
(route: *) => route.routeName === 'DrawerClose'
(route: *) => route.routeName === drawerCloseRoute
);
return navigationState;
};
@@ -168,7 +178,7 @@ export default class DrawerView extends React.PureComponent<
render() {
const DrawerScreen = this.props.router.getComponentForRouteName(
'DrawerClose'
this.props.drawerCloseRoute
);
const screenNavigation = addNavigationHelpers({