diff --git a/Examples/UIExplorer/NavigationExperimental/NavigationAnimatedExample.js b/Examples/UIExplorer/NavigationExperimental/NavigationAnimatedExample.js index 3054a8a97..e74d80e26 100644 --- a/Examples/UIExplorer/NavigationExperimental/NavigationAnimatedExample.js +++ b/Examples/UIExplorer/NavigationExperimental/NavigationAnimatedExample.js @@ -74,31 +74,34 @@ class NavigationAnimatedExample extends React.Component { ( + renderOverlay={(props) => ( state.key} /> )} setTiming={(pos, navState) => { Animated.timing(pos, {toValue: navState.index, duration: 1000}).start(); }} - renderScene={(state, index, position, layout) => ( + renderScene={(props) => ( + key={props.navigationState.key} + index={props.index} + navigationState={props.navigationParentState} + position={props.position} + layout={props.layout}> { - onNavigate({ type: 'push', key: 'Route #' + navigationState.children.length }); + onNavigate({ + type: 'push', + key: 'Route #' + props.navigationParentState.children.length + }); }} /> ); } - _renderHeader(position, layout) { + _renderHeader(props) { return ( stateTypeTitleMap(state)} /> ); } - _renderScene(child, index, position, layout) { + _renderScene(props) { return ( + key={props.navigationState.key} + index={props.index} + navigationState={props.navigationParentState} + position={props.position} + layout={props.layout}> { - if (err || !example) { + if (err || !example || !EXAMPLES[example]) { this.setState({ example: 'menu', }); diff --git a/Examples/UIExplorer/UIExplorerApp.ios.js b/Examples/UIExplorer/UIExplorerApp.ios.js index 5a1733d43..3bfb2e28a 100644 --- a/Examples/UIExplorer/UIExplorerApp.ios.js +++ b/Examples/UIExplorer/UIExplorerApp.ios.js @@ -34,6 +34,7 @@ const { TouchableHighlight, View, } = React; + const { AnimatedView: NavigationAnimatedView, Card: NavigationCard, @@ -41,19 +42,14 @@ const { Reducer: NavigationReducer, RootContainer: NavigationRootContainer, } = NavigationExperimental; -const StackReducer = NavigationReducer.StackReducer; - -import type { - NavigationState, -} from 'NavigationStateUtils' import type { Value } from 'Animated'; -import type { Layout } from 'NavigationAnimatedView'; + +import type { NavigationStateRendererProps } from 'NavigationAnimatedView'; + import type { UIExplorerNavigationState } from './UIExplorerNavigationReducer'; -import type { - UIExplorerExample, -} from './UIExplorerList.ios' +import type { UIExplorerExample } from './UIExplorerList.ios'; function PathActionMap(path: string): ?Object { // Warning! Hacky parsing for example code. Use a library for this! @@ -86,8 +82,12 @@ function URIActionMap(uri: ?string): ?Object { class UIExplorerApp extends React.Component { _navigationRootRef: ?NavigationRootContainer; _renderNavigation: Function; + _renderOverlay: Function; + _renderScene: Function; componentWillMount() { this._renderNavigation = this._renderNavigation.bind(this); + this._renderOverlay = this._renderOverlay.bind(this); + this._renderScene = this._renderScene.bind(this); } render() { return ( @@ -119,41 +119,31 @@ class UIExplorerApp extends React.Component { ); } - _renderOverlay( - navigationState: NavigationState, - position: Value, - layout: Layout - ): ReactElement { + _renderOverlay(props: NavigationStateRendererProps): ReactElement { return ( - ); + ); } - _renderSceneContainer( - navigationState: NavigationState, - scene: NavigationState, - index: number, - position: Value, - layout: Layout - ): ReactElement { + _renderOverlay(props: NavigationStateRendererProps): ReactElement { return ( - {this._renderScene(scene)} + index={props.index} + key={props.navigationState.key} + layout={props.layout} + navigationState={props.navigationParentState} + position={props.position}> + {this._renderScene(props.navigationState)} ); } diff --git a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js b/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js index f2cabdda8..b4e53a63a 100644 --- a/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js +++ b/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js @@ -44,22 +44,22 @@ import type { import type { Layout, - OverlayRenderer, + NavigationStateRenderer, + NavigationStateRendererProps, Position, - SceneRenderer, } from 'NavigationAnimatedView'; type Props = { navigationState: NavigationParentState, - renderOverlay: OverlayRenderer, - renderScene: SceneRenderer, + renderOverlay: NavigationStateRenderer, + renderScene: NavigationStateRenderer, }; /** * A controlled navigation view that renders a list of cards. */ class NavigationCardStack extends React.Component { - _renderScene : SceneRenderer; + _renderScene : NavigationStateRenderer; constructor(props: Props, context: any) { super(props, context); @@ -77,20 +77,22 @@ class NavigationCardStack extends React.Component { ); } - _renderScene( - navigationState: NavigationState, - index: number, - position: Position, - layout: Layout, - ): ReactElement { + _renderScene(props: NavigationStateRendererProps): ReactElement { + const { + index, + layout, + navigationParentState, + navigationState, + position, + } = props; return ( - {this.props.renderScene(navigationState, index, position, layout)} + {this.props.renderScene(props)} ); } diff --git a/Libraries/NavigationExperimental/NavigationAnimatedView.js b/Libraries/NavigationExperimental/NavigationAnimatedView.js index a1f5df0f3..b19502166 100644 --- a/Libraries/NavigationExperimental/NavigationAnimatedView.js +++ b/Libraries/NavigationExperimental/NavigationAnimatedView.js @@ -70,30 +70,39 @@ type Layout = { height: Animated.Value; }; -type OverlayRenderer = ( - position: Animated.Value, - layout: Layout -) => ReactElement; - type Position = Animated.Value; -type SceneRenderer = ( - state: NavigationState, +/** + * Definition of the props object that is passed to the functions + * that render the overlay and the scene. + */ +type NavigationStateRendererProps = { + // The state of the child view. + navigationState: NavigationState, + // The index of the child view. index: number, + // The "progressive index" of the containing navigation state. position: Position, - layout: Layout + // The layout of the the containing navigation view. + layout: Layout, + // The state of the the containing navigation view. + navigationParentState: NavigationParentState, +}; + +type NavigationStateRenderer = ( + props: NavigationStateRendererProps, ) => ReactElement; type TimingSetter = ( position: Animated.Value, newState: NavigationParentState, - lastState: NavigationParentState + lastState: NavigationParentState, ) => void; type Props = { navigationState: NavigationParentState; - renderScene: SceneRenderer; - renderOverlay: ?OverlayRenderer; + renderScene: NavigationStateRenderer; + renderOverlay: ?NavigationStateRenderer; style: any; setTiming: ?TimingSetter; }; @@ -194,7 +203,7 @@ class NavigationAnimatedView extends React.Component { }} style={this.props.style}> {this.state.scenes.map(this._renderScene, this)} - {this._renderOverlay(this._renderOverlay, this)} + {this._renderOverlay()} ); } @@ -207,20 +216,25 @@ class NavigationAnimatedView extends React.Component { }; } _renderScene(scene: NavigationScene) { - return this.props.renderScene( - scene.state, - scene.index, - this.state.position, - this._getLayout() - ); + return this.props.renderScene({ + index: scene.index, + layout: this._getLayout(), + navigationParentState: this.props.navigationState, + navigationState: scene.state, + position: this.state.position, + }); } _renderOverlay() { const {renderOverlay} = this.props; if (renderOverlay) { - return renderOverlay( - this.state.position, - this._getLayout() - ); + const parentState = this.props.navigationState; + return renderOverlay({ + index: parentState.index, + layout: this._getLayout(), + navigationParentState: parentState, + navigationState: parentState.children[parentState.index], + position: this.state.position, + }); } return null; }