I’m working on a React application that uses @shadcn/ui for the UI framework and react-markdown for rendering Markdown content. My problem is that the Markdown content is not displaying correctly because the typography styles from @shadcn/ui are overriding the Markdown styles. Specifically, the Markdown headers and other text elements are not showing the expected formatting.
Here is the relevant part of my React component:
import React, { useEffect, useState } from "react"
import { MarkdownFile, isHTTPValidationError } from "@/types"
import { useParams, useNavigate } from "react-router-dom"
import { fetchMarkdown, updateMarkdown } from "@/endpoint"
import { Button } from "./ui/button"
import Markdown from "react-markdown"
import rehypeHighlight from "rehype-highlight"
import remarkGfm from "remark-gfm"
import "./styles.css"
const MarkdownEdit: React.FC = () => {
const [markdown, setMarkdown] = useState<MarkdownFile | null>(null)
const { id } = useParams<{ id: string }>()
const navigate = useNavigate()
const [error, setError] = useState<string>("")
useEffect(() => {
if (id) {
fetchMarkdown(id, setMarkdown)
}
}, [id])
const handleSave = async (e: React.FormEvent) => {
e.preventDefault()
setError("")
if (!markdown) return
try {
await updateMarkdown(markdown.id, markdown, setMarkdown)
navigate("/")
} catch (err: unknown) {
if (isHTTPValidationError(err)) {
setError((err as Error & { detail: string }).detail)
} else {
setError("An unknown error occurred.")
}
}
}
return (
<div
style={{
display: "flex",
flexDirection: "column",
minHeight: "100vh",
backgroundColor: "#F9FAFB",
}}
>
{markdown && (
<div
style={{
display: "flex",
flexDirection: "column",
height: "calc(100vh - 100px)", // Adjust this value as needed
overflow: "hidden", // Prevents the page from scrolling
}}
>
<h2
style={{
marginBottom: "0.5rem",
fontSize: "1.875rem",
fontWeight: "600",
}}
>
Company: {markdown.company_name}
</h2>
<h4 style={{ fontSize: "1.25rem", fontWeight: "600" }}>
Business: {markdown.business_type}
</h4>
{error && <div className="text-red-500 mb-4">{error}</div>}
<div
style={{
display: "flex",
flexDirection: "row",
height: "100%", // Take up remaining space
overflow: "hidden", // Prevents this div from scrolling
}}
>
<textarea
style={{
flex: 1,
width: "50%",
overflowY: "auto",
resize: "none",
}}
placeholder="Type your message here."
value={markdown.products}
onChange={(e) =>
setMarkdown({ ...markdown, products: e.target.value })
}
/>
<div
className="markdown-content"
style={{
flex: 1,
width: "50%",
overflowY: "auto",
padding: "0.5rem",
}}
>
<Markdown rehypePlugins={[rehypeHighlight, remarkGfm]}>
{markdown.products}
</Markdown>
</div>
</div>
</div>
)}
<Button style={{ margin: "1rem" }} onClick={handleSave}>
Save
</Button>
</div>
)
}
export default MarkdownEdit
To solve this issue, I created a custom CSS class to override the global typography styles from @shadcn/ui. Here is the CSS:
/* styles.css */
.markdown-content h1,
.markdown-content h2,
.markdown-content h3,
.markdown-content h4,
.markdown-content h5,
.markdown-content h6 {
font-size: inherit;
font-weight: inherit;
line-height: inherit;
}
.markdown-content p {
margin-top: inherit;
margin-bottom: inherit;
font-size: inherit;
line-height: inherit;
}
.markdown-content blockquote {
font-size: inherit;
line-height: inherit;
margin: inherit;
padding: inherit;
border-left: inherit;
color: inherit;
}
.markdown-content ul,
.markdown-content ol {
list-style: inherit;
margin: inherit;
padding: inherit;
}
.markdown-content table {
width: inherit;
border-collapse: inherit;
margin: inherit;
}
By wrapping the Markdown component in a div with the markdown-content class, I ensured the Markdown styles were correctly applied:
<div className="markdown-content">
<Markdown rehypePlugins={[rehypeHighlight, remarkGfm]}>
{markdown.products}
</Markdown>
</div>
Unfortunately, the header still doesn’t show the correct format in the Markdown component.