import {useEffect,useMemo,useRef,useState} from 'react'; import {createPortal} from 'react-dom'; import {Check,Copy,Download,Maximize2,Minimize2,X} from 'lucide-react'; import {highlightPython} from './python-highlight'; type Props={code:string;error:string;url:string;id:string;version:string;onClose:()=>void}; export default function CodePanel({code,error,url,id,version,onClose}:Props){ const [copied,setCopied]=useState(false),[copyError,setCopyError]=useState(false),[expanded,setExpanded]=useState(false); const panel=useRef(null),expandButton=useRef(null); const collapse=()=>{setExpanded(false);requestAnimationFrame(()=>expandButton.current?.focus());}; useEffect(()=>{ if(!expanded)return; const app=document.querySelector('.app-shell'),wasInert=app?.inert; if(app)app.inert=true; panel.current?.querySelector('pre,button')?.focus(); const key=(e:KeyboardEvent)=>{ if(e.key==='Escape'){e.preventDefault();collapse();} if(e.key==='Tab'){ const nodes=Array.from(panel.current?.querySelectorAll('button:not(:disabled),a[href],pre[tabindex]')??[]),first=nodes[0],last=nodes.at(-1); if(e.shiftKey&&document.activeElement===first){e.preventDefault();last?.focus();} else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first?.focus();} } }; document.addEventListener('keydown',key);return()=>{document.removeEventListener('keydown',key);if(app)app.inert=wasInert??false;}; },[expanded]); const html=useMemo(()=>highlightPython(code),[code]); const copy=async()=>{try{await navigator.clipboard.writeText(code);setCopied(true);setCopyError(false);}catch{setCopied(false);setCopyError(true);}}; const content=

The program

Python · sand3d {version}{code?` · ${code.split('\n').length} lines`:''}

{copyError&&

Clipboard unavailable. Select the code below to copy it.

} {error?

{error}

:code?
:

Loading program…

}
; return expanded?createPortal(
{content}
,document.body):content; }