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 = / l a n g u a g e - ( \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