import { GestureResponderEvent, Pressable } from "react-native"; import Animated, { interpolateColor, useAnimatedProps, useReducedMotion } from "react-native-reanimated"; import { useIOTheme } from "../../context"; import { IOColors, IOIconButtonStyles, IOThemeLight, hexToRgba } from "../../core"; import { useScaleAnimation } from "../../hooks"; import { WithTestID } from "../../utils/types"; import { AnimatedIcon, AnimatedIconWithColorTransition, IOIconSizeScale, IOIcons } from "../icons"; export type IconButton = WithTestID<{ color?: "primary" | "neutral" | "contrast"; icon: IOIcons; iconSize?: IOIconSizeScale; disabled?: boolean; accessibilityLabel: string; accessibilityHint?: string; onPress: (event: GestureResponderEvent) => void; persistentColorMode?: boolean; }>; type ColorStates = { icon: { default: string; pressed: string; disabled: string; }; }; export const IconButton = ({ color = "primary", persistentColorMode = false, icon, iconSize = 24, disabled = false, onPress, accessibilityLabel, accessibilityHint, testID }: IconButton) => { const theme = useIOTheme(); const { progress, onPressIn, onPressOut, scaleAnimatedStyle } = useScaleAnimation("exaggerated"); const reducedMotion = useReducedMotion(); const mapColorStates: Record< NonNullable, ColorStates > = { // Primary button primary: { icon: { default: IOColors[theme["interactiveElem-default"]], pressed: IOColors[theme["interactiveElem-pressed"]], disabled: IOColors[theme["interactiveElem-disabled"]] } }, // Neutral button neutral: { icon: { default: persistentColorMode ? IOColors[IOThemeLight["neutralButton-default"]] : IOColors[theme["neutralButton-default"]], pressed: persistentColorMode ? IOColors[IOThemeLight["neutralButton-pressed"]] : IOColors[theme["neutralButton-pressed"]], disabled: persistentColorMode ? IOColors[IOThemeLight["neutralButton-disabled"]] : IOColors[theme["neutralButton-disabled"]] } }, // Contrast button contrast: { icon: { default: IOColors.white, pressed: hexToRgba(IOColors.white, 0.85), disabled: hexToRgba(IOColors.white, 0.25) } } }; // Animate the color prop const animatedColor = useAnimatedProps(() => { const iconColor = interpolateColor( progress.value, [0, 1], [mapColorStates[color].icon.default, mapColorStates[color].icon.pressed] ); return { color: iconColor }; }); return ( {!disabled ? ( ) : ( )} ); };