Ramble-FE / components / ui / LoginButton.tsx
LoginButton.tsx
Raw
import { OAuthProvider } from "@/types";
import React, { useState } from "react";
import { Pressable, StyleSheet, Text } from "react-native";
import AppleIcon from "./AppleIcon";
import GoogleIcon from "./GoogleIcon";

interface LoginButtonProps {
    provider: OAuthProvider;
    onPress: () => void;
    isDisabled?: boolean;
}

export default function LoginButton({
    provider,
    onPress,
    isDisabled = false,
}: LoginButtonProps) {
    const [textDisplay, setTextDisplay] = useState<'full' | 'short' | 'icon'>('full');
    
    const getIcon = () => {
        return provider === OAuthProvider.GOOGLE ? 
            <GoogleIcon style={styles.buttonIcon} /> : 
            <AppleIcon style={styles.buttonIcon} />;
    };

    const getDisplayText = () => {
        switch (textDisplay) {
            case 'full':
                return `Sign in with ${provider}`;
            case 'short':
                return provider;
            case 'icon':
                return null;
            default:
                return `Sign in with ${provider}`;
        }
    };

    const handleLayout = (event: any) => {
        const { width } = event.nativeEvent.layout;
        
        // 임시 값
        const iconWidth = 22;
        const gap = 10;
        const fullTextWidth = 15 * 10;
        const shortTextWidth = 6 * 10;
        
        const requiredWidthForFull = iconWidth + gap + fullTextWidth;
        const requiredWidthForShort = iconWidth + gap + shortTextWidth;
        
        if (width >= requiredWidthForFull) {
            setTextDisplay('full');
        } else if (width >= requiredWidthForShort) {
            setTextDisplay('short');
        } else {
            setTextDisplay('icon');
        }
    };

    return (
        <Pressable
            onPress={onPress}
            disabled={isDisabled}
            onLayout={handleLayout}
            style={({ hovered, pressed }) => [
                styles.button,
                isDisabled && styles.buttonDisabled,
                hovered && !isDisabled && styles.buttonHover,
                pressed && !isDisabled && styles.buttonPressed,
            ]}
        >
            {getIcon()}
            {getDisplayText() && (
                <Text
                    style={[
                        styles.buttonText,
                        isDisabled && styles.buttonTextDisabled,
                    ]}
                >
                    {getDisplayText()}
                </Text>
            )}
        </Pressable>
    );
}

// 색상 상수
const COLORS = {
    text: "#333333",
    textDisabled: "#999999",
    border: "#ededef",
    borderActive: "#2d79f3",
    background: "#ffffff",
    shadow: "rgba(0, 0, 0, 0.1)",
};

const styles = StyleSheet.create({
    button: {
        marginTop: 8,
        width: "100%",
        height: 52,
        borderRadius: 12,
        flexDirection: "row",
        justifyContent: "center",
        alignItems: "center",
        gap: 10,
        borderWidth: 1.5,
        borderColor: COLORS.border,
        backgroundColor: COLORS.background,
        boxShadow: `0px 0px 8px ${COLORS.shadow}`
    },
    buttonDisabled: {
        opacity: 0.6,
        borderColor: COLORS.border,
        backgroundColor: "#f8f8f8",
    },
    buttonHover: {
        borderColor: COLORS.borderActive,
        backgroundColor: "#f8f9ff",
        transform: [{ scale: 1.02 }],
    },
    buttonPressed: {
        backgroundColor: "#f0f4ff",
        transform: [{ scale: 0.98 }],
    },
    buttonText: {
        fontWeight: "600",
        fontSize: 16,
        color: COLORS.text,
        textAlign: "center",
    },
    buttonTextDisabled: {
        color: COLORS.textDisabled,
    },
    buttonIcon: {
        width: 22,
        height: 22,
    },
});