// CRITICAL 'use client'; import { useId } from 'react'; import { Copy, Check, Play, Code2, Maximize2, Minimize2 } from 'lucide-react'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { vscDarkPlus, vs } from 'react-syntax-highlighter/dist/esm/styles/prism'; import { CodeSandbox } from './code-sandbox'; import { ArtifactRenderer, getArtifactType } from './artifact-renderer'; import { useAppStore } from '@/store'; interface EnhancedCodeBlockProps { children: string; className?: string; artifactsEnabled?: boolean; isStreaming?: boolean; language?: string; } export function EnhancedCodeBlock({ children, className, artifactsEnabled, isStreaming, language }: EnhancedCodeBlockProps) { const blockId = useId(); const blockState = useAppStore( (state) => state.codeBlockState[blockId] ?? { copied: false, showPreview: false, isExpanded: false, }, ); const updateCodeBlockState = useAppStore((state) => state.updateCodeBlockState); const { copied, showPreview, isExpanded } = blockState; const updateState = (partial: Partial) => { updateCodeBlockState(blockId, (prev) => ({ ...prev, ...partial })); }; const lang = language || className?.replace('language-', '') || 'text'; const code = String(children).replace(/\n$/, ''); const copyCode = () => { navigator.clipboard.writeText(code); updateState({ copied: true }); setTimeout(() => updateState({ copied: false }), 2000); }; // Check if this should be rendered as an artifact const artifactType = getArtifactType(lang); const canPreview = artifactsEnabled && artifactType && ['html', 'react', 'javascript', 'svg'].includes(artifactType); // If showing preview, render CodeSandbox if (showPreview && canPreview && artifactType) { if (artifactType === 'svg') { return (
); } return (
); } const lineCount = code.split('\n').length; const isLongCode = lineCount > 20; const shouldCollapse = isLongCode && !isExpanded; return (
{/* Header */}
{lang || 'code'} {isLongCode && ( {lineCount} lines )}
{canPreview && ( )} {isLongCode && ( )}
{/* Code */}
{code} {shouldCollapse && (
)}
); }