Skip to content

Commit feb3033

Browse files
committed
refactor: enhance MarkdownRenderer styles for improved dark mode support and list item handling
1 parent 2ff99e7 commit feb3033

File tree

1 file changed

+96
-29
lines changed

1 file changed

+96
-29
lines changed

packages/web/app/components/custom/MarkdownRenderer.tsx

Lines changed: 96 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,35 +75,65 @@ export function MarkdownRenderer({
7575

7676
// Preprocess content to handle single line breaks
7777
const processedContent = preserveLineBreaks ? preprocessContent(content) : content;
78-
78+
7979
const wrapperClassName = cn(
80-
"prose prose-slate max-w-none",
81-
!noPadding && "p-4",
82-
maxHeight && "overflow-y-auto scrollbar-thin scrollbar-thumb-muted scrollbar-track-background",
83-
className
80+
'prose prose-slate max-w-none dark:prose-invert',
81+
'prose-headings:text-foreground prose-strong:text-foreground',
82+
'prose-p:text-foreground prose-li:text-foreground',
83+
'prose-blockquote:text-muted-foreground prose-code:text-foreground',
84+
'prose-pre:bg-muted prose-pre:text-foreground',
85+
'prose-th:text-foreground prose-td:text-foreground',
86+
'prose-a:text-primary hover:prose-a:text-primary/80',
87+
// Fix list item paragraphs - make them inline and remove margins
88+
'[&_li>p]:inline [&_li>p]:!m-0 [&_li>p]:!p-0',
89+
'[&_ul_li>p]:inline [&_ul_li>p]:!m-0 [&_ul_li>p]:!p-0',
90+
'[&_ol_li>p]:inline [&_ol_li>p]:!m-0 [&_ol_li>p]:!p-0',
91+
!noPadding && 'p-4',
92+
maxHeight && 'overflow-y-auto scrollbar-thin scrollbar-thumb-muted scrollbar-track-background',
93+
className,
8494
);
8595

8696
const markdownContent = (
87-
<div
97+
<div
8898
className={wrapperClassName}
89-
style={maxHeight && typeof maxHeight === 'number' ? { maxHeight: `${maxHeight}px` } : undefined}
99+
style={
100+
maxHeight && typeof maxHeight === 'number' ? { maxHeight: `${maxHeight}px` } : undefined
101+
}
90102
>
91103
<ReactMarkdown
92104
remarkPlugins={[remarkGfm]}
93105
rehypePlugins={[rehypeHighlight, [rehypeSanitize, sanitizeSchema]]}
94106
components={{
95-
// Use Tailwind-styled components
96-
p: ({ children }) => <p className="mb-4 leading-relaxed">{children}</p>,
97-
h1: ({ children }) => <h1 className="text-3xl font-bold mb-6 mt-8 text-foreground border-b border-border pb-2">{children}</h1>,
98-
h2: ({ children }) => <h2 className="text-2xl font-semibold mb-4 mt-6 text-foreground">{children}</h2>,
99-
h3: ({ children }) => <h3 className="text-xl font-semibold mb-3 mt-5 text-foreground">{children}</h3>,
100-
h4: ({ children }) => <h4 className="text-lg font-semibold mb-2 mt-4 text-foreground">{children}</h4>,
101-
h5: ({ children }) => <h5 className="text-base font-semibold mb-2 mt-3 text-foreground">{children}</h5>,
102-
h6: ({ children }) => <h6 className="text-sm font-semibold mb-2 mt-3 text-muted-foreground">{children}</h6>,
107+
// Use Tailwind-styled components with improved dark mode support
108+
p: ({ children }) => <p className="mb-4 leading-relaxed text-foreground">{children}</p>,
109+
h1: ({ children }) => (
110+
<h1 className="text-3xl font-bold mb-6 mt-8 text-foreground border-b border-border pb-2">
111+
{children}
112+
</h1>
113+
),
114+
h2: ({ children }) => (
115+
<h2 className="text-2xl font-semibold mb-4 mt-6 text-foreground">{children}</h2>
116+
),
117+
h3: ({ children }) => (
118+
<h3 className="text-xl font-semibold mb-3 mt-5 text-foreground">{children}</h3>
119+
),
120+
h4: ({ children }) => (
121+
<h4 className="text-lg font-semibold mb-2 mt-4 text-foreground">{children}</h4>
122+
),
123+
h5: ({ children }) => (
124+
<h5 className="text-base font-semibold mb-2 mt-3 text-foreground">{children}</h5>
125+
),
126+
h6: ({ children }) => (
127+
<h6 className="text-sm font-semibold mb-2 mt-3 text-muted-foreground">{children}</h6>
128+
),
103129
code: ({ children, className: codeClassName, ...props }) => {
104130
const isInline = !codeClassName;
105131
if (isInline) {
106-
return <code className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">{children}</code>;
132+
return (
133+
<code className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono text-foreground">
134+
{children}
135+
</code>
136+
);
107137
}
108138
// For code blocks, let ReactMarkdown handle the structure with rehypeHighlight
109139
return (
@@ -140,9 +170,14 @@ export function MarkdownRenderer({
140170
return (
141171
<div className="relative bg-muted rounded-lg overflow-hidden my-4">
142172
<div className="flex items-center justify-between px-4 py-2 bg-muted-foreground/10 border-b border-border">
143-
<span className="text-xs font-mono text-muted-foreground uppercase tracking-wide">{language}</span>
173+
<span className="text-xs font-mono text-muted-foreground uppercase tracking-wide">
174+
{language}
175+
</span>
144176
</div>
145-
<pre className={cn("overflow-x-auto p-4 text-sm bg-transparent", className)} {...props}>
177+
<pre
178+
className={cn('overflow-x-auto p-4 text-sm bg-transparent', className)}
179+
{...props}
180+
>
146181
{children}
147182
</pre>
148183
</div>
@@ -151,19 +186,45 @@ export function MarkdownRenderer({
151186

152187
// Fallback to regular pre if no language detected
153188
return (
154-
<pre className={cn("bg-muted rounded p-4 overflow-x-auto text-sm my-4", className)} {...props}>
189+
<pre
190+
className={cn('bg-muted rounded p-4 overflow-x-auto text-sm my-4', className)}
191+
{...props}
192+
>
155193
{children}
156194
</pre>
157195
);
158196
},
159-
blockquote: ({ children }) => <blockquote className="border-l-4 border-primary pl-4 my-4 italic text-muted-foreground">{children}</blockquote>,
160-
ul: ({ children }) => <ul className="list-disc list-inside space-y-1 my-4 ml-4">{children}</ul>,
161-
ol: ({ children }) => <ol className="list-decimal list-inside space-y-1 my-4 ml-4">{children}</ol>,
162-
li: ({ children }) => <li className="leading-relaxed">{children}</li>,
197+
blockquote: ({ children }) => (
198+
<blockquote className="border-l-4 border-primary pl-4 my-4 italic text-muted-foreground">
199+
{children}
200+
</blockquote>
201+
),
202+
ul: ({ children }) => (
203+
<ul className="list-disc list-outside space-y-1 my-4 ml-6 text-foreground">
204+
{children}
205+
</ul>
206+
),
207+
ol: ({ children }) => (
208+
<ol className="list-decimal list-outside space-y-1 my-4 ml-6 text-foreground">
209+
{children}
210+
</ol>
211+
),
212+
li: ({ children }) => {
213+
// If the children contains a single paragraph, unwrap it
214+
if (React.Children.count(children) === 1) {
215+
const child = React.Children.only(children);
216+
if (React.isValidElement(child) && child.type === 'p') {
217+
return (
218+
<li className="leading-relaxed text-foreground pl-1">{child.props.children}</li>
219+
);
220+
}
221+
}
222+
return <li className="leading-relaxed text-foreground pl-1">{children}</li>;
223+
},
163224
a: ({ href, children }) => (
164-
<a
165-
href={href}
166-
target="_blank"
225+
<a
226+
href={href}
227+
target="_blank"
167228
rel="noopener noreferrer"
168229
className="text-primary hover:text-primary/80 underline transition-colors"
169230
>
@@ -175,8 +236,14 @@ export function MarkdownRenderer({
175236
<table className="w-full border-collapse">{children}</table>
176237
</div>
177238
),
178-
th: ({ children }) => <th className="border border-border bg-muted px-4 py-2 text-left font-semibold">{children}</th>,
179-
td: ({ children }) => <td className="border border-border px-4 py-2">{children}</td>,
239+
th: ({ children }) => (
240+
<th className="border border-border bg-muted px-4 py-2 text-left font-semibold text-foreground">
241+
{children}
242+
</th>
243+
),
244+
td: ({ children }) => (
245+
<td className="border border-border px-4 py-2 text-foreground">{children}</td>
246+
),
180247
hr: () => <hr className="border-t border-border my-6" />,
181248
}}
182249
>
@@ -198,4 +265,4 @@ export function MarkdownRenderer({
198265
}
199266

200267
return markdownContent;
201-
}
268+
}

0 commit comments

Comments
 (0)