import React from 'react'
import { StyleSheet } from 'react-native'
import { Pressable, type PressableProps } from 'react-native-gesture-handler'
import { useCreateAndroidRippleColor, useTheme } from '../../hooks'
import { Haptic } from '../../utils/native_adapters/configuration'
import {
MAX_FONT_SIZE_MULTIPLIER,
platformFontWeightMedium,
platformPressedOpacityStyle,
} from '../../utils/styles'
import { tokens } from '../../vendor/tapestry/tokens'
import { Icon, IconString, Spinner, Text } from '../display'
interface SwipeableToggleButtonProps extends PressableProps {
backgroundColor: string
toggled: boolean
toggleContent: {
true: { iconName: IconString; label: string }
false: { iconName: IconString; label: string }
}
loading?: boolean
}
export function SwipeableToggleButton({
backgroundColor,
onPress,
toggleContent,
disabled = false,
toggled,
loading = false,
...props
}: SwipeableToggleButtonProps) {
const styles = useStyles({ backgroundColor, disabled })
const androidRippleColor = useCreateAndroidRippleColor({
color: backgroundColor,
})
const { iconName, label } = toggleContent[toggled ? 'true' : 'false']
return (
{
Haptic.impactLight()
onPress?.(event)
}}
style={({ pressed }) => [styles.button, pressed && platformPressedOpacityStyle]}
android_ripple={{ color: androidRippleColor, borderless: false, foreground: true }}
disabled={disabled || loading}
accessibilityRole="togglebutton"
accessibilityState={{ checked: toggled }}
{...props}
>
{loading ? (
) : (
<>
{label}
>
)}
)
}
const useStyles = ({ backgroundColor, disabled }: Partial) => {
const { colors } = useTheme()
const fillColor = disabled ? colors.textColorDefaultDisabled : tokens.colorNeutral100White
const buttonBackgroundColor = disabled
? colors.fillColorButtonNeutralSolidDisabled
: backgroundColor
return StyleSheet.create({
button: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: 4,
height: '100%',
backgroundColor: buttonBackgroundColor,
},
icon: {
fontSize: 20,
color: fillColor,
marginTop: 4,
},
text: {
color: fillColor,
fontWeight: platformFontWeightMedium,
textAlign: 'center',
paddingHorizontal: 8,
},
})
}