Skip to content

Commit acffe89

Browse files
committedAug 12, 2018
Merge branch 'code-refactoring with latest convention'
2 parents 8728555 + 71d5e47 commit acffe89

File tree

2 files changed

+318
-188
lines changed

2 files changed

+318
-188
lines changed
 

‎SegmentedControlTab.js

+136-188
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,40 @@
1-
import React, { Component } from 'react';
2-
import {
3-
View,
4-
ViewPropTypes,
5-
TouchableOpacity,
6-
StyleSheet,
7-
Text
8-
} from 'react-native';
1+
import React, {PureComponent} from 'react';
92
import PropTypes from 'prop-types';
3+
import {View, ViewPropTypes, StyleSheet, Text} from 'react-native';
4+
import TabOption from './TabOption';
105

6+
const styles = StyleSheet.create({
7+
tabsContainerStyle: {
8+
backgroundColor: 'transparent',
9+
flexDirection: 'row',
10+
},
11+
tabStyle: {
12+
paddingVertical: 5,
13+
flex: 1,
14+
justifyContent: 'center',
15+
alignItems: 'center',
16+
borderColor: '#0076FF',
17+
borderWidth: 1,
18+
backgroundColor: 'white',
19+
},
20+
});
1121
const handleTabPress = (index, multiple, selectedIndex, onTabPress) => {
12-
if (multiple) {
13-
onTabPress(index);
14-
}
15-
else if (selectedIndex !== index) {
16-
onTabPress(index);
17-
}
22+
if (multiple) {
23+
onTabPress(index);
24+
} else if (selectedIndex !== index) {
25+
onTabPress(index);
26+
}
1827
};
1928

