70 lines
3.2 KiB
TypeScript
70 lines
3.2 KiB
TypeScript
import ReactMarkdown from "react-markdown";
|
|
import remarkGfm from "remark-gfm";
|
|
|
|
export function MarkdownContent({ content }: { content: string }) {
|
|
return (
|
|
<div className="space-y-4 text-sm leading-7 text-gray-300 sm:text-base">
|
|
<ReactMarkdown
|
|
remarkPlugins={[remarkGfm]}
|
|
components={{
|
|
h1: ({ children }) => <h1 className="mt-8 text-3xl font-semibold text-white first:mt-0">{children}</h1>,
|
|
h2: ({ children }) => <h2 className="mt-8 text-2xl font-semibold text-white">{children}</h2>,
|
|
h3: ({ children }) => <h3 className="mt-6 text-xl font-semibold text-white">{children}</h3>,
|
|
p: ({ children }) => <p>{children}</p>,
|
|
ul: ({ children }) => <ul className="list-disc space-y-2 pl-6">{children}</ul>,
|
|
ol: ({ children }) => <ol className="list-decimal space-y-2 pl-6">{children}</ol>,
|
|
li: ({ children }) => <li>{children}</li>,
|
|
a: ({ href, children }) => (
|
|
<a
|
|
href={href}
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
className="text-white underline decoration-white/30 underline-offset-4 hover:decoration-white"
|
|
>
|
|
{children}
|
|
</a>
|
|
),
|
|
blockquote: ({ children }) => (
|
|
<blockquote className="border-l-2 border-white/20 pl-4 italic text-gray-400">{children}</blockquote>
|
|
),
|
|
img: ({ src, alt }) => (
|
|
// Markdown images should feel deliberate in the article layout.
|
|
<img
|
|
src={src || ""}
|
|
alt={alt || ""}
|
|
className="my-6 w-full rounded-2xl border border-white/10 bg-black/40 object-cover"
|
|
/>
|
|
),
|
|
table: ({ children }) => (
|
|
<div className="my-6 overflow-x-auto rounded-2xl border border-white/10">
|
|
<table className="min-w-full border-collapse text-left text-sm">{children}</table>
|
|
</div>
|
|
),
|
|
thead: ({ children }) => <thead className="bg-white/6 text-white">{children}</thead>,
|
|
tbody: ({ children }) => <tbody className="divide-y divide-white/10">{children}</tbody>,
|
|
tr: ({ children }) => <tr className="divide-x divide-white/10">{children}</tr>,
|
|
th: ({ children }) => <th className="px-4 py-3 font-semibold">{children}</th>,
|
|
td: ({ children }) => <td className="px-4 py-3 align-top text-gray-300">{children}</td>,
|
|
code: ({ className, children }) => {
|
|
const inline = !className;
|
|
if (inline) {
|
|
return <code className="rounded bg-white/8 px-1.5 py-0.5 font-mono text-[0.95em] text-white">{children}</code>;
|
|
}
|
|
|
|
return (
|
|
<code className="block overflow-x-auto rounded-2xl border border-white/10 bg-black/50 p-4 font-mono text-sm text-gray-200">
|
|
{children}
|
|
</code>
|
|
);
|
|
},
|
|
pre: ({ children }) => <pre>{children}</pre>,
|
|
hr: () => <hr className="border-white/10" />,
|
|
strong: ({ children }) => <strong className="font-semibold text-white">{children}</strong>,
|
|
}}
|
|
>
|
|
{content}
|
|
</ReactMarkdown>
|
|
</div>
|
|
);
|
|
}
|