// public/views/cards/search.js import { el, mount } from '../../dom.js'; import { api } from '../../api.js'; import { navigate } from '../../router.js'; const ROUTE = { page: id => '#/page/' + id, ref: id => '#/ref/' + id, source_doc: () => '#/', message: () => '#/' }; let body, input, results, deb; async function run(q) { if (!q) { mount(results); return; } try { const hits = await api.get('/api/search?q=' + encodeURIComponent(q)); mount(results, (hits || []).slice(0, 6).map(h => el('div', { class: 'sv-row', style: { cursor: 'pointer' }, onclick: () => { const r = ROUTE[h.kind]; if (r) navigate(r(h.id)); } }, el('span', {}, h.title_or_snippet || '(untitled)'), el('span', { class: 'k' }, h.kind)) )); } catch { mount(results, el('span', { class: 'muted' }, 'Search failed')); } } export default { id: 'search', title: 'Spotlight', size: 'l', mount(el_) { body = el_; input = el('input', { class: 'sv-search-input', placeholder: 'Search the Void…', oninput: e => { clearTimeout(deb); const q = e.target.value.trim(); deb = setTimeout(() => run(q), 250); } }); results = el('div', { style: { marginTop: '10px' } }); mount(body, input, results); }, start() {}, stop() { body = null; } };