import React , { useMemo , useState } from 'react' ; import { StyleSheet , ViewStyle , Text , View , TouchableOpacity , Image } from 'react-native' ; import { colors } from '../../theme' ; export type ButtonTypes = 'primary' | 'secondary' | 'tertiary' | 'link' ; export type ButtonVariants = 'inverted' | 'dark' | 'green' | 'small' ; interface ButtonColors { shadow : string ; background : string ; text : string ; pressedText ? : string ; border ? : string ; } interface ButtonProps { type ? : ButtonTypes ; variant ? : ButtonVariants ; rounded ? : boolean ; disabled ? : boolean ; onPress : ( ) => void ; style ? : ViewStyle ; width ? : number | string ; children : React . ReactNode ; label ? : string ; hint ? : string ; textColor ? : keyof typeof colors ; icon ? : any ; buttonStyle ? : ViewStyle ; } const Button = ( { type = 'primary' , variant , rounded = false , disabled = false , onPress , style , width , children , hint , label , textColor : textColorProp , icon , buttonStyle } ) => { const [ pressed , setPressed ] = useState ( false ) ; const selectedColors = useMemo ( ( ) => { switch ( type ) { case 'primary' : return { ... buttonColors . primary , ... ( variant === 'inverted' && buttonColors . primaryInverted ) , ... ( variant === 'dark' && buttonColors . primaryDark ) , ... ( variant === 'green' && buttonColors . primaryGreen ) } ; case 'secondary' : return { ... buttonColors . secondary , ... ( variant === 'dark' && buttonColors . secondaryDark ) , ... ( variant === 'green' && buttonColors . secondaryGreen ) } ; case 'link' : return buttonColors . link ; case 'tertiary' : return buttonColors . tertiary ; } } , [ type , variant ] ) ; let backgroundColor = selectedColors . shadow ; let foregroundColor = selectedColors . background ; let borderColor = selectedColors . border ; let textColor = textColorProp ? colors [ textColorProp ] : selectedColors . text ; if ( pressed ) { foregroundColor = backgroundColor ; if ( selectedColors . pressedText ) { textColor = selectedColors . pressedText ; } } else if ( disabled ) { backgroundColor += '66' ; foregroundColor += '66' ; if ( borderColor ) { borderColor += '66' ; } } const pressHandlers = disabled ? { } : { onPressIn : ( ) => setPressed ( true ) , onPressOut : ( ) => setPressed ( false ) , onPress : ( ) => { setPressed ( false ) ; onPress ( ) ; } } ; return ( < View style = { [ styles . wrapper , type !== 'secondary' && { backgroundColor } , type === 'link' && styles . wrapperLink , variant === 'small' && styles . variantSmall , rounded && styles . rounded , ! ! width && { width } , style ] } > < TouchableOpacity style = { [ styles . button , { backgroundColor : type === 'secondary' && disabled ? buttonColors . secondary . background : foregroundColor } , ! ! borderColor && { ... styles . buttonBorder , borderColor } , type === 'link' && styles . buttonLink , variant === 'green' && styles . buttonGreen , variant === 'small' && styles . variantSmall , rounded && styles . rounded , buttonStyle ] } accessibilityRole = "button" importantForAccessibility = "yes" activeOpacity = { 1 } accessibilityHint = { hint } accessibilityLabel = { label } { ... pressHandlers } > < View style = { styles . row } > { icon && ( < Image source = { icon } style = { styles . icon } accessibilityIgnoresInvertColors = { false } / > ) } < Text style = { [ styles . text , { color : textColor } ] } > { children } < /Text> < /View> < /TouchableOpacity> < /View>); } ; const buttonColors = { primary : { shadow : colors . darkPurple , text : colors . white , background : colors . primaryPurple } , primaryInverted : { shadow : colors . white , text : colors . primaryPurple , background : colors . white } , primaryDark : { shadow : colors . blueGrey , text : colors . white , background : colors . darkGrey } , primaryGreen : { shadow : colors . white , text : colors . white , background : colors . validationGreen , border : colors . validationGreen } , secondary : { shadow : colors . primaryPurple , text : colors . primaryPurple , background : colors . transparent , pressedText : colors . white , border : colors . primaryPurple } , secondaryDark : { shadow : colors . darkGrey , text : colors . darkGrey , background : colors . transparent , pressedText : colors . white , border : colors . darkGrey } , secondaryGreen : { shadow : colors . white , text : colors . validationGreen , background : colors . white , border : colors . validationGreen } , link : { shadow : colors . darkGrey , background : 'transparent' , text : colors . darkGrey } , tertiary : { shadow : colors . primaryPurple , text : colors . primaryPurple , background : colors . lighterPurple , pressedText : colors . lighterPurple } } ; const styles = StyleSheet . create ( { wrapper : { minHeight : 75 , justifyContent : 'flex-start' , borderRadius : 3 } , wrapperLink : { minHeight : 20 , backgroundColor : 'transparent' } , wrapperBack : { minHeight : 30 , minWidth : 30 , borderRadius : 15 } , button : { minHeight : 75 , justifyContent : 'center' , alignItems : 'center' , borderRadius : 3 , paddingHorizontal : 12 } , buttonLink : { minHeight : 20 , backgroundColor : 'transparent' } , buttonGreen : { borderWidth : 1 } , buttonBorder : { borderWidth : 2 } , rounded : { borderRadius : 10 } , variantSmall : { minHeight : 60 } , text : { textAlign : 'center' , textAlignVertical : 'center' , fontStyle : 'normal' , fontWeight : 'bold' , fontSize : 17 , lineHeight : 20 } , row : { flexDirection : 'row' } , icon : { marginRight : 10 } } ) ; export default Button ;