import React, { useCallback, useEffect, useRef, useState } from "react"; import { AccessibilityProps, Animated } from "react-native"; import { Pressable, Factory, Flex, Text, HStack } from "native-base"; import { FlipColors } from "@flip.id/ui-kit"; const PressableAnimated = Animated.createAnimatedComponent(Pressable); const AnimatedView = Factory(Animated.View); // @ts-ignore const AnimatedPressable = Factory(PressableAnimated); export interface IToggleSwitch { onChange?: (result: boolean) => void; isOn?: boolean; isDisableActiveColor?: boolean; onLabel?: string; offLabel?: string; testID?: string; } export const ToggleSwitch: React.FC = ( props ) => { const { isOn, isDisableActiveColor, onChange, onLabel, offLabel, ...rest } = props; const [isActive, setIsOn] = useState(isOn ?? false); const toggleLeft = useRef(new Animated.Value(0)).current; const toggleWidth = useRef(new Animated.Value(24)).current; const initialRender = useRef(true); const toggleOnOff = useCallback(() => { setIsOn((val) => !val); }, []); useEffect(() => { setIsOn(isOn ?? false); }, [isOn]); function composeAnimation( animatedValue: Animated.Value, value: number, duration: number ) { return Animated.timing(animatedValue, { toValue: value, duration: duration, useNativeDriver: false, }); } const runAnimationAndSendCallback = useCallback( (_isActive: boolean) => { if (initialRender.current) { initialRender.current = false; return; } Animated.sequence([ composeAnimation(toggleWidth, _isActive ? 50 : 24, 100), Animated.parallel([ composeAnimation(toggleLeft, _isActive ? 1 : 0, 200), composeAnimation(toggleWidth, _isActive ? 24 : 50, 200), ]), composeAnimation(toggleWidth, 24, 100), ]).start(); onChange?.(_isActive); }, [toggleLeft, initialRender, onChange, toggleWidth] ); useEffect(() => { runAnimationAndSendCallback(isActive); // eslint-disable-next-line react-hooks/exhaustive-deps }, [isActive]); return ( {offLabel} {onLabel} ); }; export default ToggleSwitch;