diff --git a/packages/react-navigation/docs/api/navigators/DrawerNavigator.md b/packages/react-navigation/docs/api/navigators/DrawerNavigator.md
index bd759db9..a524b3f4 100644
--- a/packages/react-navigation/docs/api/navigators/DrawerNavigator.md
+++ b/packages/react-navigation/docs/api/navigators/DrawerNavigator.md
@@ -94,21 +94,6 @@ The route configs object is a mapping from route name to a route config, which t
- `useNativeAnimations` - Enable native animations. Default is `true`.
- `drawerBackgroundColor` - Use the Drawer background for some color. The Default is `white`.
-#### Example:
-
-Default the `DrawerView` isn't scrollable.
-To achieve a scrollable `View`, you have to use the `contentComponent` to customize the container,
-as you can see in the example below.
-
-```js
-{
- drawerWidth: 200,
- drawerPosition: 'right',
- contentComponent: props => ,
- drawerBackgroundColor: 'transparent'
-}
-```
-
Several options get passed to the underlying router to modify navigation logic:
- `initialRouteName` - The routeName for the initial route.
@@ -118,15 +103,17 @@ Several options get passed to the underlying router to modify navigation logic:
### Providing a custom `contentComponent`
-You can easily override the default component used by `react-navigation`:
+The default component for the drawer is scrollable and only contains links for the routes in the RouteConfig. You can easily override the default component to add a header, footer, or other content to the drawer. By default the drawer is scrollable and supports iPhone X safe area. If you customize the content, be sure to wrap the content in a SafeAreaView:
```js
-import { DrawerItems } from 'react-navigation';
+import { DrawerItems, SafeAreaView } from 'react-navigation';
const CustomDrawerContentComponent = (props) => (
-
-
-
+
+
+
+
+
);
const styles = StyleSheet.create({
@@ -145,7 +132,6 @@ const styles = StyleSheet.create({
- `inactiveTintColor` - label and icon color of the inactive label
- `inactiveBackgroundColor` - background color of the inactive label
- `onItemPress(route)` - function to be invoked when an item is pressed
-- `itemsContainerForceInset` - override default forceInset on the SafeAreaView that wraps the items container component
- `itemsContainerStyle` - style object for the content section
- `itemStyle` - style object for the single item, which can contain an Icon and/or a Label
- `labelStyle` - style object to overwrite `Text` style inside content section, when your label is a string
diff --git a/packages/react-navigation/src/navigators/DrawerNavigator.js b/packages/react-navigation/src/navigators/DrawerNavigator.js
index 42efc57d..6b597226 100644
--- a/packages/react-navigation/src/navigators/DrawerNavigator.js
+++ b/packages/react-navigation/src/navigators/DrawerNavigator.js
@@ -1,7 +1,7 @@
/* @flow */
import React from 'react';
-import { Dimensions, Platform } from 'react-native';
+import { Dimensions, Platform, ScrollView } from 'react-native';
import createNavigator from './createNavigator';
import createNavigationContainer from '../createNavigationContainer';
@@ -9,6 +9,7 @@ import TabRouter from '../routers/TabRouter';
import DrawerScreen from '../views/Drawer/DrawerScreen';
import DrawerView from '../views/Drawer/DrawerView';
import DrawerItems from '../views/Drawer/DrawerNavigatorItems';
+import SafeAreaView from '../views/SafeAreaView';
import NavigatorTypes from './NavigatorTypes';
@@ -25,13 +26,21 @@ export type DrawerNavigatorConfig = {
const { height, width } = Dimensions.get('window');
+const defaultContentComponent = (props: *) => (
+
+
+
+
+
+);
+
const DefaultDrawerConfig = {
/*
* Default drawer width is screen width - header width
* https://material.io/guidelines/patterns/navigation-drawer.html
*/
drawerWidth: Math.min(height, width) - (Platform.OS === 'android' ? 56 : 64),
- contentComponent: DrawerItems,
+ contentComponent: defaultContentComponent,
drawerPosition: 'left',
drawerBackgroundColor: 'white',
useNativeAnimations: true,
diff --git a/packages/react-navigation/src/navigators/__tests__/__snapshots__/DrawerNavigator-test.js.snap b/packages/react-navigation/src/navigators/__tests__/__snapshots__/DrawerNavigator-test.js.snap
index 34462de9..9b39e994 100644
--- a/packages/react-navigation/src/navigators/__tests__/__snapshots__/DrawerNavigator-test.js.snap
+++ b/packages/react-navigation/src/navigators/__tests__/__snapshots__/DrawerNavigator-test.js.snap
@@ -91,99 +91,146 @@ exports[`DrawerNavigator renders successfully 1`] = `
]
}
>
-
-
-
- Welcome anonymous
-
+
+
+ Welcome anonymous
+
+
+
-
-
+
+
diff --git a/packages/react-navigation/src/views/Drawer/DrawerNavigatorItems.js b/packages/react-navigation/src/views/Drawer/DrawerNavigatorItems.js
index 3ed4427e..0fbcf7e3 100644
--- a/packages/react-navigation/src/views/Drawer/DrawerNavigatorItems.js
+++ b/packages/react-navigation/src/views/Drawer/DrawerNavigatorItems.js
@@ -31,6 +31,7 @@ type Props = {
itemStyle?: ViewStyleProp,
labelStyle?: TextStyleProp,
iconContainerStyle?: ViewStyleProp,
+ drawerPosition: 'left' | 'right',
};
/**
@@ -47,61 +48,63 @@ const DrawerNavigatorItems = ({
getLabel,
renderIcon,
onItemPress,
- itemsContainerForceInset = { horizontal: 'never', top: 'always' },
itemsContainerStyle,
itemStyle,
labelStyle,
iconContainerStyle,
+ drawerPosition,
}: Props) => (
-
-
- {items.map((route: NavigationRoute, index: number) => {
- const focused = activeItemKey === route.key;
- const color = focused ? activeTintColor : inactiveTintColor;
- const backgroundColor = focused
- ? activeBackgroundColor
- : inactiveBackgroundColor;
- const scene = { route, index, focused, tintColor: color };
- const icon = renderIcon(scene);
- const label = getLabel(scene);
- return (
- {
- onItemPress({ route, focused });
+
+ {items.map((route: NavigationRoute, index: number) => {
+ const focused = activeItemKey === route.key;
+ const color = focused ? activeTintColor : inactiveTintColor;
+ const backgroundColor = focused
+ ? activeBackgroundColor
+ : inactiveBackgroundColor;
+ const scene = { route, index, focused, tintColor: color };
+ const icon = renderIcon(scene);
+ const label = getLabel(scene);
+ return (
+ {
+ onItemPress({ route, focused });
+ }}
+ delayPressIn={0}
+ >
+
-
-
- {icon ? (
-
- {icon}
-
- ) : null}
- {typeof label === 'string' ? (
-
- {label}
-
- ) : (
- label
- )}
-
-
-
- );
- })}
-
-
+
+ {icon ? (
+
+ {icon}
+
+ ) : null}
+ {typeof label === 'string' ? (
+
+ {label}
+
+ ) : (
+ label
+ )}
+
+
+
+ );
+ })}
+
);
/* Material design specs - https://material.io/guidelines/patterns/navigation-drawer.html#navigation-drawer-specs */
diff --git a/packages/react-navigation/src/views/Drawer/DrawerSidebar.js b/packages/react-navigation/src/views/Drawer/DrawerSidebar.js
index a2d3d898..1a04114c 100644
--- a/packages/react-navigation/src/views/Drawer/DrawerSidebar.js
+++ b/packages/react-navigation/src/views/Drawer/DrawerSidebar.js
@@ -7,6 +7,8 @@ import withCachedChildNavigation from '../../withCachedChildNavigation';
import NavigationActions from '../../NavigationActions';
import invariant from '../../utils/invariant';
+import SafeAreaView from '../SafeAreaView';
+
import type {
NavigationScreenProp,
NavigationRoute,
@@ -34,6 +36,7 @@ type Props = {
contentOptions?: {},
screenProps?: {},
style?: ViewStyleProp,
+ drawerPosition?: 'left' | 'right',
};
/**
@@ -123,6 +126,7 @@ class DrawerSidebar extends React.PureComponent {
renderIcon={this._renderIcon}
onItemPress={this._onItemPress}
router={this.props.router}
+ drawerPosition={this.props.drawerPosition}
/>
);
diff --git a/packages/react-navigation/src/views/Drawer/DrawerView.js b/packages/react-navigation/src/views/Drawer/DrawerView.js
index d7597c51..732324c1 100644
--- a/packages/react-navigation/src/views/Drawer/DrawerView.js
+++ b/packages/react-navigation/src/views/Drawer/DrawerView.js
@@ -134,6 +134,7 @@ export default class DrawerView extends React.PureComponent<
router={this.props.router}
contentComponent={this.props.contentComponent}
contentOptions={this.props.contentOptions}
+ drawerPosition={this.props.drawerPosition}
style={this.props.style}
/>
);