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>
  );
}