import React from "react"; import { ActivityIndicator, GestureResponderEvent, StyleProp, StyleSheet, Text, TouchableOpacity, View, ViewStyle, } from "react-native"; type ButtonType = "primary" | "default" | "dashed" | "text" | "link" | "danger"; type ButtonShape = "default" | "circle" | "round"; type ButtonSize = "small" | "middle" | "large"; export interface IconButtonProps { type?: ButtonType; shape?: ButtonShape; size?: ButtonSize; icon?: React.ReactNode; // render an icon component, e.g. loading?: boolean; disabled?: boolean; onPress?: (e?: GestureResponderEvent) => void; children?: React.ReactNode; // label text style?: StyleProp; block?: boolean; // full width activeOpacity?: number; } /** * IconButton * A lightweight Button component inspired by Ant Design Button API, tuned for React Native. * Accepts an `icon` prop as a React node for maximum flexibility. */ const IconButton: React.FC = ({ type = "default", shape = "default", size = "middle", icon, loading = false, disabled = false, onPress, children, style, block = false, activeOpacity = 0.8, }) => { const sizeMap = { small: { height: 32, fontSize: 14, paddingHorizontal: 10 }, middle: { height: 40, fontSize: 16, paddingHorizontal: 14 }, large: { height: 48, fontSize: 18, paddingHorizontal: 18 }, } as const; const colors: Record< ButtonType, { backgroundColor?: string; textColor: string; borderColor?: string } > = { primary: { backgroundColor: "#4ecdc4", textColor: "#fff" }, default: { backgroundColor: "#f2f2f2", textColor: "#111", borderColor: "#e6e6e6", }, dashed: { backgroundColor: "#fff", textColor: "#111", borderColor: "#d9d9d9", }, text: { backgroundColor: "transparent", textColor: "#111" }, link: { backgroundColor: "transparent", textColor: "#4ecdc4" }, danger: { backgroundColor: "#e74c3c", textColor: "#fff" }, }; const sz = sizeMap[size]; const color = colors[type]; const isCircle = shape === "circle"; const isRound = shape === "round"; const handlePress = (e: GestureResponderEvent) => { if (disabled || loading) return; onPress?.(e); }; return ( {loading ? ( ) : icon ? ( {icon} ) : null} {children ? ( {children} ) : null} ); }; const styles = StyleSheet.create({ button: { flexDirection: "row", alignItems: "center", justifyContent: "center", borderRadius: 8, borderColor: "transparent", }, content: { flexDirection: "row", alignItems: "center", }, iconContainer: { alignItems: "center", justifyContent: "center", }, text: { fontWeight: "600", }, }); export default IconButton;