BlueWallet/components/Button.tsx
2026-03-02 14:54:47 +00:00

101 lines
2.6 KiB
TypeScript

import React, { forwardRef } from 'react';
import { ActivityIndicator, StyleProp, StyleSheet, Text, Pressable, PressableProps, View, ViewStyle, Platform } from 'react-native';
import Icon, { type IconProps } from './Icon';
import { useTheme } from './themes';
interface ButtonProps extends PressableProps {
backgroundColor?: string;
buttonTextColor?: string;
disabled?: boolean;
testID?: string;
icon?: Pick<IconProps, 'name' | 'type'> & { color: string };
title?: string;
style?: StyleProp<ViewStyle>;
onPress?: () => void;
showActivityIndicator?: boolean;
}
export const Button = forwardRef<React.ElementRef<typeof Pressable>, ButtonProps>((props, ref) => {
const { colors } = useTheme();
let backgroundColor = props.backgroundColor ?? colors.mainColor;
let fontColor = props.buttonTextColor ?? colors.buttonTextColor;
if (props.disabled) {
backgroundColor = colors.buttonDisabledBackgroundColor;
fontColor = colors.buttonDisabledTextColor;
}
const buttonStyle = {
...styles.button,
backgroundColor,
borderColor: props.disabled ? colors.buttonDisabledBackgroundColor : 'transparent',
};
const textStyle = {
...styles.text,
color: fontColor,
};
const buttonView = props.showActivityIndicator ? (
<ActivityIndicator size="small" color={textStyle.color} />
) : (
<>
{props.icon && <Icon {...props.icon} />}
{props.title && <Text style={textStyle}>{props.title}</Text>}
</>
);
return props.onPress ? (
<View style={styles.pressableWrapper}>
<Pressable
ref={ref}
testID={props.testID}
android_ripple={{ color: colors.androidRippleColor }}
style={({ pressed }) => [Platform.OS === 'ios' && pressed ? styles.pressed : null, buttonStyle, props.style, styles.content]}
accessibilityRole="button"
onPress={props.onPress}
disabled={props.disabled}
{...props}
>
{buttonView}
</Pressable>
</View>
) : (
<View style={[buttonStyle, props.style, styles.content]}>{buttonView}</View>
);
});
const styles = StyleSheet.create({
button: {
borderWidth: 0.7,
minHeight: 45,
height: 48,
maxHeight: 48,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 16,
flexGrow: 1,
},
content: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
text: {
marginHorizontal: 8,
fontSize: 16,
fontWeight: '600',
},
pressableWrapper: {
overflow: 'hidden',
borderRadius: 25,
},
pressed: {
opacity: 0.6,
},
});
export default Button;