import React from 'react'; import { TouchableOpacity, StyleSheet, ActivityIndicator, TouchableOpacityProps, ViewStyle, TextStyle, } from 'react-native'; import { Text } from '@/components/ui/Text'; import { useThemeColor } from '@/hooks/use-theme-color'; function toTestId(title: string): string { return title .normalize('NFD') .replace(/[\u0300-\u036f]/g, '') .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, ''); } interface ButtonProps extends TouchableOpacityProps { title: string; variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'dashed' | 'danger'; size?: 'small' | 'medium' | 'large'; loading?: boolean; disabled?: boolean; style?: ViewStyle; textStyle?: TextStyle; } export const Button: React.FC = ({ title, variant = 'primary', size = 'medium', loading = false, disabled = false, style, textStyle, onPress, ...props }) => { const primaryColor = useThemeColor({}, 'tint'); const textColor = useThemeColor({}, 'text'); const textSecondaryColor = useThemeColor({}, 'textSecondary'); const backgroundColor = useThemeColor({}, 'background'); const borderColor = useThemeColor({}, 'border'); const borderDashedColor = useThemeColor({}, 'borderDashed'); const getBackgroundColor = () => { if (disabled) return useThemeColor({ light: '#e5e5e5', dark: '#404040' }, 'background'); switch (variant) { case 'primary': return primaryColor; case 'secondary': return useThemeColor({}, 'secondaryBackground'); case 'danger': return useThemeColor({}, 'danger'); case 'outline': case 'ghost': case 'dashed': return 'transparent'; default: return primaryColor; } }; const getTextColor = () => { if (disabled) return useThemeColor({}, 'text'); switch (variant) { case 'primary': return textColor; case 'secondary': return useThemeColor({}, 'white'); case 'outline': case 'ghost': return textColor; case 'dashed': return textSecondaryColor; default: return '#fff'; } }; const getBorderWidth = () => { if (variant === 'outline' || variant === 'dashed') { return 1; } else { return 0; } }; const getBorderColor = () => { if (variant === 'outline' || variant === 'dashed') { if (disabled) { return borderColor; } else if (variant === 'dashed') { return borderDashedColor; } else { return primaryColor; } } return 'transparent'; }; const getBorderStyle = () => { return variant === 'dashed' ? 'dashed' : 'solid'; } const getHeight = () => { switch (size) { case 'small': return 36; case 'medium': return 44; case 'large': return 52; default: return 44; } }; const getFontSize = () => { switch (size) { case 'small': return 14; case 'medium': return 16; case 'large': return 18; default: return 16; } }; const getLineHeight = () => { switch (size) { case 'small': return 18; case 'medium': return 20; case 'large': return 22; default: return 20; } }; return ( {loading ? ( ) : ( {title} )} ); }; const styles = StyleSheet.create({ button: { borderRadius: 8, paddingHorizontal: 20, alignItems: 'center', justifyContent: 'center', marginVertical: 8, }, text: { fontWeight: '600', }, });