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