(
hotkey: RegisterableHotkey | (() => RegisterableHotkey),
callback: HotkeyCallback,
options: CreateHotkeyOptions | (() => CreateHotkeyOptions) = {},
)
| 80 | * ``` |
| 81 | */ |
| 82 | export function createHotkey( |
| 83 | hotkey: RegisterableHotkey | (() => RegisterableHotkey), |
| 84 | callback: HotkeyCallback, |
| 85 | options: CreateHotkeyOptions | (() => CreateHotkeyOptions) = {}, |
| 86 | ): void { |
| 87 | const defaultOptions = useDefaultHotkeysOptions() |
| 88 | const manager = getHotkeyManager() |
| 89 | |
| 90 | let registration: HotkeyRegistrationHandle | null = null |
| 91 | let lastHotkeyString: Hotkey | null = null |
| 92 | let lastTarget: HTMLElement | Document | Window | null = null |
| 93 | |
| 94 | onCleanup(() => { |
| 95 | if (registration?.isActive) { |
| 96 | registration.unregister() |
| 97 | registration = null |
| 98 | } |
| 99 | lastHotkeyString = null |
| 100 | lastTarget = null |
| 101 | }) |
| 102 | |
| 103 | createEffect(() => { |
| 104 | // Resolve reactive values |
| 105 | const resolvedHotkey = typeof hotkey === 'function' ? hotkey() : hotkey |
| 106 | const resolvedOptions = typeof options === 'function' ? options() : options |
| 107 | |
| 108 | const mergedOptions = { |
| 109 | ...defaultOptions.hotkey, |
| 110 | ...resolvedOptions, |
| 111 | } |
| 112 | |
| 113 | // Normalize to hotkey string |
| 114 | const platform = mergedOptions.platform ?? detectPlatform() |
| 115 | const hotkeyString = normalizeRegisterableHotkey(resolvedHotkey, platform) |
| 116 | |
| 117 | // Resolve target: when explicitly provided (even as null), use it and skip if null. |
| 118 | // When not provided, default to document. Matches React's ref handling. |
| 119 | const resolvedTarget = |
| 120 | 'target' in mergedOptions |
| 121 | ? (mergedOptions.target ?? null) |
| 122 | : typeof document !== 'undefined' |
| 123 | ? document |
| 124 | : null |
| 125 | |
| 126 | if (!resolvedTarget) { |
| 127 | if (registration?.isActive) { |
| 128 | registration.unregister() |
| 129 | registration = null |
| 130 | } |
| 131 | lastHotkeyString = null |
| 132 | lastTarget = null |
| 133 | return |
| 134 | } |
| 135 | |
| 136 | // Extract options without target (target is handled separately) |
| 137 | const { target: _target, ...optionsWithoutTarget } = mergedOptions |
| 138 | |
| 139 | // Untrack store mutations so that registering/updating the hotkey doesn't |
searching dependent graphs…