diff --git a/tgui/packages/common/keys.ts b/tgui/packages/common/keys.ts new file mode 100644 index 000000000000..3e913151707f --- /dev/null +++ b/tgui/packages/common/keys.ts @@ -0,0 +1,58 @@ +/** + * ### Key codes. + * event.keyCode is deprecated, use this reference instead. + * + * Handles modifier keys (Shift, Alt, Control) and arrow keys. + * + * For alphabetical keys, use the actual character (e.g. 'a') instead of the key code. + * Don't access Esc or Escape directly, use isEscape() instead + * + * Something isn't here that you want? Just add it: + * @url https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values + * @usage + * ```ts + * import { KEY } from 'tgui/common/keys'; + * + * if (event.key === KEY.Enter) { + * // do something + * } + * ``` + * + * + */ +export enum KEY { + Alt = 'Alt', + Backspace = 'Backspace', + Control = 'Control', + Delete = 'Delete', + Down = 'ArrowDown', + End = 'End', + Enter = 'Enter', + Esc = 'Esc', + Escape = 'Escape', + Home = 'Home', + Insert = 'Insert', + Left = 'ArrowLeft', + PageDown = 'PageDown', + PageUp = 'PageUp', + Right = 'ArrowRight', + Shift = 'Shift', + Space = ' ', + Tab = 'Tab', + Up = 'ArrowUp', +} + +/** + * ### isEscape + * + * Checks if the user has hit the 'ESC' key on their keyboard. + * There's a weirdness in BYOND where this could be either the string + * 'Escape' or 'Esc' depending on the browser. This function handles + * both cases. + * + * @param key - the key to check, typically from event.key + * @returns true if key is Escape or Esc, false otherwise + */ +export function isEscape(key: string): boolean { + return key === KEY.Esc || key === KEY.Escape; +} diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/KeybindingsPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/KeybindingsPage.tsx index 322d9e84aa19..e4cdb71e6ab7 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/KeybindingsPage.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/KeybindingsPage.tsx @@ -1,4 +1,5 @@ import { range, sortBy } from 'common/collections'; +import { isEscape, KEY } from 'common/keys'; import { Component } from 'react'; import { resolveAsset } from '../../assets'; @@ -36,14 +37,14 @@ type KeybindingsPageState = { selectedKeybindings?: PreferencesMenuData['keybindings']; }; -const isStandardKey = (event: KeyboardEvent): boolean => { +function isStandardKey(event: KeyboardEvent): boolean { return ( - event.key !== 'Alt' && - event.key !== 'Control' && - event.key !== 'Shift' && - event.key !== 'Esc' + event.key !== KEY.Alt && + event.key !== KEY.Control && + event.key !== KEY.Shift && + !isEscape(event.key) ); -}; +} const KEY_CODE_TO_BYOND: Record = { DEL: 'Delete', @@ -134,7 +135,10 @@ class KeybindingButton extends Component<{ fluid textAlign="center" captureKeys={typingHotkey === undefined} - onClick={onClick} + onClick={(event) => { + event.stopPropagation(); + onClick?.(); + }} selected={typingHotkey !== undefined} > {typingHotkey || currentHotkey || 'Unbound'} @@ -284,7 +288,7 @@ export class KeybindingsPage extends Component<{}, KeybindingsPageState> { if (isStandardKey(event)) { this.setRebindingHotkey(formatKeyboardEvent(event)); return; - } else if (event.key === 'Esc') { + } else if (isEscape(event.key)) { this.setRebindingHotkey(undefined); return; }