From 4ec53ee8fa2183fdeef52f0cb03c40bd6c56c451 Mon Sep 17 00:00:00 2001 From: Christine Abernathy Date: Wed, 22 Jun 2016 15:27:40 -0700 Subject: [PATCH] Update Navigator component doc Summary: Related to #8203 to update the Navigator component reference doc. **Test plan (required)** Started up the website and checked: http://localhost:8079/react-native/docs/navigator.html ![component_navigator_2](https://cloud.githubusercontent.com/assets/691109/16280426/3f2cdc32-3874-11e6-810b-ca34d7bd4972.png) **Note** The code is not Flow-ified so depended on jsdoc formatting to get the method parameter types. There's a current issue with handling optional types via react-docgen which parses components. There's an open PR to look into this: https://github.com/reactjs/react-docgen/pull/89. When that's resolved the `replaceAtIndex` method parameter type that's documented for `cb` needs to be updated to make it optional. Closes https://github.com/facebook/react-native/pull/8318 Differential Revision: D3471185 Pulled By: JoelMarcey fbshipit-source-id: 99f85ee2ab00dc200cf2812cce5b3ccec743d6a0 --- .../CustomComponents/Navigator/Navigator.js | 246 +++++++++++++----- 1 file changed, 188 insertions(+), 58 deletions(-) diff --git a/Libraries/CustomComponents/Navigator/Navigator.js b/Libraries/CustomComponents/Navigator/Navigator.js index c855a94df..f09f6488a 100644 --- a/Libraries/CustomComponents/Navigator/Navigator.js +++ b/Libraries/CustomComponents/Navigator/Navigator.js @@ -129,54 +129,168 @@ var GESTURE_ACTIONS = [ ]; /** - * Use `Navigator` to transition between different scenes in your app. To - * accomplish this, provide route objects to the navigator to identify each - * scene, and also a `renderScene` function that the navigator can use to - * render the scene for a given route. + * `Navigator` handles the transition between different scenes in your app. + * You should consider using this component instead of `NavigatorIOS` if you're + * building a cross-platform app. `Navigator` is implemented in JavaScript + * whereas `NavigatorIOS` is a wrapper around `UINavigationController`. * - * To change the animation or gesture properties of the scene, provide a - * `configureScene` prop to get the config object for a given route. See - * `Navigator.SceneConfigs` for default animations and more info on - * scene config options. - * - * ### Basic Usage + * To set up the `Navigator` you provide one or more objects called routes, + * to identify each scene. You also provide a `renderScene` function that + * renders the scene for each route object. * * ``` - * - * { - * var nextIndex = route.index + 1; - * navigator.push({ - * name: 'Scene ' + nextIndex, - * index: nextIndex, - * }); - * }} - * onBack={() => { - * if (route.index > 0) { + * import React, { Component } from 'react'; + * import { Text, Navigator } from 'react-native'; + * + * class NavAllDay extends Component { + * render() { + * return ( + * + * Hello {route.name}! + * } + * style={{padding: 100}} + * /> + * ); + * } + * } + * ``` + * + * In the above example, `initialRoute` is used to specify the first route. It + * contains a `name` property that identifies the route. The `renderScene` + * prop returns a function that displays text based on the route's name. + * + * ### Additional Scenes + * + * The first example demonstrated one scene. To set up multiple scenes, you pass + * the `initialRouteStack` prop to `Navigator`: + * + * ``` + * render() { + * const routes = [ + * {name: 'First Scene', index: 0}, + * {name: 'Second Scene', index: 1}, + * ]; + * return ( + * + * { + * if (route.index === 0) { + * navigator.push(routes[1]); + * } else { * navigator.pop(); * } - * }} - * /> - * } - * /> + * }}> + * Hello {route.name}! + * + * } + * style={{padding: 100}} + * /> + * ); + * } * ``` + * + * In the above example, a `routes` variable is defined with two route objects + * representing two scenes. Each route has an `index` property that is used to + * manage the scene being rendered. The `renderScene` method is changed to + * either push or pop the navigator depending on the current route's index. + * Finally, the `Text` component in the scene is now wrapped in a + * `TouchableHighlight` component to help trigger the navigator transitions. + * + * ### Navigation Bar + * + * You can optionally pass in your own navigation bar by returning a + * `Navigator.NavigationBar` component to the `navigationBar` prop in + * `Navigator`. You can configure the navigation bar properties, through + * the `routeMapper` prop. There you set up the left, right, and title + * properties of the navigation bar: + * + * ``` + * + * // ... + * } + * navigationBar={ + * + * { return (Cancel); }, + * RightButton: (route, navigator, index, navState) => + * { return (Done); }, + * Title: (route, navigator, index, navState) => + * { return (Awesome Nav Bar); }, + * }} + * style={{backgroundColor: 'gray'}} + * /> + * } + * /> + * ``` + * + * When configuring the left, right, and title items for the navigation bar, + * you have access to info such as the current route object and navigation + * state. This allows you to customize the title for each scene as well as + * the buttons. For example, you can choose to hide the left button for one of + * the scenes. + * + * Typically you want buttons to represent the left and right buttons. Building + * on the previous example, you can set this up as follows: + * + * ``` + * LeftButton: (route, navigator, index, navState) => + * { + * if (route.index === 0) { + * return null; + * } else { + * return ( + * navigator.pop()}> + * Back + * + * ); + * } + * }, + * ``` + * + * This sets up a left navigator bar button that's visible on scenes after the + * the first one. When the button is tapped the navigator is popped. + * + * ### Scene Transitions + * + * To change the animation or gesture properties of the scene, provide a + * `configureScene` prop to get the config object for a given route: + * + * ``` + * + * // ... + * } + * configureScene={(route, routeStack) => + * Navigator.SceneConfigs.FloatFromBottom} + * /> + * ``` + * In the above example, the newly pushed scene will float up from the bottom. + * See `Navigator.SceneConfigs` for default animations and more info on + * available [scene config options](/react-native/docs/navigator.html#configurescene). */ var Navigator = React.createClass({ propTypes: { /** - * Optional function that allows configuration about scene animations and - * gestures. Will be invoked with the route and the routeStack and should - * return a scene configuration object + * Optional function where you can configure scene animations and + * gestures. Will be invoked with `route` and `routeStack` parameters, + * where `route` corresponds to the current scene being rendered by the + * `Navigator` and `routeStack` is the set of currently mounted routes + * that the navigator could transition to. + * + * The function should return a scene configuration object. * * ``` * (route, routeStack) => Navigator.SceneConfigs.FloatFromRight * ``` * - * Available options are: + * Available scene configutation options are: * * - Navigator.SceneConfigs.PushFromRight (default) * - Navigator.SceneConfigs.FloatFromRight @@ -194,7 +308,7 @@ var Navigator = React.createClass({ /** * Required function which renders the scene for a given route. Will be - * invoked with the route and the navigator object + * invoked with the `route` and the `navigator` object. * * ``` * (route, navigator) => @@ -204,45 +318,53 @@ var Navigator = React.createClass({ renderScene: PropTypes.func.isRequired, /** - * Specify a route to start on. A route is an object that the navigator - * will use to identify each scene to render. `initialRoute` must be - * a route in the `initialRouteStack` if both props are provided. The - * `initialRoute` will default to the last item in the `initialRouteStack`. + * The initial route for navigation. A route is an object that the navigator + * will use to identify each scene it renders. + * + * If both `initialRoute` and `initialRouteStack` props are passed to + * `Navigator`, then `initialRoute` must be in a route in + * `initialRouteStack`. If `initialRouteStack` is passed as a prop but + * `initialRoute` is not, then `initialRoute` will default internally to + * the last item in `initialRouteStack`. */ initialRoute: PropTypes.object, /** - * Provide a set of routes to initially mount. Required if no initialRoute - * is provided. Otherwise, it will default to an array containing only the - * `initialRoute` + * Pass this in to provide a set of routes to initially mount. This prop + * is required if `initialRoute` is not provided to the navigator. If this + * prop is not passed in, it will default internally to an array + * containing only `initialRoute`. */ initialRouteStack: PropTypes.arrayOf(PropTypes.object), /** - * Will emit the target route upon mounting and before each nav transition + * Pass in a function to get notified with the target route when + * the navigator component is mounted and before each navigator transition. */ onWillFocus: PropTypes.func, /** * Will be called with the new route of each scene after the transition is - * complete or after the initial mounting + * complete or after the initial mounting. */ onDidFocus: PropTypes.func, /** - * Optionally provide a component as navigation bar that persists across scene - * transitions. The component will receive two props: `navigator` and `navState`. - * It will be rerendered when the routes change. + * Use this to provide an optional component representing a navigation bar + * that is persisted across scene transitions. This component will receive + * two props: `navigator` and `navState` representing the navigator + * component and its state. The component is re-rendered when the route + * changes. */ navigationBar: PropTypes.node, /** - * Optionally provide the navigator object from a parent Navigator + * Optionally pass in the navigator object from a parent `Navigator`. */ navigator: PropTypes.object, /** - * Styles to apply to the container of each scene + * Styles to apply to the container of each scene. */ sceneStyle: View.propTypes.style, }, @@ -348,11 +470,10 @@ var Navigator = React.createClass({ /** * Reset every scene with an array of routes. * - * @param {RouteStack} nextRouteStack Next route stack to reinitialize. This - * doesn't accept stack item `id`s, which implies that all existing items are - * destroyed, and then potentially recreated according to `routeStack`. Does - * not animate, immediately replaces and rerenders navigation bar and stack - * items. + * @param {RouteStack} nextRouteStack Next route stack to reinitialize. + * All existing route stacks are destroyed an potentially recreated. There + * is no accompanying animation and this method immediately replaces and + * re-renders the navigation bar and the stack items. */ immediatelyResetRouteStack: function(nextRouteStack) { var destIndex = nextRouteStack.length - 1; @@ -893,7 +1014,9 @@ var Navigator = React.createClass({ }, /** - * Transition to an existing scene without unmounting + * Transition to an existing scene without unmounting. + * @param {object} route Route to transition to. The specified route must + * be in the currently mounted set of routes defined in `routeStack`. */ jumpTo: function(route) { var destIndex = this.state.routeStack.indexOf(route); @@ -920,7 +1043,8 @@ var Navigator = React.createClass({ /** * Navigate forward to a new scene, squashing any scenes that you could - * `jumpForward` to. + * jump forward to. + * @param {object} route Route to push into the navigator stack. */ push: function(route) { invariant(!!route, 'Must supply route to push'); @@ -984,10 +1108,11 @@ var Navigator = React.createClass({ }, /** - * Replace a scene as specified by an index - * - * `index` specifies the route in the stack that should be replaced. - * If it's negative, it counts from the back. + * Replace a scene as specified by an index. + * @param {object} route Route representing the new scene to render. + * @param {number} index The route in the stack that should be replaced. + * If negative, it counts from the back of the stack. + * @param {Function} cb Callback function when the scene has been replaced. */ replaceAtIndex: function(route, index, cb) { invariant(!!route, 'Must supply route to replace'); @@ -1020,6 +1145,7 @@ var Navigator = React.createClass({ /** * Replace the current scene with a new route. + * @param {object} route Route that replaces the current scene. */ replace: function(route) { this.replaceAtIndex(route, this.state.presentedIndex); @@ -1027,6 +1153,7 @@ var Navigator = React.createClass({ /** * Replace the previous scene. + * @param {object} route Route that replaces the previous scene. */ replacePrevious: function(route) { this.replaceAtIndex(route, this.state.presentedIndex - 1); @@ -1042,6 +1169,7 @@ var Navigator = React.createClass({ /** * Pop to a particular scene, as specified by its route. * All scenes after it will be unmounted. + * @param {object} route Route to pop to. */ popToRoute: function(route) { var indexOfRoute = this.state.routeStack.indexOf(route); @@ -1055,6 +1183,7 @@ var Navigator = React.createClass({ /** * Replace the previous scene and pop to it. + * @param {object} route Route that replaces the previous scene. */ replacePreviousAndPop: function(route) { if (this.state.routeStack.length < 2) { @@ -1066,6 +1195,7 @@ var Navigator = React.createClass({ /** * Navigate to a new scene and reset route stack. + * @param {object} route Route to navigate to. */ resetTo: function(route) { invariant(!!route, 'Must supply route to push');