90 lines
3.0 KiB
TypeScript
90 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import ReactMarkdown from "react-markdown";
|
|
import remarkGfm from "remark-gfm";
|
|
|
|
type MarkdownContentProps = {
|
|
content: string;
|
|
className?: string;
|
|
};
|
|
|
|
export function MarkdownContent({ content, className = "" }: MarkdownContentProps) {
|
|
return (
|
|
<article
|
|
className={`markdown-content text-[var(--foreground)] ${className}`}
|
|
>
|
|
<ReactMarkdown
|
|
remarkPlugins={[remarkGfm]}
|
|
components={{
|
|
h1: ({ children }) => (
|
|
<h1 className="mb-4 mt-8 border-b border-[var(--border)] pb-2 text-2xl font-bold first:mt-0 sm:text-3xl">
|
|
{children}
|
|
</h1>
|
|
),
|
|
h2: ({ children }) => (
|
|
<h2 className="mb-3 mt-6 text-xl font-semibold sm:text-2xl">{children}</h2>
|
|
),
|
|
h3: ({ children }) => (
|
|
<h3 className="mb-2 mt-4 text-lg font-semibold sm:text-xl">{children}</h3>
|
|
),
|
|
p: ({ children }) => <p className="mb-4 leading-7">{children}</p>,
|
|
ul: ({ children }) => (
|
|
<ul className="mb-4 list-disc space-y-1 pl-6">{children}</ul>
|
|
),
|
|
ol: ({ children }) => (
|
|
<ol className="mb-4 list-decimal space-y-1 pl-6">{children}</ol>
|
|
),
|
|
li: ({ children }) => <li className="leading-7">{children}</li>,
|
|
code: ({ className: codeClassName, children }) => {
|
|
const isBlock = codeClassName?.includes("language-");
|
|
if (isBlock) {
|
|
return (
|
|
<pre className="mb-4 overflow-x-auto rounded-lg border border-[var(--border)] bg-[var(--muted)] p-4 text-sm">
|
|
<code className={codeClassName}>{children}</code>
|
|
</pre>
|
|
);
|
|
}
|
|
return (
|
|
<code className="rounded bg-[var(--muted)] px-1.5 py-0.5 font-mono text-sm">
|
|
{children}
|
|
</code>
|
|
);
|
|
},
|
|
blockquote: ({ children }) => (
|
|
<blockquote className="border-l-4 border-[var(--accent)] pl-4 italic text-[var(--muted-foreground)]">
|
|
{children}
|
|
</blockquote>
|
|
),
|
|
a: ({ href, children }) => (
|
|
<a
|
|
href={href}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="text-[var(--accent)] underline hover:opacity-80"
|
|
>
|
|
{children}
|
|
</a>
|
|
),
|
|
table: ({ children }) => (
|
|
<div className="mb-4 overflow-x-auto">
|
|
<table className="min-w-full border-collapse border border-[var(--border)]">
|
|
{children}
|
|
</table>
|
|
</div>
|
|
),
|
|
th: ({ children }) => (
|
|
<th className="border border-[var(--border)] bg-[var(--muted)] px-4 py-2 text-left font-semibold">
|
|
{children}
|
|
</th>
|
|
),
|
|
td: ({ children }) => (
|
|
<td className="border border-[var(--border)] px-4 py-2">{children}</td>
|
|
),
|
|
}}
|
|
>
|
|
{content}
|
|
</ReactMarkdown>
|
|
</article>
|
|
);
|
|
}
|