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;