1
1
import Link from "@material-ui/core/Link"
2
- import { makeStyles, Theme, useTheme } from "@material-ui/core/styles"
2
+ import { makeStyles } from "@material-ui/core/styles"
3
3
import Table from "@material-ui/core/Table"
4
4
import TableBody from "@material-ui/core/TableBody"
5
5
import TableCell from "@material-ui/core/TableCell"
6
6
import TableContainer from "@material-ui/core/TableContainer"
7
7
import TableHead from "@material-ui/core/TableHead"
8
8
import TableRow from "@material-ui/core/TableRow"
9
- import { FC } from "react"
9
+ import React, { FC } from "react"
10
10
import ReactMarkdown from "react-markdown"
11
- import SyntaxHighlighter from "react-syntax-highlighter"
12
- import { dracula as dark } from "react-syntax-highlighter/dist/cjs/styles/hljs"
11
+ import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
13
12
import gfm from "remark-gfm"
13
+ import { colors } from "theme/colors"
14
+ import darcula from "react-syntax-highlighter/dist/cjs/styles/prism/darcula"
14
15
15
16
export interface MarkdownProps {
16
17
children: string
17
18
}
18
19
19
20
export const Markdown: FC<{ children: string }> = ({ children }) => {
20
- const theme: Theme = useTheme()
21
21
const styles = useStyles()
22
22
23
23
return (
24
24
<ReactMarkdown
25
+ className={styles.markdown}
25
26
remarkPlugins={[gfm]}
26
27
components={{
27
28
a: ({ href, target, children }) => (
@@ -30,22 +31,27 @@ export const Markdown: FC<{ children: string }> = ({ children }) => {
30
31
</Link>
31
32
),
32
33
34
+ pre: ({ node, children }) => {
35
+ const firstChild = node.children[0]
36
+ // When pre is wrapping a code, the SyntaxHighlighter is already going
37
+ // to wrap it with a pre so we don't need it
38
+ if (firstChild.type === "element" && firstChild.tagName === "code") {
39
+ return <>{children}</>
40
+ }
41
+ return <pre>{children}</pre>
42
+ },
43
+
33
44
code: ({ node, inline, className, children, ...props }) => {
34
45
const match = /language-(\w+)/.exec(className || "")
46
+
35
47
return !inline && match ? (
36
48
<SyntaxHighlighter
37
- // Custom style to match our main colors
38
- style={{
39
- ...dark,
40
- hljs: {
41
- ...dark.hljs,
42
- background: theme.palette.background.default,
43
- borderRadius: theme.shape.borderRadius,
44
- color: theme.palette.text.primary,
45
- },
46
- }}
49
+ style={darcula}
47
50
language={match[1]}
48
- PreTag="div"
51
+ useInlineStyles={false}
52
+ // Use inline styles does not work correctly
53
+ // https://github.com/react-syntax-highlighter/react-syntax-highlighter/issues/329
54
+ codeTagProps={{ style: {} }}
49
55
{...props}
50
56
>
51
57
{String(children).replace(/\n$/, "")}
@@ -91,12 +97,50 @@ export const Markdown: FC<{ children: string }> = ({ children }) => {
91
97
)
92
98
}
93
99
100
+ export const MemoizedMarkdown = React.memo(Markdown)
101
+
94
102
const useStyles = makeStyles((theme) => ({
103
+ markdown: {
104
+ fontSize: 16,
105
+ lineHeight: "24px",
106
+
107
+ "& h1, & h2, & h3, & h4, & h5, & h6": {
108
+ marginTop: theme.spacing(4),
109
+ marginBottom: theme.spacing(2),
110
+ lineHeight: "1.25",
111
+ },
112
+
113
+ "& p": {
114
+ marginTop: 0,
115
+ marginBottom: theme.spacing(2),
116
+ },
117
+
118
+ "& ul, & ol": {
119
+ display: "flex",
120
+ flexDirection: "column",
121
+ gap: theme.spacing(1),
122
+ },
123
+
124
+ "& .prismjs": {
125
+ background: theme.palette.background.paperLight,
126
+ borderRadius: theme.shape.borderRadius,
127
+ padding: theme.spacing(2, 3),
128
+
129
+ "& code": {
130
+ color: theme.palette.text.secondary,
131
+ },
132
+
133
+ "& .key, & .property": {
134
+ color: colors.turquoise[7],
135
+ },
136
+ },
137
+ },
138
+
95
139
codeWithoutLanguage: {
96
- overflowX: "auto",
97
- padding: "0.5em",
98
- background: theme.palette.background.default,
99
- borderRadius: theme.shape.borderRadius,
140
+ padding: theme.spacing(0.5, 1),
141
+ background: theme.palette.divider,
142
+ borderRadius: 4,
100
143
color: theme.palette.text.primary,
144
+ fontSize: 14,
101
145
},
102
146
}))
0 commit comments