import React, { useMemo } from 'react'; import type { FC, JSX } from 'react'; import { ActivityIndicator, StyleSheet, TouchableOpacity, type ViewStyle } from "react-native"; import { verticalScale, horizontalScale } from "../../helpers/ResponsiveCalculations"; import { StyledText, StyledView } from '../StyledComponents'; import { useTheme } from '../../hooks'; import { getButtonColors } from './utils'; import type { ButtonProps } from '../../types'; const Button: FC = ({ variant = 'contained', type = 'flat', fullWidth = false, paddingH = 19, paddingV = 12, bg, br = 8, stroke = 1, strokeColor, titleColor, title, fScale = 'base', fs, ff, size = 50, rippleColor, renderIcon, renderLeftIcon, renderRightIcon, disabled = false, loading = false, containerStyle, titleStyle, onPress, children, ...rest }) => { const theme: any = useTheme(); const { backgroundColor, buttonTextColor, buttonBorderColor } = getButtonColors({ theme, variant, bg, titleColor, strokeColor, disabled, loading }); const STYLES = useMemo(customStyles, []); const dynamicStyles = { BUTTON_CONT: { backgroundColor: backgroundColor, borderWidth: variant === 'contained' ? 0 : stroke, borderColor: buttonBorderColor, }, BUTTON_TEXT: { color: buttonTextColor, fontFamily: ff ?? '', }, FLAT_BTN_MAIN_CONT: { borderRadius: verticalScale(br), alignSelf: fullWidth ? 'stretch' : 'flex-start' as ViewStyle['alignSelf'], }, FLAT_BTN_INNER_CONT: { paddingVertical: verticalScale(paddingV), paddingHorizontal: horizontalScale(!fullWidth ? paddingH : 30), borderRadius: verticalScale(br), }, ROUND_BTN_INNER_CONT: { height: verticalScale(size), width: verticalScale(size), } }; const cloneElement = (element: JSX.Element): JSX.Element | null => { if (React.isValidElement<{ color?: string }>(element)) { return React.cloneElement(element, { color: element.props.color ?? buttonTextColor }) } return null; } return (<> {type === 'flat' && ( {/* */} {(renderLeftIcon || (fullWidth && renderRightIcon)) && ( {renderLeftIcon && cloneElement(renderLeftIcon)} )} {!loading ? ( (title ?? children) ? ( {title ?? children} ) : ( renderIcon && cloneElement(renderIcon) ) ) : ( )} {(renderRightIcon || (fullWidth && renderLeftIcon)) && ( {renderRightIcon && cloneElement(renderRightIcon)} )} {/* */} )} {type === 'round' && ( {renderIcon && cloneElement(renderIcon)} )} ); }; export default Button; export type { ButtonProps }; const customStyles = () => StyleSheet.create({ BUTTON_CONT: { maxWidth: '100%', }, BUTTON_TEXT: { textAlign: 'center', }, FLAT_BTN_MAIN_CONT: { overflow: 'hidden', }, FLAT_BTN_INNER_CONT: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: horizontalScale(10), }, ROUND_BTN_MAIN_CONT: { overflow: 'hidden', borderRadius: verticalScale(100), alignSelf: 'flex-start', }, ROUND_BTN_INNER_CONT: { alignItems: 'center', justifyContent: 'center', } });