Image
Image component with loading placeholder, error fallback, and rounded variants.
import { Image } from "@/components/ui/image";
<Image src="https://picsum.photos/400/300" alt="Sample" width={200} height={150} />Installation
npx @aniui/cli add imageRounded Variants
<Image src="https://picsum.photos/200/200" rounded="none" width={100} height={100} />
<Image src="https://picsum.photos/200/200" rounded="md" width={100} height={100} />
<Image src="https://picsum.photos/200/200" rounded="xl" width={100} height={100} />
<Image src="https://picsum.photos/200/200" rounded="full" width={100} height={100} />Error Fallback
When the image fails to load, a fallback message is shown. You can provide a custom fallback prop.

<Image
src="https://invalid-url.example.com/broken.png"
alt="Broken image"
width={200}
height={150}
/>Props
PropTypeDefault
srcstring—altstring—rounded"none" | "sm" | "md" | "lg" | "xl" | "full""md"widthnumber—heightnumber—fallbackReactNode—classNamestring—Source
components/ui/image.tsx
import React, { useState } from "react";
import { Image as RNImage, View, Text } from "react-native";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const imageVariants = cva("overflow-hidden bg-muted", {
variants: {
rounded: {
none: "",
sm: "rounded-sm",
md: "rounded-md",
lg: "rounded-lg",
xl: "rounded-xl",
full: "rounded-full",
},
},
defaultVariants: { rounded: "md" },
});
export interface ImageProps
extends Omit<React.ComponentPropsWithoutRef<typeof RNImage>, "source">,
VariantProps<typeof imageVariants> {
className?: string;
src: string;
alt?: string;
width?: number;
height?: number;
fallback?: React.ReactNode;
}
export function Image({ rounded, className, src, alt, width, height, fallback, style, ...props }: ImageProps) {
const [status, setStatus] = useState<"loading" | "loaded" | "error">("loading");
return (
<View className={cn(imageVariants({ rounded }), className)} style={[width && height ? { width, height } : undefined, style as object]}>
{status === "loading" && (
<View className="absolute inset-0 items-center justify-center bg-muted">
<View className="h-8 w-8 rounded-full bg-muted-foreground/10" />
</View>
)}
{status === "error" ? (
fallback ?? (
<View className="flex-1 items-center justify-center bg-muted">
<Text className="text-xs text-muted-foreground">Failed to load</Text>
</View>
)
) : (
<RNImage
source={{ uri: src }}
className="w-full h-full"
accessibilityLabel={alt}
onLoad={() => setStatus("loaded")}
onError={() => setStatus("error")}
{...props}
/>
)}
</View>
);
}