UNPKG

box-ui-elements-mlh

Version:
85 lines (72 loc) 2.31 kB
/** * @flow * @file Helper functions for keyboard events * @author Box */ /** * Function to decode key events into keys. * Works for both React synthetic and native events. * * Will output in the format Shift+I, Control+I... * Will outpur Space for spacebar. * Will return empty string for modifiers only. * * @public * @param {Event} event - Keyboard event * @return {string} Decoded keydown key or empty string */ function decode(event: KeyboardEvent | SyntheticKeyboardEvent<HTMLElement>) { let modifier = ''; // KeyboardEvent.key is the new spec supported in Chrome, Firefox and IE. // KeyboardEvent.keyIdentifier is the old spec supported in Safari. // Priority is given to the new spec. // $FlowFixMe const { keyIdentifier } = event; let key: string = event.key || keyIdentifier || ''; // Get the modifiers on their own if (event.ctrlKey) { modifier = 'Control'; } else if (event.shiftKey) { modifier = 'Shift'; } else if (event.metaKey) { modifier = 'Meta'; } // The key and keyIdentifier specs also include modifiers. // Since we are manually getting the modifiers above we do // not want to trap them again here. if (key === modifier) { key = ''; } // keyIdentifier spec returns UTF8 char codes // Need to convert them back to ascii. if (key.indexOf('U+') === 0) { if (key === 'U+001B') { key = 'Escape'; } else { key = String.fromCharCode(Number(key.replace('U+', '0x'))); } } // If nothing was pressed or we evaluated to nothing, just return if (!key) { return ''; } // Special casing for space bar if (key === ' ') { key = 'Space'; } // Edge bug which outputs "Esc" instead of "Escape" // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/5290772/ if (key === 'Esc') { key = 'Escape'; } // keyIdentifier spec does not prefix the word Arrow. // Newer key spec does it automatically. if (key === 'Right' || key === 'Left' || key === 'Down' || key === 'Up') { key = `Arrow${key}`; } if (modifier) { modifier += '+'; } return modifier + key; } export { decode }; // eslint-disable-line