UNPKG

@cometchat/chat-uikit-react-native

Version:

Ready-to-use Chat UI Components for React Native

141 lines 4.98 kB
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