- TipTap 2 → 3: Extension from @tiptap/core, Placeholder from @tiptap/extensions, TaskList/TaskItem from @tiptap/extension-list, link: false in StarterKit (now bundles Link), @tiptap/core added - marked 15 → 17: heading renderer updated to tokens/parseInline API - Pinia 2 → 3, Vue Router 4 → 5 (no code changes required) - Vite 6 → 7, @vitejs/plugin-vue 5 → 6, vue-tsc 2 → 3 - TypeScript 5.6 → 5.9: fixed Uint8Array<ArrayBuffer> strictness in push.ts, removed unused bodyEl ref in NoteViewerView.vue - .npmrc: legacy-peer-deps=true for TipTap v3 peer dep resolution TipTap 3 new capabilities now available: static renderer (createStaticRenderer), MarkViews, @tiptap/extensions package. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
import { Extension } from "@tiptap/core";
|
|
import { PluginKey } from "@tiptap/pm/state";
|
|
import Suggestion from "@tiptap/suggestion";
|
|
import { createSuggestionRenderer } from "./suggestionRenderer";
|
|
import { apiGet } from "@/api/client";
|
|
import type { SuggestionItem } from "@/components/SuggestionDropdown.vue";
|
|
|
|
interface NoteListResponse {
|
|
notes: Array<{ id: number; title: string }>;
|
|
}
|
|
|
|
const wikilinkSuggestionPluginKey = new PluginKey("wikilinkSuggestion");
|
|
|
|
export const WikilinkSuggestion = Extension.create({
|
|
name: "wikilinkSuggestion",
|
|
|
|
addProseMirrorPlugins() {
|
|
return [
|
|
Suggestion<SuggestionItem>({
|
|
editor: this.editor,
|
|
pluginKey: wikilinkSuggestionPluginKey,
|
|
char: "[[",
|
|
allowSpaces: true,
|
|
items: async ({ query }): Promise<SuggestionItem[]> => {
|
|
try {
|
|
const data = await apiGet<NoteListResponse>(
|
|
`/api/notes?q=${encodeURIComponent(query)}&limit=8`
|
|
);
|
|
return data.notes.map((n) => ({
|
|
label: n.title || "Untitled",
|
|
value: n.title || "Untitled",
|
|
}));
|
|
} catch {
|
|
return [];
|
|
}
|
|
},
|
|
command: ({ editor, range, props: item }) => {
|
|
editor
|
|
.chain()
|
|
.focus()
|
|
.deleteRange(range)
|
|
.insertContent(`[[${item.value}]]`)
|
|
.run();
|
|
},
|
|
render: createSuggestionRenderer,
|
|
}),
|
|
];
|
|
},
|
|
});
|