'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 (
);
},
thead({ children }) {
return
{children};
},
th({ children }) {
return
{children} | ;
},
td({ children }) {
return
{children} | ;
},
// 5. 이미지 (비율 유지 및 중앙 정렬)
img({ src, alt }) {
return (
// 🛠️ [Fix] flex-col 추가: 이미지와 캡션을 세로로 정렬
// items-center 추가: 가로축 중앙 정렬
{
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 (