mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {StyleProp, StyleSheet, TextStyle, View, ViewStyle} from 'react-native'
2
3import {choose} from '#/lib/functions'
4import {colors} from '#/lib/styles'
5import {useTheme} from '#/lib/ThemeContext'
6import {TypographyVariant} from '#/lib/ThemeContext'
7import {Text} from '../text/Text'
8import {Button, ButtonType} from './Button'
9
10export function ToggleButton({
11 testID,
12 type = 'default-light',
13 label,
14 isSelected,
15 style,
16 labelType,
17 onPress,
18}: {
19 testID?: string
20 type?: ButtonType
21 label: string
22 isSelected: boolean
23 style?: StyleProp<ViewStyle>
24 labelType?: TypographyVariant
25 onPress?: () => void
26}) {
27 const theme = useTheme()
28 const circleStyle = choose<TextStyle, Record<ButtonType, TextStyle>>(type, {
29 primary: {
30 borderColor: theme.palette.primary.text,
31 },
32 secondary: {
33 borderColor: theme.palette.secondary.text,
34 },
35 inverted: {
36 borderColor: theme.palette.inverted.text,
37 },
38 'primary-outline': {
39 borderColor: theme.palette.primary.border,
40 },
41 'secondary-outline': {
42 borderColor: theme.palette.secondary.border,
43 },
44 'primary-light': {
45 borderColor: theme.palette.primary.border,
46 },
47 'secondary-light': {
48 borderColor: theme.palette.secondary.border,
49 },
50 default: {
51 borderColor: theme.palette.default.border,
52 },
53 'default-light': {
54 borderColor: theme.palette.default.border,
55 },
56 })
57 const circleFillStyle = choose<TextStyle, Record<ButtonType, TextStyle>>(
58 type,
59 {
60 primary: {
61 backgroundColor: theme.palette.primary.text,
62 opacity: isSelected ? 1 : 0.33,
63 },
64 secondary: {
65 backgroundColor: theme.palette.secondary.text,
66 opacity: isSelected ? 1 : 0.33,
67 },
68 inverted: {
69 backgroundColor: theme.palette.inverted.text,
70 opacity: isSelected ? 1 : 0.33,
71 },
72 'primary-outline': {
73 backgroundColor: theme.palette.primary.background,
74 opacity: isSelected ? 1 : 0.5,
75 },
76 'secondary-outline': {
77 backgroundColor: theme.palette.secondary.background,
78 opacity: isSelected ? 1 : 0.5,
79 },
80 'primary-light': {
81 backgroundColor: theme.palette.primary.background,
82 opacity: isSelected ? 1 : 0.5,
83 },
84 'secondary-light': {
85 backgroundColor: theme.palette.secondary.background,
86 opacity: isSelected ? 1 : 0.5,
87 },
88 default: {
89 backgroundColor: isSelected
90 ? theme.palette.primary.background
91 : colors.gray3,
92 },
93 'default-light': {
94 backgroundColor: isSelected
95 ? theme.palette.primary.background
96 : colors.gray3,
97 },
98 },
99 )
100 const labelStyle = choose<TextStyle, Record<ButtonType, TextStyle>>(type, {
101 primary: {
102 color: theme.palette.primary.text,
103 fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined,
104 },
105 secondary: {
106 color: theme.palette.secondary.text,
107 fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined,
108 },
109 inverted: {
110 color: theme.palette.inverted.text,
111 fontWeight: theme.palette.inverted.isLowContrast ? '600' : undefined,
112 },
113 'primary-outline': {
114 color: theme.palette.primary.textInverted,
115 fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined,
116 },
117 'secondary-outline': {
118 color: theme.palette.secondary.textInverted,
119 fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined,
120 },
121 'primary-light': {
122 color: theme.palette.primary.textInverted,
123 fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined,
124 },
125 'secondary-light': {
126 color: theme.palette.secondary.textInverted,
127 fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined,
128 },
129 default: {
130 color: theme.palette.default.text,
131 fontWeight: theme.palette.default.isLowContrast ? '600' : undefined,
132 },
133 'default-light': {
134 color: theme.palette.default.text,
135 fontWeight: theme.palette.default.isLowContrast ? '600' : undefined,
136 },
137 })
138 return (
139 <Button testID={testID} type={type} onPress={onPress} style={style}>
140 <View style={styles.outer}>
141 <View style={[circleStyle, styles.circle]}>
142 <View
143 style={[
144 circleFillStyle,
145 styles.circleFill,
146 isSelected ? styles.circleFillSelected : undefined,
147 ]}
148 />
149 </View>
150 {label === '' ? null : (
151 <Text type={labelType || 'button'} style={[labelStyle, styles.label]}>
152 {label}
153 </Text>
154 )}
155 </View>
156 </Button>
157 )
158}
159
160const styles = StyleSheet.create({
161 outer: {
162 flexDirection: 'row',
163 alignItems: 'center',
164 gap: 10,
165 },
166 circle: {
167 width: 42,
168 height: 26,
169 borderRadius: 15,
170 padding: 3,
171 borderWidth: 2,
172 },
173 circleFill: {
174 width: 16,
175 height: 16,
176 borderRadius: 10,
177 },
178 circleFillSelected: {
179 marginLeft: 16,
180 },
181 label: {
182 flex: 1,
183 },
184})