20-
const TabOption = ({
21-
isTabActive, index, badge, text,
22-
firstTabStyle, lastTabStyle,
23-
tabStyle, activeTabStyle,
24-
tabTextStyle, activeTabTextStyle,
25-
tabBadgeContainerStyle, activeTabBadgeContainerStyle,
26-
tabBadgeStyle, activeTabBadgeStyle,
27-
onTabPress, textNumberOfLines,
28-
allowFontScaling,
29-
accessible,
30-
activeTabOpacity,
31-
accessibilityLabel,
32-
enabled,
33-
}) => {
34-
return (
35-
<TouchableOpacity style={[
36-
styles.tabStyle,
37-
tabStyle,
38-
isTabActive ? [styles.activeTabStyle, activeTabStyle] : {},
39-
firstTabStyle,
40-
lastTabStyle]}
41-
accessible={accessible}
42-
accessibilityLabel={accessibilityLabel}
43-
accessibilityTraits={isTabActive ? "selected" : "button"}
44-
accessibilityComponentType={"button"}
45-
onPress={() => onTabPress(index)}
46-
disabled={!enabled}
47-
activeOpacity={activeTabOpacity}>
48-
<View style={{ flexDirection: "row" }}>
49-
<Text style={[
50-
styles.tabTextStyle,
51-
tabTextStyle,
52-
isTabActive ? [styles.activeTabTextStyle, activeTabTextStyle] : {}]}
53-
numberOfLines={textNumberOfLines}
54-
allowFontScaling={allowFontScaling}
55-
ellipsizeMode="tail">
56-
{text}
57-
</Text>
58-
{
59-
Boolean(badge) ?
60-
<View style={[
61-
styles.tabBadgeContainerStyle,
62-
tabBadgeContainerStyle,
63-
isTabActive ? [styles.activeTabBadgeContainerStyle, activeTabBadgeContainerStyle] : {}]}>
64-
<Text style={[
65-
styles.tabBadgeStyle,
66-
tabBadgeStyle,
67-
isTabActive ? [styles.activeTabBadgeStyle, activeTabBadgeStyle] : {}]}
68-
allowFontScaling={allowFontScaling}>
69-
{badge}
70-
</Text>
71-
</View> : false
72-
}
73-
</View>
74-
</TouchableOpacity>
75-
);
76-
}
77-
78-
const getAccessibilityLabelByIndex = (accessibilityLabels, index) => {
79-
return accessibilityLabels && accessibilityLabels.length > 0 && accessibilityLabels[index] ? accessibilityLabels[index] : undefined
80-
}
81-
82-
const SegmentedControlTab = ({
83-
multiple, selectedIndex, selectedIndices, values,
84-
badges, borderRadius, tabsContainerStyle, tabsContainerDisableStyle,
85-
tabStyle, activeTabStyle,
86-
tabTextStyle, activeTabTextStyle,
87-
tabBadgeContainerStyle, activeTabBadgeContainerStyle,
88-
tabBadgeStyle, activeTabBadgeStyle,
89-
onTabPress, textNumberOfLines,
90-
allowFontScaling,
91-
accessible,
92-
accessibilityLabels,
93-
activeTabOpacity,
94-
enabled
95-
}) => {
96-
97-
const firstTabStyle = [{ borderRightWidth: values.length == 2 ? 1 : 0, borderTopLeftRadius: borderRadius, borderBottomLeftRadius: borderRadius }]
98-
const lastTabStyle = [{ borderLeftWidth: 0, borderTopRightRadius: borderRadius, borderBottomRightRadius: borderRadius }]
99-
100-
const tabsContainerStyles = [styles.tabsContainerStyle, tabsContainerStyle]
101-
if(!enabled) {
102-
tabsContainerStyles.push(tabsContainerDisableStyle)
103-
}
104-
105-
return (
106-
<View
107-
style={tabsContainerStyles}
108-
removeClippedSubviews={false}>
109-
{
110-
values.map((item, index) => {
111-
const accessibilityText = getAccessibilityLabelByIndex(accessibilityLabels, index)
112-
return (
113-
<TabOption
114-
key={index}
115-
index={index}
116-
badge={badges && badges[index] ? badges[index] : false}
117-
isTabActive={multiple ? selectedIndices.includes(index) : selectedIndex === index}
118-
text={item}
119-
textNumberOfLines={textNumberOfLines}
120-
onTabPress={(index) => handleTabPress(index, multiple, selectedIndex, onTabPress)}
121-
firstTabStyle={index === 0 ? [{ borderRightWidth: 0 }, firstTabStyle] : {}}
122-
lastTabStyle={index === values.length - 1 ? [{ borderLeftWidth: 0 }, lastTabStyle] : {}}
123-
tabStyle={[tabStyle, index !== 0 && index !== values.length - 1 ? { marginLeft: -1 } : {}]}
124-
activeTabStyle={activeTabStyle}
125-
tabTextStyle={tabTextStyle}
126-
activeTabTextStyle={activeTabTextStyle}
127-
tabBadgeContainerStyle={tabBadgeContainerStyle}
128-
activeTabBadgeContainerStyle={activeTabBadgeContainerStyle}
129-
tabBadgeStyle={tabBadgeStyle}
130-
activeTabBadgeStyle={activeTabBadgeStyle}
131-
allowFontScaling={allowFontScaling}
132-
activeTabOpacity={activeTabOpacity}
133-
accessible={accessible}
134-
accessibilityLabel={accessibilityText ? accessibilityText : item }
135-
enabled={enabled}
136-
/>
137-
);
138-
})
139-
}
140-
</View>
141-
);
142-
};
29+
const getAccessibilityLabelByIndex = (accessibilityLabels, index) =>
30+
accessibilityLabels &&
31+
accessibilityLabels.length > 0 &&
32+
accessibilityLabels[index]
33+
? accessibilityLabels[index]
34+
: undefined;
14335

