/** * public/search.ts — scrollback search box for the active terminal (M1). * * Adds a 🔍 button to the toolbar that toggles a small search overlay. * Enter = next, Shift+Enter = previous, Esc = close. */ export interface SearchHooks { find: (query: string, dir: 'next' | 'prev') => void clear: () => void } function makeBtn(label: string, title: string): HTMLButtonElement { const b = document.createElement('button') b.textContent = label b.title = title b.setAttribute('aria-label', title) return b } export function mountSearch(toolbar: HTMLElement, hooks: SearchHooks): void { const box = document.createElement('div') box.id = 'searchbox' box.style.display = 'none' const input = document.createElement('input') input.type = 'text' input.className = 'search-input' input.placeholder = 'Search scrollback…' const prev = makeBtn('↑', 'Previous match (Shift+Enter)') const next = makeBtn('↓', 'Next match (Enter)') const close = makeBtn('×', 'Close (Esc)') box.append(input, prev, next, close) document.body.appendChild(box) const open = (): void => { box.style.display = 'flex' input.focus() input.select() } const hide = (): void => { box.style.display = 'none' hooks.clear() } input.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault() hooks.find(input.value, e.shiftKey ? 'prev' : 'next') } else if (e.key === 'Escape') { e.preventDefault() hide() } e.stopPropagation() }) prev.addEventListener('click', () => hooks.find(input.value, 'prev')) next.addEventListener('click', () => hooks.find(input.value, 'next')) close.addEventListener('click', hide) const toggle = makeBtn('🔍', 'Search scrollback') toggle.className = 'toolbtn' toggle.addEventListener('click', () => (box.style.display === 'none' ? open() : hide())) toolbar.appendChild(toggle) }