matchEvent.ts38 lines · main
1import { getSequenceManager, matchesKeyboardEvent } from '@tanstack/react-hotkeys'
2
3import { SHORTCUT_DEFINITIONS } from './registry'
4import type { RegistryDefinations } from './types'
5
6/**
7 * Returns true if the given keyboard event matches a shortcut that is both:
8 *
9 * 1. **In the target registry** (defaults to every known shortcut, but callers
10 * can pass a subset like `tableEditorRegistry` to scope the check)
11 * 2. **Currently active and enabled** — i.e. a `useShortcut` is mounted for it
12 * AND its `enabled` option is not `false`
13 *
14 * Chord sequences (e.g. `['G', 'T']`) match on any individual step, so
15 * pressing `G` counts as a match while the chord is in flight.
16 *
17 * Respecting the live `enabled` state matters: if a shortcut is registered but
18 * gated off (e.g. `enabled: !!snap.selectedCellPosition`), we must NOT suppress
19 * the default behavior on its behalf, because the shortcut won't actually fire.
20 */
21
22export function eventMatchesAnyShortcut(
23 event: KeyboardEvent,
24 registry: RegistryDefinations<string> = SHORTCUT_DEFINITIONS
25): boolean {
26 const scopedSteps = new Set(Object.values(registry).flatMap((def) => def.sequence))
27 const activeRegistrations = getSequenceManager().registrations.state.values()
28
29 for (const view of activeRegistrations) {
30 if (view.options.enabled === false) continue
31 const matches = view.sequence.some(
32 (step) => scopedSteps.has(step) && matchesKeyboardEvent(event, step)
33 )
34 if (matches) return true
35 }
36
37 return false
38}