@@ -5,13 +5,14 @@ import TableCell from "@mui/material/TableCell";
5
5
import TableContainer from "@mui/material/TableContainer" ;
6
6
import TableHead from "@mui/material/TableHead" ;
7
7
import TableRow from "@mui/material/TableRow" ;
8
- import { FC , memo } from "react" ;
9
- import ReactMarkdown from "react-markdown" ;
8
+ import { type Interpolation , type Theme } from "@emotion/react" ;
9
+ import isEqual from "lodash/isEqual" ;
10
+ import { type FC , memo } from "react" ;
11
+ import ReactMarkdown , { type Options } from "react-markdown" ;
10
12
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter" ;
11
13
import gfm from "remark-gfm" ;
12
14
import { colors } from "theme/colors" ;
13
15
import { darcula } from "react-syntax-highlighter/dist/cjs/styles/prism" ;
14
- import { type Interpolation , type Theme } from "@emotion/react" ;
15
16
16
17
interface MarkdownProps {
17
18
/**
@@ -20,10 +21,15 @@ interface MarkdownProps {
20
21
children : string ;
21
22
22
23
className ?: string ;
24
+
25
+ /**
26
+ * Can override the behavior of the generated elements
27
+ */
28
+ components ?: Options [ "components" ] ;
23
29
}
24
30
25
31
export const Markdown : FC < MarkdownProps > = ( props ) => {
26
- const { children, className } = props ;
32
+ const { children, className, components = { } } = props ;
27
33
28
34
return (
29
35
< ReactMarkdown
@@ -106,14 +112,74 @@ export const Markdown: FC<MarkdownProps> = (props) => {
106
112
th : ( { children } ) => {
107
113
return < TableCell > { children } </ TableCell > ;
108
114
} ,
115
+
116
+ ...components ,
117
+ } }
118
+ >
119
+ { children }
120
+ </ ReactMarkdown >
121
+ ) ;
122
+ } ;
123
+
124
+ interface MarkdownInlineProps {
125
+ /**
126
+ * The Markdown text to parse and render
127
+ */
128
+ children : string ;
129
+
130
+ className ?: string ;
131
+
132
+ /**
133
+ * Can override the behavior of the generated elements
134
+ */
135
+ components ?: Options [ "components" ] ;
136
+ }
137
+
138
+ /**
139
+ * Supports a strict subset of Markdown that bahaves well as inline/confined content.
140
+ */
141
+ export const InlineMarkdown : FC < MarkdownInlineProps > = ( props ) => {
142
+ const { children, className, components = { } } = props ;
143
+
144
+ return (
145
+ < ReactMarkdown
146
+ className = { className }
147
+ allowedElements = { [ "p" , "em" , "strong" , "a" , "pre" , "code" ] }
148
+ unwrapDisallowed
149
+ components = { {
150
+ p : ( { children } ) => < > { children } </ > ,
151
+
152
+ a : ( { href, target, children } ) => (
153
+ < Link href = { href } target = { target } >
154
+ { children }
155
+ </ Link >
156
+ ) ,
157
+
158
+ code : ( { node, className, children, style, ...props } ) => (
159
+ < code
160
+ css = { ( theme ) => ( {
161
+ padding : "1px 4px" ,
162
+ background : theme . palette . divider ,
163
+ borderRadius : 4 ,
164
+ color : theme . palette . text . primary ,
165
+ fontSize : 14 ,
166
+ } ) }
167
+ { ...props }
168
+ >
169
+ { children }
170
+ </ code >
171
+ ) ,
172
+
173
+ ...components ,
109
174
} }
110
175
>
111
176
{ children }
112
177
</ ReactMarkdown >
113
178
) ;
114
179
} ;
115
180
116
- export const MemoizedMarkdown = memo ( Markdown ) ;
181
+ export const MemoizedMarkdown = memo ( Markdown , isEqual ) ;
182
+ export const MemoizedInlineMarkdown = memo ( InlineMarkdown , isEqual ) ;
117
183
118
184
const markdownStyles : Interpolation < Theme > = ( theme : Theme ) => ( {
119
185
fontSize : 16 ,
0 commit comments