UNPKG

react-key-handler

Version:

React component to handle keyboard events

124 lines (98 loc) 2.58 kB
/* @flow */ import { KEYDOWN, KEYPRESS, KEYUP, KEY_CODE_KEYS, NORMALIZED_KEYS, } from './constants'; import { type primitiveOrArray } from './types'; type KeyboardKey = {| +keyValue: ?primitiveOrArray<string>, +keyCode: ?primitiveOrArray<number>, +code: ?primitiveOrArray<string>, |}; /** * Check if `given` element is an input / textarea form element or acts as one. */ export function isInput(element: HTMLElement): boolean { if (!element) { return false; } const { tagName } = element; const editable = isContentEditable(element); return tagName === 'INPUT' || tagName === 'TEXTAREA' || editable; } function isContentEditable(element: HTMLElement): boolean { if (typeof element.getAttribute !== 'function') { return false; } return !!element.getAttribute('contenteditable'); } /** * Matches an event against a given keyboard key. */ function matchesElementOrArray<T>(a: T | T[], b: T) { if (Array.isArray(a)) { return a.includes(b); } return a === b; } export function matchesKeyboardEvent( event: KeyboardEvent, { keyCode, keyValue, code }: KeyboardKey, ): boolean { if (!isNullOrUndefined(keyValue)) { const value = eventKey(event); if (matchesElementOrArray(keyValue, value)) { return true; } } if (!isNullOrUndefined(code)) { if (matchesElementOrArray(code, event.code)) { return true; } } if (!isNullOrUndefined(keyCode)) { // Firefox handles keyCode through which const keyCodeTarget = event.keyCode || event.which; if (matchesElementOrArray(keyCode, keyCodeTarget)) { return true; } } return false; } function isNullOrUndefined(value): boolean { return value === undefined || value === null; } export function eventKey(event: KeyboardEvent): string { const { key, keyCode, type } = event; if (key) { const normalizedKey = NORMALIZED_KEYS[key] || key; if (normalizedKey !== 'Unidentified') { return normalizedKey; } } if (type === KEYPRESS) { const charCode = eventCharCode(event); return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); } if (type === KEYDOWN || type === KEYUP) { return KEY_CODE_KEYS[String(keyCode)] || 'Unidentified'; } return ''; } function eventCharCode(event: KeyboardEvent): number { let { charCode, keyCode } = event; if ('charCode' in event) { if (charCode === 0 && keyCode === 13) { return 13; } } else { charCode = keyCode; } if (charCode >= 32 || charCode === 13) { return charCode; } return 0; }