// ========================================== // NotesPane Kit — Default Assembly // ========================================== // Wires useNotes + all sub-components into the standard // notes experience. Surfaces that need a different // layout import individual pieces instead. // // Usage: // import { NotesPane } from './components/notes-pane/index.js'; // html`<${NotesPane} handleRef=${ref} standalone=${true} />` // // Re-exports all pieces for kit consumers: // import { useNotes, NoteList, NoteEditor, ... } from './components/notes-pane/index.js'; import { useNotes } from './use-notes.js'; import { NoteList } from './note-list.js'; import { NoteListItem } from './note-list-item.js'; import { NoteEditor } from './note-editor.js'; import { NoteReader } from './note-reader.js'; import { QuickSwitcher, saveRecentNote } from './quick-switcher.js'; import { SaveToNoteDialog } from './save-to-note.js'; import { renderNoteMarkdown, attachWikilinkHandlers, resolveTransclusions, extractHeadings } from './markdown.js'; const { useState, useRef, useEffect, useCallback } = window.hooks; const html = window.html; /** * Default NotesPane assembly. * * @param {{ * initialFolder?: string, * initialNoteId?: string, * standalone?: boolean, * onNoteChange?: (note: object|null) => void, * handleRef?: { current: any }, * className?: string, * }} props */ export function NotesPane(props) { const { initialFolder, initialNoteId, standalone = true, onNoteChange, handleRef, className, } = props; const notes = useNotes({ initialFolder, initialNoteId, onNoteChange, standalone, enableGraph: true, enableQuickSwitcher: true, }); // ── Lazy-load graph component ─────────── const [GraphComp, setGraphComp] = useState(null); useEffect(() => { if (notes.view === 'graph' && !GraphComp) { import('./note-graph.js').then(m => setGraphComp(() => m.NoteGraph)); } }, [notes.view, GraphComp]); const graphHandleRef = useRef(null); // ── Graph data loading ────────────────── useEffect(() => { if (notes.view === 'graph' && !notes.graphData) { notes.loadGraph(); } }, [notes.view]); // ── Expose imperative handle ──────────── useEffect(() => { if (handleRef) { handleRef.current = { getView() { return notes.view; }, setView(v) { notes.setView(v); }, openNote(id) { saveRecentNote({ id, title: '' }); notes.openNote(id); }, newNote() { notes.newNote(); }, openDailyNote() { notes.openDailyNote(); }, refreshList() { notes.refreshList(); }, getEditingId() { return notes.editingId; }, openQuickSwitcher() { notes.setQuickSwitcherOpen(true); }, // Surface-driven filter controls (v0.37.11) setFolder(f) { notes.setFolder(f); }, setTagFilter(t) { notes.setTagFilter(t); }, setSearchQuery(q) { notes.setSearchQuery(q); }, getFolder() { return notes.folder; }, getTagFilter() { return notes.tagFilter; }, }; } }); // ── Quick switcher create-new handler ─── const onQuickSwitcherCreate = useCallback((title) => { notes.newNote(); // The editor will open blank — we can't pre-fill via state here // but the title will be empty for the user to type }, [notes.newNote]); // ── View routing ──────────────────────── const renderView = () => { switch (notes.view) { case 'list': return html` <${NoteList} notes=${notes.notes} loading=${notes.loading} hasMore=${notes.hasMore} loadMore=${notes.loadMore} folders=${notes.folders} folder=${notes.folder} setFolder=${notes.setFolder} sort=${notes.sort} setSort=${notes.setSort} searchQuery=${notes.searchQuery} setSearchQuery=${notes.setSearchQuery} tagFilter=${notes.tagFilter} setTagFilter=${notes.setTagFilter} selectMode=${notes.selectMode} selectedIds=${notes.selectedIds} enterSelectMode=${notes.enterSelectMode} exitSelectMode=${notes.exitSelectMode} toggleSelect=${notes.toggleSelect} toggleSelectAll=${notes.toggleSelectAll} bulkDelete=${notes.bulkDelete} onNoteClick=${(id) => { saveRecentNote({ id, title: '' }); notes.openNote(id); }} onNewNote=${notes.newNote} onDailyNote=${notes.openDailyNote} onGraphClick=${() => notes.setView('graph')} pinnedIds=${notes.pinnedIds} togglePin=${notes.togglePin} standalone=${standalone} />`; case 'editor': return html` <${NoteEditor} currentNote=${notes.currentNote} editingId=${notes.editingId} folders=${notes.folders} onSave=${notes.saveNote} onCancel=${() => { if (notes.currentNote) { notes.setEditorMode('read'); notes.setView('reader'); } else { notes.setView('list'); notes.refreshList(); } }} onDelete=${notes.deleteNote} />`; case 'reader': return html` <${NoteReader} note=${notes.currentNote} backlinks=${notes.backlinks} onEdit=${() => { notes.setEditorMode('edit'); notes.setView('editor'); }} onDelete=${notes.deleteNote} onCopy=${notes.copyNote} onNavigateLink=${notes.navigateToLink} onBack=${() => { notes.setView('list'); notes.refreshList(); }} isDailyNote=${notes.isDailyNote} onDailyPrev=${() => notes.navigateDaily(-1)} onDailyNext=${() => notes.navigateDaily(1)} />`; case 'graph': if (!GraphComp) { return html`