Skip to content

Commit 90605fd

Browse files
adamTrzsouhe
authored andcommitted
TabBar (#21)
* TabBar Initial work * Removed badge prop * some styling tweaks * Updated expo * CR fixes * CR review continue * Fiexd travis error
1 parent d734e21 commit 90605fd

File tree

5 files changed

+170
-0
lines changed

5 files changed

+170
-0
lines changed

example/src/ExampleList.js

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ListView, TouchableHighlight, StyleSheet, Text } from 'react-native';
55

66
import Buttons from './scenes/Buttons';
77
import Typography from './scenes/Typography';
8+
import TabBar from './scenes/TabBar';
89

910
type Route = {
1011
/* eslint-disable react/no-unused-prop-types */
@@ -22,6 +23,10 @@ const dataSource = ds.cloneWithRows([
2223
component: Typography,
2324
title: 'Typography',
2425
},
26+
{
27+
component: TabBar,
28+
title: 'TabBar',
29+
},
2530
]);
2631

2732
type Props = {

example/src/scenes/TabBar.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* @flow */
2+
import React, { Component } from 'react';
3+
import { View, StyleSheet } from 'react-native';
4+
5+
import { TabBar, withTheme, Headline } from 'react-native-ios-kit';
6+
import type { Theme } from 'react-native-ios-kit/types';
7+
8+
type Props = {
9+
theme: Theme,
10+
};
11+
type State = {
12+
activeTab: number,
13+
};
14+
15+
class TabBarExample extends Component<Props, State> {
16+
state = {
17+
activeTab: 0,
18+
};
19+
20+
selectTab = (tabIndex: number) => this.setState({ activeTab: tabIndex });
21+
22+
render() {
23+
return (
24+
<View style={styles.screen}>
25+
<View>
26+
<Headline>{`Active Tab: ${this.state.activeTab}`}</Headline>
27+
</View>
28+
<TabBar
29+
tabs={[
30+
{
31+
icon: 'ios-paper-outline',
32+
title: 'News',
33+
onPress: this.selectTab,
34+
isActive: this.state.activeTab === 0,
35+
},
36+
{
37+
icon: 'ios-podium',
38+
title: 'Scores',
39+
onPress: this.selectTab,
40+
isActive: this.state.activeTab === 1,
41+
},
42+
{
43+
icon: 'ios-star-outline',
44+
title: 'Favourites',
45+
onPress: this.selectTab,
46+
isActive: this.state.activeTab === 2,
47+
},
48+
{
49+
icon: 'ios-people',
50+
title: 'Disabled',
51+
onPress: this.selectTab,
52+
isActive: this.state.activeTab === 3,
53+
disabled: true,
54+
},
55+
]}
56+
/>
57+
</View>
58+
);
59+
}
60+
}
61+
62+
export default withTheme(TabBarExample);
63+
64+
const styles = StyleSheet.create({
65+
screen: {
66+
flexGrow: 1,
67+
justifyContent: 'center',
68+
alignItems: 'center',
69+
},
70+
});

src/components/TabBar.js

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* @flow */
2+
import React, { PureComponent } from 'react';
3+
import { View, StyleSheet, TouchableWithoutFeedback } from 'react-native';
4+
5+
import Icon from './Icon';
6+
import { Caption2 } from './Typography';
7+
import { withTheme } from '../';
8+
import type { Theme } from '../types/Theme';
9+
10+
type TabItem = {
11+
icon: string,
12+
title: string,
13+
onPress: (tabIndex: number) => void,
14+
isActive: boolean,
15+
disabled?: boolean,
16+
};
17+
18+
type Props = {
19+
/**
20+
* Array of Tabs. Each TabItem needs to have below shape:
21+
* icon: Icon name, one of https://github.com/oblador/react-native-vector-icons/blob/master/glyphmaps/Ionicons.json
22+
* title: string,
23+
* onPress: function to be called when Tab is tapped
24+
* isActive: boolean, indicating wheter Tab is active
25+
* disabled?: boolean, (optional), diasables a Tab
26+
*/
27+
tabs: Array<TabItem>,
28+
/**
29+
* Provided by the ThemeProvider
30+
*/
31+
theme: Theme,
32+
};
33+
34+
class TabBar extends PureComponent<Props> {
35+
render() {
36+
const { theme, tabs } = this.props;
37+
const tabBarStyle = {
38+
backgroundColor: theme.barColor,
39+
borderTopColor: theme.borderColor,
40+
};
41+
const activeColor = theme.buttonColor;
42+
const inactiveColor = theme.buttonDisabledColor;
43+
return (
44+
<View style={[styles.wrapper, tabBarStyle]}>
45+
{tabs.map((tab, idx) => (
46+
<TouchableWithoutFeedback
47+
key={`tabItem_${idx}`}
48+
onPress={() => tab.onPress(idx)}
49+
disabled={tab.disabled || tab.isActive}
50+
>
51+
<View style={styles.tabItem}>
52+
<Icon
53+
name={tab.icon}
54+
size={30}
55+
color={tab.isActive ? activeColor : inactiveColor}
56+
/>
57+
<Caption2
58+
style={{
59+
color: tab.isActive ? activeColor : inactiveColor,
60+
}}
61+
>
62+
{tab.title}
63+
</Caption2>
64+
</View>
65+
</TouchableWithoutFeedback>
66+
))}
67+
</View>
68+
);
69+
}
70+
}
71+
72+
export default withTheme(TabBar);
73+
74+
const styles = StyleSheet.create({
75+
wrapper: {
76+
position: 'absolute',
77+
bottom: 0,
78+
left: 0,
79+
right: 0,
80+
flexDirection: 'row',
81+
borderTopWidth: 1,
82+
},
83+
tabItem: {
84+
flexGrow: 1,
85+
justifyContent: 'center',
86+
alignItems: 'center',
87+
paddingVertical: 4,
88+
},
89+
});

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export { default as ThemeProvider } from './core/ThemeProvider';
55

66
export { default as Button } from './components/Button';
77
export { default as Icon } from './components/Icon';
8+
export { default as TabBar } from './components/TabBar';
89
export * from './components/Typography';

types.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* @flow */
2+
3+
import type { Theme as _Theme } from './src/types/Theme';
4+
5+
export type Theme = _Theme;

0 commit comments

Comments
 (0)