feat: add Markdown component

This commit is contained in:
Paul Pan 2024-03-15 16:00:17 +08:00
parent 21e5244807
commit 8cb5f37308
4 changed files with 1173 additions and 50 deletions

View File

@ -23,11 +23,19 @@
"@emotion/styled": "^11.11.0",
"@reduxjs/toolkit": "^2.2.1",
"framer-motion": "^11.0.13",
"github-markdown-css": "^5.5.1",
"prism-react-renderer": "^2.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.0.1",
"react-markdown": "^9.0.1",
"react-redux": "^9.1.0",
"react-router-dom": "^6.22.3"
"react-router-dom": "^6.22.3",
"rehype-mathjax": "^6.0.0",
"rehype-raw": "^7.0.0",
"remark-emoji": "^4.0.1",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0"
},
"devDependencies": {
"@types/react": "^18.2.66",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
.react-markdown {
padding: 16px;
}

View File

@ -0,0 +1,66 @@
import { Code } from "@chakra-ui/react";
import ReactMarkdown from "react-markdown";
import { Highlight, themes } from "prism-react-renderer";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import emoji from "remark-emoji";
import rehypeRaw from "rehype-raw";
import rehypeMathJaxSvg from "rehype-mathjax";
import "github-markdown-css";
import "./Markdown.css";
interface MarkdownProps {
markdown: string;
}
export default function Markdown(props: MarkdownProps) {
const remarkPlugins = [remarkGfm, emoji, remarkMath];
const rehypePlugins = [rehypeRaw, rehypeMathJaxSvg];
return (
<>
<ReactMarkdown
className={"markdown-body react-markdown"}
remarkPlugins={remarkPlugins}
rehypePlugins={rehypePlugins}
components={{
code({ className, children }) {
const inline = className == undefined;
const match = /language-(\w+)/.exec(className || "");
const lang = (match || ["", "text"])[1];
const code = String(children).replace(/\n$/, "");
const codeBlock = (
<Highlight language={lang} code={code} theme={themes.okaidia}>
{({ style, tokens, getLineProps, getTokenProps }) => (
<Code
padding={2}
rounded="md"
display="block"
whiteSpace="pre"
backgroundColor={style.backgroundColor}
overflow="auto"
>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({ line })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token })} />
))}
</div>
))}
</Code>
)}
</Highlight>
);
const codeInline = <Code>{children}</Code>;
return !inline && match ? codeBlock : codeInline;
},
}}
>
{props.markdown}
</ReactMarkdown>
</>
);
}