···
const [input, setInput] = createSignal<string>();
67
+
const [selectedIndex, setSelectedIndex] = createSignal(-1);
const [search] = createResource(createDebouncedValue(input, 250), fetchTypeahead);
const processInput = async (input: string) => {
input = input.trim().replace(/^@/, "");
if (!input.length) return;
73
+
const index = selectedIndex() >= 0 ? selectedIndex() : 0;
75
+
setInput(undefined);
76
+
setSelectedIndex(-1);
74
-
navigate(`/at://${search()![0].did}`);
78
+
navigate(`/at://${search()![index].did}`);
} else if (input.startsWith("https://") || input.startsWith("http://")) {
const hostLength = input.indexOf("/", 8);
const host = input.slice(0, hostLength).replace("https://", "").replace("http://", "");
···
class="grow py-1 select-none placeholder:text-sm focus:outline-none"
121
-
onInput={(e) => setInput(e.currentTarget.value)}
126
+
setInput(e.currentTarget.value);
127
+
setSelectedIndex(-1);
129
+
onKeyDown={(e) => {
130
+
const results = search();
131
+
if (!results?.length) return;
133
+
if (e.key === "ArrowDown") {
134
+
e.preventDefault();
135
+
setSelectedIndex((prev) => (prev === -1 ? 0 : (prev + 1) % results.length));
136
+
} else if (e.key === "ArrowUp") {
137
+
e.preventDefault();
138
+
setSelectedIndex((prev) =>
139
+
prev === -1 ? results.length - 1 : (prev - 1 + results.length) % results.length,
<Show when={input()} fallback={ListUrlsTooltip()}>
···
<Show when={search()?.length && input()}>
<div class="dark:bg-dark-300 dark:shadow-dark-700 absolute z-30 mt-1 flex w-full flex-col rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-2 shadow-md transition-opacity duration-200 dark:border-neutral-700 starting:opacity-0">
157
+
{(actor, index) => (
138
-
class="flex items-center gap-2 rounded-lg p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
159
+
class={`flex items-center gap-2 rounded-lg p-1 transition-colors duration-150 ${
160
+
index() === selectedIndex() ?
161
+
"bg-neutral-200 dark:bg-neutral-700"
162
+
: "hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600"
href={`/at://${actor.did}`}
onClick={() => setShowSearch(false)}