@@ -38,7 +38,10 @@ import ThMessage from './TableMessage/ThMessage';
3838import { TableProps } from '@patternfly/react-table' ;
3939import ImageMessage from './ImageMessage/ImageMessage' ;
4040import rehypeUnwrapImages from 'rehype-unwrap-images' ;
41+ import rehypeExternalLinks from 'rehype-external-links' ;
42+ import rehypeSanitize from 'rehype-sanitize' ;
4143import { PluggableList } from 'react-markdown/lib' ;
44+ import LinkMessage from './LinkMessage/LinkMessage' ;
4245
4346export interface MessageAttachment {
4447 /** Name of file attached to the message */
@@ -136,6 +139,8 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
136139 tableProps ?: Required < Pick < TableProps , 'aria-label' > > & TableProps ;
137140 /** Additional rehype plugins passed from the consumer */
138141 additionalRehypePlugins ?: PluggableList ;
142+ /** Whether to open links in message in new tab. */
143+ openLinkInNewTab ?: boolean ;
139144}
140145
141146export const MessageBase : React . FunctionComponent < MessageProps > = ( {
@@ -162,10 +167,18 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
162167 isLiveRegion = true ,
163168 innerRef,
164169 tableProps,
170+ openLinkInNewTab = true ,
165171 additionalRehypePlugins = [ ] ,
166172 ...props
167173} : MessageProps ) => {
168174 const { beforeMainContent, afterMainContent, endContent } = extraContent || { } ;
175+ let rehypePlugins : PluggableList = [ rehypeUnwrapImages ] ;
176+ if ( openLinkInNewTab ) {
177+ rehypePlugins = rehypePlugins . concat ( [ [ rehypeExternalLinks , { target : '_blank' } , rehypeSanitize ] ] ) ;
178+ }
179+ if ( additionalRehypePlugins ) {
180+ rehypePlugins . push ( ...additionalRehypePlugins ) ;
181+ }
169182 let avatarClassName ;
170183 if ( avatarProps && 'className' in avatarProps ) {
171184 const { className, ...rest } = avatarProps ;
@@ -175,9 +188,6 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
175188 // Keep timestamps consistent between Timestamp component and aria-label
176189 const date = new Date ( ) ;
177190 const dateString = timestamp ?? `${ date . toLocaleDateString ( ) } ${ date . toLocaleTimeString ( ) } ` ;
178-
179- const rehypePlugins = [ rehypeUnwrapImages , ...( additionalRehypePlugins ?? [ ] ) ] ;
180-
181191 return (
182192 < section
183193 aria-label = { `Message from ${ role } - ${ dateString } ` }
@@ -244,7 +254,12 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
244254 return < TdMessage { ...rest } /> ;
245255 } ,
246256 th : ( props ) => < ThMessage { ...props } /> ,
247- img : ( props ) => < ImageMessage { ...props } />
257+ img : ( props ) => < ImageMessage { ...props } /> ,
258+ a : ( props ) => (
259+ < LinkMessage href = { props . href } rel = { props . rel } target = { props . target } >
260+ { props . children }
261+ </ LinkMessage >
262+ )
248263 } }
249264 remarkPlugins = { [ remarkGfm ] }
250265 rehypePlugins = { rehypePlugins }
0 commit comments