Skip to content

Commit

Permalink
Introducing flat options (react-navigation#984)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
grabbou authored and ericvicenti committed Apr 12, 2017
1 parent fb2a0ad commit 93976d3
Show file tree
Hide file tree
Showing 59 changed files with 1,164 additions and 4,723 deletions.
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2

[*.gradle]
indent_size = 4
6 changes: 5 additions & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*

; Ignore website node_modules react and react-native
<PROJECT_ROOT>/website/node_modules/react/.*
<PROJECT_ROOT>/website/node_modules/react-native/.*
<PROJECT_ROOT>/website/node_modules/fbjs/.*

; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
Expand All @@ -23,7 +28,6 @@
<PROJECT_ROOT>/lib
<PROJECT_ROOT>/lib-rn
<PROJECT_ROOT>/examples
<PROJECT_ROOT>/website

[include]

Expand Down
File renamed without changes.
70 changes: 26 additions & 44 deletions docs/api/navigators/DrawerNavigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -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 (
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -124,8 +120,8 @@ const CustomDrawerContentComponent = (props) => (
);

const styles = StyleSheet.create({
container : {
flex : 1,
container: {
flex: 1,
},
});
```
Expand All @@ -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 = {

title: ({ state }) => `${state.params.name}'s Profile!`,

drawer: {
icon: (
<Image src={require('./my-icon.png')} />
),
},
};
...
```
#### `drawerLabel`

All `navigationOptions` for the `DrawerNavigator`:
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

- `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

Expand All @@ -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 */}
/>
```
79 changes: 42 additions & 37 deletions docs/api/navigators/StackNavigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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!`,

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})}
/>
),
}),
};
...
```
True or false to show or hide the header. Only works when `headerMode` is `screen`. Default value is `true`.

#### `headerTitle`

String or React Element used by the header. Defaults to scene `title`

#### `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`

All `navigationOptions` for the `StackNavigator`:
- `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
Whether you can use gestures to dismiss this screen. Defaults to true on iOS, false on Android

### Navigator Props

Expand Down
73 changes: 29 additions & 44 deletions docs/api/navigators/TabNavigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -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 (
Expand Down Expand Up @@ -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 */}
/>
```
18 changes: 10 additions & 8 deletions docs/api/routers/RoutersAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
```
Loading

0 comments on commit 93976d3

Please sign in to comment.