import React from 'react'; import { TouchableOpacity, Text, StyleSheet, ActivityIndicator, View, type TouchableOpacityProps, type ViewStyle, type TextStyle, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { AppColors, BorderRadius, FontSizes, FontWeights, Spacing, Shadows } from '@/constants/theme'; interface ButtonProps extends TouchableOpacityProps { title: string; variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger'; size?: 'sm' | 'md' | 'lg'; loading?: boolean; fullWidth?: boolean; icon?: keyof typeof Ionicons.glyphMap; iconPosition?: 'left' | 'right'; } export function Button({ title, variant = 'primary', size = 'md', loading = false, fullWidth = false, icon, iconPosition = 'left', disabled, style, ...props }: ButtonProps) { const isDisabled = disabled || loading; const buttonStyles = [ styles.base, styles[variant], styles[`size_${size}`], fullWidth && styles.fullWidth, isDisabled && styles.disabled, variant === 'primary' && !isDisabled && Shadows.primary, style, ].filter(Boolean) as ViewStyle[]; const textStyles = [ styles.text, styles[`text_${variant}`], styles[`text_${size}`], isDisabled && styles.textDisabled, ].filter(Boolean) as TextStyle[]; const iconSize = size === 'sm' ? 16 : size === 'lg' ? 22 : 18; const iconColor = variant === 'primary' || variant === 'danger' ? AppColors.white : variant === 'secondary' ? AppColors.textPrimary : AppColors.primary; const renderContent = () => { if (loading) { return ( ); } return ( {icon && iconPosition === 'left' && ( )} {title} {icon && iconPosition === 'right' && ( )} ); }; return ( {renderContent()} ); } const styles = StyleSheet.create({ base: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', borderRadius: BorderRadius.lg, }, content: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, primary: { backgroundColor: AppColors.primary, }, secondary: { backgroundColor: AppColors.surfaceSecondary, borderWidth: 1, borderColor: AppColors.border, }, outline: { backgroundColor: 'transparent', borderWidth: 1.5, borderColor: AppColors.primary, }, ghost: { backgroundColor: 'transparent', }, danger: { backgroundColor: AppColors.error, }, size_sm: { paddingVertical: Spacing.sm, paddingHorizontal: Spacing.md, minHeight: 40, borderRadius: BorderRadius.md, }, size_md: { paddingVertical: Spacing.sm + 4, paddingHorizontal: Spacing.lg, minHeight: 48, }, size_lg: { paddingVertical: Spacing.md, paddingHorizontal: Spacing.xl, minHeight: 56, borderRadius: BorderRadius.xl, }, fullWidth: { width: '100%', }, disabled: { opacity: 0.5, shadowOpacity: 0, }, text: { fontWeight: FontWeights.semibold, letterSpacing: 0.3, }, text_primary: { color: AppColors.white, }, text_secondary: { color: AppColors.textPrimary, }, text_outline: { color: AppColors.primary, }, text_ghost: { color: AppColors.primary, }, text_danger: { color: AppColors.white, }, text_sm: { fontSize: FontSizes.sm, }, text_md: { fontSize: FontSizes.base, }, text_lg: { fontSize: FontSizes.lg, }, textDisabled: { color: AppColors.textDisabled, }, iconLeft: { marginRight: Spacing.sm, }, iconRight: { marginLeft: Spacing.sm, }, });