Skip to content

Commit

Permalink
NavigationExperimental
Browse files Browse the repository at this point in the history
Summary:
A new API to unify internal navigation. Also addresses a highly-rated community 'pain': https://productpains.com/post/react-native/better-navigator-api-and-docs/

Offers the following improvements:

- Redux-style navigation logic is easy to reason about
- Navigation state can be easily saved and restored through refreshes
- Declarative navigation views can be implemented in native or JS
- Animations and gestures are isolated and now use the Animated library

public

Reviewed By: hedgerwang

Differential Revision: D2798048

fb-gh-sync-id: 88027ef9ead8a80afa38354252bc377455cc6dbb
  • Loading branch information
Eric Vicenti authored and facebook-github-bot-9 committed Feb 5, 2016
1 parent 2f73ad0 commit a308546
Show file tree
Hide file tree
Showing 26 changed files with 2,504 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

var React = require('react-native');
var {
NavigationExperimental,
StyleSheet,
ScrollView,
} = React;
var NavigationExampleRow = require('./NavigationExampleRow');
var {
AnimatedView: NavigationAnimatedView,
Card: NavigationCard,
RootContainer: NavigationRootContainer,
Reducer: NavigationReducer,
Header: NavigationHeader,
} = NavigationExperimental;

const NavigationBasicReducer = NavigationReducer.StackReducer({
initialStates: [
{key: 'First Route'}
],
matchAction: action => true,
actionStateMap: actionString => ({key: actionString}),
});

class NavigationAnimatedExample extends React.Component {
componentWillMount() {
this._renderNavigated = this._renderNavigated.bind(this);
}
render() {
return (
<NavigationRootContainer
reducer={NavigationBasicReducer}
persistenceKey="NavigationAnimatedExampleState"
renderNavigation={this._renderNavigated}
/>
);
}
_renderNavigated(navigationState, onNavigate) {
if (!navigationState) {
return null;
}
return (
<NavigationAnimatedView
navigationState={navigationState}
style={styles.animatedView}
renderOverlay={(position, layout) => (
<NavigationHeader
navigationState={navigationState}
position={position}
getTitle={state => state.key}
/>
)}
renderScene={(state, index, position, layout) => (
<NavigationCard
key={state.key}
index={index}
navigationState={navigationState}
position={position}
layout={layout}>
<ScrollView style={styles.scrollView}>
<NavigationExampleRow
text={navigationState.children[navigationState.index].key}
/>
<NavigationExampleRow
text="Push!"
onPress={() => {
onNavigate('Route #' + navigationState.children.length);
}}
/>
<NavigationExampleRow
text="Exit Animated Nav Example"
onPress={this.props.onExampleExit}
/>
</ScrollView>
</NavigationCard>
)}
/>
);
}
}

const styles = StyleSheet.create({
animatedView: {
flex: 1,
},
scrollView: {
marginTop: 64
},
});

module.exports = NavigationAnimatedExample;
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

const React = require('react-native');
const {
NavigationExperimental,
ScrollView,
StyleSheet,
} = React;
const NavigationExampleRow = require('./NavigationExampleRow');
const {
RootContainer: NavigationRootContainer,
Reducer: NavigationReducer,
} = NavigationExperimental;
const StackReducer = NavigationReducer.StackReducer;

const NavigationBasicReducer = StackReducer({
initialStates: [
{key: 'first_page'}
],
matchAction: action => true,
actionStateMap: action => ({key: action}),
});

const NavigationBasicExample = React.createClass({
render: function() {
return (
<NavigationRootContainer
reducer={NavigationBasicReducer}
persistenceKey="NavigationBasicExampleState"
renderNavigation={(navState, onNavigate) => {
if (!navState) { return null; }
return (
<ScrollView style={styles.topView}>
<NavigationExampleRow
text={`Current page: ${navState.children[navState.index].key}`}
/>
<NavigationExampleRow
text={`Push page #${navState.children.length}`}
onPress={() => {
onNavigate('page #' + navState.children.length);
}}
/>
<NavigationExampleRow
text="pop"
onPress={() => {
onNavigate(StackReducer.PopAction());
}}
/>
<NavigationExampleRow
text="Exit Basic Nav Example"
onPress={this.props.onExampleExit}
/>
</ScrollView>
);
}}
/>
);
},
});

const styles = StyleSheet.create({
topView: {
backgroundColor: '#E9E9EF',
flex: 1,
paddingTop: 30,
},
});

module.exports = NavigationBasicExample;
Loading

0 comments on commit a308546

Please sign in to comment.