33import React from 'react' ;
44import PropTypes from 'prop-types' ;
55import { Box , Container , Header } from '@awsui/components-react' ;
6+ import ReactMarkdown from 'react-markdown' ;
7+ import remarkGfm from 'remark-gfm' ;
8+ import rehypeRaw from 'rehype-raw' ;
9+
10+ // Custom heading components with stronger inline styles
11+ const H1Component = ( { children } ) => (
12+ < h1
13+ style = { {
14+ fontSize : '1.75em' ,
15+ fontWeight : 'bold' ,
16+ color : '#232f3e' ,
17+ marginTop : '0.5em' ,
18+ marginBottom : '0.5em' ,
19+ lineHeight : '1.2' ,
20+ } }
21+ >
22+ { children }
23+ </ h1 >
24+ ) ;
25+
26+ const H2Component = ( { children } ) => (
27+ < h2
28+ style = { {
29+ fontSize : '1.5em' ,
30+ fontWeight : 'bold' ,
31+ color : '#232f3e' ,
32+ marginTop : '0.75em' ,
33+ marginBottom : '0.5em' ,
34+ lineHeight : '1.3' ,
35+ } }
36+ >
37+ { children }
38+ </ h2 >
39+ ) ;
40+
41+ const H3Component = ( { children } ) => (
42+ < h3
43+ style = { {
44+ fontSize : '1.25em' ,
45+ fontWeight : 'bold' ,
46+ color : '#232f3e' ,
47+ marginTop : '0.75em' ,
48+ marginBottom : '0.5em' ,
49+ lineHeight : '1.3' ,
50+ } }
51+ >
52+ { children }
53+ </ h3 >
54+ ) ;
55+
56+ const H4Component = ( { children } ) => (
57+ < h4
58+ style = { {
59+ fontSize : '1.1em' ,
60+ fontWeight : 'bold' ,
61+ color : '#232f3e' ,
62+ marginTop : '0.75em' ,
63+ marginBottom : '0.5em' ,
64+ lineHeight : '1.3' ,
65+ } }
66+ >
67+ { children }
68+ </ h4 >
69+ ) ;
70+
71+ const ParagraphComponent = ( { children } ) => (
72+ < p
73+ style = { {
74+ marginBottom : '1em' ,
75+ lineHeight : '1.6' ,
76+ color : '#16191f' ,
77+ } }
78+ >
79+ { children }
80+ </ p >
81+ ) ;
82+
83+ const CodeComponent = ( { inline, children } ) => {
84+ if ( inline ) {
85+ return (
86+ < code
87+ style = { {
88+ backgroundColor : '#f4f4f4' ,
89+ padding : '0.2em 0.4em' ,
90+ borderRadius : '3px' ,
91+ fontFamily : 'Monaco, Consolas, "Courier New", monospace' ,
92+ fontSize : '0.9em' ,
93+ color : '#d63384' ,
94+ } }
95+ >
96+ { children }
97+ </ code >
98+ ) ;
99+ }
100+ return (
101+ < code
102+ style = { {
103+ fontFamily : 'Monaco, Consolas, "Courier New", monospace' ,
104+ fontSize : '0.9em' ,
105+ } }
106+ >
107+ { children }
108+ </ code >
109+ ) ;
110+ } ;
111+
112+ const PreComponent = ( { children } ) => (
113+ < pre
114+ style = { {
115+ backgroundColor : '#f8f9fa' ,
116+ border : '1px solid #e9ecef' ,
117+ padding : '1em' ,
118+ borderRadius : '5px' ,
119+ overflow : 'auto' ,
120+ marginBottom : '1em' ,
121+ fontFamily : 'Monaco, Consolas, "Courier New", monospace' ,
122+ fontSize : '0.9em' ,
123+ } }
124+ >
125+ { children }
126+ </ pre >
127+ ) ;
128+
129+ const UlComponent = ( { children } ) => < ul style = { { marginBottom : '1em' , paddingLeft : '2em' } } > { children } </ ul > ;
130+
131+ const OlComponent = ( { children } ) => < ol style = { { marginBottom : '1em' , paddingLeft : '2em' } } > { children } </ ol > ;
132+
133+ const LiComponent = ( { children } ) => < li style = { { marginBottom : '0.25em' } } > { children } </ li > ;
134+
135+ const BlockquoteComponent = ( { children } ) => (
136+ < blockquote
137+ style = { {
138+ borderLeft : '4px solid #0073bb' ,
139+ paddingLeft : '1em' ,
140+ marginLeft : '0' ,
141+ marginBottom : '1em' ,
142+ fontStyle : 'italic' ,
143+ color : '#5f6368' ,
144+ } }
145+ >
146+ { children }
147+ </ blockquote >
148+ ) ;
149+
150+ const TableComponent = ( { children } ) => (
151+ < table
152+ style = { {
153+ borderCollapse : 'collapse' ,
154+ width : '100%' ,
155+ marginBottom : '1em' ,
156+ border : '1px solid #ddd' ,
157+ } }
158+ >
159+ { children }
160+ </ table >
161+ ) ;
162+
163+ const ThComponent = ( { children } ) => (
164+ < th
165+ style = { {
166+ border : '1px solid #ddd' ,
167+ padding : '0.5em' ,
168+ textAlign : 'left' ,
169+ backgroundColor : '#f2f2f2' ,
170+ fontWeight : 'bold' ,
171+ } }
172+ >
173+ { children }
174+ </ th >
175+ ) ;
176+
177+ const TdComponent = ( { children } ) => (
178+ < td
179+ style = { {
180+ border : '1px solid #ddd' ,
181+ padding : '0.5em' ,
182+ textAlign : 'left' ,
183+ } }
184+ >
185+ { children }
186+ </ td >
187+ ) ;
188+
189+ const LinkComponent = ( { children, href } ) => (
190+ < a
191+ href = { href }
192+ style = { {
193+ color : '#0073bb' ,
194+ textDecoration : 'none' ,
195+ } }
196+ onMouseEnter = { ( e ) => {
197+ e . target . style . textDecoration = 'underline' ;
198+ } }
199+ onMouseLeave = { ( e ) => {
200+ e . target . style . textDecoration = 'none' ;
201+ } }
202+ >
203+ { children }
204+ </ a >
205+ ) ;
206+
207+ const StrongComponent = ( { children } ) => < strong style = { { fontWeight : 'bold' } } > { children } </ strong > ;
208+
209+ const EmComponent = ( { children } ) => < em style = { { fontStyle : 'italic' } } > { children } </ em > ;
210+
211+ // PropTypes for all components
212+ H1Component . propTypes = {
213+ children : PropTypes . node . isRequired ,
214+ } ;
215+
216+ H2Component . propTypes = {
217+ children : PropTypes . node . isRequired ,
218+ } ;
219+
220+ H3Component . propTypes = {
221+ children : PropTypes . node . isRequired ,
222+ } ;
223+
224+ H4Component . propTypes = {
225+ children : PropTypes . node . isRequired ,
226+ } ;
227+
228+ ParagraphComponent . propTypes = {
229+ children : PropTypes . node . isRequired ,
230+ } ;
231+
232+ CodeComponent . propTypes = {
233+ inline : PropTypes . bool ,
234+ children : PropTypes . node . isRequired ,
235+ } ;
236+
237+ CodeComponent . defaultProps = {
238+ inline : false ,
239+ } ;
240+
241+ PreComponent . propTypes = {
242+ children : PropTypes . node . isRequired ,
243+ } ;
244+
245+ UlComponent . propTypes = {
246+ children : PropTypes . node . isRequired ,
247+ } ;
248+
249+ OlComponent . propTypes = {
250+ children : PropTypes . node . isRequired ,
251+ } ;
252+
253+ LiComponent . propTypes = {
254+ children : PropTypes . node . isRequired ,
255+ } ;
256+
257+ BlockquoteComponent . propTypes = {
258+ children : PropTypes . node . isRequired ,
259+ } ;
260+
261+ TableComponent . propTypes = {
262+ children : PropTypes . node . isRequired ,
263+ } ;
264+
265+ ThComponent . propTypes = {
266+ children : PropTypes . node . isRequired ,
267+ } ;
268+
269+ TdComponent . propTypes = {
270+ children : PropTypes . node . isRequired ,
271+ } ;
272+
273+ LinkComponent . propTypes = {
274+ children : PropTypes . node . isRequired ,
275+ href : PropTypes . string ,
276+ } ;
277+
278+ LinkComponent . defaultProps = {
279+ href : '#' ,
280+ } ;
281+
282+ StrongComponent . propTypes = {
283+ children : PropTypes . node . isRequired ,
284+ } ;
285+
286+ EmComponent . propTypes = {
287+ children : PropTypes . node . isRequired ,
288+ } ;
6289
7290const TextDisplay = ( { textData } ) => {
8291 if ( ! textData || ! textData . content ) {
9292 return null ;
10293 }
11294
295+ const markdownComponents = {
296+ h1 : H1Component ,
297+ h2 : H2Component ,
298+ h3 : H3Component ,
299+ h4 : H4Component ,
300+ p : ParagraphComponent ,
301+ code : CodeComponent ,
302+ pre : PreComponent ,
303+ ul : UlComponent ,
304+ ol : OlComponent ,
305+ li : LiComponent ,
306+ blockquote : BlockquoteComponent ,
307+ table : TableComponent ,
308+ th : ThComponent ,
309+ td : TdComponent ,
310+ a : LinkComponent ,
311+ strong : StrongComponent ,
312+ em : EmComponent ,
313+ } ;
314+
12315 return (
13316 < Container header = { < Header variant = "h3" > Text Response</ Header > } >
14317 < Box padding = "m" >
15- < Box variant = "p" fontSize = "body-m" padding = "s" backgroundColor = "background-container-content" >
16- { textData . content }
318+ < Box variant = "div" fontSize = "body-m" padding = "s" backgroundColor = "background-container-content" >
319+ < div style = { { lineHeight : '1.6' } } >
320+ < ReactMarkdown remarkPlugins = { [ remarkGfm ] } rehypePlugins = { [ rehypeRaw ] } components = { markdownComponents } >
321+ { textData . content }
322+ </ ReactMarkdown >
323+ </ div >
17324 </ Box >
18325 </ Box >
19326 </ Container >
@@ -27,6 +334,13 @@ TextDisplay.propTypes = {
27334 } ) ,
28335} ;
29336
337+ TextDisplay . propTypes = {
338+ textData : PropTypes . shape ( {
339+ content : PropTypes . string . isRequired ,
340+ responseType : PropTypes . string ,
341+ } ) ,
342+ } ;
343+
30344TextDisplay . defaultProps = {
31345 textData : null ,
32346} ;
0 commit comments