-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ReactNative] OSS JSNavigationStack w/ Examples
- Loading branch information
Eric Vicenti
committed
Mar 24, 2015
1 parent
20a0bea
commit c9a40a9
Showing
23 changed files
with
4,026 additions
and
13 deletions.
There are no files selected for viewing
279 changes: 279 additions & 0 deletions
279
Examples/UIExplorer/JSNavigationStack/BreadcrumbNavSample.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
/** | ||
* Copyright 2004-present Facebook. All Rights Reserved. | ||
* | ||
* @providesModule BreadcrumbNavSample | ||
*/ | ||
'use strict'; | ||
|
||
var BreadcrumbNavigationBar = require('BreadcrumbNavigationBar'); | ||
var JSNavigationStack = require('JSNavigationStack'); | ||
var React = require('React'); | ||
var StyleSheet = require('StyleSheet'); | ||
var ScrollView = require('ScrollView'); | ||
var TabBarItemIOS = require('TabBarItemIOS'); | ||
var TabBarIOS = require('TabBarIOS'); | ||
var Text = require('Text'); | ||
var TouchableBounce = require('TouchableBounce'); | ||
var View = require('View'); | ||
|
||
|
||
|
||
var SAMPLE_TEXT = 'Top Pushes. Middle Replaces. Bottom Pops.'; | ||
|
||
var _getRandomRoute = function() { | ||
return { | ||
backButtonTitle: 'Back' + ('' + 10 * Math.random()).substr(0, 1), | ||
content: | ||
SAMPLE_TEXT + '\nHere\'s a random number ' + Math.random(), | ||
title: Math.random() > 0.5 ? 'Hello' : 'There', | ||
rightButtonTitle: Math.random() > 0.5 ? 'Right' : 'Button', | ||
}; | ||
}; | ||
|
||
|
||
var SampleNavigationBarRouteMapper = { | ||
rightContentForRoute: function(route, navigationOperations) { | ||
if (route.rightButtonTitle) { | ||
return ( | ||
<Text style={[styles.titleText, styles.filterText]}> | ||
{route.rightButtonTitle} | ||
</Text> | ||
); | ||
} else { | ||
return null; | ||
} | ||
}, | ||
titleContentForRoute: function(route, navigationOperations) { | ||
return ( | ||
<TouchableBounce | ||
onPress={() => navigationOperations.push(_getRandomRoute())}> | ||
<View> | ||
<Text style={styles.titleText}>{route.title}</Text> | ||
</View> | ||
</TouchableBounce> | ||
); | ||
}, | ||
iconForRoute: function(route, navigationOperations) { | ||
var onPress = | ||
navigationOperations.popToRoute.bind(navigationOperations, route); | ||
return ( | ||
<TouchableBounce onPress={onPress}> | ||
<View style={styles.crumbIconPlaceholder} /> | ||
</TouchableBounce> | ||
); | ||
}, | ||
separatorForRoute: function(route, navigationOperations) { | ||
return ( | ||
<TouchableBounce onPress={navigationOperations.pop}> | ||
<View style={styles.crumbSeparatorPlaceholder} /> | ||
</TouchableBounce> | ||
); | ||
} | ||
}; | ||
|
||
var SampleRouteMapper = { | ||
|
||
delay: 400, // Just to test for race conditions with native nav. | ||
|
||
navigationItemForRoute: function(route, navigationOperations) { | ||
var content = route.content; | ||
return ( | ||
<ScrollView> | ||
<View style={styles.scene}> | ||
<TouchableBounce | ||
onPress={this._pushRouteLater(navigationOperations.push)}> | ||
<View style={styles.button}> | ||
<Text style={styles.buttonText}>request push soon</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={this._pushRouteLater(navigationOperations.replace)}> | ||
<View style={styles.button}> | ||
<Text>{content}</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={this._pushRouteLater(navigationOperations.replace)}> | ||
<View style={styles.button}> | ||
<Text>{content}</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={this._pushRouteLater(navigationOperations.replace)}> | ||
<View style={styles.button}> | ||
<Text>{content}</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={this._pushRouteLater(navigationOperations.replace)}> | ||
<View style={styles.button}> | ||
<Text>{content}</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={this._pushRouteLater(navigationOperations.replace)}> | ||
<View style={styles.button}> | ||
<Text>{content}</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={this._popRouteLater(navigationOperations.pop)}> | ||
<View style={styles.button}> | ||
<Text style={styles.buttonText}>request pop soon</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={ | ||
this._immediatelySetTwoItemsLater( | ||
navigationOperations.immediatelyResetRouteStack | ||
) | ||
}> | ||
<View style={styles.button}> | ||
<Text style={styles.buttonText}>Immediate set two routes</Text> | ||
</View> | ||
</TouchableBounce> | ||
<TouchableBounce | ||
onPress={this._popToTopLater(navigationOperations.popToTop)}> | ||
<View style={styles.button}> | ||
<Text style={styles.buttonText}>pop to top soon</Text> | ||
</View> | ||
</TouchableBounce> | ||
</View> | ||
</ScrollView> | ||
); | ||
}, | ||
|
||
_popToTopLater: function(popToTop) { | ||
return () => setTimeout(popToTop, SampleRouteMapper.delay); | ||
}, | ||
|
||
_pushRouteLater: function(push) { | ||
return () => setTimeout( | ||
() => push(_getRandomRoute()), | ||
SampleRouteMapper.delay | ||
); | ||
}, | ||
|
||
_immediatelySetTwoItemsLater: function(immediatelyResetRouteStack) { | ||
return () => setTimeout( | ||
() => immediatelyResetRouteStack([ | ||
_getRandomRoute(), | ||
_getRandomRoute(), | ||
]) | ||
); | ||
}, | ||
|
||
_popRouteLater: function(pop) { | ||
return () => setTimeout(pop, SampleRouteMapper.delay); | ||
}, | ||
}; | ||
|
||
var BreadcrumbNavSample = React.createClass({ | ||
|
||
getInitialState: function() { | ||
return { | ||
selectedTab: 0, | ||
}; | ||
}, | ||
|
||
render: function() { | ||
var initialRoute = { | ||
backButtonTitle: 'Start', // no back button for initial scene | ||
content: SAMPLE_TEXT, | ||
title: 'Campaigns', | ||
rightButtonTitle: 'Filter', | ||
}; | ||
return ( | ||
<TabBarIOS> | ||
<TabBarItemIOS | ||
selected={this.state.selectedTab === 0} | ||
onPress={this.onTabSelect.bind(this, 0)} | ||
icon={require('image!madman_tabnav_list')} | ||
title="One"> | ||
<JSNavigationStack | ||
debugOverlay={false} | ||
style={[styles.appContainer]} | ||
initialRoute={initialRoute} | ||
routeMapper={SampleRouteMapper} | ||
navigationBar={ | ||
<BreadcrumbNavigationBar | ||
navigationBarRouteMapper={SampleNavigationBarRouteMapper} | ||
/> | ||
} | ||
/> | ||
</TabBarItemIOS> | ||
<TabBarItemIOS | ||
selected={this.state.selectedTab === 1} | ||
onPress={this.onTabSelect.bind(this, 1)} | ||
icon={require('image!madman_tabnav_create')} | ||
title="Two"> | ||
<JSNavigationStack | ||
animationConfigRouteMapper={() => JSNavigationStack.AnimationConfigs.FloatFromBottom} | ||
debugOverlay={false} | ||
style={[styles.appContainer]} | ||
initialRoute={initialRoute} | ||
routeMapper={SampleRouteMapper} | ||
navigationBar={ | ||
<BreadcrumbNavigationBar | ||
navigationBarRouteMapper={SampleNavigationBarRouteMapper} | ||
/> | ||
} | ||
/> | ||
</TabBarItemIOS> | ||
</TabBarIOS> | ||
); | ||
}, | ||
|
||
onTabSelect: function(tab, event) { | ||
if (this.state.selectedTab !== tab) { | ||
this.setState({selectedTab: tab}); | ||
} | ||
}, | ||
|
||
}); | ||
|
||
var styles = StyleSheet.create({ | ||
navigationItem: { | ||
backgroundColor: '#eeeeee', | ||
}, | ||
scene: { | ||
paddingTop: 50, | ||
flex: 1, | ||
}, | ||
button: { | ||
backgroundColor: '#cccccc', | ||
margin: 50, | ||
marginTop: 26, | ||
padding: 10, | ||
}, | ||
buttonText: { | ||
fontSize: 12, | ||
textAlign: 'center', | ||
}, | ||
appContainer: { | ||
overflow: 'hidden', | ||
backgroundColor: '#dddddd', | ||
flex: 1, | ||
}, | ||
titleText: { | ||
fontSize: 18, | ||
color: '#666666', | ||
textAlign: 'center', | ||
fontWeight: 'bold', | ||
lineHeight: 32, | ||
}, | ||
filterText: { | ||
color: '#5577ff', | ||
}, | ||
// TODO: Accept icons from route. | ||
crumbIconPlaceholder: { | ||
flex: 1, | ||
backgroundColor: '#666666', | ||
}, | ||
crumbSeparatorPlaceholder: { | ||
flex: 1, | ||
backgroundColor: '#aaaaaa', | ||
}, | ||
}); | ||
|
||
module.exports = BreadcrumbNavSample; |
101 changes: 101 additions & 0 deletions
101
Examples/UIExplorer/JSNavigationStack/JSNavigationStackExample.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/** | ||
* Copyright 2004-present Facebook. All Rights Reserved. | ||
*/ | ||
'use strict'; | ||
|
||
var React = require('React'); | ||
var JSNavigationStack = require('JSNavigationStack'); | ||
var StyleSheet = require('StyleSheet'); | ||
var Text = require('Text'); | ||
var ScrollView = require('ScrollView'); | ||
var TouchableHighlight = require('TouchableHighlight'); | ||
var BreadcrumbNavSample = require('./BreadcrumbNavSample'); | ||
var NavigationBarSample = require('./NavigationBarSample'); | ||
var JumpingNavSample = require('./JumpingNavSample'); | ||
|
||
class NavMenu extends React.Component { | ||
render() { | ||
return ( | ||
<ScrollView style={styles.scene}> | ||
<TouchableHighlight style={styles.button} onPress={() => { | ||
this.props.navigator.push({ id: 'breadcrumbs' }); | ||
}}> | ||
<Text style={styles.buttonText}>Breadcrumbs Example</Text> | ||
</TouchableHighlight> | ||
<TouchableHighlight style={styles.button} onPress={() => { | ||
this.props.navigator.push({ id: 'navbar' }); | ||
}}> | ||
<Text style={styles.buttonText}>Navbar Example</Text> | ||
</TouchableHighlight> | ||
<TouchableHighlight style={styles.button} onPress={() => { | ||
this.props.navigator.push({ id: 'jumping' }); | ||
}}> | ||
<Text style={styles.buttonText}>Jumping Example</Text> | ||
</TouchableHighlight> | ||
<TouchableHighlight style={styles.button} onPress={() => { | ||
this.props.onExampleExit(); | ||
}}> | ||
<Text style={styles.buttonText}>Exit JSNavigationStack Example</Text> | ||
</TouchableHighlight> | ||
</ScrollView> | ||
); | ||
} | ||
} | ||
|
||
var TabBarExample = React.createClass({ | ||
|
||
statics: { | ||
title: '<JSNavigationStack>', | ||
description: 'JS-implemented navigation', | ||
}, | ||
|
||
renderSceneForRoute: function(route, nav) { | ||
switch (route.id) { | ||
case 'menu': | ||
return ( | ||
<NavMenu | ||
navigator={nav} | ||
onExampleExit={this.props.onExampleExit} | ||
/> | ||
); | ||
case 'navbar': | ||
return <NavigationBarSample />; | ||
case 'breadcrumbs': | ||
return <BreadcrumbNavSample />; | ||
case 'jumping': | ||
return <JumpingNavSample />; | ||
} | ||
}, | ||
|
||
render: function() { | ||
return ( | ||
<JSNavigationStack | ||
style={styles.container} | ||
initialRoute={{ id: 'menu', }} | ||
routeMapper={{ | ||
navigationItemForRoute: this.renderSceneForRoute, | ||
}} | ||
animationConfigRouteMapper={(route) => JSNavigationStack.AnimationConfigs.FloatFromBottom} | ||
/> | ||
); | ||
}, | ||
|
||
}); | ||
|
||
var styles = StyleSheet.create({ | ||
container: { | ||
flex: 1, | ||
}, | ||
button: { | ||
backgroundColor: 'white', | ||
padding: 15, | ||
}, | ||
buttonText: { | ||
}, | ||
scene: { | ||
flex: 1, | ||
paddingTop: 64, | ||
} | ||
}); | ||
|
||
module.exports = TabBarExample; |
Oops, something went wrong.