feat: complete public wiki and embedded previews

This commit is contained in:
吉鑫升 committed 2026-08-24 20:40:44 +08:00
1 parent bc49df4561
commit 30943159bf
18 files changed
+926 -48

No files matched your search

@@ -1,7 +1,12 @@
"use client";
import { useMemo } from "react";
import type { AnchorHTMLAttributes, HTMLAttributes, ReactNode } from "react";
import type {
AnchorHTMLAttributes,
HTMLAttributes,
MouseEvent as ReactMouseEvent,
ReactNode,
} from "react";
import {
MessageResponse,
@@ -34,6 +39,12 @@ export type MarkdownContentProps = {
className?: string;
remarkPlugins?: MessageResponseProps["remarkPlugins"];
components?: MessageResponseProps["components"];
linkClassName?: (href: string, label: string) => string | undefined;
onLinkClick?: (
event: ReactMouseEvent<HTMLAnchorElement>,
href: string,
label: string,
) => void;
};
/** Renders markdown content. */
@@ -43,6 +54,8 @@ export function MarkdownContent({
className,
remarkPlugins = streamdownPlugins.remarkPlugins,
components: componentsFromProps,
linkClassName,
onLinkClick,
}: MarkdownContentProps) {
const anchorResolver = useMemo(() => createMarkdownAnchorResolver(content), [content]);
const components = useMemo(() => {
@@ -93,6 +106,7 @@ export function MarkdownContent({
);
}
const finalHref = resolvedHref ?? props.href;
const label = extractTextFromChildren(props.children);
return (
<a
{...rest}
@@ -100,6 +114,7 @@ export function MarkdownContent({
className={cn(
"text-primary decoration-primary/30 hover:decoration-primary/60 underline underline-offset-2 transition-colors",
className,
linkClassName?.(finalHref || "", label),
)}
target={target ?? (external ? "_blank" : undefined)}
rel={rel ?? (external ? "noopener noreferrer" : undefined)}
@@ -110,6 +125,7 @@ export function MarkdownContent({
event.preventDefault();
scrollToInPageAnchor(event.currentTarget, finalHref);
}
onLinkClick?.(event, finalHref || "", label);
rest.onClick?.(event);
}}
/>
@@ -117,7 +133,7 @@ export function MarkdownContent({
},
...componentsFromProps,
};
}, [anchorResolver, componentsFromProps]);
}, [anchorResolver, componentsFromProps, linkClassName, onLinkClick]);
if (!content) return null;