import React, { useMemo } from 'react' import CarouselNav from './CarouselNav' import DownloadAction from './DownloadAction' import { filenameFromUrl } from './fileMeta' import { useCarousel } from './useCarousel' import ViewerShell from './ViewerShell' export interface ImageViewerItem { src: string alt?: string /** * Filename used by the download action and as the dialog's * accessible name. Falls back to the last pathname segment of * `src` when omitted. */ filename?: string } export interface ImageViewerProps { open: boolean items: ImageViewerItem[] /** Index to display when the viewer first opens. Defaults to `0`. */ initialIndex?: number onClose: () => void } /** * Native lightbox-style image viewer — full-viewport `` with * the image centered at reasonable max dimensions, a single close * button, and a download action in the chrome. * * When `items.length > 1` the viewer becomes a carousel: * * - Prev / next on-screen controls hug the viewport sides. * - `ArrowLeft` / `ArrowRight` step between siblings (the keyboard * listener is parked while a `