fix(shortcuts): make keyboard shortcuts layout-agnostic

Shortcuts were matched against event.key, which returns a layout-dependent
character. On non-Latin layouts (Cyrillic, Greek, ...) the physical letter keys
produce non-Latin characters, so single-letter shortcuts (c, j, k, r, e, ...)
never fire and users must switch layout to use them.

Derive the letter from event.code (KeyA..KeyZ) instead, which is
layout-independent. Non-letter keys keep event.key (arrows/Enter are already
layout-independent; #, !, ?, / stay symbol-based).
This commit is contained in:
Daniil
2026-07-04 14:54:58 +02:00
committed by Linus Rath
parent 396f5f7d60
commit 97d87c44d0
+14 -1
View File
@@ -55,6 +55,19 @@ function isInputFocused(): boolean {
return isInput || isContentEditable;
}
// Latin letter shortcuts must fire regardless of the active keyboard layout
// (e.g. Cyrillic, Greek): derive the physical letter from event.code
// (KeyA..KeyZ) instead of the layout-dependent event.key. Non-letter keys keep
// event.key, which is either layout-independent (arrows, Enter, Escape) or
// intentionally symbol-based (#, !, ?, /).
function physicalShortcutKey(event: KeyboardEvent): string {
const code = event.code;
if (code && code.length === 4 && code.startsWith("Key")) {
return code.charAt(3).toLowerCase();
}
return event.key.toLowerCase();
}
export function useKeyboardShortcuts({
enabled = true,
emails,
@@ -75,7 +88,7 @@ export function useKeyboardShortcuts({
if (isInputFocused()) return;
const h = handlersRef.current;
const key = event.key.toLowerCase();
const key = physicalShortcutKey(event);
const hasModifier = event.ctrlKey || event.metaKey || event.altKey;
// Shortcuts that work with modifiers