feat: add keyboard navigation

This commit is contained in:
Henry
2025-10-01 22:15:09 +01:00
parent 6904bce96b
commit 468bd8afec

View File

@@ -1,4 +1,4 @@
import Link from "next/link"; import { useRouter } from "next/router";
import { import {
Combobox, Combobox,
ComboboxInput, ComboboxInput,
@@ -43,6 +43,7 @@ export default function CommandPallette({
}) { }) {
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const { workspace } = useWorkspace(); const { workspace } = useWorkspace();
const router = useRouter();
// Debounce to avoid too many reqs // Debounce to avoid too many reqs
const [debouncedQuery] = useDebounce(query, 300); const [debouncedQuery] = useDebounce(query, 300);
@@ -99,6 +100,21 @@ export default function CommandPallette({
placeholder="Search boards and cards..." placeholder="Search boards and cards..."
value={query} value={query}
onChange={(event) => setQuery(event.target.value)} 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();
}
}
}}
/> />
<HiMagnifyingGlass <HiMagnifyingGlass
className="pointer-events-none col-start-1 row-start-1 ml-4 size-5 self-center text-light-700 dark:text-dark-700" className="pointer-events-none col-start-1 row-start-1 ml-4 size-5 self-center text-light-700 dark:text-dark-700"
@@ -113,20 +129,20 @@ export default function CommandPallette({
isPlaceholderData ? "opacity-75" : "" isPlaceholderData ? "opacity-75" : ""
}`} }`}
> >
{results.map((result) => ( {results.map((result) => {
<ComboboxOption const url =
key={`${result.type}-${result.publicId}`} result.type === "board"
value={result} ? `/boards/${result.publicId}`
className="group" : `/cards/${result.publicId}`;
>
<Link return (
href={ <ComboboxOption
result.type === "board" key={`${result.type}-${result.publicId}`}
? `/boards/${result.publicId}` value={result}
: `/cards/${result.publicId}` className="cursor-pointer select-none px-4 py-3 data-[focus]:bg-light-200 hover:bg-light-200 focus:outline-none dark:data-[focus]:bg-dark-200 dark:hover:bg-dark-200"
}
className="block cursor-pointer select-none px-4 py-3 data-[focus]:bg-light-200 hover:bg-light-200 focus:outline-none dark:data-[focus]:bg-dark-200 dark:hover:bg-dark-200"
onClick={() => { onClick={() => {
console.log("clicked", url);
void router.push(url);
onClose(); onClose();
setQuery(""); setQuery("");
}} }}
@@ -143,9 +159,9 @@ export default function CommandPallette({
)} )}
</div> </div>
</div> </div>
</Link> </ComboboxOption>
</ComboboxOption> );
))} })}
</ComboboxOptions> </ComboboxOptions>
)} )}