import type { ReactElement } from 'react'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import type { LayoutChangeEvent, StyleProp, ViewStyle } from 'react-native'; import { Animated, Easing, Platform, TouchableWithoutFeedback, } from 'react-native'; import type { IconName } from '../../Icon'; import Option from './Option'; import { StyledKnot, StyledWrapper } from './StyledSelectorSwitch'; type StatusBadgeType = { type: 'status'; }; export type BadgeConfigType = StatusBadgeType; export type SwitchOptionType = { value: T; text: string; icon: IconName; badge?: BadgeConfigType; }; export interface SelectorSwitchProps { /** * Array of exactly TWO options to switch between. */ options: [SwitchOptionType, SwitchOptionType]; /** * Current selected value. */ value: T; /** * Callback called when an option is pressed. */ onPress?: (value: T) => void; /** * Additional style. */ style?: StyleProp; /** * Testing id of the component. */ testID?: string; } const SelectorSwitch = ({ options, value, onPress, style, testID, }: SelectorSwitchProps): ReactElement => { const [knotWidth, setKnotWidth] = useState(0); const [containerWidth, setContainerWidth] = useState(0); const animatedValue = useRef(new Animated.Value(0)).current; const translateX = animatedValue.interpolate({ inputRange: [0, 1], outputRange: [0, Math.floor(containerWidth - knotWidth)], }); useEffect(() => { Animated.timing(animatedValue, { toValue: value === options[0].value ? 0 : 1, duration: 200, easing: Easing.inOut(Easing.ease), useNativeDriver: Platform.OS === 'ios' || Platform.OS === 'android', }).start(); }, [value, animatedValue, options]); const onContainerLayout = useCallback((e: LayoutChangeEvent) => { setContainerWidth(e.nativeEvent.layout.width); }, []); const onItemLayout = useCallback( (e: LayoutChangeEvent, optionValue: T) => { if (optionValue === value) { setKnotWidth(e.nativeEvent.layout.width); } }, [value] ); return ( onPress?.(value)} testID={testID}> {options.map((opt, index) => ( ); }; export default SelectorSwitch;