diff --git a/src/hooks/use-kbd-shortcuts.ts b/src/hooks/use-kbd-shortcuts.ts new file mode 100644 index 00000000..02a65b3e --- /dev/null +++ b/src/hooks/use-kbd-shortcuts.ts @@ -0,0 +1,30 @@ +import { useEffect } from "react"; + +export function useKbdShortcuts(map: [string, () => void][]) { + return useEffect(() => { + const documentListener = (e: KeyboardEvent) => { + const target = e.target as HTMLElement; + if ( + target.tagName === "INPUT" || + target.tagName === "TEXTAREA" || + target.isContentEditable + ) { + return; + } + + for (const [key, callback] of map) { + if (e.key.toLowerCase() === key.toLowerCase()) { + e.preventDefault(); + e.stopPropagation(); + callback(); + } + } + }; + + document.addEventListener("keydown", documentListener); + + return () => { + document.removeEventListener("keydown", documentListener); + }; + }, [map]); +} diff --git a/src/lib/hrefs.ts b/src/lib/hrefs.ts new file mode 100644 index 00000000..5c124f3f --- /dev/null +++ b/src/lib/hrefs.ts @@ -0,0 +1,5 @@ +export const hrefs = { + workspaces: { + create: "/workspace/create", + }, +}; diff --git a/src/routes/route-workspaces.tsx b/src/routes/route-workspaces.tsx index 22b2dda1..b089078a 100644 --- a/src/routes/route-workspaces.tsx +++ b/src/routes/route-workspaces.tsx @@ -19,6 +19,9 @@ import { useArchivedWorkspaces } from "@/features/workspace/hooks/use-archived-w import { Workspace } from "@/api/generated"; import SvgFlipBackward from "@/components/icons/FlipBackward"; import { useRestoreWorkspaceButton } from "@/features/workspace/hooks/use-restore-workspace-button"; +import { useKbdShortcuts } from "@/hooks/use-kbd-shortcuts"; +import { useNavigate } from "react-router-dom"; +import { hrefs } from "@/lib/hrefs"; function CellName({ name, @@ -89,6 +92,10 @@ export function RouteWorkspaces() { })) ?? []), ]; + const navigate = useNavigate(); + + useKbdShortcuts([["c", () => navigate(hrefs.workspaces.create)]]); + return ( <> @@ -97,7 +104,7 @@ export function RouteWorkspaces() { - + Create Workspace