import { useEffect, type ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import { Maximize2, Minimize2, X } from 'lucide-react'; import type { PreviewFullscreen } from '../hooks/usePreviewFullscreen'; // One size for every file preview (#2976). Each modal used to carry its own // max-width (4xl/5xl/6xl at 80-85vh), which left most of a wide screen empty // for a window the user opened precisely to look at something closely. // min() keeps the panel off the edges on a laptop and stops it stretching to // a wall of pixels on an ultrawide. export const PREVIEW_PANEL_SIZE_CLASS = 'w-[min(1800px,96vw)] h-[94vh]'; // Header icon buttons of every preview. export const previewIconButtonClass = 'p-1.5 rounded hover:bg-bambu-dark text-bambu-gray hover:text-white transition-colors'; interface PreviewModalShellProps { title: string; fullscreen: PreviewFullscreen; onClose: () => void; /** Type icon left of the title. */ icon?: ReactNode; /** Rendered after the title, e.g. the 3D viewer's object-count badge. */ titleExtra?: ReactNode; /** This preview's own header buttons, left of the fullscreen/close pair. */ actions?: ReactNode; /** The 3D viewer closes on a backdrop click; the document previews do not. */ closeOnBackdropClick?: boolean; /** Panel content: tabs, body and footers, as direct flex children. */ children: ReactNode; } /** * Backdrop, panel sizing and header row shared by every file preview (#2976). * * Esc closes the modal, except while the browser owns it: in fullscreen Esc * leaves fullscreen and the preview stays open. Double-click-to-fullscreen is * wired by each modal on its own content area, because only the modal knows * which part of the panel is the preview. */ export function PreviewModalShell({ title, fullscreen, onClose, icon, titleExtra, actions, closeOnBackdropClick, children, }: PreviewModalShellProps) { const { t } = useTranslation(); const { panelRef, isFullscreen, toggleFullscreen } = fullscreen; useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape' && !document.fullscreenElement) onClose(); }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [onClose]); return (