(
handlers: MultiHotkeyHandler,
options: CreateHotkeyHandlerOptions = {},
)
| 208 | * ``` |
| 209 | */ |
| 210 | export function createMultiHotkeyHandler( |
| 211 | handlers: MultiHotkeyHandler, |
| 212 | options: CreateHotkeyHandlerOptions = {}, |
| 213 | ): (event: KeyboardEvent) => void { |
| 214 | const { preventDefault = true, stopPropagation = true, platform } = options |
| 215 | const resolvedPlatform = platform ?? detectPlatform() |
| 216 | |
| 217 | // Pre-parse all hotkeys for efficiency |
| 218 | const parsedHandlers = Object.entries(handlers) |
| 219 | .filter((entry): entry is [string, HotkeyCallback] => Boolean(entry[1])) |
| 220 | .map(([hotkey, handler]) => { |
| 221 | const parsed = parseHotkey(hotkey as Hotkey, resolvedPlatform) |
| 222 | const context: HotkeyCallbackContext = { |
| 223 | hotkey: hotkey as Hotkey, |
| 224 | parsedHotkey: parsed, |
| 225 | } |
| 226 | return { parsed, handler, context } |
| 227 | }) |
| 228 | |
| 229 | return (event: KeyboardEvent) => { |
| 230 | for (const { parsed, handler, context } of parsedHandlers) { |
| 231 | if (matchesKeyboardEvent(event, parsed, resolvedPlatform)) { |
| 232 | if (preventDefault) { |
| 233 | event.preventDefault() |
| 234 | } |
| 235 | if (stopPropagation) { |
| 236 | event.stopPropagation() |
| 237 | } |
| 238 | handler(event, context) |
| 239 | return // Only handle the first match |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | /** |
| 246 | * Formats a ParsedHotkey back to a hotkey string. |
no test coverage detected
searching dependent graphs…