'use client'; import React, { useState } from 'react'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import rehypeSanitize from 'rehype-sanitize'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; import { Copy, Check, Terminal, ExternalLink } from 'lucide-react'; import { clsx } from 'clsx'; import rehypeSlug from 'rehype-slug'; interface MarkdownRendererProps { content: string; } export default function MarkdownRenderer({ content }: MarkdownRendererProps) { return (
); } return ( {children} ); }, // 2. 인용구 blockquote({ children }) { return (
{children}
); }, // 3. 링크 a({ href, children }) { const isExternal = href?.startsWith('http'); return ( {children} {isExternal && } ); }, // 4. 테이블 table({ children }) { return (
{children}
); }, thead({ children }) { return {children}; }, th({ children }) { return {children}; }, td({ children }) { return {children}; }, // 5. 이미지 (비율 유지 및 중앙 정렬) img({ src, alt }) { return ( // 🛠️ [Fix] flex-col 추가: 이미지와 캡션을 세로로 정렬 // items-center 추가: 가로축 중앙 정렬 {alt} { e.currentTarget.style.display = 'none'; }} /> {alt && {alt}} ); }, // 6. 리스트 스타일 ul({ children }) { return ; }, ol({ children, ...props }: any) { return (
    {children}
); }, li({ children }) { return
  • {children}
  • ; }, // 7. 헤딩 스타일 (🛠️ 수정: ...props를 전달해야 id가 붙어서 목차 이동이 작동함) h1({ children, ...props }: any) { return

    {children}

    ; }, h2({ children, ...props }: any) { return

    {children}

    ; }, h3({ children, ...props }: any) { return

    {children}

    ; }, }} > {content}
    ); } // 코드 블록 컴포넌트 function CodeBlock({ language, code }: { language: string; code: string }) { const [isCopied, setIsCopied] = useState(false); const handleCopy = () => { navigator.clipboard.writeText(code); setIsCopied(true); setTimeout(() => setIsCopied(false), 2000); }; return (
    {language && (
    {language}
    )}
    {code}
    ); }