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