Skip to content

Commit d5c7e7e

Browse files
Pavlo AksonovPavlo Aksonov
authored andcommitted
introduce tab bar support with Container tag
1 parent 1e3cfdf commit d5c7e7e

File tree

12 files changed

+337
-231
lines changed

12 files changed

+337
-231
lines changed

Container.js

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class Container extends React.Component {
1818
super(props);
1919
this.state = {};
2020
this.routes = {};
21-
this.navRoutes = {};
2221
this.initial = props.initial;
2322
var self = this;
2423

@@ -48,12 +47,20 @@ class Container extends React.Component {
4847

4948
onChange({page}){
5049
console.log(page.name);
51-
var route = this.routes[page.name];
50+
var route = this.getRoute(this.routes[page.name], page.data)
51+
var found = false;
52+
var self = this;
5253
// check if route exists
53-
if (!this.navRoutes[page.name]){
54-
this.refs.nav.push(this.getRoute(route, page.data));
55-
} else {
56-
this.refs.nav.jumpTo(this.navRoutes[page.name]);
54+
this.refs.nav.getCurrentRoutes().forEach(function(navRoute){
55+
if (navRoute.name == route.name){
56+
self.refs.nav.jumpTo(navRoute);
57+
found = true;
58+
return;
59+
}
60+
});
61+
62+
if (!found){
63+
this.refs.nav.push(route);
5764
}
5865

5966
}
@@ -87,13 +94,14 @@ class Container extends React.Component {
8794
}
8895

8996
getRoute(route, data) {
90-
var sceneConfig = route.sceneConfig || Animations.None;
91-
var NavBar = route.navBar;
97+
var schema = this.props.schemas[route.schema || 'default'] || {};
98+
var sceneConfig = route.sceneConfig || schema.sceneConfig || Animations.None;
99+
var NavBar = route.navBar || schema.navBar;
92100
var navBar;
93101
if (NavBar){
94102
navBar = <NavBar {...schema} {...route} {...data} />
95103
}
96-
this.navRoutes[route.name] = {
104+
return {
97105
name: route.name,
98106
component: route.component,
99107
sceneConfig: {
@@ -103,17 +111,20 @@ class Container extends React.Component {
103111
navigationBar: route.hideNavBar ? null : navBar,
104112
passProps: { ...route, ...data }
105113
}
106-
return this.navRoutes[route.name];
107114
}
108115

109116
render(){
117+
var Component = this.props.component;
110118
return (
111-
<Navigator
112-
renderScene={this.renderScene.bind(this)}
113-
configureScene={(route) => { return route.sceneConfig;}}
114-
ref="nav"
115-
initialRoute={this.getRoute(this.initialRoute)}
116-
/>
119+
<View style={{flex:1,backgroundColor: "transparent"}}>
120+
<Navigator
121+
renderScene={this.renderScene.bind(this)}
122+
configureScene={(route) => { return route.sceneConfig;}}
123+
ref="nav"
124+
initialRoute={this.getRoute(this.initialRoute)}
125+
/>
126+
{Component && <Component {...this.props}/>}
127+
</View>
117128
);
118129
}
119130
}

Example/.idea/vcs.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Example/.idea/workspace.xml

Lines changed: 166 additions & 180 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Example/components/Launch.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Launch extends React.Component {
1414
<Button onPress={Actions.register}>Go to Register page</Button>
1515
<Button onPress={Actions.register2}>Go to Register page without animation</Button>
1616
<Button onPress={()=>Actions.error("Error message")}>Go to Error page</Button>
17+
<Button onPress={Actions.tabbar}>Go to TabBar page</Button>
1718
</View>
1819
);
1920
}

Example/components/TabBarFlux.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
var React = require('react-native');
4+
var {View, Text, StyleSheet} = React;
5+
var Button = require('react-native-button');
6+
var {Actions, ContainerStore} = require('react-native-router-flux');
7+
var Tabs = require('react-native-tabs');
8+
9+
class TabBarFlux extends React.Component {
10+
onSelect(el){
11+
Actions.switch({name: el.props.name, data:el.props});
12+
return {selected: true};
13+
}
14+
render(){
15+
var children = [];
16+
React.Children.forEach(this.props.children, function(el){
17+
if (!el.props.name)
18+
console.error("No name is defined for element");
19+
var Icon = el.props.icon || console.error("No icon class is defined for "+el.name);
20+
children.push(<Icon {...el.props}/>);
21+
});
22+
23+
return (
24+
<Tabs style={{backgroundColor:'white'}} onSelect={this.onSelect.bind(this)}>
25+
{children}
26+
</Tabs>
27+
);
28+
}
29+
}
30+
31+
module.exports = TabBarFlux;

Example/components/TabIcon.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
3+
var React = require('react-native');
4+
var {View, Text, StyleSheet} = React;
5+
6+
class TabIcon extends React.Component {
7+
render(){
8+
return (
9+
<Text style={{color: this.props.selected ? 'red' :'black'}}>{this.props.title}</Text>
10+
);
11+
}
12+
}
13+
14+
module.exports = TabIcon;

Example/components/TabView.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
var React = require('react-native');
4+
var {View, Text, StyleSheet} = React;
5+
6+
class TabView extends React.Component {
7+
render(){
8+
return (
9+
<View style={styles.container}>
10+
<Text>Tab #{this.props.name}</Text>
11+
</View>
12+
);
13+
}
14+
}
15+
16+
var styles = StyleSheet.create({
17+
container: {
18+
flex: 1,
19+
justifyContent: 'center',
20+
alignItems: 'center',
21+
backgroundColor: '#F5FCFF',
22+
},
23+
welcome: {
24+
fontSize: 20,
25+
textAlign: 'center',
26+
margin: 10,
27+
},
28+
instructions: {
29+
textAlign: 'center',
30+
color: '#333333',
31+
marginBottom: 5,
32+
},
33+
});
34+
35+
module.exports = TabView;

Example/index.ios.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
'use strict';
22

33
var React = require('react-native');
4-
var {
5-
AppRegistry,
6-
StyleSheet,
7-
Text,
8-
View,
9-
} = React;
10-
4+
var {AppRegistry, StyleSheet,Text,View} = React;
115
var Launch = require('./components/Launch');
126
var Register = require('./components/Register');
137
var Login = require('./components/Login');
14-
var {Router, Route, Actions, Animations, Schema} = require('react-native-router-flux');
8+
var {Router, Route, Container, Actions, Animations, Schema} = require('react-native-router-flux');
159
var {NavBar, NavBarModal} = require('./components/NavBar');
1610
var Error = require('./components/Error');
11+
var TabView = require('./components/TabView');
12+
var TabIcon = require('./components/TabIcon');
13+
var TabBarFlux = require('./components/TabBarFlux');
1714

1815
class Example extends React.Component {
1916
render() {
@@ -24,12 +21,22 @@ class Example extends React.Component {
2421
<Schema name="modal" sceneConfig={Animations.FlatFloatFromBottom} navBar={NavBarModal}/>
2522
<Schema name="default" sceneConfig={Animations.FlatFloatFromRight} navBar={NavBar}/>
2623
<Schema name="withoutAnimation" navBar={NavBar}/>
24+
<Schema name="tab" navBar={NavBar}/>
2725

2826
<Route name="launch" component={Launch} initial={true} hideNavBar={true} title="Launch"/>
2927
<Route name="register" component={Register} title="Register"/>
3028
<Route name="login" component={Login} schema="modal"/>
3129
<Route name="register2" component={Register} schema="withoutAnimation"/>
3230
<Route name="error" component={Error} schema="popup"/>
31+
<Route name="tabbar" hideNavBar={true} >
32+
<Container component={TabBarFlux}>
33+
<Route name="tab1" component={TabView} title="Tab #1" icon={TabIcon} schema="tab"/>
34+
<Route name="tab2" component={TabView} title="Tab #2" icon={TabIcon} schema="tab"/>
35+
<Route name="tab3" component={TabView} title="Tab #3" icon={TabIcon} schema="tab"/>
36+
<Route name="tab4" component={TabView} title="Tab #4" icon={TabIcon} schema="tab"/>
37+
<Route name="tab5" component={TabView} title="Tab #5" icon={TabIcon} schema="tab"/>
38+
</Container>
39+
</Route>
3340
</Router>
3441

3542
</View>

Example/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"react-native": "^0.10.1",
1010
"react-native-button": "^1.2.1",
1111
"react-native-navbar": "^0.8.0",
12-
"react-native-router-flux": "^0.1.2"
12+
"react-native-router-flux": "^0.1.2",
13+
"react-native-tabs": "0.0.2"
1314
}
1415
}

README.md

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ React Native Router using Flux architecture
88
- Use route "schemas" to define common property for some screens. For example some screens are "modal" (i.e. have animation from bottom and have Cancel/Close nav button), so you could define group for them to avoid any code repeatition.
99
- Use popup with Flux actions (see Error popup within Example project)
1010
- Hide nav bar for some screens easily
11+
- Use tab bars for some screens with Flux actions (see demo)
1112

1213
## Example
1314
![demo-2](https://cloud.githubusercontent.com/assets/1321329/9466261/de64558e-4b33-11e5-8ada-0fcd49442769.gif)
@@ -18,29 +19,47 @@ React Native Router using Flux architecture
1819
1920
var React = require('react-native');
2021
var {AppRegistry, StyleSheet,Text,View} = React;
21-
2222
var Launch = require('./components/Launch');
2323
var Register = require('./components/Register');
2424
var Login = require('./components/Login');
25-
var {Router, Route, Actions, Animations, Schema} = require('react-native-router-flux');
25+
var {Router, Route, Container, Actions, Animations, Schema} = require('react-native-router-flux');
2626
var {NavBar, NavBarModal} = require('./components/NavBar');
2727
var Error = require('./components/Error');
28+
var TabView = require('./components/TabView');
29+
var TabIcon = require('./components/TabIcon');
30+
var TabBarFlux = require('./components/TabBarFlux');
2831
29-
var Example = React.createClass({
30-
render: function() {
32+
class Example extends React.Component {
33+
render() {
3134
return (
32-
<Router>
33-
<Schema name="modal" sceneConfig={Animations.FlatFloatFromBottom} navBar={NavBarModal} />
34-
<Schema name="default" sceneConfig={Animations.FlatFloatFromRight} navBar={NavBar} />
35+
<View style={{flex:1}}>
36+
<View style={{position:'absolute',left:0,right:0,top:0,bottom:0,backgroundColor:'#F5FCFF'}}/>
37+
<Router>
38+
<Schema name="modal" sceneConfig={Animations.FlatFloatFromBottom} navBar={NavBarModal}/>
39+
<Schema name="default" sceneConfig={Animations.FlatFloatFromRight} navBar={NavBar}/>
40+
<Schema name="withoutAnimation" navBar={NavBar}/>
41+
<Schema name="tab" navBar={NavBar}/>
42+
43+
<Route name="launch" component={Launch} initial={true} hideNavBar={true} title="Launch"/>
44+
<Route name="register" component={Register} title="Register"/>
45+
<Route name="login" component={Login} schema="modal"/>
46+
<Route name="register2" component={Register} schema="withoutAnimation"/>
47+
<Route name="error" component={Error} schema="popup"/>
48+
<Route name="tabbar" hideNavBar={true} >
49+
<Container component={TabBarFlux}>
50+
<Route name="tab1" component={TabView} title="Tab #1" icon={TabIcon} schema="tab"/>
51+
<Route name="tab2" component={TabView} title="Tab #2" icon={TabIcon} schema="tab"/>
52+
<Route name="tab3" component={TabView} title="Tab #3" icon={TabIcon} schema="tab"/>
53+
<Route name="tab4" component={TabView} title="Tab #4" icon={TabIcon} schema="tab"/>
54+
<Route name="tab5" component={TabView} title="Tab #5" icon={TabIcon} schema="tab"/>
55+
</Container>
56+
</Route>
57+
</Router>
3558
36-
<Route name="launch" component={Launch} initial={true} hideNavBar={false} title="Launch"/>
37-
<Route name="register" component={Register} title="Register" />
38-
<Route name="login" component={Login} schema="modal"/>
39-
<Route name="error" component={Error} schema="popup" />
40-
</Router>
59+
</View>
4160
);
4261
}
43-
});
62+
}
4463
4564
AppRegistry.registerComponent('Example', () => Example);
4665
```

0 commit comments

Comments
 (0)