diff --git a/src/pages/docs/search.tsx b/src/pages/docs/search.tsx index 6720faf..8aca158 100644 --- a/src/pages/docs/search.tsx +++ b/src/pages/docs/search.tsx @@ -10,23 +10,54 @@ export function DocsSearch() { const [query, setQuery] = state(''); const [loading, setLoading] = state(false); const [results, setResults] = state([]); + const [error, setError] = state(false); + let searchGeneration = 0; + + const focusInput = (element: HTMLElement | null) => { + window.setTimeout( + () => + element + ?.querySelector('[data-docs-search-input]') + ?.focus(), + 0 + ); + }; + + const openSearch = (element?: HTMLElement | null) => { + setOpen(true); + focusInput(element ?? null); + }; const runSearch = async (value: string) => { + const generation = ++searchGeneration; setQuery(value); + setError(false); if (!value.trim()) { setResults([]); + setLoading(false); return; } setLoading(true); - const { searchDocs } = await import('./search-index'); - setResults(searchDocs(value)); - setLoading(false); + try { + const { searchDocs } = await import('./search-index'); + if (generation !== searchGeneration) return; + setResults(searchDocs(value)); + } catch { + if (generation !== searchGeneration) return; + setResults([]); + setError(true); + } finally { + if (generation === searchGeneration) setLoading(false); + } }; const close = () => { + searchGeneration += 1; setOpen(false); setQuery(''); setResults([]); + setLoading(false); + setError(false); }; return (
- element - .querySelector('[data-docs-search-input]') - ?.focus(), - 0 - ); + openSearch(element); } if (event.key === 'Escape' && open()) close(); }); @@ -60,7 +84,9 @@ export function DocsSearch() {