Feat: Enable the wiki's Markdown editor to navigate to a new Markdown file when a link is clicked. (#17019)

This commit is contained in:
balibabu
2026-07-17 11:22:18 +08:00
committed by GitHub
parent f69ed74670
commit 677960716e
12 changed files with 688 additions and 194 deletions

View File

@@ -40,6 +40,7 @@ interface Props {
placeholder?: string;
onToggleSource?: () => void;
showSource?: boolean;
onWikiLinkClick?: (pageType: 'concept' | 'entity', slug: string) => void;
}
function InitialContentPlugin({
@@ -133,6 +134,7 @@ function ChangeListener({
import FloatingSelectionToolbar from './plugins/floating-selection-toolbar';
import TableActionsPlugin from './plugins/table-actions-plugin';
import ToolbarPlugin from './plugins/toolbar-plugin';
import { WikiLinkClickPlugin } from './plugins/wiki-link-click-plugin';
export default function LexicalEditor({
content,
@@ -141,6 +143,7 @@ export default function LexicalEditor({
placeholder = 'Start writing...',
onToggleSource,
showSource = false,
onWikiLinkClick,
}: Props): JSX.Element {
const transformers = useMemo(() => CORE_TRANSFORMERS, []);
@@ -187,6 +190,7 @@ export default function LexicalEditor({
<MarkdownShortcutPlugin transformers={transformers} />
<ListPlugin />
<LinkPlugin />
<WikiLinkClickPlugin onWikiLinkClick={onWikiLinkClick} />
<HashtagPlugin />
<TablePlugin />
<TableActionsPlugin />

View File

@@ -0,0 +1,50 @@
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import {
parseWikiLinkHref,
type WikiPageType,
} from '@/pages/dataset/compilation/utils/parse-wiki-link';
import { useEffect } from 'react';
type WikiLinkClickPluginProps = {
onWikiLinkClick?: (pageType: WikiPageType, slug: string) => void;
};
function findAnchorElement(
target: EventTarget | null,
): HTMLAnchorElement | null {
if (!(target instanceof HTMLElement)) return null;
return target.closest('a[href]') as HTMLAnchorElement | null;
}
export function WikiLinkClickPlugin({
onWikiLinkClick,
}: WikiLinkClickPluginProps) {
const [editor] = useLexicalComposerContext();
useEffect(() => {
if (!onWikiLinkClick) return;
const rootElement = editor.getRootElement();
if (!rootElement) return;
const handleClick = (event: MouseEvent) => {
const anchor = findAnchorElement(event.target);
if (!anchor) return;
const href = anchor.getAttribute('href');
if (!href) return;
const parsed = parseWikiLinkHref(href);
if (!parsed) return;
event.preventDefault();
event.stopPropagation();
onWikiLinkClick(parsed.pageType, parsed.slug);
};
rootElement.addEventListener('click', handleClick);
return () => rootElement.removeEventListener('click', handleClick);
}, [editor, onWikiLinkClick]);
return null;
}