feat: full Internal Link Picker with search and type filter

Replace broken ObjectPickerModal and manual modal with proper
InternalLinkPicker component:

- Search field with debounced SearchNodes API calls
- Type tabs: Дело, Заметка, Файл, Секрет (disabled)
- Results list showing title + path, keyboard navigation
- Inserts [Title](verstak://type/id) at cursor position
- No layout breakage — picker is a normal modal via position:fixed
- Escape/Cancel close picker cleanly
- bind:this on NoteEditorPanel → MarkdownEditor.insertText()

Also:
- MarkdownEditor: added public insertText() method + bind:this
- NoteEditorPanel: added bind:this on MarkdownEditor + public insertText()
- Removed manual modal, insertInternalLinkMarkdown(), document.querySelector
This commit is contained in:
2026-06-15 09:57:11 +08:00
parent 39d3b82199
commit 7521eea109
8 changed files with 461 additions and 157 deletions
@@ -9,6 +9,23 @@
const dispatch = createEventDispatcher();
let textareaRef;
// ─── Public API: insert text at cursor ──────────────────────────
export function insertText(text) {
const ta = textareaRef;
if (!ta) return;
const start = ta.selectionStart;
const end = ta.selectionEnd;
const before = content.substring(0, start);
const after = content.substring(end);
const newContent = before + text + after;
content = newContent;
dispatch('content-change', { content: newContent });
requestAnimationFrame(() => {
ta.focus();
ta.selectionStart = ta.selectionEnd = start + text.length;
});
}
// ─── Core insert helper ──────────────────────────────────────────
function insertAtCursor(before, after = '', placeholder = '') {
const ta = textareaRef;