2021-01-03 02:00:26 +01:00
|
|
|
import Icon from '@components/Icon'
|
|
|
|
import { StyleConstants } from '@utils/styles/constants'
|
|
|
|
import layoutAnimation from '@utils/styles/layoutAnimation'
|
|
|
|
import { useTheme } from '@utils/styles/ThemeManager'
|
2021-05-09 21:59:03 +02:00
|
|
|
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
2020-12-26 23:05:17 +01:00
|
|
|
import {
|
2021-04-09 21:43:12 +02:00
|
|
|
AccessibilityProps,
|
2020-12-26 23:05:17 +01:00
|
|
|
Pressable,
|
|
|
|
StyleProp,
|
|
|
|
View,
|
|
|
|
ViewStyle
|
|
|
|
} from 'react-native'
|
2021-02-08 23:47:20 +01:00
|
|
|
import { Flow } from 'react-native-animated-spinkit'
|
2022-05-07 00:52:32 +02:00
|
|
|
import CustomText from './Text'
|
2020-12-03 01:28:56 +01:00
|
|
|
|
2020-12-26 23:05:17 +01:00
|
|
|
export interface Props {
|
2021-04-09 21:43:12 +02:00
|
|
|
accessibilityLabel?: AccessibilityProps['accessibilityLabel']
|
|
|
|
accessibilityHint?: AccessibilityProps['accessibilityHint']
|
|
|
|
|
2020-12-26 23:05:17 +01:00
|
|
|
style?: StyleProp<ViewStyle>
|
|
|
|
|
|
|
|
type: 'icon' | 'text'
|
|
|
|
content: string
|
|
|
|
|
2021-04-09 21:43:12 +02:00
|
|
|
selected?: boolean
|
2020-12-26 23:05:17 +01:00
|
|
|
loading?: boolean
|
|
|
|
destructive?: boolean
|
|
|
|
disabled?: boolean
|
|
|
|
|
2021-01-03 02:00:26 +01:00
|
|
|
strokeWidth?: number
|
2020-12-26 23:05:17 +01:00
|
|
|
size?: 'S' | 'M' | 'L'
|
|
|
|
spacing?: 'XS' | 'S' | 'M' | 'L'
|
|
|
|
round?: boolean
|
|
|
|
overlay?: boolean
|
|
|
|
|
|
|
|
onPress: () => void
|
|
|
|
}
|
|
|
|
|
|
|
|
const Button: React.FC<Props> = ({
|
2021-04-09 21:43:12 +02:00
|
|
|
accessibilityLabel,
|
|
|
|
accessibilityHint,
|
2020-12-26 23:05:17 +01:00
|
|
|
style: customStyle,
|
|
|
|
type,
|
|
|
|
content,
|
2021-04-09 21:43:12 +02:00
|
|
|
selected,
|
2020-12-26 23:05:17 +01:00
|
|
|
loading = false,
|
|
|
|
destructive = false,
|
|
|
|
disabled = false,
|
2021-01-03 02:00:26 +01:00
|
|
|
strokeWidth,
|
2020-12-26 23:05:17 +01:00
|
|
|
size = 'M',
|
|
|
|
spacing = 'S',
|
|
|
|
round = false,
|
|
|
|
overlay = false,
|
|
|
|
onPress
|
|
|
|
}) => {
|
2022-02-12 14:51:01 +01:00
|
|
|
const { colors, theme } = useTheme()
|
2020-12-26 23:05:17 +01:00
|
|
|
|
2021-01-04 10:50:24 +01:00
|
|
|
const mounted = useRef(false)
|
|
|
|
useEffect(() => {
|
|
|
|
if (mounted.current) {
|
|
|
|
layoutAnimation()
|
|
|
|
} else {
|
|
|
|
mounted.current = true
|
|
|
|
}
|
2021-04-09 21:43:12 +02:00
|
|
|
}, [content, loading, disabled])
|
2020-12-26 23:05:17 +01:00
|
|
|
|
|
|
|
const loadingSpinkit = useMemo(
|
|
|
|
() => (
|
|
|
|
<View style={{ position: 'absolute' }}>
|
2022-02-12 14:51:01 +01:00
|
|
|
<Flow size={StyleConstants.Font.Size[size]} color={colors.secondary} />
|
2020-12-26 23:05:17 +01:00
|
|
|
</View>
|
|
|
|
),
|
2022-02-12 14:51:01 +01:00
|
|
|
[theme]
|
2020-12-26 23:05:17 +01:00
|
|
|
)
|
|
|
|
|
2021-04-09 21:43:12 +02:00
|
|
|
const mainColor = useMemo(() => {
|
|
|
|
if (selected) {
|
2022-02-12 14:51:01 +01:00
|
|
|
return colors.blue
|
2021-04-09 21:43:12 +02:00
|
|
|
} else if (overlay) {
|
2022-02-12 14:51:01 +01:00
|
|
|
return colors.primaryOverlay
|
2021-04-09 21:43:12 +02:00
|
|
|
} else if (disabled || loading) {
|
2022-02-12 14:51:01 +01:00
|
|
|
return colors.disabled
|
2021-01-07 19:13:09 +01:00
|
|
|
} else {
|
2021-04-09 21:43:12 +02:00
|
|
|
if (destructive) {
|
2022-02-12 14:51:01 +01:00
|
|
|
return colors.red
|
2021-01-07 19:13:09 +01:00
|
|
|
} else {
|
2022-02-12 14:51:01 +01:00
|
|
|
return colors.primaryDefault
|
2021-01-07 19:13:09 +01:00
|
|
|
}
|
|
|
|
}
|
2022-02-12 14:51:01 +01:00
|
|
|
}, [theme, disabled, loading, selected])
|
2021-04-09 21:43:12 +02:00
|
|
|
|
2021-01-07 19:13:09 +01:00
|
|
|
const colorBackground = useMemo(() => {
|
|
|
|
if (overlay) {
|
2022-02-12 14:51:01 +01:00
|
|
|
return colors.backgroundOverlayInvert
|
2021-01-07 19:13:09 +01:00
|
|
|
} else {
|
2022-02-12 14:51:01 +01:00
|
|
|
return colors.backgroundDefault
|
2021-01-07 19:13:09 +01:00
|
|
|
}
|
2022-02-12 14:51:01 +01:00
|
|
|
}, [theme])
|
2020-12-26 23:05:17 +01:00
|
|
|
|
|
|
|
const children = useMemo(() => {
|
|
|
|
switch (type) {
|
|
|
|
case 'icon':
|
|
|
|
return (
|
|
|
|
<>
|
2021-01-03 02:00:26 +01:00
|
|
|
<Icon
|
|
|
|
name={content}
|
2021-04-09 21:43:12 +02:00
|
|
|
color={mainColor}
|
2021-01-03 02:00:26 +01:00
|
|
|
strokeWidth={strokeWidth}
|
2020-12-26 23:05:17 +01:00
|
|
|
style={{ opacity: loading ? 0 : 1 }}
|
2021-01-03 02:00:26 +01:00
|
|
|
size={StyleConstants.Font.Size[size] * (size === 'L' ? 1.25 : 1)}
|
2020-12-26 23:05:17 +01:00
|
|
|
/>
|
2021-01-18 00:23:40 +01:00
|
|
|
{loading ? loadingSpinkit : null}
|
2020-12-26 23:05:17 +01:00
|
|
|
</>
|
|
|
|
)
|
|
|
|
case 'text':
|
|
|
|
return (
|
|
|
|
<>
|
2022-05-07 00:52:32 +02:00
|
|
|
<CustomText
|
2020-12-26 23:05:17 +01:00
|
|
|
style={{
|
2021-04-09 21:43:12 +02:00
|
|
|
color: mainColor,
|
2020-12-26 23:05:17 +01:00
|
|
|
fontSize:
|
2020-12-28 17:30:20 +01:00
|
|
|
StyleConstants.Font.Size[size] * (size === 'L' ? 1.25 : 1),
|
2020-12-26 23:05:17 +01:00
|
|
|
opacity: loading ? 0 : 1
|
|
|
|
}}
|
|
|
|
children={content}
|
2020-12-28 00:59:57 +01:00
|
|
|
testID='text'
|
2020-12-26 23:05:17 +01:00
|
|
|
/>
|
2021-01-18 00:23:40 +01:00
|
|
|
{loading ? loadingSpinkit : null}
|
2020-12-26 23:05:17 +01:00
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
2022-02-12 14:51:01 +01:00
|
|
|
}, [theme, content, loading, disabled])
|
2020-12-26 23:05:17 +01:00
|
|
|
|
2021-05-09 21:59:03 +02:00
|
|
|
const [layoutHeight, setLayoutHeight] = useState<number | undefined>()
|
2020-12-26 23:05:17 +01:00
|
|
|
|
|
|
|
return (
|
2021-01-16 00:00:31 +01:00
|
|
|
<Pressable
|
2021-04-09 21:43:12 +02:00
|
|
|
accessible
|
|
|
|
accessibilityLabel={accessibilityLabel}
|
|
|
|
accessibilityHint={accessibilityHint}
|
|
|
|
accessibilityRole='button'
|
|
|
|
accessibilityState={{
|
|
|
|
selected,
|
|
|
|
disabled: disabled || selected,
|
|
|
|
busy: loading
|
|
|
|
}}
|
2021-01-16 00:00:31 +01:00
|
|
|
style={[
|
|
|
|
{
|
2022-05-07 00:52:32 +02:00
|
|
|
borderRadius: 100,
|
|
|
|
justifyContent: 'center',
|
|
|
|
alignItems: 'center',
|
2021-01-16 00:00:31 +01:00
|
|
|
borderWidth: overlay ? 0 : 1,
|
2021-04-09 21:43:12 +02:00
|
|
|
borderColor: mainColor,
|
2021-01-16 00:00:31 +01:00
|
|
|
backgroundColor: colorBackground,
|
|
|
|
paddingVertical: StyleConstants.Spacing[spacing],
|
|
|
|
paddingHorizontal:
|
2021-05-09 21:59:03 +02:00
|
|
|
StyleConstants.Spacing[spacing] + StyleConstants.Spacing.XS,
|
|
|
|
width: round && layoutHeight ? layoutHeight : undefined
|
2021-01-16 00:00:31 +01:00
|
|
|
},
|
|
|
|
customStyle
|
|
|
|
]}
|
2021-05-09 21:59:03 +02:00
|
|
|
{...(round && {
|
|
|
|
onLayout: ({ nativeEvent }) =>
|
|
|
|
setLayoutHeight(nativeEvent.layout.height)
|
|
|
|
})}
|
2021-01-16 00:00:31 +01:00
|
|
|
testID='base'
|
|
|
|
onPress={onPress}
|
|
|
|
children={children}
|
2021-04-09 21:43:12 +02:00
|
|
|
disabled={selected || disabled || loading}
|
2021-01-16 00:00:31 +01:00
|
|
|
/>
|
2020-12-26 23:05:17 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Button
|