feat: add Markdown component
This commit is contained in:
parent
21e5244807
commit
8cb5f37308
10
package.json
10
package.json
@ -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",
|
||||
|
1144
pnpm-lock.yaml
1144
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
3
src/components/Markdown.css
Normal file
3
src/components/Markdown.css
Normal file
@ -0,0 +1,3 @@
|
||||
.react-markdown {
|
||||
padding: 16px;
|
||||
}
|
66
src/components/Markdown.tsx
Normal file
66
src/components/Markdown.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user