import React from 'react';
import {
ActivityIndicator,
StyleSheet,
Text,
TouchableOpacity,
type TouchableOpacityProps,
View,
} from 'react-native';
import Animated, {
useAnimatedStyle,
useSharedValue,
withSpring,
} from 'react-native-reanimated';
import { Colors, Radius, Spacing, Typography } from '@/constants/theme';
const AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity);
interface ButtonProps extends TouchableOpacityProps {
label: string;
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
loading?: boolean;
fullWidth?: boolean;
}
export function Button({
label,
variant = 'primary',
loading = false,
fullWidth = false,
onPress,
disabled,
style,
...rest
}: ButtonProps) {
const scale = useSharedValue(1);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: scale.value }],
}));
function handlePressIn() {
scale.value = withSpring(0.96, { damping: 15, stiffness: 400 });
}
function handlePressOut() {
scale.value = withSpring(1, { damping: 15, stiffness: 400 });
}
const containerStyle = [
styles.base,
styles[variant],
fullWidth && styles.fullWidth,
(disabled || loading) && styles.disabled,
style,
];
const textColor =
variant === 'secondary' || variant === 'ghost'
? Colors.textPrimary
: Colors.white;
return (
{loading ? (
) : (
{label}
)}
);
}
interface IconButtonProps {
onPress: () => void;
children: React.ReactNode;
accessibilityLabel: string;
}
export function IconButton({ onPress, children, accessibilityLabel }: IconButtonProps) {
return (
{children}
);
}
const styles = StyleSheet.create({
base: {
height: 52,
borderRadius: Radius.md,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: Spacing.lg,
minWidth: 44, // touch target mÃnimo
},
primary: {
backgroundColor: Colors.primary,
},
secondary: {
backgroundColor: Colors.surfaceElevated,
borderWidth: 1,
borderColor: Colors.border,
},
ghost: {
backgroundColor: Colors.transparent,
},
danger: {
backgroundColor: Colors.negative,
},
fullWidth: {
width: '100%',
},
disabled: {
opacity: 0.5,
},
label: {
...Typography.bodyLarge,
fontFamily: 'DMSans_600SemiBold',
},
iconButton: {
width: 44,
height: 44,
alignItems: 'center',
justifyContent: 'center',
},
});