Skip to content

Commit 0d935a3

Browse files
feat: useKbdShortcuts hook & example implementation (#180)
* feat: useKbdShortcuts hook & example implementation * chore: tidy up remnant
1 parent 6da034d commit 0d935a3

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

src/hooks/use-kbd-shortcuts.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useEffect } from "react";
2+
3+
export function useKbdShortcuts(map: [string, () => void][]) {
4+
return useEffect(() => {
5+
const documentListener = (e: KeyboardEvent) => {
6+
const target = e.target as HTMLElement;
7+
if (
8+
target.tagName === "INPUT" ||
9+
target.tagName === "TEXTAREA" ||
10+
target.isContentEditable
11+
) {
12+
return;
13+
}
14+
15+
for (const [key, callback] of map) {
16+
if (e.key.toLowerCase() === key.toLowerCase()) {
17+
e.preventDefault();
18+
e.stopPropagation();
19+
callback();
20+
}
21+
}
22+
};
23+
24+
document.addEventListener("keydown", documentListener);
25+
26+
return () => {
27+
document.removeEventListener("keydown", documentListener);
28+
};
29+
}, [map]);
30+
}

src/lib/hrefs.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const hrefs = {
2+
workspaces: {
3+
create: "/workspace/create",
4+
},
5+
};

src/routes/route-workspaces.tsx

+8-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import { useArchivedWorkspaces } from "@/features/workspace/hooks/use-archived-w
1919
import { Workspace } from "@/api/generated";
2020
import SvgFlipBackward from "@/components/icons/FlipBackward";
2121
import { useRestoreWorkspaceButton } from "@/features/workspace/hooks/use-restore-workspace-button";
22+
import { useKbdShortcuts } from "@/hooks/use-kbd-shortcuts";
23+
import { useNavigate } from "react-router-dom";
24+
import { hrefs } from "@/lib/hrefs";
2225

2326
function CellName({
2427
name,
@@ -89,6 +92,10 @@ export function RouteWorkspaces() {
8992
})) ?? []),
9093
];
9194

95+
const navigate = useNavigate();
96+
97+
useKbdShortcuts([["c", () => navigate(hrefs.workspaces.create)]]);
98+
9299
return (
93100
<>
94101
<Breadcrumbs>
@@ -97,7 +104,7 @@ export function RouteWorkspaces() {
97104
</Breadcrumbs>
98105

99106
<WorkspaceHeading title="Manage Workspaces">
100-
<LinkButton href="/workspace/create" className="w-fit gap-2">
107+
<LinkButton href={hrefs.workspaces.create} className="w-fit gap-2">
101108
<SquarePlus /> Create Workspace
102109
</LinkButton>
103110
</WorkspaceHeading>

0 commit comments

Comments
 (0)