"use client" import * as React from "react" import { createPortal } from "react-dom" import { Button } from "@/components/ui/button" import { Kbd, KbdGroup } from "@/components/ui/kbd" import { Tip } from "@/components/ui/tip" import { cn } from "@/lib/utils" import type { ExamLockStemMedia } from "./exam-lock-delivery-types" export interface ExamLockStemFigureProps { media: ExamLockStemMedia className?: string } /** Full-viewport figure viewer — solid surface, native dialog focus trap. */ function ExamLockStemFigureViewer({ media, fullscreenSrc, open, onClose, }: { media: ExamLockStemMedia fullscreenSrc: string open: boolean onClose: () => void }) { const dialogRef = React.useRef(null) React.useEffect(() => { const dialog = dialogRef.current if (!dialog) return if (open) { if (!dialog.open) dialog.showModal() return } if (dialog.open) dialog.close() }, [open]) if (typeof document === "undefined") return null return createPortal( { event.preventDefault() onClose() }} >
{media.caption ? (

{media.caption}

) : ( {media.alt} )}
{media.alt}
, document.body, ) } /** Student-facing stem figure with expand / full-viewport viewer. */ export function ExamLockStemFigure({ media, className }: ExamLockStemFigureProps) { const [viewerOpen, setViewerOpen] = React.useState(false) const fullscreenSrc = media.fullscreenSrc ?? media.src const openViewerLabel = `View full size: ${media.alt}` const openViewer = React.useCallback(() => { setViewerOpen(true) }, []) const closeViewer = React.useCallback(() => { setViewerOpen(false) }, []) return ( <>