Skip to content

Commit cbcfce9

Browse files
committed
feat: Move state to MultiswitchController
1 parent 7a4f7a5 commit cbcfce9

4 files changed

Lines changed: 74 additions & 177 deletions

File tree

Lines changed: 42 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,36 @@
1-
import { View, StyleSheet, Text } from 'react-native';
2-
import type { ColorValue } from 'react-native';
31
import { LinearGradient } from 'expo-linear-gradient';
4-
import {
5-
PillSwitch,
6-
useControlListState,
7-
} from 'react-native-multiswitch-controller';
2+
import { StyleSheet, Text, View } from 'react-native';
3+
import { MultiswitchController } from 'react-native-multiswitch-controller';
84

95
export default function ExamplePillsScreen() {
10-
const controlListState0 = useControlListState({
11-
options: [
12-
{ value: 'morning', label: '🌅' },
13-
{ value: 'afternoon', label: '☀️' },
14-
{ value: 'evening', label: '🌇' },
15-
{ value: 'night', label: '🌙' },
16-
],
17-
defaultOption: 'morning',
18-
variant: 'segmentedControl',
19-
});
20-
21-
const getGradientColors = (timeOfDay: string): [ColorValue, ColorValue] => {
22-
switch (timeOfDay) {
23-
case 'morning':
24-
return ['#FFF5E6', '#FFE4B5'];
25-
case 'afternoon':
26-
return ['#E6F3FF', '#B3D9FF'];
27-
case 'evening':
28-
return ['#FFE6E0', '#FFD6CC'];
29-
case 'night':
30-
return ['#E6E6FA', '#D8D8F6'];
31-
default:
32-
return ['#FFFFFF', '#F8F8F8'];
33-
}
34-
};
35-
36-
const controlListState1 = useControlListState({
37-
options: [
38-
{ value: 'First', label: 'First' },
39-
{ value: 'Second', label: 'Second' },
40-
{ value: 'Third', label: 'Third' },
41-
{ value: 'Fourth', label: 'Fourth' },
42-
{ value: 'Fifth', label: 'Fifth' },
43-
{ value: 'Sixth', label: 'Sixth' },
44-
{ value: 'Seventh', label: 'Seventh' },
45-
{ value: 'Eighth', label: 'Eighth' },
46-
{ value: 'Ninth', label: 'Ninth' },
47-
{ value: 'Tenth', label: 'Tenth' },
48-
{ value: 'Eleventh', label: 'Eleventh' },
49-
{ value: 'Twelfth', label: 'Twelfth' },
50-
{ value: 'Thirteenth', label: 'Thirteenth' },
51-
{ value: 'Fourteenth', label: 'Fourteenth' },
52-
{ value: 'Fifteenth', label: 'Fifteenth' },
53-
{ value: 'Sixteenth', label: 'Sixteenth' },
54-
],
55-
defaultOption: 'First',
56-
variant: 'segmentedControl',
57-
});
58-
const controlListState2 = useControlListState({
59-
options: [
60-
{ value: 'First', label: 'First' },
61-
{ value: 'Second', label: 'Second' },
62-
],
63-
defaultOption: 'First',
64-
variant: 'segmentedControl',
65-
});
66-
const controlListState3 = useControlListState({
67-
options: [
68-
{ value: 'First', label: 'First' },
69-
{ value: 'Second', label: 'Second' },
70-
],
71-
defaultOption: 'Second',
72-
variant: 'segmentedControl',
73-
});
74-
const controlListState4 = useControlListState({
75-
options: [
76-
{ value: 'First', label: 'First is a very long label' },
77-
{ value: 'Second', label: 'Second is short' },
78-
],
79-
defaultOption: 'First',
80-
variant: 'segmentedControl',
81-
});
82-
83-
const isTestMode = false;
84-
856
return (
86-
<LinearGradient
87-
colors={getGradientColors(controlListState0.activeOption)}
88-
style={styles.container}
89-
>
7+
<LinearGradient colors={['#FFF5E6', '#FFE4B5']} style={styles.container}>
908
<View style={styles.exampleContainer}>
919
<Text style={styles.title}>Time of Day</Text>
92-
<PillSwitch
93-
controlListState={controlListState0}
94-
inactiveBackgroundColor="rgba(59, 130, 246, 0.08)"
95-
activeBackgroundColor="rgb(37, 99, 235)"
96-
inactiveTextColor="rgb(37, 99, 235)"
97-
activeTextColor="rgb(253, 230, 138)"
98-
/>
99-
{isTestMode && (
100-
<Text style={styles.selectedText}>
101-
Selected: {controlListState3.activeOption}
102-
</Text>
103-
)}
104-
</View>
105-
106-
<View style={styles.exampleContainer}>
107-
<Text style={styles.title}>Align to left, center or right</Text>
108-
<PillSwitch
109-
controlListState={controlListState2}
110-
align="left"
111-
inactiveBackgroundColor="rgb(21, 87, 21)"
112-
activeBackgroundColor="rgb(60, 180, 20)"
113-
inactiveTextColor="rgb(208, 249, 205)"
114-
/>
115-
<PillSwitch
116-
controlListState={controlListState2}
117-
align="center"
118-
inactiveBackgroundColor="rgba(220, 38, 38, 0.08)"
119-
activeBackgroundColor="rgb(185, 28, 28)"
120-
inactiveTextColor="rgb(185, 28, 28)"
121-
/>
122-
<PillSwitch
123-
controlListState={controlListState2}
124-
align="right"
125-
inactiveBackgroundColor="rgba(205, 197, 40, 0.08)"
126-
activeBackgroundColor="rgb(180, 170, 20)"
127-
inactiveTextColor="rgb(180, 170, 20)"
128-
/>
129-
{isTestMode && (
130-
<Text style={styles.selectedText}>
131-
Selected: {controlListState2.activeOption}
132-
</Text>
133-
)}
134-
</View>
135-
136-
<View style={styles.exampleContainer}>
137-
<Text style={styles.title}>Set initial value</Text>
138-
<PillSwitch
139-
controlListState={controlListState3}
140-
inactiveBackgroundColor="rgba(59, 130, 246, 0.08)"
141-
activeBackgroundColor="rgb(37, 99, 235)"
142-
inactiveTextColor="rgb(37, 99, 235)"
143-
activeTextColor="rgb(253, 230, 138)"
10+
<MultiswitchController
11+
controlListProps={{
12+
options: [
13+
{ value: 'morning', label: '🌅' },
14+
{ value: 'afternoon', label: '☀️' },
15+
{ value: 'evening', label: '🌇' },
16+
{ value: 'night', label: '🌙' },
17+
],
18+
defaultOption: 'morning',
19+
variant: 'segmentedControl',
20+
}}
21+
onControlListStateChange={(state) => {
22+
console.log(
23+
'State onControlListStateChange changed:',
24+
state.activeOption
25+
);
26+
}}
27+
pillSwitchProps={{
28+
inactiveBackgroundColor: 'rgba(59, 130, 246, 0.08)',
29+
activeBackgroundColor: 'rgb(37, 99, 235)',
30+
}}
14431
/>
145-
{isTestMode && (
146-
<Text style={styles.selectedText}>
147-
Selected: {controlListState3.activeOption}
148-
</Text>
149-
)}
150-
</View>
151-
152-
<View style={styles.exampleContainer}>
153-
<Text style={styles.title}>Use different width for labels</Text>
154-
<PillSwitch
155-
controlListState={controlListState4}
156-
containerHeight={48}
157-
itemHeight={36}
158-
inactiveBackgroundColor="rgba(30, 64, 175, 0.08)"
159-
activeBackgroundColor="rgb(30, 64, 175)"
160-
inactiveTextColor="rgb(30, 64, 175)"
161-
customTextStyle={styles.smallText}
162-
/>
163-
{isTestMode && (
164-
<Text style={styles.selectedText}>
165-
Selected: {controlListState4.activeOption}
166-
</Text>
167-
)}
168-
</View>
169-
170-
<View style={styles.exampleContainer}>
171-
<Text style={styles.title}>
172-
Scrollable if there is not enough width
173-
</Text>
174-
<PillSwitch
175-
controlListState={controlListState1}
176-
containerHeight={54}
177-
itemHeight={48}
178-
/>
179-
{isTestMode && (
180-
<Text style={styles.selectedText}>
181-
Selected: {controlListState1.activeOption}
182-
</Text>
183-
)}
18432
</View>
33+
<Text style={styles.title}>RERENDER TEST</Text>
18534
</LinearGradient>
18635
);
18736
}
@@ -209,4 +58,21 @@ const styles = StyleSheet.create({
20958
smallText: {
21059
fontSize: 12,
21160
},
61+
stateReader: {
62+
marginTop: 20,
63+
padding: 10,
64+
backgroundColor: 'rgba(255, 255, 255, 0.8)',
65+
borderRadius: 8,
66+
},
67+
subtitle: {
68+
fontSize: 14,
69+
color: '#666',
70+
marginTop: 5,
71+
},
72+
button: {
73+
fontSize: 14,
74+
color: '#007AFF',
75+
marginTop: 10,
76+
textDecorationLine: 'underline',
77+
},
21278
});

