import React from 'react'; import { GestureResponderEvent, TouchableOpacity } from 'react-native'; import { useRestyle, spacing, border, backgroundColor, createVariant, VariantProps, createRestyleComponent, } from '@shopify/restyle'; import type { Theme } from '../../theme/theme'; import { Text } from '../Text'; import { Box } from '../Box'; import { useTheme } from '../../theme/ThemeProvider'; import type { theme } from '../../theme/theme'; import { Normalize } from '../../utils/normalize'; import { Spinner } from '../Spinner'; type ButtonProps = React.ComponentProps & { label?: string; type?: TypeButton; icon?: React.ReactNode; loading?: boolean; onPress: (event: GestureResponderEvent) => void; }; type TypeButton = 'large' | 'medium' | 'small'; const restyleFunctions = [spacing, backgroundColor, border]; const ButtonContainer = createRestyleComponent< VariantProps & React.ComponentProps & { disabled?: boolean; }, Theme >( [ createVariant({ themeKey: 'buttonVariants', }), ], Box ); const colorText: { [key in keyof typeof theme.buttonVariants]: keyof typeof theme.colors; } = { primary: 'white', disabled: 'white', outlinedDisabled: 'gray60', outlined: 'darkBlueGray', outlinedPrimary: 'green', light: 'darkBlueGray', }; const typeButton: { [key in TypeButton]: number } = { large: Normalize(48), medium: Normalize(40), small: Normalize(32), }; /** * @onPress Called when the touch is released, but not if cancelled * @label Button title * @disabled Disable the onpress function * @variant Different states of the main button * @type Main button height 'large' | 'medium' | 'small'; * @loading Show a loading indicator and disable the button * @icon Library icons phosphor-react-native * @see https://zeroheight.com/502cb86ad/p/281e3e-buttons/b/93e007 */ export const Button: React.FC = ({ onPress = () => console.warn('onPress is a required field'), label, disabled, variant = 'primary', type = 'large', loading = false, icon, ...rest }) => { const props = useRestyle(restyleFunctions, rest); const { fonts } = useTheme(); const isOutlinedDisabled = disabled && variant === 'outlined'; const variantButton = isOutlinedDisabled ? 'outlinedDisabled' : disabled ? 'disabled' : variant; let textColor: keyof typeof theme.colors = 'white'; let minHeight = typeButton.large; if (typeof variant !== 'object' && variant) { textColor = colorText[isOutlinedDisabled ? 'outlinedDisabled' : variant]; minHeight = typeButton[type]; } return ( {loading ? ( ) : ( <> {!!icon && {icon}} {label} )} ); };