diff --git a/packages/components/src/utils/keyboard.js b/packages/components/src/utils/keyboard.js new file mode 100644 index 00000000000000..977b87ada21004 --- /dev/null +++ b/packages/components/src/utils/keyboard.js @@ -0,0 +1,28 @@ +/** + * WordPress dependencies + */ +import { RIGHT, UP, DOWN, LEFT } from '@wordpress/keycodes'; + +/** + * @type {number[]} + */ +const arrowKeys = [ RIGHT, UP, DOWN, LEFT ]; + +/** + * Normalizes the 'key' property of a KeyboardEvent in IE/Edge + * + * Source: + * https://github.com/downshift-js/downshift/blob/a71005bd879d05d7dcb892d1e0dc5c6ca74e9d39/src/utils.js#L279 + * + * @param {import('react').KeyboardEvent} event A keyboardEvent object + * + * @return {string} The keyboard key + */ +export function normalizeArrowKey( event ) { + const { key, keyCode } = event; + + if ( arrowKeys.includes( keyCode ) && key.indexOf( 'Arrow' ) !== 0 ) { + return `Arrow${ key }`; + } + return key; +} diff --git a/packages/components/src/utils/test/keyboard.js b/packages/components/src/utils/test/keyboard.js new file mode 100644 index 00000000000000..8ef46d8fec8603 --- /dev/null +++ b/packages/components/src/utils/test/keyboard.js @@ -0,0 +1,34 @@ +/** + * WordPress dependencies + */ +import { RIGHT, UP, DOWN, LEFT, SPACE } from '@wordpress/keycodes'; + +/** + * Internal dependencies + */ +import { normalizeArrowKey } from '../keyboard'; + +describe( 'normalizeArrowKey', () => { + it.each` + keyCode | key | normalized + ${ RIGHT } | ${ 'Right' } | ${ 'ArrowRight' } + ${ UP } | ${ 'Up' } | ${ 'ArrowUp' } + ${ DOWN } | ${ 'Down' } | ${ 'ArrowDown' } + ${ LEFT } | ${ 'Left' } | ${ 'ArrowLeft' } + ${ RIGHT } | ${ 'ArrowRight' } | ${ 'ArrowRight' } + ${ UP } | ${ 'ArrowUp' } | ${ 'ArrowUp' } + ${ DOWN } | ${ 'ArrowDown' } | ${ 'ArrowDown' } + ${ LEFT } | ${ 'ArrowLeft' } | ${ 'ArrowLeft' } + ${ SPACE } | ${ 'Space' } | ${ 'Space' } + `( + 'should return $normalized for $key with keycode $keyCode', + ( { keyCode, key, normalized } ) => { + const e = new window.KeyboardEvent( 'keydown', { + key, + keyCode, + } ); + + expect( normalizeArrowKey( e ) ).toEqual( normalized ); + } + ); +} );