Matiks-UI / src /components /StatCard.tsx
Abhisingh-18's picture
Mirror of github.com/Abhisingh18/Matiks-UI
0bedb61 verified
Raw
History Blame Contribute Delete
2.21 kB
import React, { useEffect } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
withTiming,
withDelay,
interpolate,
Easing,
} from 'react-native-reanimated';
import { BlurView } from 'expo-blur';
import { COLORS } from '../constants/colors';
const AnimatedBlurView = Animated.createAnimatedComponent(BlurView);
interface StatCardProps {
label: string;
value: string | number;
icon?: string;
delay?: number;
color?: string;
compact?: boolean;
}
export const StatCard: React.FC<StatCardProps> = ({
label,
value,
icon,
delay = 0,
color = COLORS.primary,
compact = false,
}) => {
const progress = useSharedValue(0);
useEffect(() => {
progress.value = withDelay(
delay,
withTiming(1, { duration: 500, easing: Easing.out(Easing.cubic) })
);
}, []);
const animStyle = useAnimatedStyle(() => ({
opacity: progress.value,
transform: [
{ translateY: interpolate(progress.value, [0, 1], [15, 0]) },
],
}));
return (
<AnimatedBlurView tint="dark" intensity={40} style={[styles.container, compact && styles.compact, animStyle]}>
{icon && <Text style={styles.icon}>{icon}</Text>}
<Text style={[styles.value, { color }]}>{value}</Text>
<Text style={styles.label}>{label}</Text>
</AnimatedBlurView>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: 'transparent',
borderRadius: 16,
borderWidth: 1,
borderColor: 'rgba(255,255,255,0.08)',
padding: 14,
alignItems: 'center',
justifyContent: 'center',
minWidth: 90,
flex: 1,
margin: 4,
overflow: 'hidden',
},
compact: {
padding: 10,
},
icon: {
fontSize: 20,
marginBottom: 4,
},
value: {
fontFamily: 'Outfit_900Black',
fontSize: 22,
marginBottom: 2,
fontVariant: ['tabular-nums'],
letterSpacing: 1,
},
label: {
fontFamily: 'Outfit_700Bold',
fontSize: 9,
color: COLORS.textDim,
textTransform: 'uppercase',
letterSpacing: 1.5,
textAlign: 'center',
},
});