diff --git a/src/routes/(marketing)/search/+page.svelte b/src/routes/(marketing)/search/+page.svelte index af0d27a0..ae6a85de 100644 --- a/src/routes/(marketing)/search/+page.svelte +++ b/src/routes/(marketing)/search/+page.svelte @@ -15,6 +15,7 @@ let fuse: Fuse | undefined let loading = true + let error = false onMount(async () => { try { const response = await fetch("/search/api") @@ -26,10 +27,12 @@ const index = Fuse.parseIndex(searchData.index) fuse = new Fuse(searchData.indexData, fuseOptions, index) } - } catch (error) { - console.error("Failed to load search data", error) + } catch (e) { + console.error("Failed to load search data", e) + error = true } finally { loading = false + document.getElementById("search-input")?.focus() } }) @@ -56,8 +59,29 @@ goto("#" + searchQuery, { keepFocus: true }) } } + + let focusItem = 0 + function onKeyDown(event: KeyboardEvent) { + if (event.key === "Escape") { + searchQuery = "" + } else if (event.key === "ArrowDown" || event.key === "ArrowUp") { + focusItem += event.key === "ArrowDown" ? 1 : -1 + if (focusItem < 0) { + focusItem = 0 + } else if (focusItem > results.length) { + focusItem = results.length + } + if (focusItem === 0) { + document.getElementById("search-input")?.focus() + } else { + document.getElementById(`search-result-${focusItem}`)?.focus() + } + } + } + + Search @@ -80,6 +104,7 @@ class="grow" placeholder="Search" bind:value={searchQuery} + on:focus={() => (focusItem = 0)} aria-label="Search input" /> @@ -88,7 +113,13 @@
Loading...
{/if} - {#if !loading && searchQuery.length > 0 && results.length === 0} + {#if error} +
+ Error connecting to search. Please try again later. +
+ {/if} + + {#if !loading && searchQuery.length > 0 && results.length === 0 && !error}
No results found
{#if dev}