Fix markdown image rendering without resolver
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
a9802c1962
commit
f7c766ff32
2 changed files with 69 additions and 39 deletions
31
ui/src/components/MarkdownBody.test.tsx
Normal file
31
ui/src/components/MarkdownBody.test.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
// @vitest-environment node
|
||||||
|
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { renderToStaticMarkup } from "react-dom/server";
|
||||||
|
import { ThemeProvider } from "../context/ThemeContext";
|
||||||
|
import { MarkdownBody } from "./MarkdownBody";
|
||||||
|
|
||||||
|
describe("MarkdownBody", () => {
|
||||||
|
it("renders markdown images without a resolver", () => {
|
||||||
|
const html = renderToStaticMarkup(
|
||||||
|
<ThemeProvider>
|
||||||
|
<MarkdownBody>{""}</MarkdownBody>
|
||||||
|
</ThemeProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(html).toContain('<img src="/api/attachments/test/content" alt=""/>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resolves relative image paths when a resolver is provided", () => {
|
||||||
|
const html = renderToStaticMarkup(
|
||||||
|
<ThemeProvider>
|
||||||
|
<MarkdownBody resolveImageSrc={(src) => `/resolved/${src}`}>
|
||||||
|
{""}
|
||||||
|
</MarkdownBody>
|
||||||
|
</ThemeProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(html).toContain('src="/resolved/images/org-chart.png"');
|
||||||
|
expect(html).toContain('alt="Org chart"');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { isValidElement, useEffect, useId, useState, type CSSProperties, type ReactNode } from "react";
|
import { isValidElement, useEffect, useId, useState, type CSSProperties, type ReactNode } from "react";
|
||||||
import Markdown from "react-markdown";
|
import Markdown, { type Components } from "react-markdown";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
import { parseProjectMentionHref } from "@paperclipai/shared";
|
import { parseProjectMentionHref } from "@paperclipai/shared";
|
||||||
import { cn } from "../lib/utils";
|
import { cn } from "../lib/utils";
|
||||||
|
|
@ -116,17 +116,7 @@ function MermaidDiagramBlock({ source, darkMode }: { source: string; darkMode: b
|
||||||
|
|
||||||
export function MarkdownBody({ children, className, resolveImageSrc }: MarkdownBodyProps) {
|
export function MarkdownBody({ children, className, resolveImageSrc }: MarkdownBodyProps) {
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
return (
|
const components: Components = {
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"paperclip-markdown prose prose-sm max-w-none break-words overflow-hidden",
|
|
||||||
theme === "dark" && "prose-invert",
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Markdown
|
|
||||||
remarkPlugins={[remarkGfm]}
|
|
||||||
components={{
|
|
||||||
pre: ({ node: _node, children: preChildren, ...preProps }) => {
|
pre: ({ node: _node, children: preChildren, ...preProps }) => {
|
||||||
const mermaidSource = extractMermaidSource(preChildren);
|
const mermaidSource = extractMermaidSource(preChildren);
|
||||||
if (mermaidSource) {
|
if (mermaidSource) {
|
||||||
|
|
@ -154,14 +144,23 @@ export function MarkdownBody({ children, className, resolveImageSrc }: MarkdownB
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
img: resolveImageSrc
|
};
|
||||||
? ({ src, alt, ...imgProps }) => {
|
if (resolveImageSrc) {
|
||||||
|
components.img = ({ node: _node, src, alt, ...imgProps }) => {
|
||||||
const resolved = src ? resolveImageSrc(src) : null;
|
const resolved = src ? resolveImageSrc(src) : null;
|
||||||
return <img {...imgProps} src={resolved ?? src} alt={alt ?? ""} />;
|
return <img {...imgProps} src={resolved ?? src} alt={alt ?? ""} />;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
: undefined,
|
|
||||||
}}
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"paperclip-markdown prose prose-sm max-w-none break-words overflow-hidden",
|
||||||
|
theme === "dark" && "prose-invert",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
|
<Markdown remarkPlugins={[remarkGfm]} components={components}>
|
||||||
{children}
|
{children}
|
||||||
</Markdown>
|
</Markdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue