98 lines
3.1 KiB
TypeScript
98 lines
3.1 KiB
TypeScript
|
|
import ReactMarkdown from "react-markdown"
|
||
|
|
import remarkGfm from "remark-gfm"
|
||
|
|
import CodeBlock from "@/components/CodeBlock"
|
||
|
|
import remarkMath from "remark-math"
|
||
|
|
import rehypeKatex from "rehype-katex"
|
||
|
|
import "katex/dist/katex.min.css"
|
||
|
|
import { Skeleton } from "@/components/ui/skeleton"
|
||
|
|
|
||
|
|
const EntryLoadingSkeleton = () => {
|
||
|
|
return (
|
||
|
|
<div className="space-y-2 max-w-2xl p-4 lg:p-6">
|
||
|
|
{/*
|
||
|
|
|
||
|
|
<Skeleton className="h-[400px] md:h-[800px] max-w-2xl rounded-none" />
|
||
|
|
*/}
|
||
|
|
|
||
|
|
<Skeleton className="h-4 max-w-full" />
|
||
|
|
<Skeleton className="h-4 md:max-w-xl max-w-[300px]" />
|
||
|
|
<Skeleton className="h-4 md:max-w-[400px] max-w-[250px]" />
|
||
|
|
<Skeleton className="h-4 md:max-w-[300px] max-w-[200px]" />
|
||
|
|
<Skeleton className="h-4 md:max-w-[200px] max-w-[150px]" />
|
||
|
|
<Skeleton className="h-4 md:max-w-[100px] max-w-[100px]" />
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
export default function EntryBody({ body, isLoading }) {
|
||
|
|
if (isLoading) {
|
||
|
|
return <EntryLoadingSkeleton />
|
||
|
|
} else
|
||
|
|
return (
|
||
|
|
<div className="max-w-2xl p-4 lg:p-6">
|
||
|
|
<ReactMarkdown
|
||
|
|
remarkPlugins={[remarkGfm, remarkMath]}
|
||
|
|
rehypePlugins={[rehypeKatex]}
|
||
|
|
components={{
|
||
|
|
h1: () => null,
|
||
|
|
h2: ({ children }) => (
|
||
|
|
<h2 className="scroll-m-20 font-semibold mt-8 mb-4 first:mt-0">{children}</h2>
|
||
|
|
),
|
||
|
|
h3: ({ children }) => (
|
||
|
|
<h3 className="scroll-m-20 font-semibold mt-8 mb-4 first:mt-0">{children}</h3>
|
||
|
|
),
|
||
|
|
h4: ({ children }) => (
|
||
|
|
<h4 className="scroll-m-20 font-semibold mt-8 mb-4 first:mt-0">{children}</h4>
|
||
|
|
),
|
||
|
|
p: ({ children }) => (
|
||
|
|
<p className="leading-[1.5] mb-4 not-first:mt-4">{children}</p>
|
||
|
|
),
|
||
|
|
ul: ({ children }) => (
|
||
|
|
<ul className="list-disc ml-10 mb-4 space-y-1">{children}</ul>
|
||
|
|
),
|
||
|
|
ol: ({ children }) => (
|
||
|
|
<ol className="list-decimal ml-10 mb-4 space-y-1">{children}</ol>
|
||
|
|
),
|
||
|
|
a: ({ href, children }) => (
|
||
|
|
<a href={href} target="_blank" rel="noopener noreferrer">
|
||
|
|
{children}
|
||
|
|
</a>
|
||
|
|
),
|
||
|
|
table: ({ children }) => (
|
||
|
|
<table className="w-full mb-4 text-sm">{children}</table>
|
||
|
|
),
|
||
|
|
tr: ({ children }) => (
|
||
|
|
<tr className="even:bg-muted m-0 border-t p-0">{children}</tr>
|
||
|
|
),
|
||
|
|
th: ({ children }) => (
|
||
|
|
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
|
||
|
|
{children}
|
||
|
|
</th>
|
||
|
|
),
|
||
|
|
td: ({ children }) => (
|
||
|
|
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||
|
|
{children}
|
||
|
|
</td>
|
||
|
|
),
|
||
|
|
blockquote: ({ children }) => (
|
||
|
|
<blockquote className="mt-4 border-l-2 pl-6 text-muted-foreground">
|
||
|
|
{children}
|
||
|
|
</blockquote>
|
||
|
|
),
|
||
|
|
pre: ({ children }) => {
|
||
|
|
const child = children.props
|
||
|
|
return <CodeBlock className={child.className}>{child.children}</CodeBlock>
|
||
|
|
},
|
||
|
|
code: ({ children }) => (
|
||
|
|
<code className="rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||
|
|
{children}
|
||
|
|
</code>
|
||
|
|
),
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{body}
|
||
|
|
</ReactMarkdown>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|