Image
Compound thumbnail preview — hover card in overlay mode or dialog in full-screen mode.
Image is a compound component: compose ImageThumbnail, ImageFull, and optional ImageSkeleton under a root with mode="overlay" or mode="full-screen". Overlay mode uses DS HoverCard; full-screen mode uses DS Dialog.
Installation
The component is exported from @by/experience-system. Add the package with your package manager:
pnpm add @by/experience-systemIn this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.
Composition
Image (mode="overlay" | "full-screen")
├── ImageThumbnail — thumbnail shown as the trigger
├── ImageFull — full-size image in hover card or dialog
└── ImageSkeleton — loading placeholder (required when loading={true})Usage
import { Image, ImageThumbnail, ImageFull, ImageSkeleton } from '@by/experience-system';Image is a client component ('use client'). Use it inside a Client Component or a dynamic import when using the Next.js App Router.
Overlay mode
Hovering (or tapping on touch devices) the thumbnail shows the full image in a hover card. Set placement on Image:
<Image mode="overlay" align="center" side="start" sideOffset={16}>
<ImageThumbnail src="/thumb.jpg" alt="Product thumbnail" className="size-15" />
<ImageFull
src="/large.jpg"
className="h-60 w-80 max-h-[80dvh] max-w-full"
/>
<ImageSkeleton className="size-15" />
</Image>Optional openDelay and closeDelay on Image tune hover card timing.
Full-screen mode
Clicking the thumbnail opens the full image in a modal dialog. An aria-label is required on Image:
<Image mode="full-screen" aria-label="Open full-size product image">
<ImageThumbnail src="/thumb.jpg" alt="Product image" className="size-15" />
<ImageFull src="/large.jpg" className="max-h-[80dvh] max-w-full" />
<ImageSkeleton className="size-15" />
</Image>Size images with className (Tailwind utilities such as size-15, w-10 h-10).
Examples
Overview
Hover the thumbnail to preview the full image in a hover card. Tune align, side, and sideOffset on Image.
Full-screen
Click the thumbnail to open the full image in a dialog. A maximize icon appears on hover.
Loading
Pass loading={true} on Image while URLs resolve. Include an ImageSkeleton child sized to match the thumbnail.
API Reference
Image
Root container. Props depend on the mode discriminant.
Common props (both modes):
| Prop | Type | Default |
|---|---|---|
mode | 'overlay' | 'full-screen' | — (required) |
loading | boolean | false |
dataTestId | string | 'by-es-image' |
className | string | — |
children | ReactNode | — (required) |
mode="overlay" additional props:
| Prop | Type | Default |
|---|---|---|
openDelay | number | 0 |
closeDelay | number | 0 |
align | 'start' | 'center' | 'end' | 'start' |
side | 'bottom' | 'top' | 'start' | 'end' | 'bottom' |
sideOffset | number | 4 |
alignOffset | number | — |
mode="full-screen" additional prop:
| Prop | Type | Default |
|---|---|---|
aria-label | string | — (required) |
ImageThumbnail
| Prop | Type | Default |
|---|---|---|
src | string | — (required) |
alt | string | '' |
className | string | — |
Forwards standard <img> attributes.
ImageFull
| Prop | Type | Default |
|---|---|---|
src | string | — (required) |
alt | string | '' |
className | string | — |
Forwards standard <img> attributes.
ImageSkeleton
| Prop | Type | Default |
|---|---|---|
className | string | — |
Wraps DS Skeleton. Use className for dimensions. Accepts data-testid for testing.
| Data attribute | Values |
|---|---|
data-slot | image (root), image-thumbnail, image-full, image-skeleton, image-overlay-hover-card, image-hover-overlay, image-maximize-icon, image-dialog-content, image-dialog-full |
Accessibility
- Overlay — Radix
HoverCardopens on hover and focus; tap toggles on touch devices. Provide meaningfulalttext onImageThumbnail. - Full-screen — The trigger has
aria-label(required onImage). The dialog includes sr-onlyDialogTitleandDialogDescription. Keyboard: Enter/Space opens; Esc closes (Radix Dialog).
Keyboard interactions
| Key | Description |
|---|---|
Tab / Shift+Tab | Moves focus to the thumbnail trigger. |
Enter / Space | Opens full-screen dialog when the trigger is focused. |
Esc | Closes the full-screen dialog. |
Source in the repo: packages/experience-system/src/components/Image/Image.tsx. Agent-oriented contracts: packages/experience-system/src/components/Image/Image.instructions.md.