I'm pretty new to animations in ReactNative and the first one I have to do seems pretty complicated to me. my component is composed of a horizontal list of filters ("1 to n"), they don't have specific sizes since they take their inner texts sizes and scroll is enabled starting from 3 filters available, otherwise it's not. As you can see on the image, the active filter is in pink color, what I need to do now is animate the list with a slide animation every time I switch to another filter but I don't really know how to do it since I don't have any width and it's a scrollable component, can someone help me out ? Thank you!Also I've been asked to use Spring from animated with mass: 1, stiffness: 180 and damping: 30
import { colors } from '@App/Styles/styles';import { BoxType } from '@App/Types/types';import React, { useRef, useState } from 'react';import { Animated, FlatList, Pressable, StyleProp, StyleSheet, TextStyle, View, ViewStyle,} from 'react-native';import { Text } from '../Text';type AllBoxesFilter = { _id: string; nickname: string;};export interface MessageFiltersProps { boxes?: BoxType[]; scrollEnabled?: boolean; activeTextStyle?: StyleProp<TextStyle>; inactiveTextStyle?: StyleProp<TextStyle>; activeContainerStyle?: StyleProp<ViewStyle>; inactiveContainerStyle?: StyleProp<ViewStyle>; contentContainerStyle?: StyleProp<ViewStyle>; onPressBox?(boxId: string): void; onPressAllBoxesFilter?(): void;}export const MessageFilters = ({ boxes, scrollEnabled = false, activeTextStyle, inactiveTextStyle, activeContainerStyle, inactiveContainerStyle, contentContainerStyle, onPressBox = () => {}, onPressAllBoxesFilter = () => {},}: MessageFiltersProps): React.ReactElement | null => { const [activeBoxId, setActiveBoxId] = useState<string>('All'); const allBoxesFilter: AllBoxesFilter = { _id: 'All', nickname: 'All' }; const animatedValue = useRef(new Animated.Value(0)).current; const onToggle = (id: string): void => { setActiveBoxId(id); Animated.spring(animatedValue, { toValue: 100, mass: 1, damping: 30, stiffness: 180, useNativeDriver: true, }).start(); if (id === 'All') { onPressAllBoxesFilter(); } else { onPressBox(id); } }; const renderItem = (box: BoxType | AllBoxesFilter): React.ReactElement => { const isActive = box._id === activeBoxId; return (<Animated.View style={[ styles.filterContainer, isActive ? [ styles.activeContainer, activeContainerStyle, { transform: [ { translateX: animatedValue, }, ], }, ] : inactiveContainerStyle, ]}><Pressable onPress={(): void => onToggle(box._id)} key={box._id}> {box.nickname.split('').map((word: string) => (<Text text={word} style={ isActive ? [styles.activeText, activeTextStyle] : [styles.inactiveText, inactiveTextStyle] } type={isActive ? 'bold' : 'semibold'} /> ))}</Pressable></Animated.View> ); }; return (<View style={styles.parent}> {boxes && (<FlatList contentContainerStyle={[styles.container, contentContainerStyle]} scrollEnabled={(boxes && boxes.length > 2) || scrollEnabled} horizontal data={boxes} ListHeaderComponent={<View style={styles.firstElemContainer}>{renderItem(allBoxesFilter)}</View> } renderItem={({ item }) => renderItem(item)} keyExtractor={(box) => box._id} /> )}</View> );};const styles = StyleSheet.create({ parent: { justifyContent: 'center', alignItems: 'center', borderRadius: 100, marginVertical: 10, overflow: 'hidden', }, container: { flexDirection: 'row', justifyContent: 'space-evenly', padding: 10, borderRadius: 100, backgroundColor: colors.white, }, firstElemContainer: { flex: 1, justifyContent: 'center', }, filterContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 20, paddingVertical: 8, borderRadius: 100, }, activeContainer: { backgroundColor: colors.lightPink, }, activeText: { textAlign: 'center', color: colors.darkPink, marginBottom: -5, }, inactiveText: { textAlign: 'center', color: colors.lightGrey, marginBottom: -5, },});export default MessageFilters;