From 468bd8afecfc43a0b3938ecf4299b4a76ce29642 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 1 Oct 2025 22:15:09 +0100 Subject: [PATCH] feat: add keyboard navigation --- apps/web/src/components/CommandPallette.tsx | 50 ++++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/apps/web/src/components/CommandPallette.tsx b/apps/web/src/components/CommandPallette.tsx index 5e1e6f7a..e39a9de6 100644 --- a/apps/web/src/components/CommandPallette.tsx +++ b/apps/web/src/components/CommandPallette.tsx @@ -1,4 +1,4 @@ -import Link from "next/link"; +import { useRouter } from "next/router"; import { Combobox, ComboboxInput, @@ -43,6 +43,7 @@ export default function CommandPallette({ }) { const [query, setQuery] = useState(""); const { workspace } = useWorkspace(); + const router = useRouter(); // Debounce to avoid too many reqs const [debouncedQuery] = useDebounce(query, 300); @@ -99,6 +100,21 @@ export default function CommandPallette({ placeholder="Search boards and cards..." value={query} onChange={(event) => setQuery(event.target.value)} + onKeyDown={(event) => { + if (event.key === "Enter" && results.length > 0) { + event.preventDefault(); + + // Find the active option or fallback to first option + const targetOption = + document.querySelector( + '[data-headlessui-state*="active"][role="option"]', + ) ?? document.querySelector('[role="option"]'); + + if (targetOption) { + (targetOption as HTMLElement).click(); + } + } + }} /> - {results.map((result) => ( - - { + const url = + result.type === "board" + ? `/boards/${result.publicId}` + : `/cards/${result.publicId}`; + + return ( + { + console.log("clicked", url); + void router.push(url); onClose(); setQuery(""); }} @@ -143,9 +159,9 @@ export default function CommandPallette({ )} - - - ))} + + ); + })} )}