refactor: convert MarkdownContent to server component, remove context

This commit is contained in:
2026-04-10 01:07:18 +02:00
parent 695ebf707f
commit ccde0af995

View File

@@ -1,15 +1,8 @@
"use client";
import React, { createContext, useContext } from "react";
import React from "react";
import ReactMarkdown from "react-markdown";
import type { Components } from "react-markdown";
import type { Element } from "hast";
// Lets the `code` renderer know it's inside a `pre` block vs. inline.
// React renders parent-to-child, so the Provider in `pre` is active
// when `code` renders inside it.
const InsidePreContext = createContext(false);
function GoldDot() {
return (
<span
@@ -72,40 +65,6 @@ function extractHastText(node: Element): string {
.trim();
}
function CodeRenderer({ children }: { children?: React.ReactNode }) {
const insidePre = useContext(InsidePreContext);
if (insidePre) {
return (
<code
style={{
fontFamily: "var(--font-mono, 'Geist Mono', monospace)",
fontSize: "0.9rem",
color: "#e2e8f0",
lineHeight: 1.65,
}}
>
{children}
</code>
);
}
return (
<code
style={{
background: "rgba(250, 204, 21, 0.1)",
border: "1px solid rgba(250, 204, 21, 0.3)",
borderRadius: 5,
padding: "1px 7px",
color: "#fde68a",
fontFamily: "var(--font-mono, 'Geist Mono', monospace)",
fontSize: "0.875em",
}}
>
{children}
</code>
);
}
const components: Components = {
h1: ({ children }) => (
@@ -286,10 +245,15 @@ const components: Components = {
<em style={{ color: "#e2e8f0", fontStyle: "italic" }}>{children}</em>
),
// `pre` wraps `code` for fenced code blocks. The Provider lets the
// nested `code` renderer know it's in a block context (not inline).
pre: ({ children }) => (
<InsidePreContext.Provider value={true}>
// `pre` reads code text directly from the HAST node so `code` renderer
// is only ever called for inline code — no client-side context needed.
pre: ({ node }) => {
const codeEl = node?.children?.[0] as Element | undefined;
const codeText = (codeEl?.children ?? [])
.filter((c): c is { type: "text"; value: string } => c.type === "text")
.map((c) => c.value)
.join("");
return (
<pre
style={{
background: "rgba(255, 255, 255, 0.04)",
@@ -301,12 +265,36 @@ const components: Components = {
margin: "0 0 1.25rem 0",
}}
>
{children}
<code
style={{
fontFamily: "var(--font-mono, 'Geist Mono', monospace)",
fontSize: "0.9rem",
color: "#e2e8f0",
lineHeight: 1.65,
}}
>
{codeText}
</code>
</pre>
</InsidePreContext.Provider>
),
);
},
code: CodeRenderer,
// Always inline — block code is handled entirely by the `pre` renderer above.
code: ({ children }) => (
<code
style={{
background: "rgba(250, 204, 21, 0.1)",
border: "1px solid rgba(250, 204, 21, 0.3)",
borderRadius: 5,
padding: "1px 7px",
color: "#fde68a",
fontFamily: "var(--font-mono, 'Geist Mono', monospace)",
fontSize: "0.875em",
}}
>
{children}
</code>
),
};
export default function MarkdownContent({ content }: { content: string }) {