-
-
Notifications
You must be signed in to change notification settings - Fork 425
Expand file tree
/
Copy pathuseShortcuts.ts
More file actions
47 lines (40 loc) · 1.31 KB
/
useShortcuts.ts
File metadata and controls
47 lines (40 loc) · 1.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import type { RouteLocationRaw } from 'vue-router'
import { isEditableElement, isKeyWithoutModifiers } from '~/utils/input'
type ShortcutTarget = RouteLocationRaw | null | undefined
type ShortcutTargetFactory = () => ShortcutTarget
const registry = new Map<string, ShortcutTargetFactory[]>()
export function initKeyShortcuts() {
const keyboardShortcuts = useKeyboardShortcuts()
onKeyStroke(
e => !e.repeat && keyboardShortcuts.value && !isEditableElement(e.target),
e => {
for (const [key, stack] of registry) {
if (!isKeyWithoutModifiers(e, key)) continue
const getTarget = stack.at(-1)
if (!getTarget) continue
const target = getTarget()
if (!target) return
e.preventDefault()
navigateTo(target)
return
}
},
)
}
export function useShortcuts(map: Record<string, () => ShortcutTarget>) {
if (!import.meta.client) return
for (const [key, fn] of Object.entries(map)) {
const entry = registry.get(key) ?? []
if (entry.includes(fn)) continue
entry.push(fn)
registry.set(key, entry)
}
onScopeDispose(() => {
for (const [key, fn] of Object.entries(map)) {
const stack = registry.get(key)
if (!stack) continue
const idx = stack.lastIndexOf(fn)
if (idx !== -1) stack.splice(idx, 1)
}
})
}