Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 9x 9x | import type { JSX } from "react";
import Markdown, { type Components, type ExtraProps } from "react-markdown";
import rehypePrismPlus from "rehype-prism-plus/common";
import remarkGfm from "remark-gfm";
import styles from "./DocPane.module.scss";
/** Props for {@link MarkdownPreview}. */
export interface MarkdownPreviewProps {
/** The markdown source to render. */
content: string;
/** Open a `file://` link clicked inside the document as a new doc tab. */
onOpenUri?: (uri: string) => void;
}
/**
* Renders a markdown document as trusted, first-party content (#1396).
*
* Markdown from a file in the user's own worktree is NOT agent-authored widget
* content, so it renders directly via react-markdown (GFM + Prism highlight),
* not through the widget/iframe sandbox. `file://` links open as new doc tabs;
* external links open in a new tab.
*/
export function MarkdownPreview({ content, onOpenUri }: MarkdownPreviewProps): JSX.Element {
const components: Components = {
a(props: JSX.IntrinsicElements["a"] & ExtraProps) {
const { href, children } = props;
Iif (href && href.startsWith("file://") && onOpenUri) {
return (
<a
href={href}
onClick={(e) => {
e.preventDefault();
onOpenUri(href);
}}
>
{children}
</a>
);
}
return (
<a href={href} target="_blank" rel="noreferrer noopener">
{children}
</a>
);
},
};
return (
<div className={styles.markdownBody} data-testid="doc-markdown">
<Markdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypePrismPlus]}
components={components}
>
{content}
</Markdown>
</div>
);
}
|