Files
silk/app/src/components/StatCard.tsx
T

89 lines
2.0 KiB
TypeScript

import React from 'react';
import { StyleSheet, View } from 'react-native';
import { Card, Text, useTheme } from 'react-native-paper';
import type { MD3Theme } from 'react-native-paper';
interface StatCardProps {
title: string;
value: number | string;
suffix?: string;
color?: string;
icon?: string;
}
export const StatCard: React.FC<StatCardProps> = ({ title, value, suffix, color, icon }) => {
const theme = useTheme<MD3Theme>();
return (
<Card style={styles.card} mode="elevated">
<Card.Content style={styles.content}>
<View style={styles.headerRow}>
{icon ? (
<Text style={[styles.icon, { color: color || theme.colors.primary }]}>{icon}</Text>
) : null}
<Text variant="labelMedium" style={styles.title}>
{title}
</Text>
</View>
<Text variant="headlineMedium" style={[styles.value, { color: color || '#2D2A26' }]}>
{value}
{suffix ? <Text variant="titleMedium" style={styles.suffix}> {suffix}</Text> : null}
</Text>
</Card.Content>
</Card>
);
};
const styles = StyleSheet.create({
card: {
flex: 1,
minWidth: 140,
},
content: {
paddingVertical: 12,
paddingHorizontal: 16,
},
headerRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 4,
},
icon: {
fontSize: 18,
marginRight: 6,
},
title: {
opacity: 0.7,
},
value: {
fontWeight: 'bold',
},
suffix: {
fontWeight: 'normal',
opacity: 0.6,
},
});
interface StatCardRowProps {
items: StatCardProps[];
}
export const StatCardRow: React.FC<StatCardRowProps> = ({ items }) => {
return (
<View style={statRowStyles.container}>
{items.map((item, index) => (
<StatCard key={`${item.title}-${index}`} {...item} />
))}
</View>
);
};
const statRowStyles = StyleSheet.create({
container: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 12,
marginVertical: 6,
},
});