Skip to content

Commit 482cd6e

Browse files
Merge pull request #56 from ShipFriend0516/feature/shortcut
단축키 커스텀 훅 추가
2 parents 5bd6217 + 0dc6489 commit 482cd6e

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

app/hooks/common/useShortcut.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { useEffect } from 'react';
2+
3+
const useShortcut = (
4+
onShortcutAction: () => void,
5+
keys: string[],
6+
isGlobal: boolean
7+
) => {
8+
useEffect(() => {
9+
const handler = (e: KeyboardEvent) => {
10+
const isPressed = keys?.every((key) => {
11+
if (key === 'Alt') {
12+
return e.altKey;
13+
} else if (key === 'Control' || key === 'Ctrl') {
14+
return e.ctrlKey;
15+
} else if (key === 'Shift') {
16+
return e.shiftKey;
17+
} else if (key === 'Meta') {
18+
return e.metaKey;
19+
}
20+
return e.key.toLowerCase() === key.toLowerCase();
21+
});
22+
if (isPressed) {
23+
onShortcutAction();
24+
}
25+
};
26+
// 고민
27+
// 다른 페이지로 먼저 접근하면 전역 이벤트가 설정되지 않는다.
28+
// 생각나는 해결방법: layout.tsx 에서 useShortcut 훅을 사용하여 전역 이벤트를 설정한다.
29+
// 이렇게 할 경우 어떤 페이지로 접근하든 전역 이벤트를 설정 할 수 있다.
30+
31+
if (isGlobal) {
32+
window.addEventListener('keydown', handler);
33+
} else if (window) {
34+
document.addEventListener('keydown', handler);
35+
}
36+
37+
return () => {
38+
document.removeEventListener('keydown', handler);
39+
};
40+
}, [onShortcutAction, keys, isGlobal]);
41+
42+
return;
43+
};
44+
45+
export default useShortcut;

app/page.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ import useToast from '@/app/hooks/useToast';
1616
import useDataFetch from '@/app/hooks/common/useDataFetch';
1717
import { Post } from '@/app/types/Post';
1818
import ErrorBox from '@/app/entities/common/Error/ErrorBox';
19+
import { useRouter } from 'next/navigation';
20+
import useShortcut from '@/app/hooks/common/useShortcut';
1921

2022
export default function Home() {
2123
const { fingerprint } = useFingerprint();
2224
const toast = useToast();
25+
const router = useRouter();
2326

2427
const fetchConfig = {
2528
method: 'GET' as const,
@@ -41,6 +44,19 @@ export default function Home() {
4144
}
4245
}, [fingerprint]);
4346

47+
const goToWritePage = () => {
48+
toast.success('글쓰기 페이지로 이동합니다...');
49+
router.push('/admin/write');
50+
};
51+
52+
const goToPostsPage = () => {
53+
toast.success('모든 글 목록 페이지로 이동합니다...');
54+
router.push('/posts');
55+
};
56+
57+
useShortcut(goToWritePage, ['Alt', 'N'], true);
58+
useShortcut(goToPostsPage, ['Ctrl', ';'], true);
59+
4460
return (
4561
<main className="w-full max-w-4xl mx-auto grid gap-16 p-4 md:p-8">
4662
<section className="grid gap-6">

0 commit comments

Comments
 (0)