'use client'; import { cn } from '@/lib/cn'; import { Check, Copy, Maximize2 } from 'lucide-react'; import { useEffect, useState } from "react"; import { codeToHtml } from "shiki"; type CompactCodeblockProps = { code: string, language?: string, maxHeight?: string, className?: string, } export function CompactCodeblock({ code, language = 'tsx', maxHeight = '200px', className }: CompactCodeblockProps) { const [highlightedCode, setHighlightedCode] = useState(""); const [isExpanded, setIsExpanded] = useState(false); const [copied, setCopied] = useState(false); const [isLoading, setIsLoading] = useState(true); // Update syntax highlighted code when code changes useEffect(() => { let isCancelled = false; const highlightCode = async () => { try { const html = await codeToHtml(code, { lang: language, theme: 'github-dark-default', }); if (!isCancelled) { setHighlightedCode(html); } } catch (error) { console.error('Error highlighting code:', error); if (!isCancelled) { // Fallback to plain text wrapped in
          setHighlightedCode(`
${code}
`); } } finally { if (!isCancelled) { setIsLoading(false); } } }; // eslint-disable-next-line no-restricted-syntax highlightCode().catch((error) => { console.error('Error highlighting code:', error); }); return () => { isCancelled = true; }; }, [code, language]); const handleCopy = () => { // eslint-disable-next-line no-restricted-syntax void navigator.clipboard.writeText(code).then(() => { setCopied(true); setTimeout(() => setCopied(false), 2000); }).catch((error) => { console.error('Failed to copy:', error); }); }; if (isLoading) { return (
{language}
); } return (
{/* Header */}
{language}
{/* Code content */}
{/* Fade overlay when collapsed and content overflows */} {!isExpanded && (
)}
); }