mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at tooltip 5.1 kB view raw
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})