import { useEffect, useRef } from 'react' import { createPortal } from 'react-dom' import { IconCloseOutline16 } from '@deepseek-ai/dsh-client-ui-primitives' import css from './ImageLightbox.module.css' /** Lightbox strings the owner resolves from its own locale namespace. */ export interface ImageLightboxLabels { /** Accessible name of the preview dialog. */ dialog: string /** Accessible label of the close control. */ close: string } /** * Document-level original-image preview opened by clicking a thumbnail. * Closes on Escape, backdrop press, or the close control, and restores focus * to the opener on unmount. Rendered through a body portal: an opener inside * a transformed or filtered ancestor would otherwise trap the fixed backdrop * in that ancestor's box instead of covering the viewport. * * @param props.src - the original image URL. * @param props.alt - the image's alt text. * @param props.labels - dialog and close-control strings. * @param props.onClose - dismiss callback owned by the opener. * @returns the modal preview dialog. */ export function ImageLightbox({ src, alt, labels, onClose }: { src: string alt: string labels: ImageLightboxLabels onClose: () => void }) { const closeRef = useRef(null) const restoreRef = useRef(null) useEffect(() => { restoreRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null closeRef.current?.focus() const onKeyDown = (event: globalThis.KeyboardEvent): void => { if (event.key === 'Escape') onClose() } window.addEventListener('keydown', onKeyDown) return () => { window.removeEventListener('keydown', onKeyDown) restoreRef.current?.focus() } }, [onClose]) return createPortal(
, document.body, ) }