Skip to content
Sign in
FramesAnnotated screenshotMenu

Annotated screenshotPro

A screenshot with numbered callouts and notes that point at each other, with a dimmed spotlight on the part being described.

ProA tour of the live chatcn app with four callouts. Point at a note or a marker and the other lights up; select one and the rest dims.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/annotated-screenshot

Usage

tsx
import { AnnotatedScreenshot } from "@/components/ui/chatcn/pro/annotated-screenshot"

<AnnotatedScreenshot
  src="/screens/chat.png"
  aspectRatio={16 / 10}
  callouts={[
    { id: "tools", x: 0.3, y: 0.36, title: "Every tool call", description: "…", region: { x: 0.32, y: 0.27, w: 0.56, h: 0.19 } },
  ]}
/>

Markers sit at fractions of the screenshot, so they stay on target at any width. The screenshot is an image or live UI: children lay out at viewport (1280 x 800 by default) and scale to fit, like the device frames. Point at a marker or a note and the other lights up; select one with a region and everything around it dims.

Examples

Markers only

With notes="none" each marker opens its note as a card beside it, on the side with more room.

ProEach marker opens its note as a card beside it, on the side with more room.

Phone screenshot and direction

A narrow screenshot with imageClassName for its width and a caption. In a right to left page the notes move to the other side, while the screenshot keeps its own direction: a screenshot never mirrors.

ProA phone screenshot with notes beside it and a caption, at its real phone layout.

Props

PropTypeNotes
calloutsAnnotatedCallout[]id, x, y (0 to 1), title, description, region
src / altstringAn image screenshot
childrenReactNodeLive UI instead of an image
viewport{ width, height }The size children lay out at. Default 1280 x 800
aspectRationumberWidth over height. Defaults to the viewport's
notes"side" | "below" | "none"Side stacks under 720 px. Default side
activestring | nullControlled. defaultActive and onActiveChange
captionReactNodeA caption under the figure
imageClassNamestringFor example a max width for a phone screenshot

Keyboard

KeyAction
TabMoves through the notes, or through the markers when there are no notes
Enter / SpaceSelects or clears a callout
EscapeClears the selection

Accessibility

  • Notes are toggle buttons in an ordered list; their names start with the number you see.
  • With notes, the markers are a pointer shortcut and stay out of the tab order and the accessibility tree, so nothing is read twice. Without notes they are the path and take focus; the open card is linked to its marker.
  • Markers are 24 px with a 32 px hit area.

Motion

  • The dim fades in 200 ms. Under reduced motion it is 100 ms.
  • A card opened by a pointer scales in from 0.96 at its marker's side in 180 ms; opened from the keyboard it appears at once.