init
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import React, { useRef } from 'react';
|
||||
import { Animated, Text, StyleSheet, ActivityIndicator, Pressable } from 'react-native';
|
||||
import { colors, fonts, borderRadius, spacing } from '../utils/theme';
|
||||
|
||||
export default function Button({
|
||||
title,
|
||||
onPress,
|
||||
variant = 'primary',
|
||||
loading = false,
|
||||
disabled = false,
|
||||
style,
|
||||
}) {
|
||||
const isPrimary = variant === 'primary';
|
||||
const scale = useRef(new Animated.Value(1)).current;
|
||||
|
||||
const onPressIn = () => {
|
||||
Animated.spring(scale, {
|
||||
toValue: 0.93,
|
||||
useNativeDriver: true,
|
||||
speed: 50,
|
||||
bounciness: 4,
|
||||
}).start();
|
||||
};
|
||||
|
||||
const onPressOut = () => {
|
||||
Animated.spring(scale, {
|
||||
toValue: 1,
|
||||
useNativeDriver: true,
|
||||
speed: 12,
|
||||
bounciness: 8,
|
||||
}).start();
|
||||
};
|
||||
|
||||
return (
|
||||
<Animated.View style={[{ transform: [{ scale }] }, style]}>
|
||||
<Pressable
|
||||
style={[
|
||||
styles.button,
|
||||
isPrimary ? styles.primary : styles.secondary,
|
||||
disabled && styles.disabled,
|
||||
]}
|
||||
onPress={onPress}
|
||||
onPressIn={onPressIn}
|
||||
onPressOut={onPressOut}
|
||||
disabled={disabled || loading}
|
||||
>
|
||||
{loading ? (
|
||||
<ActivityIndicator color={colors.text} />
|
||||
) : (
|
||||
<Text style={[styles.text, !isPrimary && styles.secondaryText]}>
|
||||
{title}
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
button: {
|
||||
paddingVertical: spacing.md,
|
||||
paddingHorizontal: spacing.xl,
|
||||
borderRadius: borderRadius.lg,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
minHeight: 52,
|
||||
},
|
||||
primary: {
|
||||
backgroundColor: colors.primary,
|
||||
shadowColor: colors.primary,
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
shadowOpacity: 0.4,
|
||||
shadowRadius: 12,
|
||||
elevation: 6,
|
||||
},
|
||||
secondary: {
|
||||
backgroundColor: 'transparent',
|
||||
borderWidth: 1.5,
|
||||
borderColor: colors.primary,
|
||||
},
|
||||
disabled: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
text: {
|
||||
color: colors.text,
|
||||
fontSize: fonts.sizes.md,
|
||||
fontWeight: fonts.weights.semibold,
|
||||
textAlign: 'center',
|
||||
},
|
||||
secondaryText: {
|
||||
color: colors.primary,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user