Skip to content
ContentImageMenu

Image

An image inside a message: holds its final size from the first paint, blurs up from a placeholder, fails gracefully and opens a full-screen lightbox.

A reference photo in an answer, with a blurred placeholder, caption and lightbox.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/image.json

Usage

tsx
import { Image } from "@/components/ui/chatcn/image"

<Image
  src="/uploads/facade.jpg"
  alt="A white modular facade with stacked, offset volumes"
  width={1200}
  height={1700}
  placeholder={tinyDataUrl}
  caption="Stacked volumes with deep reveals."
/>

Pass width and height (or aspectRatio) so the frame reserves the right space before the file arrives. Nothing below it moves when it loads.

Examples

Blur-up and error

With a placeholder, a tiny blurred version fills the frame and fades out when the real image has decoded. Without one, a plain fill holds the space. A failed load says so and offers Retry.

Replay the blur-up load, and the error state with retry.

Props

PropTypeNotes
srcstring
altstringRequired. Describe what the image shows
width, heightnumberIntrinsic size. Sets the aspect ratio of the frame
aspectRationumberWhen the size is unknown, for example 16 / 9
placeholderstringTiny image shown blurred while loading
captionReactNodeUnder the image and as the lightbox title
fit"contain" | "cover"Default contain
lightboxbooleanOpen full screen on click. Default true
downloadbooleanDownload action in the lightbox. Default true
onOpen() => voidReplace the built-in lightbox, for example with a shared gallery
prioritybooleanLoad eagerly above the fold
onStatusChange(status) => voidloading, loaded or error

ImageLightbox is exported too: pass images, index, onIndexChange, open and onOpenChange to show any set of images full screen.

Keyboard

KeyAction
Enter, SpaceOpen the lightbox
Left, RightPrevious and next image in a set (mirrored in right-to-left layouts)
EscClose the lightbox and return focus to the image

Accessibility

  • alt is required. The open button is labelled with it, so screen readers hear what opens.
  • The error state keeps the alt text and adds that the image could not load.
  • The lightbox is a modal dialog: focus moves in, is trapped, and returns to the image on close. Its title is the caption or the alt text.
  • Every image gets a 1 px inner hairline, kept as a real outline under forced colors.

Motion

  • The image fades in over 200 ms once decoded. Images already in the cache appear without a fade.
  • The lightbox opens with the dialog motion: 220 ms opacity and scale from 0.96, 160 ms out. Opened from the keyboard, it appears instantly.
  • Paging through a set swaps instantly. Under reduced motion only opacity changes.