AnimatedList
FlatList with smooth enter/exit animations and stagger effect.
9:41
signal_cellular_altwifibattery_full
folder
Item 1
Description
folder
Item 2
Description
folder
Item 3
Description
Preview Controls
Animation
List items animate in
This is a CSS-based preview of the animation. The actual React Native component uses physics-based springs for a more natural feel.
Installation
$
Usage
Example.tsx
import { AnimatedList } from './components/AnimatedList';import { Text, View } from 'react-native';const data = [{ id: 1, title: 'Item 1' },{ id: 2, title: 'Item 2' },{ id: 3, title: 'Item 3' },];export default function App() {return (<AnimatedListdata={data}animationType="slideUp"staggerDelay={100}renderItem={({ item }) => (<View style={{ padding: 16 }}><Text>{item.title}</Text></View>)}/>);}
Full Component Code
AnimatedList.tsx
1import React from 'react';2import { FlatList, FlatListProps, ViewStyle, StyleProp } from 'react-native';3import Animated, {4 FadeIn,5 FadeOut,6 SlideInRight,7 SlideInDown,8 SlideOutLeft,9 SlideOutUp,10 Layout,11 Easing,12} from 'react-native-reanimated';1314type AnimationType = 'fade' | 'slide' | 'slideUp';1516interface AnimatedListProps<T> extends Omit<FlatListProps<T>, 'renderItem'> {17 data: T[];18 renderItem: (info: { item: T; index: number }) => React.ReactNode;19 animationType?: AnimationType;20 staggerDelay?: number;21 duration?: number;22 itemStyle?: StyleProp<ViewStyle>;23}2425const getEnteringAnimation = (26 type: AnimationType,27 index: number,28 staggerDelay: number,29 duration: number30) => {31 const delay = index * staggerDelay;3233 switch (type) {34 case 'fade':35 return FadeIn36 .delay(delay)37 .duration(duration)38 .easing(Easing.out(Easing.ease));39 case 'slide':40 return SlideInRight41 .delay(delay)42 .duration(duration)43 .easing(Easing.out(Easing.ease));44 case 'slideUp':45 return SlideInDown46 .delay(delay)47 .duration(duration)48 .easing(Easing.out(Easing.ease));49 default:50 return FadeIn51 .delay(delay)52 .duration(duration)53 .easing(Easing.out(Easing.ease));54 }55};5657const getExitingAnimation = (type: AnimationType, duration: number) => {58 switch (type) {59 case 'fade':60 return FadeOut61 .duration(duration)62 .easing(Easing.in(Easing.ease));63 case 'slide':64 return SlideOutLeft65 .duration(duration)66 .easing(Easing.in(Easing.ease));67 case 'slideUp':68 return SlideOutUp69 .duration(duration)70 .easing(Easing.in(Easing.ease));71 default:72 return FadeOut73 .duration(duration)74 .easing(Easing.in(Easing.ease));75 }76};7778export function AnimatedList<T extends { id: string | number }>({79 data,80 renderItem,81 animationType = 'fade',82 staggerDelay = 50,83 duration = 300,84 itemStyle,85 ...flatListProps86}: AnimatedListProps<T>) {87 return (88 <FlatList89 data={data}90 keyExtractor={(item) => String(item.id)}91 renderItem={({ item, index }) => (92 <Animated.View93 style={itemStyle}94 entering={getEnteringAnimation(animationType, index, staggerDelay, duration)}95 exiting={getExitingAnimation(animationType, duration)}96 layout={Layout.duration(200).easing(Easing.out(Easing.ease))}97 >98 {renderItem({ item, index })}99 </Animated.View>100 )}101 {...flatListProps}102 />103 );104}105106export default AnimatedList;
Props
| Name | Type | Default | Description |
|---|---|---|---|
| data | T[] | - | Array of data items with id |
| renderItem | ({item, index}) => ReactNode | - | Render function for each item |
| animationType | 'fade' | 'slide' | 'slideUp' | 'fade' | Type of animation |
| staggerDelay | number | 50 | Delay between each item |
| duration | number | 300 | Animation duration per item |
| itemStyle | StyleProp<ViewStyle> | - | Style for each item container |
