nandi/oripublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/nandi/ori.git
git clone ssh://git@rickub.com/nandi/ori.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

forked from bots-garden/ori

Markdown.tsx · 48 lines · 1.3 KBTypeScript Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
 * Markdown renders agent text (GitHub-flavoured: tables, task lists, ...).
 * Kept as the single markdown entry point so styling and plugins stay
 * consistent everywhere agent content appears.
 *
 * @example
 * <Markdown text="**bold** and `code`" />
 */

import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import type { Components } from "react-markdown";
import { CopyButton } from "./CopyButton";

export function Markdown({ text }: { text: string }) {
	const components: Components = {
		pre: ({ children, ...props }) => {
			// Extract code content from pre > code structure
			// react-markdown hands `pre` its rendered <code> child; type its props so
			// the string body can be extracted for the copy button.
			const codeElement = children as React.ReactElement<{
				children?: unknown;
			}>;
			const codeContent =
				codeElement?.props?.children &&
				typeof codeElement.props.children === "string"
					? codeElement.props.children
					: "";

			return (
				<div className="code-block-wrapper">
					{codeContent && (
						<CopyButton content={codeContent} label="Copy code" />
					)}
					<pre {...props}>{children}</pre>
				</div>
			);
		},
	};

	return (
		<div className="markdown">
			<ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>
				{text}
			</ReactMarkdown>
		</div>
	);
}