import { createSignal, For, Show } from "solid-js"; import type { VaultEntry } from "../../shared/types"; import { sendMessage } from "../../shared/bridge"; import { NoteRow } from "../components/NoteRow"; interface NotesTOCProps { notes: VaultEntry[]; onBack: () => void; onOpenNote: (note: VaultEntry, rowEl: HTMLElement) => void; onNewNote: () => void; onRefresh: () => void; /** Note being expanded — other rows should fade away */ expandingNoteId?: string | null; } export function NotesTOC(props: NotesTOCProps) { const [searchVisible, setSearchVisible] = createSignal(false); const [searchQuery, setSearchQuery] = createSignal(""); let searchInputRef!: HTMLInputElement; function filteredNotes() { const q = searchQuery().trim().toLowerCase(); if (!q) return props.notes; return props.notes.filter((n) => (n.title ?? "").toLowerCase().includes(q) || (n.notes ?? "").toLowerCase().includes(q) ); } function showSearch() { setSearchVisible(true); setTimeout(() => searchInputRef?.focus(), 50); } function clearSearch() { setSearchQuery(""); setSearchVisible(false); } async function handleDelete(note: VaultEntry) { await sendMessage({ type: "DELETE_NOTE", payload: { id: note.id } }); props.onRefresh(); } async function handleArchive(note: VaultEntry) { // Archive = soft delete with a tag — for now just delete to trash await sendMessage({ type: "DELETE_ENTRY", payload: { id: note.id } }); props.onRefresh(); } return (
{/* Header */}
setSearchQuery((e.target as HTMLInputElement).value)} aria-label="Search notes" /> } > notes.
{/* Note list */}
0} fallback={

{searchQuery() ? "No notes match." : "No notes yet.\nStart writing."}

} > {(note) => { // Permanent index from the unfiltered list — never changes during search const permanentIndex = () => props.notes.findIndex((n) => n.id === note.id); const expandingIdx = () => props.notes.findIndex((n) => n.id === props.expandingNoteId); const expanding = () => props.expandingNoteId && props.expandingNoteId !== note.id; const expandingNote = () => props.expandingNoteId === note.id; return ( props.onOpenNote(n, el)} onDelete={handleDelete} onArchive={handleArchive} fadingClass={ expanding() ? (permanentIndex() < expandingIdx() ? "is-expanding-away is-expanding-away-up" : "is-expanding-away is-expanding-away-down") : expandingNote() ? "is-expanding-target" : undefined } /> ); }}
); }