xref: /MusicFree/src/components/base/switch.tsx (revision 6613e77203923e5b1742a49281bfa5de03fc1440)
1import React, {useEffect} from 'react';
2import {
3    StyleSheet,
4    SwitchProps,
5    TouchableWithoutFeedback,
6    View,
7} from 'react-native';
8import useColors from '@/hooks/useColors';
9import rpx from '@/utils/rpx';
10import Animated, {
11    useAnimatedStyle,
12    useSharedValue,
13    withTiming,
14} from 'react-native-reanimated';
15import {timingConfig} from '@/constants/commonConst';
16
17interface ISwitchProps extends SwitchProps {}
18
19const fixedWidth = rpx(40);
20
21export default function ThemeSwitch(props: ISwitchProps) {
22    const {value, onValueChange} = props;
23    const colors = useColors();
24
25    const sharedValue = useSharedValue(value ? 1 : 0);
26
27    useEffect(() => {
28        sharedValue.value = value ? 1 : 0;
29    }, [value]);
30
31    const thumbStyle = useAnimatedStyle(() => {
32        return {
33            transform: [
34                {
35                    translateX: withTiming(
36                        sharedValue.value * fixedWidth,
37                        timingConfig.animationNormal,
38                    ),
39                },
40            ],
41        };
42    });
43
44    return (
45        <TouchableWithoutFeedback
46            onPress={() => {
47                onValueChange?.(!value);
48            }}>
49            <View
50                style={[
51                    styles.container,
52                    {
53                        backgroundColor: value
54                            ? colors.primary
55                            : colors.textSecondary,
56                    },
57                    props?.style,
58                ]}>
59                <Animated.View style={[styles.thumb, thumbStyle]} />
60            </View>
61        </TouchableWithoutFeedback>
62    );
63}
64
65const styles = StyleSheet.create({
66    container: {
67        width: rpx(80),
68        height: rpx(40),
69        borderRadius: rpx(40),
70        justifyContent: 'center',
71    },
72    thumb: {
73        width: rpx(34),
74        height: rpx(34),
75        borderRadius: rpx(17),
76        backgroundColor: 'white',
77        left: rpx(3),
78    },
79});
80