Ramble-FE / components / ui / IconButton.tsx
IconButton.tsx
Raw
import { Ionicons } from "@expo/vector-icons";
import { Pressable, StyleSheet } from "react-native";
import tinycolor from "tinycolor2";

interface IconButtonProps {
    icon: keyof typeof Ionicons.glyphMap;
    iconSize?: number;
    iconColor?: string;
    backgroundColor?: string;
    onPress: () => void;
    disabled?: boolean;
}

export default function IconButton({ 
    icon, 
    iconColor = "white", 
    iconSize = 24,
    backgroundColor = "transparent",
    onPress, 
    disabled = false,
}: IconButtonProps) {
    const getBackgroundColor = (color: string, opacity: number) => {
        if (color === "transparent") {
            color = iconColor;
        }

        return tinycolor(color)
            .setAlpha(opacity)
            .toRgbString();
    };

    return (
        <Pressable
            style={({ pressed }) => {
                const baseStyle = styles.iconButton;
                const pressedStyle = { 
                    backgroundColor: pressed ? getBackgroundColor(backgroundColor, 0.2) : backgroundColor,
                    boxShadow: pressed ? "0px 0px 8px rgba(0, 0, 0, 0.1)" : "none",
                };

                return  [baseStyle, pressedStyle];
            }}
            onPress={onPress}
            disabled={disabled}
        >
            <Ionicons 
                style={styles.icon}
                name={icon}
                size={iconSize}
                color={iconColor}
            />
        </Pressable>
    );
}

const styles = StyleSheet.create({
    iconButton: {
        width: 42,
        height: 42,
        borderRadius: 21,
        justifyContent: 'center',
        alignItems: 'center',
    },
    icon: {
        textShadowColor: "rgba(0, 0, 0, 0.1)",
        textShadowOffset: { width: 0, height: 0 },
        textShadowRadius: 8,
    },
});