Experience System
Components

Image

Displays a thumbnail that expands to a full-size image—either in a hover popover (overlay mode) or a modal dialog (full-screen mode).

Sample landscape

Installation

The component is exported from @by/experience-system. Add the package with your package manager:

pnpm add @by/experience-system

In this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.

Composition

Image is a single self-contained component—no sub-parts are exported. The internal structure differs by mode:

Image (mode="overlay")
└── Popover (thumbnail anchor → full-size popover on hover/focus)

Image (mode="full-screen")
└── trigger div (thumbnail + hover overlay icon)
└── Dialog (full-size image in modal on click)

Image uses Radix Popover in overlay mode and Radix Dialog in full-screen mode. A Skeleton is rendered in place of both images when loading={true}.

Usage

import { Image } 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 focusing) the thumbnail shows the full image in a popover:

<Image
  mode="overlay"
  chipImage="/path/to/thumb.jpg"
  fullImage="/path/to/large.jpg"
  chipAlt="Product thumbnail"
  chipWidth={60}
  chipHeight={60}
  fullWidth={400}
  fullHeight={300}
/>

Full-screen mode

Clicking the thumbnail opens the full image in a modal dialog. An aria-label is required to name the interactive trigger:

<Image
  mode="full-screen"
  chipImage="/path/to/thumb.jpg"
  fullImage="/path/to/large.jpg"
  chipAlt="Product image"
  aria-label="Open full-size product image"
  chipWidth={60}
  chipHeight={60}
  fullWidth={800}
  fullHeight={600}
/>

Examples

Overlay

Hover over a thumbnail to reveal the full image in a popover. This mode is suited for data tables and grids where the user scans many rows.

Product thumbnail
Second product thumbnail

Full-screen

Click the thumbnail to open the full image in a modal dialog. A maximize icon appears on hover. Use this mode when the user needs to inspect fine detail.

Full-screen preview

Loading skeleton

Pass loading={true} while the image URL is being fetched. The skeleton inherits the chipWidth and chipHeight dimensions.

API Reference

Image is a Experience System-authored component. There is no upstream Radix primitive page for the combined API; behavior of the internal Popover and Dialog follows Radix Popover and Radix Dialog respectively.

Image

The single exported component. The accepted props depend on the mode discriminant.

Common props (both modes):

PropTypeDefault
mode'overlay' | 'full-screen'— (required)
chipImagestring— (required)
fullImagestring— (required)
chipAltstring''
chipWidthnumber60
chipHeightnumber60
fullWidthnumber120 (overlay) / 800 (full-screen)
fullHeightnumber120 (overlay) / 600 (full-screen)
loadingbooleanfalse
dataTestIdstring'lui-ccl-image'
classNamestring

mode="full-screen" additional prop:

PropTypeDefault
aria-labelstring— (required in full-screen mode)
Data attributeValues
data-slotimage (root), image-chip (thumbnail <img>), image-skeleton (loading state), image-overlay-popover (overlay popover content), image-full (overlay full <img>), image-hover-overlay (full-screen hover overlay div), image-maximize-icon (full-screen maximize icon), image-dialog-overlay (full-screen dialog backdrop), image-dialog-content (full-screen dialog content), image-dialog-full (full-screen full <img>)

Accessibility

Image handles accessibility at two levels depending on mode:

  • Overlay — The thumbnail is a plain <img> (with alt from chipAlt). The popover is opened on mouseenter / focus and is aria-hidden from keyboard navigation (onOpenAutoFocus is suppressed). Provide a meaningful chipAlt for screen readers.
  • Full-screen — The thumbnail wrapper has role="button", tabIndex={0}, and an aria-label (required prop). The dialog includes a visually-hidden <DialogTitle> ("Full-size image") and <DialogDescription> (falls back to chipAlt). The close button has aria-label="Close". Keyboard: Enter or Space opens the dialog; Esc closes it (handled by Radix Dialog).

Underlying Radix behavior: Radix Popover accessibility and Radix Dialog accessibility.

Keyboard interactions

KeyDescription
Tab / Shift+TabMoves focus to the thumbnail trigger (full-screen) or to the next focusable element.
Enter / SpaceOpens the full-screen dialog when the trigger is focused.
EscCloses the full-screen dialog; focus returns to the trigger.

Source in the repo: packages/experience-system/src/components/Image/Image.tsx. Agent-oriented contracts: packages/experience-system/src/components/Image/Image.instructions.md.