33// ============================================================================
44import { forwardRef , ReactNode , useEffect , useState } from 'react' ;
55import type { FunctionComponent , HTMLProps , MouseEvent as ReactMouseEvent , Ref } from 'react' ;
6- import Markdown from 'react-markdown' ;
6+ import Markdown , { Options } from 'react-markdown' ;
77import remarkGfm from 'remark-gfm' ;
88import {
99 AlertProps ,
@@ -185,6 +185,10 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
185185 editFormProps ?: FormProps ;
186186 /** Sets message to compact styling. */
187187 isCompact ?: boolean ;
188+ /** Disables markdown parsing for message, allowing only text input */
189+ isMarkdownDisabled ?: boolean ;
190+ /** Allows passing additional props down to markdown parser react-markdown, such as allowedElements and disallowedElements. See https://github.com/remarkjs/react-markdown?tab=readme-ov-file#options for options */
191+ reactMarkdownProps ?: Options ;
188192}
189193
190194export const MessageBase : FunctionComponent < MessageProps > = ( {
@@ -224,6 +228,8 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
224228 inputRef,
225229 editFormProps,
226230 isCompact,
231+ isMarkdownDisabled,
232+ reactMarkdownProps,
227233 ...props
228234} : MessageProps ) => {
229235 const [ messageText , setMessageText ] = useState ( content ) ;
@@ -250,6 +256,60 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
250256 const date = new Date ( ) ;
251257 const dateString = timestamp ?? `${ date . toLocaleDateString ( ) } ${ date . toLocaleTimeString ( ) } ` ;
252258
259+ const handleMarkdown = ( ) => {
260+ if ( isMarkdownDisabled ) {
261+ return (
262+ < TextMessage component = { ContentVariants . p } { ...props } >
263+ { messageText }
264+ </ TextMessage >
265+ ) ;
266+ }
267+ return (
268+ < Markdown
269+ components = { {
270+ p : ( props ) => < TextMessage component = { ContentVariants . p } { ...props } /> ,
271+ code : ( { children, ...props } ) => (
272+ < CodeBlockMessage { ...props } { ...codeBlockProps } >
273+ { children }
274+ </ CodeBlockMessage >
275+ ) ,
276+ h1 : ( props ) => < TextMessage component = { ContentVariants . h1 } { ...props } /> ,
277+ h2 : ( props ) => < TextMessage component = { ContentVariants . h2 } { ...props } /> ,
278+ h3 : ( props ) => < TextMessage component = { ContentVariants . h3 } { ...props } /> ,
279+ h4 : ( props ) => < TextMessage component = { ContentVariants . h4 } { ...props } /> ,
280+ h5 : ( props ) => < TextMessage component = { ContentVariants . h5 } { ...props } /> ,
281+ h6 : ( props ) => < TextMessage component = { ContentVariants . h6 } { ...props } /> ,
282+ blockquote : ( props ) => < TextMessage component = { ContentVariants . blockquote } { ...props } /> ,
283+ ul : ( props ) => < UnorderedListMessage { ...props } /> ,
284+ ol : ( props ) => < OrderedListMessage { ...props } /> ,
285+ li : ( props ) => < ListItemMessage { ...props } /> ,
286+ table : ( props ) => < TableMessage { ...props } { ...tableProps } /> ,
287+ tbody : ( props ) => < TbodyMessage { ...props } /> ,
288+ thead : ( props ) => < TheadMessage { ...props } /> ,
289+ tr : ( props ) => < TrMessage { ...props } /> ,
290+ td : ( props ) => {
291+ // Conflicts with Td type
292+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
293+ const { width, ...rest } = props ;
294+ return < TdMessage { ...rest } /> ;
295+ } ,
296+ th : ( props ) => < ThMessage { ...props } /> ,
297+ img : ( props ) => < ImageMessage { ...props } /> ,
298+ a : ( props ) => (
299+ < LinkMessage href = { props . href } rel = { props . rel } target = { props . target } { ...linkProps } >
300+ { props . children }
301+ </ LinkMessage >
302+ )
303+ } }
304+ remarkPlugins = { [ remarkGfm ] }
305+ rehypePlugins = { rehypePlugins }
306+ { ...reactMarkdownProps }
307+ >
308+ { messageText }
309+ </ Markdown >
310+ ) ;
311+ } ;
312+
253313 const renderMessage = ( ) => {
254314 if ( isLoading ) {
255315 return < MessageLoading loadingWord = { loadingWord } /> ;
@@ -277,51 +337,7 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
277337 return (
278338 < >
279339 { beforeMainContent && < > { beforeMainContent } </ > }
280- { error ? (
281- < ErrorMessage { ...error } />
282- ) : (
283- < Markdown
284- components = { {
285- p : ( props ) => < TextMessage component = { ContentVariants . p } { ...props } /> ,
286- code : ( { children, ...props } ) => (
287- < CodeBlockMessage { ...props } { ...codeBlockProps } >
288- { children }
289- </ CodeBlockMessage >
290- ) ,
291- h1 : ( props ) => < TextMessage component = { ContentVariants . h1 } { ...props } /> ,
292- h2 : ( props ) => < TextMessage component = { ContentVariants . h2 } { ...props } /> ,
293- h3 : ( props ) => < TextMessage component = { ContentVariants . h3 } { ...props } /> ,
294- h4 : ( props ) => < TextMessage component = { ContentVariants . h4 } { ...props } /> ,
295- h5 : ( props ) => < TextMessage component = { ContentVariants . h5 } { ...props } /> ,
296- h6 : ( props ) => < TextMessage component = { ContentVariants . h6 } { ...props } /> ,
297- blockquote : ( props ) => < TextMessage component = { ContentVariants . blockquote } { ...props } /> ,
298- ul : ( props ) => < UnorderedListMessage { ...props } /> ,
299- ol : ( props ) => < OrderedListMessage { ...props } /> ,
300- li : ( props ) => < ListItemMessage { ...props } /> ,
301- table : ( props ) => < TableMessage { ...props } { ...tableProps } /> ,
302- tbody : ( props ) => < TbodyMessage { ...props } /> ,
303- thead : ( props ) => < TheadMessage { ...props } /> ,
304- tr : ( props ) => < TrMessage { ...props } /> ,
305- td : ( props ) => {
306- // Conflicts with Td type
307- // eslint-disable-next-line @typescript-eslint/no-unused-vars
308- const { width, ...rest } = props ;
309- return < TdMessage { ...rest } /> ;
310- } ,
311- th : ( props ) => < ThMessage { ...props } /> ,
312- img : ( props ) => < ImageMessage { ...props } /> ,
313- a : ( props ) => (
314- < LinkMessage href = { props . href } rel = { props . rel } target = { props . target } { ...linkProps } >
315- { props . children }
316- </ LinkMessage >
317- )
318- } }
319- remarkPlugins = { [ remarkGfm ] }
320- rehypePlugins = { rehypePlugins }
321- >
322- { messageText }
323- </ Markdown >
324- ) }
340+ { error ? < ErrorMessage { ...error } /> : handleMarkdown ( ) }
325341 </ >
326342 ) ;
327343 } ;
0 commit comments