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