Files
digital-pilates/components/ui/InfoCard.tsx
richarjiang 81a6e43d7c feat(ui): 为药品管理页面添加渐变背景和装饰性元素
- 在药品详情页和管理页面添加线性渐变背景
- 增加装饰性圆圈元素提升视觉效果
- 为添加按钮应用玻璃效果(当可用时)
- 简化InfoCard组件,移除玻璃效果逻辑
- 统一页面视觉风格,提升用户体验
2025-11-11 17:39:52 +08:00

134 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { Colors } from '@/constants/Colors';
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export interface InfoCardProps {
label: string;
value: string;
icon: keyof typeof Ionicons.glyphMap;
colors: (typeof Colors)[keyof typeof Colors];
onPress?: () => void;
clickable?: boolean;
}
export const InfoCard: React.FC<InfoCardProps> = ({
label,
value,
icon,
colors,
onPress,
clickable = false,
}) => {
// 渲染图标 - 始终使用普通 View
const renderIcon = () => {
return (
<View style={[
styles.infoCardIcon,
clickable && styles.clickableIconFallback
]}>
<Ionicons name={icon} size={16} color="#4C6EF5" />
</View>
);
};
// 渲染箭头 - 只在可点击时显示
const renderArrow = () => {
if (!clickable) return null;
return (
<View style={styles.infoCardArrow}>
<Ionicons name="chevron-forward" size={16} color={colors.textMuted} />
</View>
);
};
// 卡片内容
const cardContent = (
<View style={[
styles.infoCard,
{ backgroundColor: colors.surface || '#fff' }
]}>
{renderArrow()}
{renderIcon()}
<Text style={[styles.infoCardLabel, { color: colors.textSecondary }]}>{label}</Text>
<Text style={[styles.infoCardValue, { color: colors.text }]}>{value}</Text>
</View>
);
// 如果可点击且有onPress回调使用TouchableOpacity包装
if (clickable && onPress) {
return (
<TouchableOpacity
style={styles.container}
onPress={onPress}
activeOpacity={0.7}
>
{cardContent}
</TouchableOpacity>
);
}
// 不可点击的版本
return (
<View style={styles.container}>
{cardContent}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
infoCard: {
flex: 1,
borderRadius: 20,
padding: 16,
backgroundColor: '#FFFFFF',
gap: 6,
shadowColor: '#000',
shadowOpacity: 0.06,
shadowRadius: 12,
shadowOffset: { width: 0, height: 3 },
elevation: 3,
position: 'relative',
borderWidth: 1,
borderColor: 'rgba(0, 0, 0, 0.04)',
},
infoCardArrow: {
position: 'absolute',
top: 12,
right: 12,
zIndex: 1,
width: 24,
height: 24,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
},
infoCardIcon: {
width: 28,
height: 28,
borderRadius: 14,
backgroundColor: '#EEF1FF',
alignItems: 'center',
justifyContent: 'center',
},
clickableIconFallback: {
borderWidth: 1,
borderColor: 'rgba(76, 110, 245, 0.3)',
},
infoCardLabel: {
fontSize: 13,
color: '#6B7280',
marginTop: 8,
},
infoCardValue: {
fontSize: 16,
fontWeight: '600',
color: '#1F2933',
},
});
export default InfoCard;