Introducing flat options (#984)

* Initial commit

* Remove HybridExample (#985)

* Remove HybridExample

* Remove last mention of HelloHybrid

* Remove console log

* Fix flow and example

* Fix routers api docs

* Keep options in single place

* chore

* Fix styling

* Organise miscs

* Better flow type for screen options

* Flow test website and add more types to options

* navigationOptions instead of prevOptions makes more sense

* Fixes

* Fix up docs

* Fix

* Update route decl

* Provide error when removed API is used

* Remove lock

* Add validators

* Make StacksOverTabs config valid again

* Do not return

* Fix redbox
This commit is contained in:
Mike Grabowski
2017-04-13 00:49:08 +02:00
committed by Eric Vicenti
parent fb2a0ad33d
commit 93976d358e
59 changed files with 1168 additions and 4727 deletions

View File

@@ -5,16 +5,14 @@ Used to easily set up a screen with a drawer navigation.
```js
class MyHomeScreen extends React.Component {
static navigationOptions = {
drawer: () => ({
label: 'Home',
icon: ({ tintColor }) => (
<Image
source={require('./chats-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
}),
}
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<Image
source={require('./chats-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
@@ -28,16 +26,14 @@ class MyHomeScreen extends React.Component {
class MyNotificationsScreen extends React.Component {
static navigationOptions = {
drawer: () => ({
label: 'Notifications',
icon: ({ tintColor }) => (
<Image
source={require('./notif-icon.png')}
style={[styles.tabIcon, {tintColor: tintColor}]}
/>
),
}),
}
drawerLabel: 'Notifications',
drawerIcon: ({ tintColor }) => (
<Image
source={require('./notif-icon.png')}
style={[styles.tabIcon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
@@ -94,7 +90,7 @@ The route configs object is a mapping from route name to a route config, which t
#### Example:
Default the `DrawerView` isn't scrollable.
To achieve a scrollable `View`, you have to use the `contentComponent` to customize the container,
To achieve a scrollable `View`, you have to use the `contentComponent` to customize the container,
as you can see in the example below.
```js
@@ -124,8 +120,8 @@ const CustomDrawerContentComponent = (props) => (
);
const styles = StyleSheet.create({
container : {
flex : 1,
container: {
flex: 1,
},
});
```
@@ -152,31 +148,17 @@ contentOptions: {
### Screen Navigation Options
Usually you define static `navigationOptions` on your screen component. For example:
#### `title`
```jsx
class ProfileScreen extends React.Component {
Generic title that can be used as a fallback for `headerTitle` and `drawerLabel`
static navigationOptions = {
#### `drawerLabel`
title: ({ state }) => `${state.params.name}'s Profile!`,
String, React Element or a function that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in drawer sidebar. When undefined, scene `title` is used
drawer: {
icon: (
<Image src={require('./my-icon.png')} />
),
},
};
...
```
All `navigationOptions` for the `DrawerNavigator`:
- `title` - a title (string) of the scene
- `drawer` - a config object for the drawer:
- `label` - String, React Element or a function that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in drawer sidebar. When undefined, scene `title` is used
- `icon` - React Element or a function, that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in drawer sidebar
#### `drawerIcon`
React Element or a function, that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in drawer sidebar
### Navigator Props
@@ -191,6 +173,6 @@ The navigator component created by `DrawerNavigator(...)` takes the following pr
});
<DrawerNav
screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
screenProps={/* this prop will get passed to the screen components and nav options as props.screenProps */}
/>
```

View File

@@ -57,9 +57,9 @@ StackNavigator({
// The action and route params are extracted from the path.
// Optional: Override the `navigationOptions` for the screen
navigationOptions: {
title: ({state}) => `${state.params.username}'s Profile'`,
},
navigationOptions: ({navigation}) => ({
title: `${navigation.state.params.username}'s Profile'`,
}),
},
...MyOtherRoutes,
@@ -91,44 +91,49 @@ Visual options:
### Screen Navigation Options
Usually you define static `navigationOptions` on your screen component. For example:
#### `title`
```jsx
class ProfileScreen extends React.Component {
Generic title that can be used as a fallback for `headerTitle` and `tabBarLabel`
static navigationOptions = {
#### `headerVisible`
title: ({ state }) => `${state.params.name}'s Profile!`,
True or false to show or hide the header. Only works when `headerMode` is `screen`. Default value is `true`.
header: ({ state, setParams }) => ({
// Render a button on the right side of the header
// When pressed switches the screen to edit mode.
right: (
<Button
title={state.params.editing ? 'Done' : 'Edit'}
onPress={() => setParams({editing: state.params.editing ? false : true})}
/>
),
}),
};
...
```
#### `headerTitle`
All `navigationOptions` for the `StackNavigator`:
String or React Element used by the header. Defaults to scene `title`
- `title` - a title (string) of the scene
- `header` - a config object for the header bar:
- `visible` - Boolean toggle of header visibility. Only works when `headerMode` is `screen`.
- `title` - String or React Element used by the header. Defaults to scene `title`
- `backTitle` - Title string used by the back button on iOS or `null` to disable label. Defaults to scene `title`
- `right` - React Element to display on the right side of the header
- `left` - React Element to display on the left side of the header
- `style` - Style object for the header
- `titleStyle` - Style object for the title component
- `tintColor` - Tint color for the header
- `pressColorAndroid` - Color for material ripple (Android >= 5.0 only)
- `cardStack` - a config object for the card stack:
- `gesturesEnabled` - Whether you can use gestures to dismiss this screen. Defaults to true on iOS, false on Android
#### `headerBackTitle`
Title string used by the back button on iOS or `null` to disable label. Defaults to scene `title`
#### `headerRight`
String or React Element to display on the right side of the header
#### `headerLeft`
String or React Element to display on the left side of the header
#### `headerStyle`
Style object for the header
#### `headerTitleStyle`
Style object for the title component
#### `headerTintColor`
Tint color for the header
#### `headerPressColorAndroid`
Color for material ripple (Android >= 5.0 only)
#### `gesturesEnabled`
Whether you can use gestures to dismiss this screen. Defaults to true on iOS, false on Android
### Navigator Props

View File

@@ -5,17 +5,15 @@ Used to easily set up a screen with several tabs with a TabRouter.
```js
class MyHomeScreen extends React.Component {
static navigationOptions = {
tabBar: {
label: 'Home',
// Note: By default the icon is only shown on iOS. Search the showIcon option below.
icon: ({ tintColor }) => (
<Image
source={require('./chats-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
},
}
tabBarLabel: 'Home',
// Note: By default the icon is only shown on iOS. Search the showIcon option below.
tabBarIcon: ({ tintColor }) => (
<Image
source={require('./chats-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
@@ -29,16 +27,14 @@ class MyHomeScreen extends React.Component {
class MyNotificationsScreen extends React.Component {
static navigationOptions = {
tabBar: {
label: 'Notifications',
icon: ({ tintColor }) => (
<Image
source={require('./notif-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
},
}
tabBarLabel: 'Notifications',
tabBarIcon: ({ tintColor }) => (
<Image
source={require('./notif-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
@@ -154,46 +150,35 @@ tabBarOptions: {
### Screen Navigation Options
Usually you define static `navigationOptions` on your screen component. For example:
#### `title`
```jsx
class ProfileScreen extends React.Component {
Generic title that can be used as a fallback for `headerTitle` and `tabBarLabel`
static navigationOptions = {
#### `tabBarVisible`
title: ({ state }) => `${state.params.name}'s Profile!`,
True or false to show or hide the tab bar, if not set then defaults to true
tabBar: ({ state, setParams }) => ({
icon: (
<Image src={require('./my-icon.png')} />
),
}),
};
...
```
#### `tabBarIcon`
All `navigationOptions` for the `TabNavigator`:
React Element or a function that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in tab bar
#### `tabBarLabel`
Title string of a tab displayed in the tab bar. When undefined, scene `title` is used. To hide, see `tabBarOptions.showLabel` in the previous section.
- `title` - a title (string) of the scene
- `tabBar` - a config object for the tab bar:
- `visible` - Boolean toggle of tab bar visibility
- `icon` - React Element or a function that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in tab bar
- `label` - Title string of a tab displayed in the tab bar. When undefined, scene `title` is used. To hide, see `tabBarOptions.showLabel` in the previous section
### Navigator Props
The navigator component created by `TabNavigator(...)` takes the following props:
- `screenProps` - Pass down extra options to child screens, for example:
- `screenProps` - Pass down extra options to child screens and navigation options, for example:
```jsx
const TabNav = TabNavigator({
// config
});
<TabNav
screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
/>
```

View File

@@ -72,30 +72,32 @@ Based on the routeNames in the state, the router is responsible for returning va
Returns the active component for a deep navigation state.
### `getActionForPathAndParams`
### `getActionForPathAndParams(path, params)`
Returns an optional navigation action that should be used when the user navigates to this path and provides optional query parameters.
### `getPathAndParamsForState`
### `getPathAndParamsForState(state)`
Returns the path and params that can be put into the URL to link the user back to the same spot in the app.
The path/params that are output from this should form an action when passed back into the router's `getActionForPathAndParams`. That action should take you to a similar state once passed through `getStateForAction`.
### `getScreenConfig`
### `getScreenOptions(navigation, screenProps)`
Used to retrieve the navigation options for a route. Must provide the screen's current navigation prop, and the name of the option to be retrieved.
Used to retrieve the navigation options for a screen. Must provide the screen's current navigation prop and optionally, other props that your navigation options may need to consume.
- `navigation` - This is the navigation prop that the screen will use, where the state refers to the screen's route/state. Dispatch will trigger actions in the context of that screen.
- `optionName` - What named option is being fetched, such as 'title'
- `screenProps` - Other props that your navigation options may need to consume
- `navigationOptions` - The previous set of options that are default or provided by the previous configurer
Inside an example view, perhaps you need to fetch the configured title:
```js
// First, prepare a navigation prop for your child, or re-use one if already available.
const childNavigation = addNavigationHelpers({
const screenNavigation = addNavigationHelpers({
// In this case we use navigation.state.index because we want the title for the active route.
state: navigation.state.routes[navigation.state.index],
dispatch: navigation.dispatch,
})
const screenTitle = this.props.router.getScreenConfig(childNavigation, 'title');
});
const options = this.props.router.getScreenOptions(screenNavigation, {});
const title = options.title;
```

View File

@@ -75,8 +75,8 @@ _configureTransition(transitionProps, prevTransitionProps) {
- An object of type [NavigationTransitionSpec](https://github.com/react-community/react-navigation/blob/master/src/TypeDefinition.js#L316) that will be fed into an Animated timing function as its config
### `navigationState` object
A plain object that represents the navigation state
### `navigation` prop
An object with `state` that represents the navigation state, with `routes` and an active route `index`. Also includes `dispatch` and other methods for requesting actions.
#### Example value