Spaces:
Running
Running
File size: 2,831 Bytes
3f76ff4 837e3ac 3f76ff4 837e3ac 3f76ff4 837e3ac 3f76ff4 | 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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | "use client";
import type { ReactNode } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { HelpCircle } from "lucide-react";
import { Button } from "@/components/ui/button";
function nodeText(value: ReactNode): string {
if (typeof value === "string" || typeof value === "number") {
return String(value);
}
if (Array.isArray(value)) {
return value.map((item) => nodeText(item)).join("");
}
if (value && typeof value === "object" && "props" in value) {
return nodeText((value as { props?: { children?: ReactNode } }).props?.children);
}
return "";
}
export function MarkdownContent(props: {
content: string;
onAskExcerpt?: (excerpt: string) => void;
}) {
const { content, onAskExcerpt } = props;
return (
<div className="markdown-content text-sm text-foreground">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={
onAskExcerpt
? {
p({ children }) {
const excerpt = nodeText(children).trim();
return (
<div className="mb-4 space-y-1.5 last:mb-0">
<p>{children}</p>
{excerpt ? (
<Button
type="button"
variant="ghost"
className="h-7 rounded-lg px-2 text-[11px] text-muted-foreground"
onClick={() => onAskExcerpt(excerpt)}
>
<HelpCircle className="h-3.5 w-3.5" />
<span className="ml-1">Ask about this paragraph</span>
</Button>
) : null}
</div>
);
},
li({ children }) {
const excerpt = nodeText(children).trim();
return (
<li>
<div className="space-y-1.5">
<div>{children}</div>
{excerpt ? (
<Button
type="button"
variant="ghost"
className="h-7 rounded-lg px-2 text-[11px] text-muted-foreground"
onClick={() => onAskExcerpt(excerpt)}
>
<HelpCircle className="h-3.5 w-3.5" />
<span className="ml-1">Ask about this item</span>
</Button>
) : null}
</div>
</li>
);
},
}
: undefined
}
>
{content}
</ReactMarkdown>
</div>
);
}
|