Skip to content

Commit 2b7c474

Browse files
authored
Feat/segmented control new style (#1327)
* add fullWidth mode * fullWidth generatedTypes * update style * remove fullWidth prop * remove trailing comma * set dynamic height * fix style
1 parent 769eba0 commit 2b7c474

File tree

4 files changed

+57
-36
lines changed

4 files changed

+57
-36
lines changed

demo/src/screens/componentScreens/SegmentedControlScreen.tsx

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ const segments = {
1414
},
1515
{label: 'Short'}
1616
],
17-
forth: [{label: 'With'}, {label: 'Custom'}, {label: 'Colors'}]
17+
forth: [{label: 'With'}, {label: 'Custom'}, {label: 'Colors'}],
18+
fifth: [{label: 'Full'}, {label: 'Width'}],
19+
sixth: [{label: 'Full'}, {label: 'Width'}, {label: 'With'}, {label: 'A'}, {label: 'Very Long Segment'}]
1820
};
1921

2022
const SegmentedControlScreen = () => {
@@ -23,30 +25,42 @@ const SegmentedControlScreen = () => {
2325
};
2426

2527
return (
26-
<View flex bottom padding-20>
27-
<View flex center>
28-
<SegmentedControl onChangeIndex={(index: number) => onChangeIndex('first', index)} segments={segments.first}/>
28+
<View flex bottom padding-page>
29+
<View flex centerV>
30+
<View center>
31+
<SegmentedControl onChangeIndex={(index: number) => onChangeIndex('first', index)} segments={segments.first}/>
32+
<SegmentedControl
33+
onChangeIndex={(index: number) => onChangeIndex('second', index)}
34+
containerStyle={styles.container}
35+
segments={segments.second}
36+
initialIndex={2}
37+
/>
38+
<SegmentedControl
39+
onChangeIndex={(index: number) => onChangeIndex('third', index)}
40+
containerStyle={styles.container}
41+
activeColor={Colors.red30}
42+
segments={segments.third}
43+
/>
44+
<SegmentedControl
45+
onChangeIndex={(index: number) => onChangeIndex('forth', index)}
46+
containerStyle={styles.container}
47+
segments={segments.forth}
48+
activeColor={Colors.grey10}
49+
borderRadius={BorderRadiuses.br20}
50+
backgroundColor={Colors.grey10}
51+
activeBackgroundColor={Colors.grey40}
52+
inactiveColor={Colors.grey70}
53+
/>
54+
</View>
2955
<SegmentedControl
30-
onChangeIndex={(index: number) => onChangeIndex('second', index)}
31-
containerStyle={styles.container}
32-
segments={segments.second}
33-
initialIndex={2}
34-
/>
35-
<SegmentedControl
36-
onChangeIndex={(index: number) => onChangeIndex('third', index)}
3756
containerStyle={styles.container}
38-
activeColor={Colors.red30}
39-
segments={segments.third}
57+
onChangeIndex={(index: number) => onChangeIndex('second', index)}
58+
segments={segments.fifth}
4059
/>
4160
<SegmentedControl
42-
onChangeIndex={(index: number) => onChangeIndex('forth', index)}
4361
containerStyle={styles.container}
44-
segments={segments.forth}
45-
activeColor={Colors.grey10}
46-
borderRadius={BorderRadiuses.br20}
47-
backgroundColor={Colors.grey10}
48-
activeBackgroundColor={Colors.grey40}
49-
inactiveColor={Colors.grey70}
62+
onChangeIndex={(index: number) => onChangeIndex('second', index)}
63+
segments={segments.sixth}
5064
/>
5165
</View>
5266
<Text text40 dark10>

generatedTypes/components/segmentedControl/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export declare type SegmentedControlProps = {
5151
* Additional spacing styles for the container
5252
*/
5353
containerStyle?: StyleProp<ViewStyle>;
54+
style?: StyleProp<ViewStyle>;
5455
testID?: string;
5556
};
5657
declare const _default: React.ComponentClass<SegmentedControlProps & {

src/components/segmentedControl/index.tsx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const {interpolate: _interpolate, interpolateNode} = Reanimated;
1111
const interpolate = interpolateNode || _interpolate;
1212
const Easing = EasingNode || _Easing;
1313
const BORDER_WIDTH = 1;
14+
const HORIZONTAL_PADDING = Spacings.s2;
1415

1516
export type SegmentedControlItemProps = SegmentProps;
1617
export type SegmentedControlProps = {
@@ -62,6 +63,7 @@ export type SegmentedControlProps = {
6263
* Additional spacing styles for the container
6364
*/
6465
containerStyle?: StyleProp<ViewStyle>;
66+
style?: StyleProp<ViewStyle>;
6567
testID?: string;
6668
};
6769

@@ -74,6 +76,7 @@ const SegmentedControl = (props: SegmentedControlProps) => {
7476
onChangeIndex,
7577
initialIndex = 0,
7678
containerStyle,
79+
style,
7780
segments,
7881
activeColor = Colors.primary,
7982
borderRadius = BorderRadiuses.br100,
@@ -86,6 +89,7 @@ const SegmentedControl = (props: SegmentedControlProps) => {
8689
const [selectedSegment, setSelectedSegment] = useState(-1);
8790

8891
const segmentsStyle = useRef([] as {x: number; width: number}[]);
92+
const segmentedControlHeight = useRef(0);
8993
const segmentsCounter = useRef(0);
9094
const animatedValue = useRef(new Reanimated.Value(initialIndex));
9195

@@ -108,8 +112,9 @@ const SegmentedControl = (props: SegmentedControlProps) => {
108112
[onChangeIndex, selectedSegment, updateSelectedSegment]);
109113

110114
const onLayout = useCallback((index: number, event: LayoutChangeEvent) => {
111-
const {x, width} = event.nativeEvent.layout;
115+
const {x, width, height} = event.nativeEvent.layout;
112116
segmentsStyle.current[index] = {x, width};
117+
segmentedControlHeight.current = height + (2 * (HORIZONTAL_PADDING - BORDER_WIDTH));
113118
segmentsCounter.current++;
114119

115120
return segmentsCounter.current === segments?.length && setSelectedSegment(initialIndex);
@@ -150,29 +155,30 @@ const SegmentedControl = (props: SegmentedControlProps) => {
150155
});
151156

152157
return (
153-
<View row center style={[styles.container, containerStyle, {borderRadius, backgroundColor}]}>
154-
<Reanimated.View
155-
style={[
156-
styles.selectedSegment,
157-
animatedStyle,
158-
{borderColor: outlineColor, borderRadius, backgroundColor: activeBackgroundColor, borderWidth: outlineWidth}
159-
]}
160-
/>
161-
{renderSegments()}
158+
<View style={containerStyle}>
159+
<View row center style={[styles.container, style, {borderRadius, backgroundColor}]}>
160+
<Reanimated.View
161+
style={[
162+
styles.selectedSegment,
163+
animatedStyle,
164+
{borderColor: outlineColor, borderRadius, backgroundColor: activeBackgroundColor, borderWidth: outlineWidth, height: segmentedControlHeight.current}
165+
]}
166+
/>
167+
{renderSegments()}
168+
</View>
162169
</View>
163170
);
164171
};
165172

166173
const styles = StyleSheet.create({
167174
container: {
168175
backgroundColor: Colors.grey80,
169-
height: Spacings.s7,
170-
borderColor: Colors.grey60
176+
borderColor: Colors.grey60,
177+
paddingVertical: HORIZONTAL_PADDING,
178+
borderWidth: BORDER_WIDTH
171179
},
172180
selectedSegment: {
173-
height: Spacings.s7 - 2 * BORDER_WIDTH,
174-
position: 'absolute',
175-
backgroundColor: Colors.white
181+
position: 'absolute'
176182
},
177183
segment: {
178184
paddingHorizontal: Spacings.s3

src/components/segmentedControl/segment.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ const Segment = React.memo((props: SegmentProps) => {
8888
[onLayout, index]);
8989

9090
return (
91-
<TouchableOpacity onLayout={segmentOnLayout} style={segmentStyle} onPress={onSegmentPress} row>
91+
<TouchableOpacity onLayout={segmentOnLayout} style={segmentStyle} onPress={onSegmentPress} row flexG center>
9292
{!iconOnRight && renderIcon()}
9393
{label && (
9494
<Text text90 numberOfLines={1} color={segmentedColor}>

0 commit comments

Comments
 (0)