import React, { memo, useEffect } from 'react'; import { Pressable, StyleSheet, Text, View, } from 'react-native'; import Animated, { interpolateColor, useAnimatedStyle, useSharedValue, withTiming, } from 'react-native-reanimated'; import { useTheme, fontFamily } from '../../../theme'; interface ToggleSwitchProps { label: string; description?: string; value: boolean; onValueChange: (value: boolean) => void; disabled?: boolean; } const ToggleSwitchComponent = ({ label, description, value, onValueChange, disabled = false, }: ToggleSwitchProps) => { const theme = useTheme(); const progress = useSharedValue(value ? 1 : 0); useEffect(() => { progress.value = withTiming(value ? 1 : 0, { duration: 180 }); }, [progress, value]); const trackStyle = useAnimatedStyle(() => ({ backgroundColor: interpolateColor( progress.value, [0, 1], [theme.colors.surfaceMuted, theme.colors.primary], ), })); const thumbStyle = useAnimatedStyle(() => ({ transform: [{ translateX: withTiming(progress.value * 22, { duration: 180 }) }], })); return ( onValueChange(!value)} style={[ styles.row, disabled && styles.rowDisabled, { borderBottomColor: theme.colors.cardBorder, }, ]} > {label} {description ? ( {description} ) : null} ); }; const styles = StyleSheet.create({ row: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 16, borderBottomWidth: StyleSheet.hairlineWidth, gap: 16, }, rowDisabled: { opacity: 0.55, }, copy: { flex: 1, gap: 4, }, label: { fontSize: 15, fontFamily: fontFamily.bold, }, description: { fontSize: 12, lineHeight: 18, }, track: { width: 52, height: 30, justifyContent: 'center', paddingHorizontal: 4, }, thumb: { width: 18, height: 18, borderRadius: 9, }, }); export const ToggleSwitch = memo(ToggleSwitchComponent);