@cometchat/chat-uikit-react-native
Version:
Ready-to-use Chat UI Components for React Native
141 lines • 4.98 kB
JavaScript
import React, { useEffect, useRef } from "react";
import { Animated, Easing, ScrollView, StyleSheet, View } from "react-native";
import Svg, { Defs, LinearGradient, Circle, Rect, Stop } from "react-native-svg";
import { useTheme } from "../../../theme";
const CircleSkeleton = () => {
const theme = useTheme();
return (<View style={styles.circleContainer}>
<Svg height={50} width={70}>
<Defs>
<LinearGradient id='circleGradient' x1={0} y1={0} x2={40} y2={1} gradientUnits='userSpaceOnUse'>
<Stop stopColor={theme.mentionsListStyle.skeletonStyle.linearGradientColors[0]}/>
<Stop offset={1} stopColor={theme.mentionsListStyle.skeletonStyle.linearGradientColors[1]}/>
</LinearGradient>
</Defs>
<Circle cx={34.5} cy={25} r={20} fill='url(#circleGradient)'/>
</Svg>
</View>);
};
const RectangleSkeleton = () => {
const theme = useTheme();
return (<View style={styles.rectangleContainer}>
<Svg height={50} width={270}>
<Defs>
<LinearGradient id='rectangleGradient' x1={0} y1={24} x2={240} y2={24} gradientUnits='userSpaceOnUse'>
<Stop stopColor={theme.mentionsListStyle.skeletonStyle.linearGradientColors[0]}/>
<Stop offset={1} stopColor={theme.mentionsListStyle.skeletonStyle.linearGradientColors[1]}/>
</LinearGradient>
</Defs>
<Rect x={0} y={17} width={270} height={20} rx={10} fill='url(#rectangleGradient)'/>
</Svg>
</View>);
};
export const Skeleton = () => {
const theme = useTheme();
const animatedValue = useRef(new Animated.Value(0)).current;
useEffect(() => {
const startShimmer = () => {
animatedValue.setValue(0);
Animated.loop(Animated.timing(animatedValue, {
toValue: 1,
duration: theme.mentionsListStyle.skeletonStyle.speed * 1000,
easing: Easing.linear,
useNativeDriver: false,
})).start();
};
startShimmer();
}, [animatedValue]);
const shimmerTranslateXCircle = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 50],
});
const shimmerTranslateXRectangle = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 130],
});
return (<ScrollView>
{new Array(20).fill(0).map((_, i) => (<View key={i} style={styles.skeletonContainer}>
<View style={theme.mentionsListStyle.listItemStyle.containerStyle}>
<View style={styles.circleWrapper}>
<CircleSkeleton />
<Animated.View style={[
styles.circleShimmer,
{
transform: [{ translateX: shimmerTranslateXCircle }],
backgroundColor: theme.mentionsListStyle.skeletonStyle.shimmerBackgroundColor,
opacity: theme.mentionsListStyle.skeletonStyle.shimmerOpacity,
},
]}/>
</View>
<View style={styles.rectangleWrapper}>
<RectangleSkeleton />
<Animated.View style={[
styles.rectangleShimmer,
{
transform: [{ translateX: shimmerTranslateXRectangle }],
backgroundColor: theme.mentionsListStyle.skeletonStyle.shimmerBackgroundColor,
opacity: theme.mentionsListStyle.skeletonStyle.shimmerOpacity,
},
]}/>
</View>
</View>
</View>))}
</ScrollView>);
};
const styles = StyleSheet.create({
skeletonContainer: {
flexDirection: "row",
alignItems: "center", // Center items vertically
},
skeletonRow: {
flexDirection: "row",
alignItems: "center", // Center align vertically
},
circleWrapper: {
position: "relative",
height: 50,
width: 40,
overflow: "hidden",
alignSelf: "center",
},
circleContainer: {
height: 50,
justifyContent: "center",
alignItems: "center", // Center content horizontally,
},
circleShimmerContainer: {
position: "absolute",
top: 5,
left: 15,
height: 40,
width: 40,
overflow: "hidden",
borderRadius: 50, // Fully round to match the circle
},
circleShimmer: {
height: 40,
width: 40,
borderRadius: 20,
position: "absolute",
left: 0,
top: 5,
},
rectangleWrapper: {
flex: 1,
position: "relative",
alignSelf: "center",
justifyContent: "center",
},
rectangleContainer: {
position: "relative",
},
rectangleShimmer: {
position: "absolute",
top: 17,
left: 0,
height: 20,
width: 140,
borderRadius: 10, // Optional: Add rounded corners to the shimmer
},
});
//# sourceMappingURL=Skeleton.js.map