144-
SegmentedControlTab.propTypes = {
36+
export default class SegmentedControlTab extends PureComponent {
37+
static propTypes = {
14538
values: PropTypes.array,
14639
badges: PropTypes.array,
14740
multiple: PropTypes.bool,
@@ -164,20 +57,20 @@ SegmentedControlTab.propTypes = {
16457
accessible: PropTypes.bool,
16558
accessibilityLabels: PropTypes.array,
16659
activeTabOpacity: PropTypes.number,
167-
enabled: PropTypes.bool
168-
};
60+
enabled: PropTypes.bool,
61+
};
16962

170-
SegmentedControlTab.defaultProps = {
63+
static defaultProps = {
17164
values: ['One', 'Two', 'Three'],
17265
accessible: true,
17366
accessibilityLabels: [],
17467
badges: ['', '', ''],
17568
multiple: false,
17669
selectedIndex: 0,
17770
selectedIndices: [0],
178-
onTabPress: () => { },
71+
onTabPress: () => {},
17972
tabsContainerStyle: {},
180-
tabsContainerDisableStyle: { opacity:0.6 },
73+
tabsContainerDisableStyle: {opacity: 0.6},
18174
tabStyle: {},
18275
activeTabStyle: {},
18376
tabTextStyle: {},
@@ -191,50 +84,105 @@ SegmentedControlTab.defaultProps = {
19184
allowFontScaling: true,
19285
activeTabOpacity: 1,
19386
enabled: true,
194-
};
87+
};
19588

196-
const styles = StyleSheet.create({
197-
tabsContainerStyle: {
198-
backgroundColor: 'transparent',
199-
flexDirection: 'row',
200-
},
201-
tabStyle: {
202-
paddingVertical: 5,
203-
flex: 1,
204-
justifyContent: 'center',
205-
alignItems: 'center',
206-
borderColor: '#0076FF',
207-
borderWidth: 1,
208-
backgroundColor: 'white',
209-
},
210-
activeTabStyle: {
211-
backgroundColor: '#0076FF'
212-
},
213-
tabTextStyle: {
214-
color: '#0076FF'
215-
},
216-
activeTabTextStyle: {
217-
color: 'white'
218-
},
219-
tabBadgeContainerStyle: {
220-
borderRadius: 20,
221-
backgroundColor: 'red',
222-
paddingLeft: 5,
223-
paddingRight: 5,
224-
marginLeft: 5,
225-
marginBottom: 3
226-
},
227-
activeTabBadgeContainerStyle: {
228-
backgroundColor: 'white'
229-
},
230-
tabBadgeStyle: {
231-
color: 'white',
232-
fontSize: 11,
233-
fontWeight: 'bold'
234-
},
235-
activeTabBadgeStyle: {
236-
color: 'black'
237-
}
238-
});
89+
render() {
90+
const {
91+
multiple,
92+
selectedIndex,
93+
selectedIndices,
94+
values,
95+
badges,
96+
borderRadius,
97+
tabsContainerStyle,
98+
tabsContainerDisableStyle,
99+
tabStyle,
100+
activeTabStyle,
101+
tabTextStyle,
102+
activeTabTextStyle,
103+
tabBadgeContainerStyle,
104+
activeTabBadgeContainerStyle,
105+
tabBadgeStyle,
106+
activeTabBadgeStyle,
107+
onTabPress,
108+
textNumberOfLines,
109+
allowFontScaling,
110+
accessible,
111+
accessibilityLabels,
112+
activeTabOpacity,
113+
enabled,
114+
} = this.props;
115+
const firstTabStyle = [
116+
{
117+
borderRightWidth: values.length === 2 ? 1 : 0,
118+
borderTopLeftRadius: borderRadius,
119+
borderBottomLeftRadius: borderRadius,
120+
},
121+
];
122+
const lastTabStyle = [
123+
{
124+
borderLeftWidth: 0,
125+
borderTopRightRadius: borderRadius,
126+
borderBottomRightRadius: borderRadius,
127+
},
128+
];
239129

240-
export default SegmentedControlTab
130+
const tabsContainerStyles = [styles.tabsContainerStyle, tabsContainerStyle];
131+
if (!enabled) {
132+
tabsContainerStyles.push(tabsContainerDisableStyle);
133+
}
134+
return (
135+
<View style={tabsContainerStyles} removeClippedSubviews={false}>
136+
{values.map((item, index) => {
137+
const accessibilityText = getAccessibilityLabelByIndex(
138+
accessibilityLabels,
139+
index,
140+
);
141+
return (
142+
<TabOption
143+
key={`${index}${item}`}
144+
index={index}
145+
badge={badges && badges[index] ? badges[index] : false}
146+
isTabActive={
147+
multiple
148+
? selectedIndices.includes(index)
149+
: selectedIndex === index
150+
}
151+
text={item}
152+
textNumberOfLines={textNumberOfLines}
153+
onTabPress={indexs =>
154+
handleTabPress(indexs, multiple, selectedIndex, onTabPress)
155+
}
156+
firstTabStyle={
157+
index === 0 ? [{borderRightWidth: 0}, firstTabStyle] : {}
158+
}
159+
lastTabStyle={
160+
index === values.length - 1
161+
? [{borderLeftWidth: 0}, lastTabStyle]
162+
: {}
163+
}
164+
tabStyle={[
165+
tabStyle,
166+
index !== 0 && index !== values.length - 1
167+
? {marginLeft: -1}
168+
: {},
169+
]}
170+
activeTabStyle={activeTabStyle}
171+
tabTextStyle={tabTextStyle}
172+
activeTabTextStyle={activeTabTextStyle}
173+
tabBadgeContainerStyle={tabBadgeContainerStyle}
174+
activeTabBadgeContainerStyle={activeTabBadgeContainerStyle}
175+
tabBadgeStyle={tabBadgeStyle}
176+
activeTabBadgeStyle={activeTabBadgeStyle}
177+
allowFontScaling={allowFontScaling}
178+
activeTabOpacity={activeTabOpacity}
179+
accessible={accessible}
180+
accessibilityLabel={accessibilityText || item}
181+
enabled={enabled}
182+
/>
183+
);
184+
})}
185+
</View>
186+
);
187+
}
188+
}

‎TabOption.js

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import React, {PureComponent} from 'react';
2+
import PropTypes from 'prop-types';
3+
import {
4+
View,
5+
TouchableOpacity,
6+
StyleSheet,
7+
Text,
8+
ViewPropTypes
9+
} from 'react-native';
10+
11+
const styles = StyleSheet.create({
12+
tabStyle: {
13+
paddingVertical: 5,
14+
flex: 1,
15+
justifyContent: 'center',
16+
alignItems: 'center',
17+
borderColor: '#0076FF',
18+
borderWidth: 1,
19+
backgroundColor: 'white',
20+
},
21+
activeTabStyle: {
22+
backgroundColor: '#0076FF',
23+
},
24+
tabTextStyle: {
25+
color: '#0076FF',
26+
},
27+
activeTabTextStyle: {
28+
color: 'white',
29+
},
30+
tabBadgeContainerStyle: {
31+
borderRadius: 20,
32+
backgroundColor: 'red',
33+
paddingLeft: 5,
34+
paddingRight: 5,
35+
marginLeft: 5,
36+
marginBottom: 3,
37+
},
38+
activeTabBadgeContainerStyle: {
39+
backgroundColor: 'white',
40+
},
41+
tabBadgeStyle: {
42+
color: 'white',
43+
fontSize: 11,
44+
fontWeight: 'bold',
45+
},
46+
activeTabBadgeStyle: {
47+
color: 'black',
48+
},
49+
});
50+
51+
export default class TabOption extends PureComponent {
52+
static propTypes = {
53+
isTabActive: PropTypes.bool,
54+
index: PropTypes.number,
55+
badge: PropTypes.any,
56+
text: PropTypes.string.isRequired,
57+
firstTabStyle: ViewPropTypes.style,
58+
lastTabStyle: ViewPropTypes.style,
59+
tabStyle: ViewPropTypes.style,
60+
activeTabStyle: ViewPropTypes.style,
61+
tabTextStyle: Text.propTypes.style,
62+
activeTabTextStyle: Text.propTypes.style,
63+
tabBadgeContainerStyle: Text.propTypes.style,
64+
activeTabBadgeContainerStyle: Text.propTypes.style,
65+
tabBadgeStyle: Text.propTypes.style,
66+
activeTabBadgeStyle: Text.propTypes.style,
67+
onTabPress: PropTypes.func,
68+
textNumberOfLines: PropTypes.number,
69+
allowFontScaling: PropTypes.bool,
70+
accessible: PropTypes.any,
71+
activeTabOpacity: PropTypes.number,
72+
accessibilityLabel: PropTypes.string,
73+
enabled: PropTypes.bool,
74+
};
75+
76+
static defaultProps = {
77+
isTabActive: false,
78+
index: 0,
79+
badge: '',
80+
firstTabStyle: {},
81+
lastTabStyle: {},
82+
tabStyle: {},
83+
activeTabStyle: {},
84+
tabTextStyle: {},
85+
activeTabTextStyle: {},
86+
tabBadgeContainerStyle: {},
87+
activeTabBadgeContainerStyle: {},
88+
tabBadgeStyle: {},
89+
activeTabBadgeStyle: {},
90+
onTabPress() {},
91+
textNumberOfLines: 1,
92+
allowFontScaling: false,
93+
accessible: {},
94+
activeTabOpacity: 1,
95+
accessibilityLabel: '',
96+
enabled: false,
97+
};
98+
99+
render() {
100+
const {
101+
isTabActive,
102+
index,
103+
badge,
104+
text,
105+
firstTabStyle,
106+
lastTabStyle,
107+
tabStyle,
108+
activeTabStyle,
109+
tabTextStyle,
110+
activeTabTextStyle,
111+
tabBadgeContainerStyle,
112+
activeTabBadgeContainerStyle,
113+
tabBadgeStyle,
114+
activeTabBadgeStyle,
115+
onTabPress,
116+
textNumberOfLines,
117+
allowFontScaling,
118+
accessible,
119+
activeTabOpacity,
120+
accessibilityLabel,
121+
enabled,
122+
} = this.props;
123+
return (
124+
<TouchableOpacity
125+
style={[
126+
styles.tabStyle,
127+
tabStyle,
128+
isTabActive ? [styles.activeTabStyle, activeTabStyle] : {},
129+
firstTabStyle,
130+
lastTabStyle,
131+
]}
132+
accessible={accessible}
133+
accessibilityLabel={accessibilityLabel}
134+
accessibilityTraits={isTabActive ? 'selected' : 'button'}
135+
accessibilityComponentType="button"
136+
onPress={() => onTabPress(index)}
137+
disabled={!enabled}
138+
activeOpacity={activeTabOpacity}>
139+
<View style={{flexDirection: 'row'}}>
140+
<Text
141+
style={[
142+
styles.tabTextStyle,
143+
tabTextStyle,
144+
isTabActive
145+
? [styles.activeTabTextStyle, activeTabTextStyle]
146+
: {},
147+
]}
148+
numberOfLines={textNumberOfLines}
149+
allowFontScaling={allowFontScaling}
150+
ellipsizeMode="tail">
151+
{text}
152+
</Text>
153+
{Boolean(badge) && (
154+
<View
155+
style={[
156+
styles.tabBadgeContainerStyle,
157+
tabBadgeContainerStyle,
158+
isTabActive
159+
? [
160+
styles.activeTabBadgeContainerStyle,
161+
activeTabBadgeContainerStyle,
162+
]
163+
: {},
164+
]}>
165+
<Text
166+
style={[
167+
styles.tabBadgeStyle,
168+
tabBadgeStyle,
169+
isTabActive
170+
? [styles.activeTabBadgeStyle, activeTabBadgeStyle]
171+
: {},
172+
]}
173+
allowFontScaling={allowFontScaling}>
174+
{badge}
175+
</Text>
176+
</View>
177+
)}
178+
</View>
179+
</TouchableOpacity>
180+
);
181+
}
182+
}

0 commit comments

Comments
 (0)
Please sign in to comment.