Client component
Image
Images with aspect ratios, captions, error fallbacks, and a built-in lightbox.
"use client";
import { Image, Box } from "astralis-ui";
export function ImageDemo() {
return (
<Box w="full" maxW="xs">
<Image
src="/placeholder.svg"
alt="A starfield gradient"
aspectRatio="video"
rounded="xl"
caption="Captions wrap the image in a semantic figure."
/>
</Box>
);
}aspectRatio
objectFit
rounded
loading
import { Image } from "astralis-ui";
<Image
src="/placeholder.svg"
alt="A starfield gradient"
width={320}
/>
Import#
import { Image } from "astralis-ui";
// Image.Group for galleriesPreview lightbox#
preview makes the image click-to-zoom. The lightbox supports zoom, rotate
and keyboard dismissal, with arrow-key navigation inside an Image.Group.
Click the image to preview
"use client";
import { Image, Text, VStack, Box } from "astralis-ui";
export function ImagePreview() {
return (
<VStack gap="2" alignItems="start">
<Box w="56">
{/* Click to open the built-in lightbox (zoom, rotate, Esc to close). */}
<Image src="/placeholder.svg" alt="Preview me" aspectRatio="video" rounded="lg" preview />
</Box>
<Text size="xs" color="muted">Click the image to preview</Text>
</VStack>
);
}Error fallbacks#
"use client";
import { Image, HStack, Text } from "astralis-ui";
export function ImageFallback() {
return (
<HStack gap="4" wrap="wrap" justifyContent="center">
{/* A broken src falls back to the default icon… */}
<Image src="/does-not-exist.png" alt="Broken" width={140} height={90} rounded="lg" />
{/* …or to whatever you pass as fallback. */}
<Image
src="/also-missing.png"
alt="Broken with custom fallback"
width={140}
height={90}
rounded="lg"
fallback={<Text size="sm" color="muted">No image</Text>}
/>
</HStack>
);
}Props#
| Prop | Type | Default | Description |
|---|---|---|---|
src / alt | string | None | Source and alternative text. Both required. |
aspectRatio | "square" | "video" | "portrait" | "wide" | CSS ratio | None | Locks the frame to 1/1, 16/9, 3/4, 21/9, or any CSS ratio such as "4/3". |
objectFit | "cover" | "contain" | "fill" | "none" | "scale-down" | "cover" | How the image fills its frame. |
rounded | "none" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "full" | "none" | Corner radius. |
width / height | number | string | None | The img element's intrinsic size attributes, which reserve space before it loads. |
loading | "lazy" | "eager" | "lazy" | Native lazy loading. |
placeholder | "blur" | "empty" | URL | "empty" | A shimmer, nothing, or a low-resolution image shown while loading. |
srcset / sizes | string | None | Responsive image sources, passed to the img element. |
fallback | ReactNode | icon | Rendered when the image fails to load. |
caption | ReactNode | None | Wraps the image in a figure with this figcaption. |
preview | boolean | false | Opens a lightbox with zoom and rotate on click. |
onLoad / onError | () => void | None | Fire when the image loads or fails. |
ariaLabel | string | None | aria-label for the img element. |
Image.Group#
| Prop | Type | Default | Description |
|---|---|---|---|
items | { src, alt, caption? }[] | None | The gallery images. Required. |
columns | 2 | 3 | 4 | 3 | Grid columns. |
gap | "sm" | "md" | "lg" | "md" | Space between images. |
rounded | "none" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "full" | "md" | Corner radius of every image. |
objectFit | "cover" | "contain" | "fill" | "none" | "scale-down" | "cover" | How every image fills its cell. |
Keyboard#
With the preview lightbox open:
| Key | Action |
|---|---|
Esc | Close the lightbox |
← / → | Previous / next image (inside an Image.Group) |