Skip to content
File

Blob: src/client/components/editor/controllers/page-mention/picker-overlay.ts

typescript59 lines
1import type { Editor } from "@tiptap/core";
2import { mountEditorRenderer } from "../menu/renderer";
3import {
4 PageMentionPickerPanel,
5 type PageMentionItem,
6 type PageMentionFilterMode,
7 type PageMentionPickerPanelHandle,
8 type PageMentionPickerPanelProps,
9} from "./picker-panel";
10 
11interface PageMentionPickerMountOpts {
12 contextElement?: HTMLElement | null;
13 items: PageMentionItem[];
14 filterMode: PageMentionFilterMode;
15 command: (item: PageMentionItem) => void;
16 clientRect: (() => DOMRect | null) | null;
17 onCancel?: () => void;
18}
19 
20export interface PageMentionPickerHandle {
21 updateProps(next: Partial<PageMentionPickerMountOpts>): void;
22 onKeyDown(event: KeyboardEvent): boolean;
23 destroy(): void;
24}
25 
26export function mountPageMentionPicker(editor: Editor, opts: PageMentionPickerMountOpts): PageMentionPickerHandle {
27 const component = mountEditorRenderer<PageMentionPickerPanelHandle, PageMentionPickerPanelProps>(
28 editor,
29 PageMentionPickerPanel,
30 {
31 items: opts.items,
32 filterMode: opts.filterMode,
33 command: (item: PageMentionItem) => opts.command(item),
34 clientRect: opts.clientRect,
35 contextElement: opts.contextElement ?? editor.view.dom,
36 onCancel: opts.onCancel,
37 },
38 );
39 
40 return {
41 updateProps(next) {
42 component.updateProps({
43 ...(next.items !== undefined && { items: next.items }),
44 ...(next.filterMode !== undefined && { filterMode: next.filterMode }),
45 ...(next.command !== undefined && { command: (item: PageMentionItem) => next.command!(item) }),
46 ...(next.clientRect !== undefined && { clientRect: next.clientRect }),
47 ...(next.contextElement !== undefined && { contextElement: next.contextElement }),
48 ...(next.onCancel !== undefined && { onCancel: next.onCancel }),
49 });
50 },
51 onKeyDown(event) {
52 return component.ref?.onKeyDown(event) ?? false;
53 },
54 destroy() {
55 component.destroy();
56 },
57 };
58}