Unify scene rederer params that are used render the scene / header.

Reviewed By: fkgozali

Differential Revision: D2981045

fb-gh-sync-id: 21688d92e31d882c5a31dd83ca064c2a01837164
shipit-source-id: 21688d92e31d882c5a31dd83ca064c2a01837164
This commit is contained in:
Hedger Wang 2016-02-29 13:21:43 -08:00 committed by Facebook Github Bot 9
parent e55cefc476
commit 73bdef4089
7 changed files with 103 additions and 95 deletions

View File

@ -74,31 +74,34 @@ class NavigationAnimatedExample extends React.Component {
<NavigationAnimatedView
navigationState={navigationState}
style={styles.animatedView}
renderOverlay={(position, layout) => (
renderOverlay={(props) => (
<NavigationHeader
navigationState={navigationState}
position={position}
navigationState={props.navigationParentState}
position={props.position}
getTitle={state => state.key}
/>
)}
setTiming={(pos, navState) => {
Animated.timing(pos, {toValue: navState.index, duration: 1000}).start();
}}
renderScene={(state, index, position, layout) => (
renderScene={(props) => (
<NavigationCard
key={state.key}
index={index}
navigationState={navigationState}
position={position}
layout={layout}>
key={props.navigationState.key}
index={props.index}
navigationState={props.navigationParentState}
position={props.position}
layout={props.layout}>
<ScrollView style={styles.scrollView}>
<NavigationExampleRow
text={navigationState.children[navigationState.index].key}
text={props.navigationState.key}
/>
<NavigationExampleRow
text="Push!"
onPress={() => {
onNavigate({ type: 'push', key: 'Route #' + navigationState.children.length });
onNavigate({
type: 'push',
key: 'Route #' + props.navigationParentState.children.length
});
}}
/>
<NavigationExampleRow

View File

@ -79,11 +79,11 @@ class NavigationCardStackExample extends React.Component {
});
}
_renderScene(navigationState, index, position, layout) {
_renderScene(props) {
return (
<ScrollView style={styles.scrollView}>
<NavigationExampleRow
text={JSON.stringify(navigationState)}
text={JSON.stringify(props.navigationState)}
/>
<NavigationExampleRow
text="Push Route"

View File

@ -154,25 +154,24 @@ class ExampleTabScreen extends React.Component {
/>
);
}
_renderHeader(position, layout) {
_renderHeader(props) {
return (
<NavigationHeader
navigationState={this.props.navigationState}
position={position}
layout={layout}
navigationState={props.navigationParentState}
position={props.position}
layout={props.layout}
getTitle={state => stateTypeTitleMap(state)}
/>
);
}
_renderScene(child, index, position, layout) {
_renderScene(props) {
return (
<NavigationCard
key={child.key}
index={index}
childState={child}
navigationState={this.props.navigationState}
position={position}
layout={layout}>
key={props.navigationState.key}
index={props.index}
navigationState={props.navigationParentState}
position={props.position}
layout={props.layout}>
<ScrollView style={styles.scrollView}>
<NavigationExampleRow
text="Open page"

View File

@ -30,13 +30,13 @@ var NavigationExampleRow = require('./NavigationExampleRow');
var EXAMPLES = {
'Tabs': require('./NavigationTabsExample'),
'Basic': require('./NavigationBasicExample'),
'Animated Card Stack': require('./NavigationAnimatedExample'),
'Animated Example': require('./NavigationAnimatedExample'),
'Composition': require('./NavigationCompositionExample'),
'Card Stack Example': require('./NavigationCardStackExample'),
'Tic Tac Toe': require('./NavigationTicTacToeExample'),
};
var EXAMPLE_STORAGE_KEY = 'xNavigationExperimentalExample';
var EXAMPLE_STORAGE_KEY = 'NavigationExperimentalExample';
var NavigationExperimentalExample = React.createClass({
statics: {
@ -47,13 +47,13 @@ var NavigationExperimentalExample = React.createClass({
getInitialState: function() {
return {
exampe: null,
example: null,
};
},
componentDidMount() {
AsyncStorage.getItem(EXAMPLE_STORAGE_KEY, (err, example) => {
if (err || !example) {
if (err || !example || !EXAMPLES[example]) {
this.setState({
example: 'menu',
});

View File

@ -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 {
<NavigationAnimatedView
navigationState={stack}
style={styles.container}
renderOverlay={this._renderOverlay.bind(this, stack)}
renderScene={this._renderSceneContainer.bind(this, stack)}
renderOverlay={this._renderOverlay}
renderScene={this._renderScene}
/>
);
}
_renderOverlay(
navigationState: NavigationState,
position: Value,
layout: Layout
): ReactElement {
_renderOverlay(props: NavigationStateRendererProps): ReactElement {
return (
<NavigationHeader
navigationState={navigationState}
position={position}
navigationState={props.navigationParentState}
position={props.position}
getTitle={UIExplorerStateTitleMap}
/>
);
);
}
_renderSceneContainer(
navigationState: NavigationState,
scene: NavigationState,
index: number,
position: Value,
layout: Layout
): ReactElement {
_renderOverlay(props: NavigationStateRendererProps): ReactElement {
return (
<NavigationCard
key={scene.key}
index={index}
navigationState={navigationState}
position={position}
layout={layout}>
{this._renderScene(scene)}
index={props.index}
key={props.navigationState.key}
layout={props.layout}
navigationState={props.navigationParentState}
position={props.position}>
{this._renderScene(props.navigationState)}
</NavigationCard>
);
}

View File

@ -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 (
<NavigationCard
key={navigationState.key}
index={index}
navigationState={navigationState}
navigationState={navigationParentState}
position={position}
layout={layout}>
{this.props.renderScene(navigationState, index, position, layout)}
{this.props.renderScene(props)}
</NavigationCard>
);
}

View File

@ -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()}
</View>
);
}
@ -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;
}