Skip to content

Commit 0aabb20

Browse files
committed
smartly ignore hot keys when inputs focussed unless they are target element
1 parent f23dca1 commit 0aabb20

File tree

4 files changed

+391
-1
lines changed

4 files changed

+391
-1
lines changed

packages/keys/src/manager.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export class HotkeyManager {
110110
eventType: 'keydown',
111111
requireReset: false,
112112
enabled: true,
113+
ignoreInputs: true,
113114
...options,
114115
platform,
115116
},
@@ -235,6 +236,16 @@ export class HotkeyManager {
235236
continue
236237
}
237238

239+
// Check if we should ignore input elements (defaults to true)
240+
if (registration.options.ignoreInputs !== false) {
241+
if (this.isInputElement(event.target)) {
242+
// Don't ignore if the hotkey is explicitly scoped to this input element
243+
if (event.target !== registration.target) {
244+
continue
245+
}
246+
}
247+
}
248+
238249
// Handle keydown events
239250
if (eventType === 'keydown') {
240251
if (registration.options.eventType !== 'keydown') {
@@ -357,6 +368,39 @@ export class HotkeyManager {
357368
return false
358369
}
359370

371+
/**
372+
* Checks if an element is an input-like element that should be ignored.
373+
*
374+
* This includes:
375+
* - HTMLInputElement (all input types)
376+
* - HTMLTextAreaElement
377+
* - HTMLSelectElement
378+
* - Elements with contentEditable enabled
379+
*/
380+
private isInputElement(element: EventTarget | null): boolean {
381+
if (!element) {
382+
return false
383+
}
384+
385+
// Check for standard input elements
386+
if (
387+
element instanceof HTMLInputElement ||
388+
element instanceof HTMLTextAreaElement ||
389+
element instanceof HTMLSelectElement
390+
) {
391+
return true
392+
}
393+
394+
// Check for contenteditable elements
395+
if (element instanceof HTMLElement) {
396+
const contentEditable = element.contentEditable
397+
if (contentEditable === 'true' || contentEditable === '') {
398+
return true
399+
}
400+
}
401+
402+
return false
403+
}
360404

361405
/**
362406
* Determines if a registration should be reset based on the keyup event.

packages/keys/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ export interface HotkeyOptions {
409409
requireReset?: boolean
410410
/** Whether the hotkey is enabled. Defaults to true */
411411
enabled?: boolean
412+
/** Whether to ignore hotkeys when keyboard events originate from input-like elements (input, textarea, select, contenteditable). Defaults to true */
413+
ignoreInputs?: boolean
412414
/** The DOM element to attach the event listener to. Defaults to document. */
413415
target?: HTMLElement | Document | Window | null
414416
}

0 commit comments

Comments
 (0)