From 9488670b1b8b1c2f0cae4c5a7035617f58f90956 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Mon, 27 Apr 2026 02:10:23 -0400 Subject: [PATCH] fix(ext/popup): fix reversed search, remove auto-focus, Enter opens items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Search no longer auto-focuses; use "/" to focus it - Typing in search no longer re-renders the entire view, just the item list — fixes backwards text caused by cursor reset to pos 0 - Arrow keys also update list without full re-render - Enter opens the selected item even when search is focused Co-Authored-By: Claude --- extension/src/popup/components/item-list.ts | 57 +++++++++++++-------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/extension/src/popup/components/item-list.ts b/extension/src/popup/components/item-list.ts index 111b1ef..9b03960 100644 --- a/extension/src/popup/components/item-list.ts +++ b/extension/src/popup/components/item-list.ts @@ -25,11 +25,10 @@ function typeIcon(t: ItemType): string { } } -export function renderItemList(app: HTMLElement): void { +function buildRowsHtml(): string { const state = getState(); const filtered = getFilteredEntries(); - - const rowsHtml = filtered.length > 0 + return filtered.length > 0 ? filtered.map(([id, e], i) => `
${escapeHtml(e.title)}${e.attachment_summaries.length > 0 ? ' 📎' : ''} @@ -37,7 +36,28 @@ export function renderItemList(app: HTMLElement): void {
`).join('') : '
no items
'; +} +function updateItemList(): void { + const list = document.getElementById('item-list'); + if (list) { + list.innerHTML = buildRowsHtml(); + wireRowClicks(); + } +} + +function wireRowClicks(): void { + document.querySelectorAll('.entry-row').forEach(row => { + row.addEventListener('click', async () => { + const id = (row as HTMLElement).dataset.id!; + document.removeEventListener('keydown', handleListKeydown); + await openItem(id); + }); + }); +} + +export function renderItemList(app: HTMLElement): void { + const state = getState(); app.innerHTML = `
- ${rowsHtml} + ${buildRowsHtml()}
/ search @@ -64,7 +84,12 @@ export function renderItemList(app: HTMLElement): void { const searchInput = document.getElementById('search-input') as HTMLInputElement | null; searchInput?.addEventListener('input', () => { - setState({ searchQuery: searchInput.value, selectedIndex: 0 }); + const state2 = getState(); + state2.searchQuery = searchInput.value; + state2.selectedIndex = 0; + const list = document.getElementById('item-list'); + if (list) list.innerHTML = buildRowsHtml(); + wireRowClicks(); }); document.getElementById('new-btn')?.addEventListener('click', () => { @@ -98,21 +123,9 @@ export function renderItemList(app: HTMLElement): void { showSettingsPicker(e.currentTarget as HTMLElement); }); - // Item row clicks. - const rows = app.querySelectorAll('.entry-row'); - rows.forEach(row => { - row.addEventListener('click', async () => { - const id = (row as HTMLElement).dataset.id!; - document.removeEventListener('keydown', handleListKeydown); - await openItem(id); - }); - }); + wireRowClicks(); - // Keyboard navigation. document.addEventListener('keydown', handleListKeydown); - - // Focus search on open. - searchInput?.focus(); } async function openItem(id: ItemId): Promise { @@ -195,17 +208,19 @@ function handleListKeydown(e: KeyboardEvent): void { if (e.key === 'ArrowDown') { e.preventDefault(); const max = Math.max(filtered.length - 1, 0); - setState({ selectedIndex: Math.min(state.selectedIndex + 1, max) }); + state.selectedIndex = Math.min(state.selectedIndex + 1, max); + updateItemList(); return; } if (e.key === 'ArrowUp') { e.preventDefault(); - setState({ selectedIndex: Math.max(state.selectedIndex - 1, 0) }); + state.selectedIndex = Math.max(state.selectedIndex - 1, 0); + updateItemList(); return; } - if (e.key === 'Enter' && !isSearch) { + if (e.key === 'Enter') { e.preventDefault(); const selected = filtered[state.selectedIndex]; if (selected) {