Button.tsx
import { styles } from './Button.style';
import { type ForwardedRef, forwardRef, useCallback, useState } from 'react';
import {
type GestureResponderEvent,
type PressableProps,
Pressable,
View,
} from 'react-native';
import Text from '../text/Text';
type Props = {
children: string;
size: 36 | 40 | 44 | 48;
disabled?: boolean;
wide?: boolean;
} & Omit<PressableProps, 'ref'>;
const Button = (
{ children, size, disabled = false, wide = false, ...props }: Props,
ref: ForwardedRef<View>
) => {
const [pressed, setPressed] = useState(false);
const handlePressIn = useCallback(
(event: GestureResponderEvent) => {
setPressed(true);
props.onPressIn?.(event);
},
[props]
);
const handlePressOut = useCallback(
(event: GestureResponderEvent) => {
setPressed(false);
props.onPressOut?.(event);
},
[props]
);
return (
<View style={styles.container}>
<Pressable
{...props}
ref={ref}
disabled={disabled}
style={[wide && styles.wide]}
onPressIn={handlePressIn}
onPressOut={handlePressOut}
>
<View
style={[
styles.button,
styles[`button${size}`],
disabled && styles.disabled,
wide && styles.wide,
!disabled && pressed && styles.pressed,
]}
>
<Text
style={[
styles.buttonText,
styles[`buttonText${size}`],
disabled && styles.disabledText,
]}
>
{children}
</Text>
</View>
</Pressable>
</View>
);
};
export default forwardRef(Button);
Button.style.ts
import { StyleSheet } from 'react-native';
import theme from '../../theme';
export const styles = StyleSheet.create({
container: {
flexWrap: 'wrap',
justifyContent: 'center',
flexDirection: 'row',
},
button: {
backgroundColor: theme.color_primary_60,
borderRadius: 10,
flexDirection: 'row',
justifyContent: 'center',
},
buttonText: {
color: theme.color_white,
},
button36: {
paddingVertical: 8,
paddingHorizontal: 16,
},
buttonText36: {
fontSize: 14,
lineHeight: 20,
},
button40: {
paddingVertical: 10,
paddingHorizontal: 16,
},
buttonText40: {
fontSize: 14,
lineHeight: 20,
},
button44: {
paddingVertical: 11,
paddingHorizontal: 16,
},
buttonText44: {
fontSize: 15,
lineHeight: 22,
},
button48: {
paddingVertical: 14,
paddingHorizontal: 16,
},
buttonText48: {
fontSize: 14,
lineHeight: 20,
},
disabled: {
backgroundColor: theme.color_icon_gray_10,
},
disabledText: {
color: theme.color_icon_gray_40,
},
wide: {
width: '100%',
},
pressed: {
backgroundColor: theme.color_primary_80,
},
});