Files
bw-expo-app/components/ui/button.tsx
imeepos b9399bf4cf feat: 应用界面重构 - 从模板中心到AI内容生成平台
- 重构首页:从模板列表展示改为AI功能展示界面
- 更新底部导航:将explore改为content,index改为home
- 新增多个页面:积分、兑换、历史记录、结果展示、设置等
- 优化UI组件:新增通用按钮、分类标签、加载状态等组件
- 清理冗余文件:删除旧的认证文档和积分详情页面
- 更新主题配置:调整配色方案和视觉风格
- 修复导入路径:优化组件导入结构

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 17:53:56 +08:00

138 lines
2.8 KiB
TypeScript

import {
Pressable,
StyleSheet,
Text,
type PressableProps,
type TextStyle,
ViewStyle,
} from 'react-native';
import { ThemedText } from '@/components/themed-text';
import { useThemeColor } from '@/hooks/use-theme-color';
export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost';
export type ButtonSize = 'sm' | 'md' | 'lg';
interface ButtonProps extends PressableProps {
variant?: ButtonVariant;
size?: ButtonSize;
children: React.ReactNode;
textStyle?: TextStyle;
}
export function Button({
variant = 'primary',
size = 'md',
children,
style,
textStyle,
...props
}: ButtonProps) {
const backgroundColor = useThemeColor(
variantStyles[variant].background,
'tint'
);
const borderColor = useThemeColor(
variantStyles[variant].border,
'tint'
);
const textColor = useThemeColor(
variantStyles[variant].text,
'tint'
);
const dynamicStyles = {
backgroundColor,
borderColor,
borderWidth: variantStyles[variant].borderWidth,
};
return (
<Pressable
style={[
styles.base,
styles[size],
dynamicStyles,
style,
] as any}
{...props}
>
<ThemedText
style={[
styles.text,
styles[`${size}Text`],
{ color: textColor },
variant === 'ghost' && { paddingHorizontal: 0, paddingVertical: 0 },
textStyle,
]}
>
{children}
</ThemedText>
</Pressable>
);
}
const styles = StyleSheet.create({
base: {
borderRadius: 8,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
sm: {
paddingHorizontal: 12,
paddingVertical: 8,
minHeight: 36,
},
md: {
paddingHorizontal: 16,
paddingVertical: 12,
minHeight: 44,
},
lg: {
paddingHorizontal: 20,
paddingVertical: 16,
minHeight: 52,
},
text: {
fontWeight: '600',
textAlign: 'center',
},
smText: {
fontSize: 14,
},
mdText: {
fontSize: 16,
},
lgText: {
fontSize: 18,
},
});
const variantStyles = {
primary: {
background: { light: '#0a7ea4', dark: '#fff' },
text: { light: '#fff', dark: '#000' },
border: { light: 'transparent', dark: 'transparent' },
borderWidth: 0,
},
secondary: {
background: { light: '#f0f0f0', dark: '#2C2E2F' },
text: { light: '#11181C', dark: '#ECEDEE' },
border: { light: 'transparent', dark: 'transparent' },
borderWidth: 0,
},
outline: {
background: { light: 'transparent', dark: 'transparent' },
text: { light: '#0a7ea4', dark: '#fff' },
border: { light: '#0a7ea4', dark: '#fff' },
borderWidth: 1,
},
ghost: {
background: { light: 'transparent', dark: 'transparent' },
text: { light: '#0a7ea4', dark: '#fff' },
border: { light: 'transparent', dark: 'transparent' },
borderWidth: 0,
},
};