src/MultiswitchController.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useEffect } from 'react';
2+
import PillSwitch, { type PillSwitchProps } from './PillSwitch';
3+
import type { ControlListProps, ControlListState } from './useControlListState';
4+
import useControlListState from './useControlListState';
5+
6+
type MultiswitchControllerProps<TValue> = {
7+
controlListProps: ControlListProps<TValue>;
8+
onControlListStateChange: (state: ControlListState<TValue>) => void;
9+
pillSwitchProps?: Omit<PillSwitchProps<TValue>, 'controlListState'>;
10+
};
11+
12+
export default function MultiswitchController<TValue>({
13+
controlListProps,
14+
onControlListStateChange,
15+
pillSwitchProps,
16+
}: MultiswitchControllerProps<TValue>) {
17+
const controlListState = useControlListState(controlListProps);
18+
19+
useEffect(() => {
20+
if (onControlListStateChange) {
21+
onControlListStateChange(controlListState);
22+
}
23+
}, [controlListState, onControlListStateChange]);
24+
25+
return (
26+
<PillSwitch controlListState={controlListState} {...pillSwitchProps} />
27+
);
28+
}

src/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
export { default as PillSwitch } from './PillSwitch';
2+
export { default as PillSwitchItem } from './PillSwitchItem';
3+
export type { ControlOption } from './types';
24
export { default as useControlListState } from './useControlListState';
5+
export { default as MultiswitchController } from './MultiswitchController';

src/useControlListState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
} from 'react-native-reanimated';
2020
import type { ControlOption } from './types';
2121

22-
type ControlListProps<TValue> = {
22+
export type ControlListProps<TValue> = {
2323
options: ControlOption<TValue>[];
2424
optionPadding?: number;
2525
optionGap?: number;

0 commit comments

Comments
 (0)