Skip to content

Commit 491259f

Browse files
committed
Refactor: Combine SegmentedControl and Tab, reuse in Example screen
1 parent 534ae26 commit 491259f

16 files changed

Lines changed: 498 additions & 439 deletions

example/src/Navigation.tsx

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,15 @@
11
import { createStaticNavigation } from '@react-navigation/native';
22
import { createNativeStackNavigator } from '@react-navigation/native-stack';
3-
import { Button } from 'react-native';
43
import ExampleInitialSetScreen from './screens/ExampleInitialSet';
5-
import TabsExampleScreen from './screens/TabsExample';
6-
import SegmentedControlExampleScreen from './screens/SegmentedControlExample';
4+
import ExamplesScreen from './screens/Examples';
75

86
export const RootStack = createNativeStackNavigator({
97
initialRouteName: 'SegmentedControlExample',
108
screens: {
119
SegmentedControlExample: {
12-
screen: SegmentedControlExampleScreen,
13-
options: ({ navigation }) => ({
14-
title: 'Segmeneted Control',
15-
headerRight: () => (
16-
<Button
17-
title="Tabs"
18-
onPress={() => {
19-
navigation.navigate('TabsExample');
20-
}}
21-
/>
22-
),
23-
}),
24-
},
25-
TabsExample: {
26-
screen: TabsExampleScreen,
10+
screen: ExamplesScreen,
2711
options: () => ({
28-
title: 'Example Tabs',
12+
title: 'Examples',
2913
}),
3014
},
3115
ExampleInitialSet: {

example/src/examples/Align.tsx

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* eslint-disable react-native/no-inline-styles */
2+
import {
3+
MultiswitchController,
4+
type ControllerVariant,
5+
} from 'react-native-multiswitch-controller';
6+
import ExampleWrapper from './ExampleWrapper';
7+
8+
type AlignProps = {
9+
variant: ControllerVariant;
10+
};
11+
12+
export default function Align({ variant }: AlignProps) {
13+
return (
14+
<ExampleWrapper title="Align to left, center or right">
15+
<MultiswitchController<'First' | 'Second'>
16+
options={[
17+
{ value: 'First', label: 'First' },
18+
{ value: 'Second', label: 'Second' },
19+
]}
20+
defaultOption="First"
21+
variant={variant}
22+
styleProps={{
23+
align: 'left',
24+
inactiveBackgroundColor: 'rgb(21, 87, 21)',
25+
activeBackgroundColor: 'rgb(60, 180, 20)',
26+
inactiveTextColor: 'rgb(208, 249, 205)',
27+
containerHeight: 52,
28+
itemHeight: 46,
29+
}}
30+
/>
31+
<MultiswitchController<'First' | 'Second'>
32+
options={[
33+
{ value: 'First', label: 'First' },
34+
{ value: 'Second', label: 'Second' },
35+
]}
36+
defaultOption="Second"
37+
variant={variant}
38+
styleProps={{
39+
align: 'center',
40+
inactiveBackgroundColor: 'rgba(220, 38, 38, 0.08)',
41+
activeBackgroundColor: 'rgb(185, 28, 28)',
42+
inactiveTextColor: 'rgb(185, 28, 28)',
43+
containerHeight: 28,
44+
itemHeight: 24,
45+
customTextStyle: {
46+
fontSize: 10,
47+
},
48+
customItemStyle: {
49+
paddingHorizontal: 8,
50+
paddingVertical: 2,
51+
borderRadius: 0,
52+
},
53+
customActiveOptionStyle: {
54+
borderRadius: 0,
55+
},
56+
customContainerStyle: {
57+
borderRadius: 0,
58+
},
59+
}}
60+
/>
61+
<MultiswitchController<'First' | 'Second' | 'Third'>
62+
options={[
63+
{ value: 'First', label: 'First' },
64+
{ value: 'Second', label: 'Second' },
65+
{ value: 'Third', label: 'Third' },
66+
]}
67+
defaultOption="First"
68+
variant={variant}
69+
styleProps={{
70+
align: 'right',
71+
inactiveBackgroundColor: 'rgba(205, 197, 40, 0.08)',
72+
activeBackgroundColor: 'rgb(180, 170, 20)',
73+
inactiveTextColor: 'rgb(180, 170, 20)',
74+
containerHeight: 28,
75+
itemHeight: 24,
76+
customTextStyle: {
77+
fontSize: 10,
78+
},
79+
customItemStyle: {
80+
paddingHorizontal: 8,
81+
paddingVertical: 2,
82+
},
83+
}}
84+
/>
85+
</ExampleWrapper>
86+
);
87+
}

example/src/examples/DayOfTime.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import type { RefObject } from 'react';
2+
import { Button, StyleSheet, View } from 'react-native';
3+
import {
4+
MultiswitchController,
5+
type ControllerVariant,
6+
type ControlListRef,
7+
} from 'react-native-multiswitch-controller';
8+
import type { TimeOfDay } from '../types';
9+
import ExampleWrapper from './ExampleWrapper';
10+
11+
type DayOfTimeProps = {
12+
multiswitchControllerRef: RefObject<ControlListRef<TimeOfDay> | null>;
13+
onChangeOption: (value: TimeOfDay) => void;
14+
variant: ControllerVariant;
15+
};
16+
17+
export default function DayOfTime({
18+
multiswitchControllerRef,
19+
onChangeOption,
20+
variant,
21+
}: DayOfTimeProps) {
22+
return (
23+
<ExampleWrapper title="Day of Time">
24+
<MultiswitchController<TimeOfDay>
25+
variant={variant}
26+
defaultOption="morning"
27+
options={[
28+
{ value: 'morning', label: '🌅' },
29+
{ value: 'afternoon', label: '☀️' },
30+
{ value: 'evening', label: '🌇' },
31+
{ value: 'night', label: '🌙' },
32+
]}
33+
ref={multiswitchControllerRef}
34+
onChangeOption={onChangeOption}
35+
onPressItem={(_value) => {
36+
// Instant callback, without waiting for animation to finish
37+
}}
38+
styleProps={{
39+
inactiveBackgroundColor: 'rgba(59, 130, 246, 0.08)',
40+
activeBackgroundColor: 'rgb(37, 99, 235)',
41+
}}
42+
/>
43+
<View style={styles.buttonsContainer}>
44+
<Button
45+
title="Set morning"
46+
onPress={() => {
47+
multiswitchControllerRef.current?.setForcedOption('morning');
48+
}}
49+
/>
50+
<Button
51+
title="Set night"
52+
onPress={() => {
53+
multiswitchControllerRef.current?.setForcedOption('night');
54+
}}
55+
/>
56+
</View>
57+
</ExampleWrapper>
58+
);
59+
}
60+
61+
const styles = StyleSheet.create({
62+
buttonsContainer: {
63+
flexDirection: 'row',
64+
gap: 10,
65+
justifyContent: 'center',
66+
alignItems: 'center',
67+
},
68+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { StyleSheet, Text, View } from 'react-native';
2+
3+
export default function ExampleWrapper({
4+
children,
5+
title,
6+
}: {
7+
children: React.ReactNode;
8+
title: string;
9+
}) {
10+
return (
11+
<View style={styles.exampleContainer}>
12+
<Text style={styles.title}>{title}</Text>
13+
{children}
14+
</View>
15+
);
16+
}
17+
18+
const styles = StyleSheet.create({
19+
exampleContainer: {},
20+
21+
title: {
22+
fontSize: 18,
23+
padding: 10,
24+
},
25+
});

example/src/examples/LongLabel.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* eslint-disable react-native/no-inline-styles */
2+
import {
3+
MultiswitchController,
4+
type ControllerVariant,
5+
} from 'react-native-multiswitch-controller';
6+
import ExampleWrapper from './ExampleWrapper';
7+
import { StyleSheet } from 'react-native';
8+
9+
type LongLabelProps = {
10+
variant: ControllerVariant;
11+
};
12+
13+
export default function LongLabel({ variant }: LongLabelProps) {
14+
return (
15+
<ExampleWrapper title="Use different width for labels">
16+
<MultiswitchController<'First' | 'Second'>
17+
options={[
18+
{ value: 'First', label: 'First is a very long label' },
19+
{ value: 'Second', label: 'Second is short' },
20+
]}
21+
variant={variant}
22+
defaultOption="First"
23+
styleProps={{
24+
containerHeight: 48,
25+
itemHeight: 36,
26+
inactiveBackgroundColor: 'rgba(30, 64, 175, 0.08)',
27+
activeBackgroundColor: 'rgb(30, 64, 175)',
28+
inactiveTextColor: 'rgb(30, 64, 175)',
29+
customTextStyle: styles.smallText,
30+
}}
31+
/>
32+
</ExampleWrapper>
33+
);
34+
}
35+
36+
const styles = StyleSheet.create({
37+
smallText: {
38+
fontSize: 12,
39+
},
40+
});
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* eslint-disable react-native/no-inline-styles */
2+
import {
3+
MultiswitchController,
4+
type ControllerVariant,
5+
} from 'react-native-multiswitch-controller';
6+
import ExampleWrapper from './ExampleWrapper';
7+
8+
type ScrollableProps = {
9+
variant: ControllerVariant;
10+
};
11+
12+
export default function Scrollable({ variant }: ScrollableProps) {
13+
return (
14+
<ExampleWrapper title="Scrollable if there is not enough width">
15+
<MultiswitchController<
16+
| 'First'
17+
| 'Second'
18+
| 'Third'
19+
| 'Fourth'
20+
| 'Fifth'
21+
| 'Sixth'
22+
| 'Seventh'
23+
| 'Eighth'
24+
| 'Ninth'
25+
| 'Tenth'
26+
| 'Eleventh'
27+
| 'Twelfth'
28+
| 'Thirteenth'
29+
| 'Fourteenth'
30+
| 'Fifteenth'
31+
| 'Sixteenth'
32+
>
33+
options={[
34+
{ value: 'First', label: 'First' },
35+
{ value: 'Second', label: 'Second' },
36+
{ value: 'Third', label: 'Third' },
37+
{ value: 'Fourth', label: 'Fourth' },
38+
{ value: 'Fifth', label: 'Fifth' },
39+
{ value: 'Sixth', label: 'Sixth' },
40+
{ value: 'Seventh', label: 'Seventh' },
41+
{ value: 'Eighth', label: 'Eighth' },
42+
{ value: 'Ninth', label: 'Ninth' },
43+
{ value: 'Tenth', label: 'Tenth' },
44+
{ value: 'Eleventh', label: 'Eleventh' },
45+
{ value: 'Twelfth', label: 'Twelfth' },
46+
{ value: 'Thirteenth', label: 'Thirteenth' },
47+
{ value: 'Fourteenth', label: 'Fourteenth' },
48+
{ value: 'Fifteenth', label: 'Fifteenth' },
49+
{ value: 'Sixteenth', label: 'Sixteenth' },
50+
]}
51+
defaultOption="First"
52+
variant={variant}
53+
styleProps={{
54+
containerHeight: 54,
55+
itemHeight: 48,
56+
}}
57+
/>
58+
</ExampleWrapper>
59+
);
60+
}

example/src/screens/ExampleInitialSet.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ export default function ExampleInitialSetScreen({
3131
{ value: 'night', label: '🌙' },
3232
]}
3333
defaultOption="morning"
34-
variant="segmentedControl"
35-
onControlListStateChange={(value) => {
34+
variant="tabs"
35+
onChangeOption={(value) => {
3636
console.log(
37-
'State ExampleInitialSetScreen onControlListStateChange changed:',
37+
'State ExampleInitialSetScreen onChangeOption changed:',
3838
value
3939
);
4040
}}
41-
segmentedControlProps={{
41+
styleProps={{
4242
inactiveBackgroundColor: 'rgba(59, 130, 246, 0.08)',
4343
activeBackgroundColor: 'rgb(37, 99, 235)',
4444
}}

0 commit comments

Comments
 (0)