learning_ai_invt_trdg/mobile/components/SkeletonLoader.tsx

63 lines
1.4 KiB
TypeScript

import React, { useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import Animated, {
useAnimatedStyle,
useSharedValue,
withRepeat,
withTiming,
Easing,
} from 'react-native-reanimated';
import { LinearGradient } from 'expo-linear-gradient';
import { Colors, BorderRadius } from '@/constants/theme';
interface SkeletonLoaderProps {
width?: number | string;
height?: number;
borderRadius?: number;
style?: any;
}
export default function SkeletonLoader({
width = '100%',
height = 120,
borderRadius = BorderRadius.large,
style,
}: SkeletonLoaderProps) {
const translateX = useSharedValue(-300);
useEffect(() => {
translateX.value = withRepeat(
withTiming(300, { duration: 1200, easing: Easing.linear }),
-1
);
}, []);
const shimmerStyle = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}));
return (
<View
style={[
{
width: width as any,
height,
borderRadius,
backgroundColor: Colors.background.card,
overflow: 'hidden',
},
style,
]}
>
<Animated.View style={[StyleSheet.absoluteFill, shimmerStyle]}>
<LinearGradient
colors={['transparent', 'rgba(255,255,255,0.04)', 'transparent']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={StyleSheet.absoluteFill}
/>
</Animated.View>
</View>
);
}