feat: improve release notes markdown rendering (#148)

- Add react-markdown and remark-gfm for proper markdown parsing
- Add @tailwindcss/typography plugin for prose styling
- Replace plain text rendering with custom ReactMarkdown components
- Headers now render with proper sizing and hierarchy
- Lists display with bullets and proper indentation
- Links are clickable and styled appropriately
- Emojis render correctly
- Maintain dark mode compatibility
This commit is contained in:
Michel Roegl-Brunner
2025-10-14 15:53:27 +02:00
committed by GitHub
parent efa924cb82
commit 67ac02ea1a
4 changed files with 1357 additions and 7 deletions

1340
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-slot": "^1.2.3",
"@t3-oss/env-nextjs": "^0.13.8",
"@tailwindcss/typography": "^0.5.19",
"@tanstack/react-query": "^5.90.3",
"@trpc/client": "^11.6.0",
"@trpc/react-query": "^11.6.0",
@@ -44,8 +45,10 @@
"node-pty": "^1.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-markdown": "^10.1.0",
"react-syntax-highlighter": "^15.6.6",
"refractor": "^5.0.0",
"remark-gfm": "^4.0.1",
"server-only": "^0.0.1",
"strip-ansi": "^7.1.2",
"superjson": "^2.2.1",

View File

@@ -5,6 +5,8 @@ import { api } from '~/trpc/react';
import { Button } from './ui/button';
import { Badge } from './ui/badge';
import { X, ExternalLink, Calendar, Tag, Loader2 } from 'lucide-react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
interface ReleaseNotesModalProps {
isOpen: boolean;
@@ -170,9 +172,23 @@ export function ReleaseNotesModal({ isOpen, onClose, highlightVersion }: Release
{/* Release Body */}
{release.body && (
<div className="prose prose-sm max-w-none dark:prose-invert">
<div className="whitespace-pre-wrap text-sm text-card-foreground leading-relaxed">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
h1: ({children}) => <h1 className="text-2xl font-bold text-card-foreground mb-4 mt-6">{children}</h1>,
h2: ({children}) => <h2 className="text-xl font-semibold text-card-foreground mb-3 mt-5">{children}</h2>,
h3: ({children}) => <h3 className="text-lg font-medium text-card-foreground mb-2 mt-4">{children}</h3>,
p: ({children}) => <p className="text-card-foreground mb-3 leading-relaxed">{children}</p>,
ul: ({children}) => <ul className="list-disc list-inside text-card-foreground mb-3 space-y-1">{children}</ul>,
ol: ({children}) => <ol className="list-decimal list-inside text-card-foreground mb-3 space-y-1">{children}</ol>,
li: ({children}) => <li className="text-card-foreground">{children}</li>,
a: ({href, children}) => <a href={href} className="text-blue-500 hover:text-blue-400 underline" target="_blank" rel="noopener noreferrer">{children}</a>,
strong: ({children}) => <strong className="font-semibold text-card-foreground">{children}</strong>,
em: ({children}) => <em className="italic text-card-foreground">{children}</em>,
}}
>
{release.body}
</div>
</ReactMarkdown>
</div>
)}
</div>

View File

@@ -1,4 +1,5 @@
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@layer base {
:root {