Skip to content

Commit 93976d3

Browse files
grabbouericvicenti
authored andcommitted
Introducing flat options (react-navigation#984)
* Initial commit * Remove HybridExample (react-navigation#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
1 parent fb2a0ad commit 93976d3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1164
-4723
lines changed

.editorconfig

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# EditorConfig is awesome: http://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
# Unix-style newlines with a newline ending every file
7+
[*]
8+
end_of_line = lf
9+
insert_final_newline = true
10+
indent_style = space
11+
indent_size = 2
12+
13+
[*.gradle]
14+
indent_size = 4

.flowconfig

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
; Ignore unexpected extra "@providesModule"
1515
.*/node_modules/.*/node_modules/fbjs/.*
1616

17+
; Ignore website node_modules react and react-native
18+
<PROJECT_ROOT>/website/node_modules/react/.*
19+
<PROJECT_ROOT>/website/node_modules/react-native/.*
20+
<PROJECT_ROOT>/website/node_modules/fbjs/.*
21+
1722
; Ignore duplicate module providers
1823
; For RN Apps installed via npm, "Libraries" folder is inside
1924
; "node_modules/react-native" but in the source repo it is in the root
@@ -23,7 +28,6 @@
2328
<PROJECT_ROOT>/lib
2429
<PROJECT_ROOT>/lib-rn
2530
<PROJECT_ROOT>/examples
26-
<PROJECT_ROOT>/website
2731

2832
[include]
2933

File renamed without changes.

docs/api/navigators/DrawerNavigator.md

+26-44
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,14 @@ Used to easily set up a screen with a drawer navigation.
55
```js
66
class MyHomeScreen extends React.Component {
77
static navigationOptions = {
8-
drawer: () => ({
9-
label: 'Home',
10-
icon: ({ tintColor }) => (
11-
<Image
12-
source={require('./chats-icon.png')}
13-
style={[styles.icon, {tintColor: tintColor}]}
14-
/>
15-
),
16-
}),
17-
}
8+
drawerLabel: 'Home',
9+
drawerIcon: ({ tintColor }) => (
10+
<Image
11+
source={require('./chats-icon.png')}
12+
style={[styles.icon, {tintColor: tintColor}]}
13+
/>
14+
),
15+
};
1816

1917
render() {
2018
return (
@@ -28,16 +26,14 @@ class MyHomeScreen extends React.Component {
2826

2927
class MyNotificationsScreen extends React.Component {
3028
static navigationOptions = {
31-
drawer: () => ({
32-
label: 'Notifications',
33-
icon: ({ tintColor }) => (
34-
<Image
35-
source={require('./notif-icon.png')}
36-
style={[styles.tabIcon, {tintColor: tintColor}]}
37-
/>
38-
),
39-
}),
40-
}
29+
drawerLabel: 'Notifications',
30+
drawerIcon: ({ tintColor }) => (
31+
<Image
32+
source={require('./notif-icon.png')}
33+
style={[styles.tabIcon, {tintColor: tintColor}]}
34+
/>
35+
),
36+
};
4137

4238
render() {
4339
return (
@@ -94,7 +90,7 @@ The route configs object is a mapping from route name to a route config, which t
9490
#### Example:
9591

9692
Default the `DrawerView` isn't scrollable.
97-
To achieve a scrollable `View`, you have to use the `contentComponent` to customize the container,
93+
To achieve a scrollable `View`, you have to use the `contentComponent` to customize the container,
9894
as you can see in the example below.
9995

10096
```js
@@ -124,8 +120,8 @@ const CustomDrawerContentComponent = (props) => (
124120
);
125121

126122
const styles = StyleSheet.create({
127-
container : {
128-
flex : 1,
123+
container: {
124+
flex: 1,
129125
},
130126
});
131127
```
@@ -152,31 +148,17 @@ contentOptions: {
152148

153149
### Screen Navigation Options
154150

155-
Usually you define static `navigationOptions` on your screen component. For example:
151+
#### `title`
156152

157-
```jsx
158-
class ProfileScreen extends React.Component {
153+
Generic title that can be used as a fallback for `headerTitle` and `drawerLabel`
159154

160-
static navigationOptions = {
161-
162-
title: ({ state }) => `${state.params.name}'s Profile!`,
163-
164-
drawer: {
165-
icon: (
166-
<Image src={require('./my-icon.png')} />
167-
),
168-
},
169-
};
170-
...
171-
```
155+
#### `drawerLabel`
172156

173-
All `navigationOptions` for the `DrawerNavigator`:
157+
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
174158

175-
- `title` - a title (string) of the scene
176-
- `drawer` - a config object for the drawer:
177-
- `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
178-
- `icon` - React Element or a function, that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in drawer sidebar
159+
#### `drawerIcon`
179160

161+
React Element or a function, that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in drawer sidebar
180162

181163
### Navigator Props
182164

@@ -191,6 +173,6 @@ The navigator component created by `DrawerNavigator(...)` takes the following pr
191173
});
192174

193175
<DrawerNav
194-
screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
176+
screenProps={/* this prop will get passed to the screen components and nav options as props.screenProps */}
195177
/>
196178
```

docs/api/navigators/StackNavigator.md

+42-37
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ StackNavigator({
5757
// The action and route params are extracted from the path.
5858

5959
// Optional: Override the `navigationOptions` for the screen
60-
navigationOptions: {
61-
title: ({state}) => `${state.params.username}'s Profile'`,
62-
},
60+
navigationOptions: ({navigation}) => ({
61+
title: `${navigation.state.params.username}'s Profile'`,
62+
}),
6363
},
6464

6565
...MyOtherRoutes,
@@ -91,44 +91,49 @@ Visual options:
9191

9292
### Screen Navigation Options
9393

94-
Usually you define static `navigationOptions` on your screen component. For example:
94+
#### `title`
9595

96-
```jsx
97-
class ProfileScreen extends React.Component {
96+
Generic title that can be used as a fallback for `headerTitle` and `tabBarLabel`
9897

99-
static navigationOptions = {
98+
#### `headerVisible`
10099

101-
title: ({ state }) => `${state.params.name}'s Profile!`,
102-
103-
header: ({ state, setParams }) => ({
104-
// Render a button on the right side of the header
105-
// When pressed switches the screen to edit mode.
106-
right: (
107-
<Button
108-
title={state.params.editing ? 'Done' : 'Edit'}
109-
onPress={() => setParams({editing: state.params.editing ? false : true})}
110-
/>
111-
),
112-
}),
113-
};
114-
...
115-
```
100+
True or false to show or hide the header. Only works when `headerMode` is `screen`. Default value is `true`.
101+
102+
#### `headerTitle`
103+
104+
String or React Element used by the header. Defaults to scene `title`
105+
106+
#### `headerBackTitle`
107+
108+
Title string used by the back button on iOS or `null` to disable label. Defaults to scene `title`
109+
110+
#### `headerRight`
111+
112+
String or React Element to display on the right side of the header
113+
114+
#### `headerLeft`
115+
116+
String or React Element to display on the left side of the header
117+
118+
#### `headerStyle`
119+
120+
Style object for the header
121+
122+
#### `headerTitleStyle`
123+
124+
Style object for the title component
125+
126+
#### `headerTintColor`
127+
128+
Tint color for the header
129+
130+
#### `headerPressColorAndroid`
131+
132+
Color for material ripple (Android >= 5.0 only)
133+
134+
#### `gesturesEnabled`
116135

117-
All `navigationOptions` for the `StackNavigator`:
118-
119-
- `title` - a title (string) of the scene
120-
- `header` - a config object for the header bar:
121-
- `visible` - Boolean toggle of header visibility. Only works when `headerMode` is `screen`.
122-
- `title` - String or React Element used by the header. Defaults to scene `title`
123-
- `backTitle` - Title string used by the back button on iOS or `null` to disable label. Defaults to scene `title`
124-
- `right` - React Element to display on the right side of the header
125-
- `left` - React Element to display on the left side of the header
126-
- `style` - Style object for the header
127-
- `titleStyle` - Style object for the title component
128-
- `tintColor` - Tint color for the header
129-
- `pressColorAndroid` - Color for material ripple (Android >= 5.0 only)
130-
- `cardStack` - a config object for the card stack:
131-
- `gesturesEnabled` - Whether you can use gestures to dismiss this screen. Defaults to true on iOS, false on Android
136+
Whether you can use gestures to dismiss this screen. Defaults to true on iOS, false on Android
132137

133138
### Navigator Props
134139

docs/api/navigators/TabNavigator.md

+29-44
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@ Used to easily set up a screen with several tabs with a TabRouter.
55
```js
66
class MyHomeScreen extends React.Component {
77
static navigationOptions = {
8-
tabBar: {
9-
label: 'Home',
10-
// Note: By default the icon is only shown on iOS. Search the showIcon option below.
11-
icon: ({ tintColor }) => (
12-
<Image
13-
source={require('./chats-icon.png')}
14-
style={[styles.icon, {tintColor: tintColor}]}
15-
/>
16-
),
17-
},
18-
}
8+
tabBarLabel: 'Home',
9+
// Note: By default the icon is only shown on iOS. Search the showIcon option below.
10+
tabBarIcon: ({ tintColor }) => (
11+
<Image
12+
source={require('./chats-icon.png')}
13+
style={[styles.icon, {tintColor: tintColor}]}
14+
/>
15+
),
16+
};
1917

2018
render() {
2119
return (
@@ -29,16 +27,14 @@ class MyHomeScreen extends React.Component {
2927

3028
class MyNotificationsScreen extends React.Component {
3129
static navigationOptions = {
32-
tabBar: {
33-
label: 'Notifications',
34-
icon: ({ tintColor }) => (
35-
<Image
36-
source={require('./notif-icon.png')}
37-
style={[styles.icon, {tintColor: tintColor}]}
38-
/>
39-
),
40-
},
41-
}
30+
tabBarLabel: 'Notifications',
31+
tabBarIcon: ({ tintColor }) => (
32+
<Image
33+
source={require('./notif-icon.png')}
34+
style={[styles.icon, {tintColor: tintColor}]}
35+
/>
36+
),
37+
};
4238

4339
render() {
4440
return (
@@ -154,46 +150,35 @@ tabBarOptions: {
154150

155151
### Screen Navigation Options
156152

157-
Usually you define static `navigationOptions` on your screen component. For example:
153+
#### `title`
158154

159-
```jsx
160-
class ProfileScreen extends React.Component {
155+
Generic title that can be used as a fallback for `headerTitle` and `tabBarLabel`
161156

162-
static navigationOptions = {
157+
#### `tabBarVisible`
163158

164-
title: ({ state }) => `${state.params.name}'s Profile!`,
159+
True or false to show or hide the tab bar, if not set then defaults to true
165160

166-
tabBar: ({ state, setParams }) => ({
167-
icon: (
168-
<Image src={require('./my-icon.png')} />
169-
),
170-
}),
171-
};
172-
...
173-
```
161+
#### `tabBarIcon`
174162

175-
All `navigationOptions` for the `TabNavigator`:
163+
React Element or a function that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in tab bar
164+
165+
#### `tabBarLabel`
166+
167+
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.
176168

177-
- `title` - a title (string) of the scene
178-
- `tabBar` - a config object for the tab bar:
179-
- `visible` - Boolean toggle of tab bar visibility
180-
- `icon` - React Element or a function that given `{ focused: boolean, tintColor: string }` returns a React.Element, to display in tab bar
181-
- `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
182-
183169
### Navigator Props
184170

185171
The navigator component created by `TabNavigator(...)` takes the following props:
186172

187-
- `screenProps` - Pass down extra options to child screens, for example:
173+
- `screenProps` - Pass down extra options to child screens and navigation options, for example:
188174

189175

190176
```jsx
191177
const TabNav = TabNavigator({
192178
// config
193179
});
194-
180+
195181
<TabNav
196182
screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
197183
/>
198184
```
199-

docs/api/routers/RoutersAPI.md

+10-8
Original file line numberDiff line numberDiff line change
@@ -72,30 +72,32 @@ Based on the routeNames in the state, the router is responsible for returning va
7272

7373
Returns the active component for a deep navigation state.
7474

75-
### `getActionForPathAndParams`
75+
### `getActionForPathAndParams(path, params)`
7676

7777
Returns an optional navigation action that should be used when the user navigates to this path and provides optional query parameters.
7878

79-
### `getPathAndParamsForState`
79+
### `getPathAndParamsForState(state)`
8080

8181
Returns the path and params that can be put into the URL to link the user back to the same spot in the app.
8282

8383
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`.
8484

85-
### `getScreenConfig`
85+
### `getScreenOptions(navigation, screenProps)`
8686

87-
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.
87+
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.
8888

8989
- `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.
90-
- `optionName` - What named option is being fetched, such as 'title'
90+
- `screenProps` - Other props that your navigation options may need to consume
91+
- `navigationOptions` - The previous set of options that are default or provided by the previous configurer
9192

9293
Inside an example view, perhaps you need to fetch the configured title:
9394
```js
9495
// First, prepare a navigation prop for your child, or re-use one if already available.
95-
const childNavigation = addNavigationHelpers({
96+
const screenNavigation = addNavigationHelpers({
9697
// In this case we use navigation.state.index because we want the title for the active route.
9798
state: navigation.state.routes[navigation.state.index],
9899
dispatch: navigation.dispatch,
99-
})
100-
const screenTitle = this.props.router.getScreenConfig(childNavigation, 'title');
100+
});
101+
const options = this.props.router.getScreenOptions(screenNavigation, {});
102+
const title = options.title;
101103
```

0 commit comments

Comments
 (0)