Repository: SuperDami/react-native-custom-navigation
Branch: master
Commit: 40ead26ff616
Files: 13
Total size: 33.8 KB
Directory structure:
gitextract_lhqzowum/
├── .gitignore
├── .npmignore
├── README.md
├── components/
│ ├── NavBarContainer.js
│ ├── NavBarContent.js
│ └── StaticNavBarContent.js
├── example/
│ ├── demo1.js
│ ├── demo2.js
│ ├── index.ios.js
│ ├── navbar.js
│ └── package.json
├── index.js
└── package.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
config.js
pids
logs
results
public
npm-debug.log
.DS_Store
node_modules
ACCOUNTS
Pods
.env
================================================
FILE: .npmignore
================================================
.*.swp
._*
.DS_Store
.git
.hg
.lock-wscript
.svn
.wafpickle-*
CVS
npm-debug.log
node_modules
example/node_modules
================================================
FILE: README.md
================================================
react-native-custom-navigation
===================
The goal is making a easy navigation router for react-native, you could plug-in different navigation-bar in each view stack, and update navigation-bar background style at any time. The router would provide your navigation-bar a smooth transition animation when push, pop or swipe-back gesture is activating.
Inspired by [react-native-router](https://github.com/t4t5/react-native-router)
Case 1:
Different view stack using different navgation bar

Case 2:
Using singleton navigation bar for all views

Install
-------
In your React Native project directory and run:
```npm install react-native-custom-navigation --save```
Demo
-------
In node_modules/react-native-custom-navigation/example directory and run:
```npm install```
In ```index.ios.js```, 2 demos are ready for you.
```javascript
var React = require('react-native');
var Demo1 = require('./demo1');
var Demo2 = require('./demo2');
var {
AppRegistry,
} = React;
AppRegistry.registerComponent('ReactTest', () => Demo1);
```
Update
-------
0.2.1:
- Not specifying react-native as dependency in package.json
- Demo using react-native 0.11
0.2.0:
- You can pass initial props to your navbar component by
setting **`navbarPassProps`** when pushing a route object.
- You can update current navbar props in current view module by calling **`this.props.updateNavbarProps`**.
- Access the passing props in your navbar module by **`this.props.xxx`**,
- Handle the passing props in **`componentWillMound`** or **`componentWillReceiveProps`** to render navbar UI.
- The usage of these features can be found in the example that had been updated.
Basic Usage
-------
```javascript
var Router = require('react-native-custom-navigation');
```
Your route object should contain component object for the page to render.
I would like setting a back-button component for each view stack, also you can pass this and manage the back-button by your navigation-bar.
```javascript
var BackButton = React.createClass({
render() {
return (
<Text style={{
alignSelf: 'center',
textAlign: 'center',
fontSize: 16,
color: '#fff',
}}>Back</Text>)
}
});
var route = {
component: FirstView,
backButton:
title: 'Root',
titleStyle: {
color: '#ddd',
fontSize: 22
}
}
var RootController = React.createClass({
render() {
return (
<Router
backButtonComponent={BackButton}
initialRoute=route/>);
}
});
AppRegistry.registerComponent('ReactTest', () => RootController);
```
Here we go.
Now we got a scrollView here, we can have fade-in navbar-background when we scrolling down.
```javascript
var FirstView = React.createClass({
render() {
return (
<ScrollView
scrollEventThrottle={16}
onScroll={this._handleScroll}>
<TouchableHighlight
onPress={this._push}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Push with custom navbar</Text>
</View>
</TouchableHighlight>
</ScrollView>
)
},
_handleScroll(e) {
var alpha = (e.nativeEvent.contentInset.top + e.nativeEvent.contentOffset.y) / 200;
if (alpha < 0) alpha = 0;
if (alpha > 1) alpha = 1;
var style = {backgroundColor: 'rgba(102, 106, 136, ' + alpha +')'};
this.props.route.updateNavbarStyle(style);
}
_push() {
var navbarContent = (
<CustomNavbar
style={{backgroundColor: color}}/>);
this.props.route.push({
component: FirstView,
title: 'title would never show',
navbarComponent: navbarContent
});
},
});
```
You can then navigate further to a new component by calling
```javascript
this.props.route.push()
```
You can set "navbarComponent" as navigation-bar in next route object.
If you want still have the fade-in effect, make sure the background color of your "navbarComponent" is transparent.
Configurations
--------------
The **`<Router />`** object used to initialize the navigation can take the following props:
- `initialRoute` (required)
- `backButtonComponent`
- `navbarComponent`: Set the component as the singleton navbar for all views.
- `navbarPassProps`: Send initial props to your singleton navbar, access it by `this.props.xxx`
The **`this.props.route.push()`** callback prop takes one parameter (a JavaScript object) which can have the following keys:
- `title`
- `titleStyle`
- `component` (required) The next view component
- `navbarComponent`: Set the component as the navbar in this route
- `passProps`: Send object data to your view component. access the data by `this.props.xxx`
- `navbarPassProps`: Send initial data to your navbar, access it by `this.props.xxx`
The **`navbarComponent` and `component`** access route parameter or function by ***`this.props.route`*** which have the following keys:
- `index`
- `previousIndex`(for singleton navbar only)
- `progress`(for singleton navbar only): current transition animation progress (0 - 1)
- ~~`updateNavbarStyle`(view component only)~~
- `push`
- `pop`
- `popToTop`
~~The **`this.props.route.updateNavbarStyle()`** callback prop takes style object which update the style of navbar background~~
**`this.props.route.updateNavbarStyle`** this function had been abandoned, replace with **`this.props.updateBarBackgroundStyle()`** .
Todos
-------
- Less and clear code
- Make transition animation looks naturally when using singleton navbar and stack navbar at same time.
Questions?
---------
feel free to [follow me on Twitter](https://twitter.com/eatdami)
================================================
FILE: components/NavBarContainer.js
================================================
'use strict';
var React = require('react-native');
var NavBarContent = require('./NavBarContent').NavBarContent;
var NavbarBackground = require('./NavBarContent').NavbarBackground;
var StaticNavBarContent = require('./StaticNavBarContent');
var {
StyleSheet,
View
} = React;
var NavBarContainer = React.createClass({
getInitialState: function() {
return {};
},
componentWillReceiveProps: function(newProps) {
if (!this.props.currentRoute || (this.props.currentRoute.index === null)) {
newProps.currentRoute.index = 0;
}
if (newProps.currentRoute === this.props.currentRoute) {
return;
}
this.setState({
previousRoute: this.props.currentRoute,
currentRoute: newProps.currentRoute
});
},
_goBack: function() {
this.props.onBack(this.props.navigator);
},
_goForward: function(route) {
this.props.onForward(route, this.props.navigator);
},
_goFirst: function() {
this.props.onFirst(this.props.navigator);
},
_onAnimationChange: function(progress, fromIndex, toIndex) {
this.setState({
progress: progress
});
},
onAnimationStart: function(fromIndex, toIndex) {
var routeStack = this.props.navState.routeStack;
var fromRoute = routeStack.length > fromIndex ? routeStack[fromIndex] : null;
var toRoute = routeStack.length > toIndex ? routeStack[toIndex] : null;
this.state = {
previousRoute: fromRoute,
currentRoute: toRoute,
};
},
onAnimationEnd: function() {
},
updateProgress: function(progress, fromIndex, toIndex) {
this._onAnimationChange(progress, fromIndex, toIndex);
},
// We render both the current and the previous navbar (for animation)
render: function() {
var currentProps = {
progress:this.state.progress,
route:this.state.currentRoute,
};
var previousProps = {
progress:this.state.progress,
route:this.state.previousRoute,
willDisappear:true
};
var navigatorProps = {
goForward: this._goForward,
goBack: this._goBack,
goFirst: this._goFirst
};
var previousContent, currentContent;
var previousBackground, currentBackground;
if (this.state.previousRoute) {
previousBackground = (
<NavbarBackground
{...previousProps}
style={styles.background}/>);
currentBackground = (
<NavbarBackground
{...currentProps}
style={styles.background}/>);
currentContent = (
<NavBarContent
{...currentProps}
{...navigatorProps}
direction={this.state.currentRoute.index - this.state.previousRoute.index}
backButtonComponent={this.props.backButtonComponent}/>);
previousContent = (
<NavBarContent
{...previousProps}
{...navigatorProps}
direction={this.state.currentRoute.index - this.state.previousRoute.index}
backButtonComponent={this.props.backButtonComponent}/>);
} else if (this.state.currentRoute){
currentBackground = (
<NavbarBackground
{...currentProps}
style={styles.background}/>);
currentContent = (
<NavBarContent
{...currentProps}
{...navigatorProps}
direction={0}
backButtonComponent={this.props.backButtonComponent}/>);
}
var staticContent;
if (this.props.navbarComponent) {
staticContent = (
<StaticNavBarContent
previousRoute={this.state.previousRoute}
currentRoute={this.state.currentRoute}
progress={this.state.progress}
navbarComponent={this.props.navbarComponent}
navbarPassProps={this.props.navbarPassProps}
{...navigatorProps}/>
)
}
// Using createFragment to prevent 'Each child in an array should have a unique "key" prop.'
// warning message
var navbarContents = React.addons.createFragment({
"staticContent": staticContent,
"previousCountent" : previousContent,
"currentContent":currentContent
});
return (
<View style={[styles.navbarContainer, this.props.style]}>
{previousBackground}
{currentBackground}
{navbarContents}
</View>
)
}
});
var styles = StyleSheet.create({
navbar: {
position: 'absolute',
top: 0,
left: 0,
height: 64,
justifyContent: 'center',
flexDirection: 'row',
},
background: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: 64,
},
navbarContainer: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: 64,
backgroundColor: 'rgba(0,0,0,0)'
}
});
module.exports = NavBarContainer;
================================================
FILE: components/NavBarContent.js
================================================
'use strict';
var React = require('react-native');
var TimerMixin = require('react-timer-mixin');
var {
StyleSheet,
Text,
View,
TouchableHighlight,
Dimensions,
} = React;
var NavbarBackground = React.createClass({
mixins: [TimerMixin],
getInitialState: function() {
return {};
},
_initState: function(fadeIn) {
var state = {};
state.opacityStart = fadeIn ? 0 : 1;
state.opacityEnd = fadeIn ? 1 : 0;
state.progress = 0;
this.state = state;
},
componentWillMount: function() {
this.props.route.updateBarBackgroundStyle = this._updateBarBackgroundStyle;
this._initState(false);
},
componentWillReceiveProps: function(newProps) {
if (newProps.route !== this.props.route) {
this._initState(!this.props.willDisappear);
if (!this.props.willDisappear) {
newProps.route.updateBarBackgroundStyle = this._updateBarBackgroundStyle;
}
}
this.state.progress = newProps.progress;
},
_updateBarBackgroundStyle: function(style) {
this.props.route.barBackgroundStyle = style;
this.setTimeout(this.forceUpdate, 0);
},
render() {
var opacity = (this.state.opacityEnd - this.state.opacityStart) * this.state.progress + this.state.opacityStart;
var transitionStyle = {
opacity: opacity,
};
return (
<View style={[this.props.style, transitionStyle, this.props.route.barBackgroundStyle]} />
);
}
});
var screen = Dimensions.get('window');
var NavBarContent = React.createClass({
mixins: [TimerMixin],
getInitialState: function() {
return {};
},
_initState: function(direction, fadeIn) {
var state = {};
state.opacityStart = fadeIn ? 0 : 1;
state.opacityEnd = fadeIn ? 1 : 0;
if (direction > 0) {
state.leftStart = fadeIn ? screen.width : 0;
state.leftEnd = fadeIn ? 0 : -screen.width;
} else if (direction < 0) {
state.leftStart = fadeIn ? -screen.width : 0;
state.leftEnd = fadeIn ? 0: screen.width;
} else {
//todo replace
}
this.state = state;
},
componentWillMount: function() {
this._initState(1, false);
this.props.route.updateNavbarProps = this._updateNavbarProps;
},
componentWillReceiveProps: function(newProps) {
if (this.props.route !== newProps.route) {
this._initState(newProps.direction, !this.props.willDisappear);
if (!newProps.willDisappear) {
newProps.route.updateNavbarProps = this._updateNavbarProps;
}
}
},
_updateNavbarProps: function(props) {
this.props.route.navbarProps = props;
this.setTimeout(this.forceUpdate, 0);
},
render() {
var left = (this.state.leftEnd - this.state.leftStart) * this.props.progress + this.state.leftStart;
var opacity = (this.state.opacityEnd - this.state.opacityStart) * this.props.progress + this.state.opacityStart;
var transitionStyle = {
position: 'absolute',
opacity: opacity,
left: left
};
var mainContent;
if (this.props.route.navbarComponent) {
var navbarProps = this.props.route.navbarProps ? this.props.route.navbarProps : this.props.route.navbarPassProps
var NavbarComponent = this.props.route.navbarComponent;
mainContent = (
<NavbarComponent
route={{
index: this.props.route.index,
push: this.props.goForward,
pop: this.props.goBack,
popToTop: this.props.goFirst
}}
{...navbarProps}/>
);
} else {
var leftCorner;
var leftCornerContent;
var BackButton = this.props.backButtonComponent
if (this.props.route.index > 0 && BackButton) {
leftCornerContent = (
<TouchableHighlight onPress={this.props.goBack} underlayColor="transparent">
<View style={styles.backView}>
<BackButton />
</View>
</TouchableHighlight>);
}
leftCorner = (
<View
key='nav-back'
style={[styles.corner, styles.alignLeft]}>
{leftCornerContent}
</View>
);
mainContent = [leftCorner];
if (this.props.route.title) {
mainContent.push(
<Text
key='nav-title'
style={[styles.title, this.props.route.titleStyle]}
numberOfLines={1}>{this.props.route.title}</Text>
);
}
}
return (
<View style={[styles.navbar, transitionStyle]}>
{mainContent}
</View>
);
}
});
var styles = StyleSheet.create({
navbar: {
position: 'absolute',
top: 0,
left: 0,
height: 64,
justifyContent: 'center',
flexDirection: 'row',
},
corner: {
flex: 1,
left:0,
top: 18,
position: 'absolute',
justifyContent: 'center',
},
alignLeft: {
alignItems: 'flex-start'
},
title: {
position: 'absolute',
width: screen.width - 100,
top: 28,
left: 50,
fontSize: 18,
color: '#fff',
textAlign: 'center',
},
backView: {
width: 44,
height: 44,
justifyContent: 'center',
}
});
module.exports = {
NavBarContent: NavBarContent,
NavbarBackground: NavbarBackground,
};
================================================
FILE: components/StaticNavBarContent.js
================================================
'use strict';
var React = require('react-native');
var TimerMixin = require('react-timer-mixin');
var {
StyleSheet,
Text,
View,
TouchableHighlight
} = React;
var StaticNavBarContent = React.createClass({
mixins: [TimerMixin],
getInitialState() {
return {
navbarProps: this.props.navbarPassProps
};
},
componentWillMount() {
this.props.currentRoute &&
(this.props.currentRoute.updateStaticNavbarProps = this._updateNavbarProps)
},
componentWillReceiveProps(newProps) {
if (this.props.currentRoute !== newProps.currentRoute) {
newProps.currentRoute.updateStaticNavbarProps = this._updateNavbarProps;
};
},
render() {
var previousIndex = this.props.previousRoute ? this.props.previousRoute.index : null;
var index = this.props.currentRoute ? this.props.currentRoute.index : null;
return (
<View style={styles.navbar}>
<this.props.navbarComponent
route={{
progress: this.props.progress,
previousIndex: previousIndex,
index: index,
push: this.props.goForward,
pop: this.props.goBack,
popToTop: this.props.goFirst
}}
{...this.state.navbarProps}/>
</View>
);
},
_updateNavbarProps(props) {
this.setTimeout(
() => {
this.setState({
navbarProps: props
});
},
0
);
}
});
var styles = StyleSheet.create({
navbar: {
position: 'absolute',
top: 0,
left: 0,
height: 64,
justifyContent: 'center',
flexDirection: 'row',
},
});
module.exports = StaticNavBarContent;
================================================
FILE: example/demo1.js
================================================
var React = require('react-native');
var {
Image,
View,
ScrollView,
StyleSheet,
Text,
TouchableHighlight
} = React;
var Router = require('react-native-custom-navigation');
var navbarColors = [
'#acc7bf',
'#5e5f67',
'#c37070',
'#eae160',
'#bf7aa3',
'#b7d967'
];
var NavbarContent = require('./navbar');
var screen = require('Dimensions').get('window');
var BackButton = React.createClass({
render() {
return (
<Text style={{
alignSelf: 'center',
textAlign: 'center',
fontSize: 16,
color: '#fff',
}}>Back</Text>)
}
});
var RootController = React.createClass({
render() {
return (
<Router
backButtonComponent={BackButton}
initialRoute={{
component: DemoView,
title: 'Root',
titleStyle: {
color: '#ddd',
fontSize: 22
},
}}/>);
}
});
var NavbarWrapper = React.createClass({
getInitialState() {
return {};
},
componentWillMount() {
this.setState({
style: this.props.style
});
},
componentWillReceiveProps(newProps) {
if (newProps.style !== this.props.style) {
this.setState({
style: newProps.style
});
}
},
render() {
return (
<NavbarContent
goFoward = {this._push}
goBack = {this.props.route.pop}
style={this.state.style}/>);
},
_push() {
var colorIndex = this.props.route.index % navbarColors.length;
var color = navbarColors[colorIndex];
this.props.route.push({
component: DemoView,
navbarComponent: NavbarWrapper,
navbarPassProps: {
style: {
backgroundColor: color
}
}
});
},
});
var DemoView = React.createClass({
render() {
var imageUri = 'https://divnil.com/wallpaper/iphone5/img/app/c/l/clear-your-desktop-wallpaper-for-640x1136-iphone-5-311-46_33a8356f2205d7c0be8727720a21a207_raw.jpg';
return (
<View style={styles.container}>
<ScrollView
scrollEventThrottle={16}
onScroll={this._handleScroll}>
<Image
style={styles.image}
source={{uri: imageUri}}>
<TouchableHighlight
style={[styles.button, {marginTop: 120}]}
onPress={this._pushToNext}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Push</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._pushToNextCustomNavbar}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Push with custom navbar</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._back}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Back</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._popToTop}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Pop to top</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._changeColor}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>*custom bar become gray</Text>
</View>
</TouchableHighlight>
</Image>
</ScrollView>
</View>
)
},
_back() {
this.props.route.pop();
},
_pushToNext() {
var nextIndex = ++this.props.route.index;
this.props.route.push({
component: DemoView,
title: nextIndex,
titleStyle: {
fontSize: 22,
color: '#eee'
}
});
},
_pushToNextCustomNavbar() {
var colorIndex = this.props.route.index % navbarColors.length;
var color = navbarColors[colorIndex];
this.props.route.push({
component: DemoView,
navbarComponent: NavbarWrapper,
navbarPassProps: {
style: {
backgroundColor: color
}
}
});
},
_popToTop() {
this.props.route.popToTop();
},
_changeColor() {
this.props.updateNavbarProps({
style: {
backgroundColor: '#666'
}
});
},
_handleScroll(e) {
var alpha = (e.nativeEvent.contentInset.top + e.nativeEvent.contentOffset.y) / 200;
if (alpha < 0) alpha = 0;
if (alpha > 1) alpha = 1;
var style = {backgroundColor: 'rgba(102, 106, 136, ' + alpha +')'};
this.props.updateBarBackgroundStyle(style);
}
});
var styles = StyleSheet.create({
container: {
width: screen.width,
height: screen.height,
},
buttonView: {
justifyContent: 'center',
padding: 4,
width: 180,
height: 60,
backgroundColor: 'rgba(0,0,0,0.5)',
borderRadius: 4
},
button: {
marginBottom: 40
},
buttonText: {
fontSize: 20,
textAlign: 'center',
color: '#fff',
backgroundColor: 'rgba(0,0,0,0)'
},
image: {
alignItems: 'center',
width: screen.width,
height: screen.height * 1.5,
},
});
module.exports = RootController;
================================================
FILE: example/demo2.js
================================================
var React = require('react-native');
var {
Image,
View,
ScrollView,
StyleSheet,
Text,
TouchableHighlight
} = React;
var Router = require('react-native-custom-navigation');
var navbarColors = [
'#acc7bf',
'#5e5f67',
'#c37070',
'#eae160',
'#bf7aa3',
'#b7d967'
];
var NavbarContent = require('./navbar');
var screen = require('Dimensions').get('window');
var axisWidth = screen.width - 120;
var NavbarWrapper = React.createClass({
getInitialState() {
return {
backgroundColor: this.props.backgroundColor,
progress: 0
};
},
componentWillReceiveProps(newProps) {
if (newProps.route !== this.props.route) {
var route = newProps.route;
var progress;
var n = Math.abs(route.previousIndex - route.index) * route.progress;
if (route.index > route.previousIndex) {
progress = (route.previousIndex + n) * 0.2;
} else {
progress = (route.previousIndex - n) * 0.2;
}
this.setState({
progress : progress
});
}
if (newProps.backgroundColor !== this.props.backgroundColor) {
this.setState({
backgroundColor: newProps.backgroundColor
})
}
},
_push() {
if (this.props.route.index > 4) {
return;
}
this.props.route.push({
component: DemoView,
});
},
render() {
var width = this.state.progress * axisWidth;
return (
<View>
<NavbarContent
goFoward = {this._push}
goBack = {this.props.route.pop}
style={{backgroundColor: '#5e5f67'}} />
<View style={styles.activity}>
<View style={styles.axisView}>
<View style={[styles.progress, {width: width, backgroundColor: this.state.backgroundColor}]}/>
</View>
</View>
</View>
);
}
});
var RootController = React.createClass({
render() {
return (
<Router
navbarComponent={NavbarWrapper}
navbarPassProps={{
backgroundColor: '#b7d967'
}}
initialRoute={{
component: DemoView,
}}/>);
}
});
var DemoView = React.createClass({
render() {
var imageUri = 'https://divnil.com/wallpaper/iphone5/img/app/c/l/clear-your-desktop-wallpaper-for-640x1136-iphone-5-311-46_33a8356f2205d7c0be8727720a21a207_raw.jpg';
return (
<View style={styles.container}>
<Image
style={styles.image}
source={{uri: imageUri}}>
<TouchableHighlight
style={styles.button}
onPress={this._pushToNext}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Push</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._back}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Back</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._popToTop}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>Pop to top </Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._changeColor}>
<View style={styles.buttonView}>
<Text style={styles.buttonText}>{'*change progress red'}</Text>
</View>
</TouchableHighlight>
</Image>
</View>
)
},
_back() {
this.props.route.pop();
},
_pushToNext() {
if (this.props.route.index > 4) {
return;
}
this.props.route.push({
component: DemoView,
});
},
_popToTop() {
this.props.route.popToTop();
},
_changeColor() {
this.props.updateNavbarProps({backgroundColor: 'rgba(255,0,0,1)'});
}
});
var styles = StyleSheet.create({
container: {
width: screen.width,
height: screen.height,
},
buttonView: {
justifyContent: 'center',
padding: 4,
width: 180,
height: 60,
backgroundColor: 'rgba(0,0,0,0.5)',
borderRadius: 4
},
button: {
marginBottom: 40
},
buttonText: {
fontSize: 20,
textAlign: 'center',
color: '#fff',
backgroundColor: 'rgba(0,0,0,0)'
},
image: {
alignItems: 'center',
width: screen.width,
height: screen.height,
justifyContent: 'center'
},
activity: {
position: 'absolute',
height: 64,
width: axisWidth,
top: 0,
left: (screen.width - axisWidth) / 2
},
navbar: {
width:screen.width,
height: 64,
backgroundColor: '#5e5f67',
justifyContent: 'center'
},
axisView: {
marginTop: 40,
width: axisWidth,
height: 8,
borderRadius: 4,
backgroundColor : '#fff',
alignSelf: 'center',
justifyContent: 'center'
},
progress: {
alignSelf: 'flex-start',
height: 6,
borderRadius: 3,
}
});
module.exports = RootController;
================================================
FILE: example/index.ios.js
================================================
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var Demo1 = require('./demo1');
var Demo2 = require('./demo2');
var {
AppRegistry,
} = React;
AppRegistry.registerComponent('ReactTest', () => Demo1);
================================================
FILE: example/navbar.js
================================================
'use strict';
var React = require('react-native');
var {
View,
Text,
StyleSheet,
TouchableHighlight,
} = React;
var screen = require('Dimensions').get('window');
var NavbarContent = React.createClass({
render() {
return (
<View style={[styles.container, this.props.style]}>
<View style={[styles.corner, styles.leftCorner]}>
<TouchableHighlight onPress={this.props.goBack} underlayColor="transparent">
<View style={styles.backView}>
<Text style={styles.buttonText}>{'<'}</Text>
</View>
</TouchableHighlight>
</View>
<View style={[styles.corner, styles.rightCorner]}>
<TouchableHighlight onPress={this.props.goFoward} underlayColor="transparent">
<View style={styles.backView}>
<Text style={styles.buttonText}>{'>'}</Text>
</View>
</TouchableHighlight>
</View>
<Text style={styles.titleText}>{this.props.title}</Text>
</View>
)
},
});
var styles = StyleSheet.create({
container: {
width: screen.width,
height: 64,
justifyContent: 'center',
},
titleText: {
fontSize: 22,
color: '#fff',
textAlign: 'center',
alignSelf: 'center',
},
buttonText: {
fontSize: 32,
color: '#111',
textAlign: 'center',
},
corner: {
top: 20,
flex: 1,
position: 'absolute',
justifyContent: 'center',
},
leftCorner: {
left:0,
},
rightCorner: {
right:0,
},
backView: {
width: 44,
height: 44,
justifyContent: 'center',
}
});
module.exports = NavbarContent;
================================================
FILE: example/package.json
================================================
{
"name": "sample-react-native-custom-navigation",
"version": "0.2.1",
"private": true,
"scripts": {
"start": "node_modules/react-native/packager/packager.sh"
},
"dependencies": {
"react-native" : "^0.11.0",
"react-native-custom-navigation" : "file:../"
}
}
================================================
FILE: index.js
================================================
'use strict';
var React = require('react-native');
var NavBarContainer = require('./components/NavBarContainer');
var {
StyleSheet,
Navigator,
StatusBarIOS,
View,
} = React;
var self;
var Router = React.createClass({
getInitialState: function() {
self = this;
return {
route: null,
dragStartX: null,
didSwitchView: null,
};
},
/*
* This changes the title in the navigation bar
* It should preferrably be called for "onWillFocus" instad >
* > but a recent update to React Native seems to break the animation
*/
onDidFocus: function(route) {
this.setState({ route: route });
},
onBack: function(navigator) {
if (this.state.route.index > 0) {
navigator.pop();
}
},
onForward: function(route, navigator) {
route.index = this.state.route.index + 1 || 1;
navigator.push(route);
},
onFirst: function(navigator) {
navigator.popToTop();
},
renderScene: function(route, navigator) {
var goForward = function(route) {
route.index = this.state.route.index + 1 || 1;
navigator.push(route);
}.bind(this);
var goBackwards = function() {
this.onBack(navigator);
}.bind(this);
var goToFirstRoute = function() {
navigator.popToTop();
};
var didStartDrag = function(evt) {
var x = evt.nativeEvent.pageX;
if (x < 28) {
this.setState({
dragStartX: x,
didSwitchView: false
});
return true;
}
}.bind(this);
// Recognize swipe back gesture for navigation
var didMoveFinger = function(evt) {
var draggedAway = ((evt.nativeEvent.pageX - this.state.dragStartX) > 30);
if (!this.state.didSwitchView && draggedAway) {
this.onBack(navigator);
this.setState({ didSwitchView: true });
}
}.bind(this);
// Set to false to prevent iOS from hijacking the responder
var preventDefault = function(evt) {
return true;
};
var updateNavbarProps = function(props) {
route.updateNavbarProps && route.updateNavbarProps(props);
route.updateStaticNavbarProps && route.updateStaticNavbarProps(props);
}
var Content = route.component;
return (
<View
style={[styles.container]}
onStartShouldSetResponder={didStartDrag}
onResponderMove={didMoveFinger}
onResponderTerminationRequest={preventDefault}>
<Content
route={{
index:route.index,
push:goForward,
pop:goBackwards,
popToTop:goToFirstRoute,
}}
updateBarBackgroundStyle={
(style)=>{
route.updateBarBackgroundStyle &&
route.updateBarBackgroundStyle(style)
}
}
updateNavbarProps={updateNavbarProps}
{...route.passProps}/>
</View>
)
},
render: function() {
// Status bar color
if (this.props.statusBarColor === "black") {
StatusBarIOS.setStyle(0);
} else {
StatusBarIOS.setStyle(1);
}
var navigationBar =
<NavBarContainer
navbarComponent={this.props.navbarComponent}
navbarPassProps={this.props.navbarPassProps}
currentRoute={this.state.route}
backButtonComponent={this.props.backButtonComponent}
onForward={this.onForward}
onBack={this.onBack}
onFirst={this.onFirst}/>
var initialRoute = this.props.initialRoute;
initialRoute.index = 0;
return (
<Navigator
initialRoute={initialRoute}
navigationBar={navigationBar}
renderScene={this.renderScene}
onDidFocus={this.onDidFocus}/>)
},
});
var styles = StyleSheet.create({
container: {
flex: 1,
},
});
module.exports = Router;
================================================
FILE: package.json
================================================
{
"name": "react-native-custom-navigation",
"version": "0.2.2",
"description": "A navigation that allow to custom the appearance of navigation bar in your app",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/superdami/react-native-custom-navigation.git"
},
"keywords": [
"react",
"react component",
"react native",
"react navigation",
"ios",
"navigation",
"navbar",
"router"
],
"author": "Chen Zhejun <devsuperdami@gmail.com>",
"license": "MIT",
"homepage": "https://github.com/superdami/react-native-custom-navigation",
"dependencies": {
"react-timer-mixin" : "*"
}
}
gitextract_lhqzowum/ ├── .gitignore ├── .npmignore ├── README.md ├── components/ │ ├── NavBarContainer.js │ ├── NavBarContent.js │ └── StaticNavBarContent.js ├── example/ │ ├── demo1.js │ ├── demo2.js │ ├── index.ios.js │ ├── navbar.js │ └── package.json ├── index.js └── package.json
SYMBOL INDEX (32 symbols across 5 files)
FILE: components/NavBarContent.js
method render (line 50) | render() {
method render (line 106) | render() {
FILE: components/StaticNavBarContent.js
method getInitialState (line 16) | getInitialState() {
method componentWillMount (line 22) | componentWillMount() {
method componentWillReceiveProps (line 27) | componentWillReceiveProps(newProps) {
method render (line 33) | render() {
method _updateNavbarProps (line 53) | _updateNavbarProps(props) {
FILE: example/demo1.js
method render (line 26) | render() {
method render (line 38) | render() {
method getInitialState (line 54) | getInitialState() {
method componentWillMount (line 58) | componentWillMount() {
method componentWillReceiveProps (line 64) | componentWillReceiveProps(newProps) {
method render (line 72) | render() {
method _push (line 80) | _push() {
method render (line 97) | render() {
method _back (line 149) | _back() {
method _pushToNext (line 153) | _pushToNext() {
method _pushToNextCustomNavbar (line 166) | _pushToNextCustomNavbar() {
method _popToTop (line 181) | _popToTop() {
method _changeColor (line 185) | _changeColor() {
method _handleScroll (line 193) | _handleScroll(e) {
FILE: example/demo2.js
method getInitialState (line 27) | getInitialState() {
method componentWillReceiveProps (line 34) | componentWillReceiveProps(newProps) {
method _push (line 57) | _push() {
method render (line 67) | render() {
method render (line 86) | render() {
method render (line 100) | render() {
method _back (line 141) | _back() {
method _pushToNext (line 145) | _pushToNext() {
method _popToTop (line 155) | _popToTop() {
method _changeColor (line 159) | _changeColor() {
FILE: example/navbar.js
method render (line 14) | render() {
Condensed preview — 13 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (37K chars).
[
{
"path": ".gitignore",
"chars": 144,
"preview": "lib-cov\n*.seed\n*.log\n*.csv\n*.dat\n*.out\n*.pid\n*.gz\nconfig.js\n\npids\nlogs\nresults\npublic\n\nnpm-debug.log\n.DS_Store\n\nnode_mod"
},
{
"path": ".npmignore",
"chars": 113,
"preview": ".*.swp\n._*\n.DS_Store\n.git\n.hg\n.lock-wscript\n.svn\n.wafpickle-*\nCVS\nnpm-debug.log\nnode_modules\nexample/node_modules"
},
{
"path": "README.md",
"chars": 5734,
"preview": "react-native-custom-navigation\n===================\nThe goal is making a easy navigation router for react-native, you cou"
},
{
"path": "components/NavBarContainer.js",
"chars": 4731,
"preview": "'use strict';\n\nvar React = require('react-native');\n\nvar NavBarContent = require('./NavBarContent').NavBarContent;\nvar N"
},
{
"path": "components/NavBarContent.js",
"chars": 5184,
"preview": "'use strict';\n\nvar React = require('react-native');\nvar TimerMixin = require('react-timer-mixin');\n\nvar {\n StyleSheet,\n"
},
{
"path": "components/StaticNavBarContent.js",
"chars": 1646,
"preview": "'use strict';\n\nvar React = require('react-native');\nvar TimerMixin = require('react-timer-mixin');\n\nvar {\n StyleSheet,\n"
},
{
"path": "example/demo1.js",
"chars": 5352,
"preview": "var React = require('react-native');\nvar {\n\tImage,\n\tView,\n ScrollView,\n\tStyleSheet,\n Text,\n TouchableHighlight\n} = Re"
},
{
"path": "example/demo2.js",
"chars": 5002,
"preview": "var React = require('react-native');\nvar {\n Image,\n View,\n ScrollView,\n StyleSheet,\n Text,\n TouchableHighlight\n} ="
},
{
"path": "example/index.ios.js",
"chars": 285,
"preview": "/**\n * Sample React Native App\n * https://github.com/facebook/react-native\n */\n'use strict';\n\nvar React = require('react"
},
{
"path": "example/navbar.js",
"chars": 1629,
"preview": "'use strict';\n\nvar React = require('react-native');\n\nvar {\n View,\n Text,\n StyleSheet,\n TouchableHighlight,\n} = React"
},
{
"path": "example/package.json",
"chars": 284,
"preview": "{\n \"name\": \"sample-react-native-custom-navigation\",\n \"version\": \"0.2.1\",\n \"private\": true,\n \"scripts\": {\n \"start\""
},
{
"path": "index.js",
"chars": 3788,
"preview": "'use strict';\n\nvar React = require('react-native');\n\nvar NavBarContainer = require('./components/NavBarContainer');\n\nvar"
},
{
"path": "package.json",
"chars": 670,
"preview": "{\n \"name\": \"react-native-custom-navigation\",\n \"version\": \"0.2.2\",\n \"description\": \"A navigation that allow to custom "
}
]
About this extraction
This page contains the full source code of the SuperDami/react-native-custom-navigation GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 13 files (33.8 KB), approximately 8.7k tokens, and a symbol index with 32 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.