refactor: convert MarkdownContent to server component, remove context
This commit is contained in:
@@ -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 }) {
|
||||
|
||||
Reference in New Issue
Block a user