alphasim-competition-page / app /src /components /markdown-content.tsx
fei-1995's picture
feat: using new style
34d72cb
import ReactMarkdown, { type Components } from "react-markdown"
import rehypeRaw from "rehype-raw"
import remarkGfm from "remark-gfm"
import { cn } from "@/lib/utils"
type MarkdownContentProps = {
markdown: string
className?: string
}
const markdownComponents: Components = {
h1: ({ className, ...props }) => (
<h1
className={cn(
"mt-8 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 sm:text-4xl",
className
)}
{...props}
/>
),
h2: ({ className, ...props }) => (
<h2
className={cn(
"mt-8 scroll-m-20 border-b border-border/70 pb-2 text-2xl font-semibold tracking-tight first:mt-0",
className
)}
{...props}
/>
),
h3: ({ className, ...props }) => (
<h3
className={cn(
"mt-6 scroll-m-20 text-xl font-semibold tracking-tight",
className
)}
{...props}
/>
),
h4: ({ className, ...props }) => (
<h4 className={cn("mt-5 text-lg font-semibold", className)} {...props} />
),
p: ({ className, ...props }) => (
<p className={cn("leading-7 [&:not(:first-child)]:mt-4", className)} {...props} />
),
ul: ({ className, ...props }) => (
<ul className={cn("my-4 ml-6 list-disc space-y-2", className)} {...props} />
),
ol: ({ className, ...props }) => (
<ol className={cn("my-4 ml-6 list-decimal space-y-2", className)} {...props} />
),
li: ({ className, ...props }) => (
<li className={cn("pl-1", className)} {...props} />
),
blockquote: ({ className, ...props }) => (
<blockquote
className={cn(
"mt-4 border-l-4 border-border bg-muted/40 py-1 pl-4 italic text-foreground/80",
className
)}
{...props}
/>
),
a: ({ className, ...props }) => (
<a
className={cn(
"font-medium text-foreground underline decoration-border underline-offset-4 transition-colors hover:text-muted-foreground",
className
)}
rel="noreferrer"
target="_blank"
{...props}
/>
),
code: ({ className, ...props }) => (
<code
className={cn(
"rounded-md bg-muted px-1.5 py-0.5 font-mono text-[0.85em]",
className
)}
{...props}
/>
),
pre: ({ className, ...props }) => (
<pre
className={cn(
"mt-4 overflow-x-auto rounded-xl border border-border bg-zinc-950 px-4 py-3 font-mono text-sm text-zinc-50",
className
)}
{...props}
/>
),
hr: ({ className, ...props }) => (
<hr className={cn("my-8 border-border/70", className)} {...props} />
),
table: ({ className, ...props }) => (
<div className="my-6 overflow-x-auto rounded-xl border border-border/70">
<table className={cn("w-full border-collapse text-sm", className)} {...props} />
</div>
),
thead: ({ className, ...props }) => (
<thead className={cn("bg-muted/50", className)} {...props} />
),
tbody: ({ className, ...props }) => (
<tbody className={cn("[&_tr:last-child]:border-b-0", className)} {...props} />
),
tr: ({ className, ...props }) => (
<tr className={cn("border-b border-border/70", className)} {...props} />
),
th: ({ className, ...props }) => (
<th
className={cn(
"px-4 py-3 text-left font-medium text-foreground whitespace-nowrap",
className
)}
{...props}
/>
),
td: ({ className, ...props }) => (
<td
className={cn(
"px-4 py-3 align-top text-muted-foreground whitespace-pre-wrap",
className
)}
{...props}
/>
),
img: ({ className, alt, ...props }) => (
<img
alt={alt ?? ""}
className={cn(
"my-6 w-full rounded-2xl border border-border/70 object-cover shadow-sm",
className
)}
{...props}
/>
),
}
export function MarkdownContent({
markdown,
className,
}: MarkdownContentProps) {
return (
<div className={cn("text-[15px] text-foreground", className)}>
<ReactMarkdown
components={markdownComponents}
rehypePlugins={[rehypeRaw]}
remarkPlugins={[remarkGfm]}
>
{markdown}
</ReactMarkdown>
</div>
)
}