diff --git a/CHANGELOG.md b/CHANGELOG.md index e3d7e33c073..be8a23cf810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - A fixed `EuiHeader` no longer automatically padding directly to the `` element ([#3538](https://github.com/elastic/eui/pull/3538)) - Improved `EuiPagination`, `EuiDataGrid`, `EuiBasicTable` and `EuiInMemoryTable` accessibility, causing `EuiPaginationButton` to require a new prop `pageIndex` ([#3294](https://github.com/elastic/eui/pull/3294)) +- Replaced all usages of [`KeyboardEvent.keyCode`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) (deprecated) with [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key). From `@elastic/eui/lib/services`, `keyCodes` has been replaced with `keys`, as has `cascadingMenuKeyCodes`->`cascadingMenuKeys`, and `comboBoxKeyCodes`->`comboBoxKeys`. The implementation of all of those exports (as well as `accessibleClickKeys`) all now use `KeyboardEvent.key` values. ([#3517](https://github.com/elastic/eui/pull/3517)) ## [`24.1.0`](https://github.com/elastic/eui/tree/v24.1.0) diff --git a/src-docs/src/views/app_view.js b/src-docs/src/views/app_view.js index 956a1fc3ca4..e3e89dd8804 100644 --- a/src-docs/src/views/app_view.js +++ b/src-docs/src/views/app_view.js @@ -11,7 +11,7 @@ import { EuiContext, } from '../../../src/components'; -import { keyCodes } from '../../../src/services'; +import { keys } from '../../../src/services'; export class AppView extends Component { constructor(...args) { @@ -83,23 +83,23 @@ export class AppView extends Component { return
{this.renderContent()}
; } - onKeydown = e => { - if (e.target !== document.body) { + onKeydown = event => { + if (event.target !== document.body) { return; } - if (e.metaKey) { + if (event.metaKey) { return; } const { routes, currentRoute } = this.props; - if (e.keyCode === keyCodes.LEFT) { + if (event.key === keys.ARROW_LEFT) { pushRoute(routes.getPreviousRoute); return; } - if (e.keyCode === keyCodes.RIGHT) { + if (event.key === keys.ARROW_RIGHT) { pushRoute(routes.getNextRoute); } diff --git a/src-docs/src/views/window_event/window_event_conflict.js b/src-docs/src/views/window_event/window_event_conflict.js index 2859298e7bf..0975dc996f7 100644 --- a/src-docs/src/views/window_event/window_event_conflict.js +++ b/src-docs/src/views/window_event/window_event_conflict.js @@ -9,6 +9,7 @@ import { EuiFieldText, EuiSpacer, } from '../../../../src/components'; +import { keys } from '../../../../src/services'; import { ModalExample } from './modal_example_container'; @@ -18,10 +19,10 @@ const ConflictModal = props => { const updateInputValue = e => { setInputValue(e.target.value); }; - const clearInputValueOnEscape = e => { - if (e.key === 'Escape') { + const clearInputValueOnEscape = event => { + if (event.key === keys.ESCAPE) { setInputValue(''); - e.stopPropagation(); + event.stopPropagation(); } }; diff --git a/src/components/accessibility/keyboard_accessible.test.tsx b/src/components/accessibility/keyboard_accessible.test.tsx index 15771e270bf..79e29d015ce 100644 --- a/src/components/accessibility/keyboard_accessible.test.tsx +++ b/src/components/accessibility/keyboard_accessible.test.tsx @@ -23,7 +23,7 @@ import { render, shallow } from 'enzyme'; import { EuiKeyboardAccessible } from './keyboard_accessible'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; const noop = () => { // eslint-disable-line no-empty @@ -194,7 +194,7 @@ describe('EuiKeyboardAccessible', () => { ); $button.find('[data-div]').simulate('keyup', { - keyCode: keyCodes.ENTER, + key: keys.ENTER, }); expect(onClickHandler).toBeCalled(); @@ -210,7 +210,7 @@ describe('EuiKeyboardAccessible', () => { ); $button.find('[data-div]').simulate('keyup', { - keyCode: keyCodes.SPACE, + key: keys.SPACE, }); expect(onClickHandler).toBeCalled(); diff --git a/src/components/accessibility/keyboard_accessible.ts b/src/components/accessibility/keyboard_accessible.ts index a7565b5379f..1a8a2ac7b71 100644 --- a/src/components/accessibility/keyboard_accessible.ts +++ b/src/components/accessibility/keyboard_accessible.ts @@ -41,33 +41,33 @@ import { Component, cloneElement, KeyboardEvent, ReactElement } from 'react'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; interface Props { children: ReactElement; } export class EuiKeyboardAccessible extends Component { - onKeyDown = (e: KeyboardEvent) => { + onKeyDown = (event: KeyboardEvent) => { // Prevent a scroll from occurring if the user has hit space. - if (e.keyCode === keyCodes.SPACE) { - e.preventDefault(); + if (event.key === keys.SPACE) { + event.preventDefault(); } if (this.props.children.props.onKeyDown) { - this.props.children.props.onKeyDown(e); + this.props.children.props.onKeyDown(event); } }; - onKeyUp = (e: KeyboardEvent) => { + onKeyUp = (event: KeyboardEvent) => { // Support keyboard accessibility by emulating mouse click on ENTER or SPACE keypress. - if (e.keyCode === keyCodes.ENTER || e.keyCode === keyCodes.SPACE) { + if (event.key === keys.ENTER || event.key === keys.SPACE) { // Delegate to the click handler on the element. - this.props.children.props.onClick(e); + this.props.children.props.onClick(event); } if (this.props.children.props.onKeyUp) { - this.props.children.props.onKeyUp(e); + this.props.children.props.onKeyUp(event); } }; diff --git a/src/components/basic_table/in_memory_table.test.tsx b/src/components/basic_table/in_memory_table.test.tsx index 28a47b29798..b6e8ed25082 100644 --- a/src/components/basic_table/in_memory_table.test.tsx +++ b/src/components/basic_table/in_memory_table.test.tsx @@ -22,8 +22,7 @@ import { mount, shallow } from 'enzyme'; import { requiredProps } from '../../test'; import { EuiInMemoryTable, EuiInMemoryTableProps } from './in_memory_table'; -import { ENTER } from '../../services/key_codes'; -import { SortDirection } from '../../services'; +import { keys, SortDirection } from '../../services'; import { SearchFilterConfig } from '../search_bar/filters'; jest.mock('../../services/accessibility', () => ({ @@ -766,7 +765,7 @@ describe('EuiInMemoryTable', () => { target: { value: 'is:active', }, - keyCode: ENTER, + key: keys.ENTER, }); component.update(); @@ -777,7 +776,7 @@ describe('EuiInMemoryTable', () => { target: { value: 'active:false', }, - keyCode: ENTER, + key: keys.ENTER, }); component.update(); diff --git a/src/components/code/_code_block.tsx b/src/components/code/_code_block.tsx index f35bfce9ee6..a2f7bf7c3c7 100644 --- a/src/components/code/_code_block.tsx +++ b/src/components/code/_code_block.tsx @@ -37,7 +37,7 @@ import { EuiOverlayMask } from '../overlay_mask'; import { EuiFocusTrap } from '../focus_trap'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { EuiI18n } from '../i18n'; import { EuiInnerText } from '../inner_text'; import { keysOf } from '../common'; @@ -146,7 +146,7 @@ export const EuiCodeBlockImpl: FunctionComponent = ({ }); const onKeyDown = (event: KeyboardEvent) => { - if (event.keyCode === keyCodes.ESCAPE) { + if (event.key === keys.ESCAPE) { event.preventDefault(); event.stopPropagation(); closeFullScreen(); diff --git a/src/components/code_editor/code_editor.test.tsx b/src/components/code_editor/code_editor.test.tsx index 394309fa1f9..f00c92ff6ad 100644 --- a/src/components/code_editor/code_editor.test.tsx +++ b/src/components/code_editor/code_editor.test.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { mount, ReactWrapper } from 'enzyme'; import { EuiCodeEditor } from './code_editor'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { findTestSubject, requiredProps, @@ -85,7 +85,7 @@ describe('EuiCodeEditor', () => { test('should be disabled when the ui ace box gains focus', () => { const hint = findTestSubject(component, 'codeEditorHint'); - hint.simulate('keyup', { keyCode: keyCodes.ENTER }); + hint.simulate('keyup', { key: keys.ENTER }); expect( findTestSubject(component, 'codeEditorHint').getDOMNode() ).toMatchSnapshot(); @@ -93,7 +93,7 @@ describe('EuiCodeEditor', () => { test('should be enabled when the ui ace box loses focus', () => { const hint = findTestSubject(component, 'codeEditorHint'); - hint.simulate('keyup', { keyCode: keyCodes.ENTER }); + hint.simulate('keyup', { key: keys.ENTER }); // @ts-ignore component.instance().onBlurAce(); expect( @@ -116,7 +116,7 @@ describe('EuiCodeEditor', () => { component.instance().onKeydownAce({ preventDefault: () => {}, stopPropagation: () => {}, - keyCode: keyCodes.ESCAPE, + key: keys.ESCAPE, }); const hint = findTestSubject(component, 'codeEditorHint').getDOMNode(); expect(hint).toBe(document.activeElement); diff --git a/src/components/code_editor/code_editor.tsx b/src/components/code_editor/code_editor.tsx index fb3da63061e..94f89c65ebc 100644 --- a/src/components/code_editor/code_editor.tsx +++ b/src/components/code_editor/code_editor.tsx @@ -22,7 +22,7 @@ import classNames from 'classnames'; import AceEditor, { IAceEditorProps } from 'react-ace'; import { keysOf } from '../common'; -import { htmlIdGenerator, keyCodes } from '../../services'; +import { htmlIdGenerator, keys } from '../../services'; import { EuiI18n } from '../i18n'; const DEFAULT_MODE = 'text'; @@ -115,7 +115,7 @@ export class EuiCodeEditor extends Component< }; onKeydownAce = (event: KeyboardEvent) => { - if (event.keyCode === keyCodes.ESCAPE) { + if (event.key === keys.ESCAPE) { // If the autocompletion context menu is open then we want to let ESCAPE close it but // **not** exit out of editing mode. if (this.aceEditor !== null && !this.aceEditor.editor.completer) { @@ -146,7 +146,7 @@ export class EuiCodeEditor extends Component< }; onKeyDownHint: KeyboardEventHandler = event => { - if (event.keyCode === keyCodes.ENTER) { + if (event.key === keys.ENTER) { event.preventDefault(); this.startEditing(); } diff --git a/src/components/collapsible_nav/collapsible_nav.tsx b/src/components/collapsible_nav/collapsible_nav.tsx index 265e5446946..7b699db1cbf 100644 --- a/src/components/collapsible_nav/collapsible_nav.tsx +++ b/src/components/collapsible_nav/collapsible_nav.tsx @@ -28,7 +28,7 @@ import React, { } from 'react'; import classNames from 'classnames'; import { throttle } from '../color_picker/utils'; -import { EuiWindowEvent, keyCodes, htmlIdGenerator } from '../../services'; +import { EuiWindowEvent, keys, htmlIdGenerator } from '../../services'; import { EuiFocusTrap } from '../focus_trap'; import { EuiOverlayMask } from '../overlay_mask'; import { CommonProps } from '../common'; @@ -118,7 +118,7 @@ export const EuiCollapsibleNav: FunctionComponent = ({ }, [navIsDocked, functionToCallOnWindowResize, isOpen]); const onKeyDown = (event: KeyboardEvent) => { - if (event.keyCode === keyCodes.ESCAPE) { + if (event.key === keys.ESCAPE) { event.preventDefault(); collapse(); } diff --git a/src/components/color_picker/color_picker.test.tsx b/src/components/color_picker/color_picker.test.tsx index 2c5b8c3db0b..29176eeb89a 100644 --- a/src/components/color_picker/color_picker.test.tsx +++ b/src/components/color_picker/color_picker.test.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { render, mount } from 'enzyme'; import { EuiColorPicker } from './color_picker'; -import { VISUALIZATION_COLORS, keyCodes } from '../../services'; +import { VISUALIZATION_COLORS, keys } from '../../services'; import { requiredProps, findTestSubject, sleep } from '../../test'; jest.mock('../portal', () => ({ @@ -186,7 +186,7 @@ test('popover color selector is hidden when the ESC key pressed', async () => { findTestSubject(colorPicker, 'colorPickerAnchor').simulate('click'); await sleep(); findTestSubject(colorPicker, 'colorPickerPopover').simulate('keydown', { - keyCode: keyCodes.ESCAPE, + key: keys.ESCAPE, }); // Portal removal not working with Jest. The blur handler is called just before the portal would be removed. expect(onBlurHandler).toBeCalled(); @@ -205,7 +205,7 @@ test('popover color selector is hidden and input regains focus when the ENTER ke findTestSubject(colorPicker, 'colorPickerAnchor').simulate('click'); findTestSubject(colorPicker, 'euiSaturation').simulate('keydown', { - keyCode: keyCodes.ENTER, + key: keys.ENTER, }); expect( findTestSubject(colorPicker, 'colorPickerAnchor').getDOMNode() diff --git a/src/components/color_picker/color_picker.tsx b/src/components/color_picker/color_picker.tsx index 3ec4e6190d9..7f5ac8cc23a 100644 --- a/src/components/color_picker/color_picker.tsx +++ b/src/components/color_picker/color_picker.tsx @@ -46,7 +46,7 @@ import { import { EuiI18n } from '../i18n'; import { EuiPopover } from '../popover'; import { EuiSpacer } from '../spacer'; -import { VISUALIZATION_COLORS, keyCodes } from '../../services'; +import { VISUALIZATION_COLORS, keys } from '../../services'; import { EuiHue } from './hue'; import { EuiSaturation } from './saturation'; @@ -150,7 +150,7 @@ export interface EuiColorPickerProps function isKeyboardEvent( event: React.MouseEvent | React.KeyboardEvent ): event is React.KeyboardEvent { - return typeof event === 'object' && 'keyCode' in event; + return typeof event === 'object' && 'key' in event; } const getOutput = ( @@ -312,8 +312,8 @@ export const EuiColorPicker: FunctionComponent = ({ closeColorSelector(true); }; - const handleOnKeyDown = (e: React.KeyboardEvent) => { - if (e.keyCode === keyCodes.ENTER) { + const handleOnKeyDown = (event: React.KeyboardEvent) => { + if (event.key === keys.ENTER) { if (isColorSelectorShown) { handleFinalSelection(); } else { @@ -323,13 +323,13 @@ export const EuiColorPicker: FunctionComponent = ({ }; const handleInputActivity = ( - e: + event: | React.KeyboardEvent | React.MouseEvent ) => { - if (isKeyboardEvent(e)) { - if (e.keyCode === keyCodes.ENTER) { - e.preventDefault(); + if (isKeyboardEvent(event)) { + if (event.key === keys.ENTER) { + event.preventDefault(); handleToggle(); } } else { @@ -337,9 +337,11 @@ export const EuiColorPicker: FunctionComponent = ({ } }; - const handleToggleOnKeyDown = (e: React.KeyboardEvent) => { - if (e.keyCode === keyCodes.DOWN) { - e.preventDefault(); + const handleToggleOnKeyDown = ( + event: React.KeyboardEvent + ) => { + if (event.key === keys.ARROW_DOWN) { + event.preventDefault(); if (isColorSelectorShown) { const nextFocusEl = mode !== 'swatch' ? satruationRef : swatchRef; if (nextFocusEl.current) { @@ -351,9 +353,9 @@ export const EuiColorPicker: FunctionComponent = ({ } }; - const handleColorInput = (e: React.ChangeEvent) => { - handleOnChange(e.target.value); - const newColor = getChromaColor(e.target.value, showAlpha); + const handleColorInput = (event: React.ChangeEvent) => { + handleOnChange(event.target.value); + const newColor = getChromaColor(event.target.value, showAlpha); if (newColor) { updateColorAsHsv(newColor.hsv()); } diff --git a/src/components/color_picker/color_stops/color_stop_thumb.tsx b/src/components/color_picker/color_stops/color_stop_thumb.tsx index 615265d9742..a63c1f2e5e8 100644 --- a/src/components/color_picker/color_stops/color_stop_thumb.tsx +++ b/src/components/color_picker/color_stops/color_stop_thumb.tsx @@ -35,7 +35,7 @@ import { isStopInvalid, } from './utils'; import { useMouseMove, getChromaColor } from '../utils'; -import { keyCodes } from '../../../services'; +import { keys } from '../../../services'; import { EuiButtonIcon } from '../../button'; import { EuiColorPicker, EuiColorPickerProps } from '../color_picker'; @@ -200,21 +200,21 @@ export const EuiColorStopThumb: FunctionComponent = ({ handleStopChange(newStop); }; - const handleKeyDown = (e: React.KeyboardEvent) => { - switch (e.keyCode) { - case keyCodes.ENTER: - e.preventDefault(); + const handleKeyDown = (event: React.KeyboardEvent) => { + switch (event.key) { + case keys.ENTER: + event.preventDefault(); openPopover(); break; - case keyCodes.LEFT: - e.preventDefault(); + case keys.ARROW_LEFT: + event.preventDefault(); if (readOnly) return; handleStopChange(stop - 1); break; - case keyCodes.RIGHT: - e.preventDefault(); + case keys.ARROW_RIGHT: + event.preventDefault(); if (readOnly) return; handleStopChange(stop + 1); break; diff --git a/src/components/color_picker/color_stops/color_stops.test.tsx b/src/components/color_picker/color_stops/color_stops.test.tsx index 43b35a6ec21..a54808d8a61 100644 --- a/src/components/color_picker/color_stops/color_stops.test.tsx +++ b/src/components/color_picker/color_stops/color_stops.test.tsx @@ -25,7 +25,7 @@ import { EuiColorStops } from './color_stops'; import { VISUALIZATION_COLORS, DEFAULT_VISUALIZATION_COLOR, - keyCodes, + keys, } from '../../../services'; import { requiredProps, findTestSubject } from '../../../test'; @@ -369,11 +369,11 @@ test('thumb focus changes', () => { const thumbs = findTestSubject(colorStops, 'euiColorStopThumb'); wrapper.simulate('focus'); wrapper.simulate('keydown', { - keyCode: keyCodes.DOWN, + key: keys.ARROW_DOWN, }); expect(thumbs.first().getDOMNode()).toEqual(document.activeElement); thumbs.first().simulate('keydown', { - keyCode: keyCodes.DOWN, + key: keys.ARROW_DOWN, }); expect(thumbs.at(1).getDOMNode()).toEqual(document.activeElement); }); @@ -394,11 +394,11 @@ test('thumb direction movement', () => { const thumbs = findTestSubject(colorStops, 'euiColorStopThumb'); wrapper.simulate('focus'); wrapper.simulate('keydown', { - keyCode: keyCodes.DOWN, + key: keys.ARROW_DOWN, }); expect(thumbs.first().getDOMNode()).toEqual(document.activeElement); thumbs.first().simulate('keydown', { - keyCode: keyCodes.RIGHT, + key: keys.ARROW_RIGHT, }); expect(onChange).toBeCalledWith( [ @@ -409,7 +409,7 @@ test('thumb direction movement', () => { false ); thumbs.first().simulate('keydown', { - keyCode: keyCodes.LEFT, + key: keys.ARROW_LEFT, }); expect(onChange).toBeCalledWith( [ @@ -436,7 +436,7 @@ test('add new thumb via keyboard', () => { const wrapper = findTestSubject(colorStops, 'euiColorStops'); wrapper.simulate('focus'); wrapper.simulate('keydown', { - keyCode: keyCodes.ENTER, + key: keys.ENTER, }); expect(onChange).toBeCalled(); expect(onChange).toBeCalledWith( diff --git a/src/components/color_picker/color_stops/color_stops.tsx b/src/components/color_picker/color_stops/color_stops.tsx index d0b82ce6b87..79cc179f018 100644 --- a/src/components/color_picker/color_stops/color_stops.tsx +++ b/src/components/color_picker/color_stops/color_stops.tsx @@ -27,7 +27,7 @@ import React, { import classNames from 'classnames'; import { CommonProps } from '../../common'; -import { keyCodes, DEFAULT_VISUALIZATION_COLOR } from '../../../services'; +import { keys, DEFAULT_VISUALIZATION_COLOR } from '../../../services'; import { EuiColorStopThumb, ColorStop } from './color_stop_thumb'; import { addStop, @@ -293,21 +293,21 @@ export const EuiColorStops: FunctionComponent = ({ handleOnChange(newColorStops); }; - const handleKeyDown = (e: React.KeyboardEvent) => { + const handleKeyDown = (event: React.KeyboardEvent) => { if (disabled) return; - switch (e.keyCode) { - case keyCodes.ESCAPE: + switch (event.key) { + case keys.ESCAPE: onFocusWrapper(); break; - case keyCodes.ENTER: + case keys.ENTER: if (readOnly || !hasFocus) return; onAdd(); break; - case keyCodes.BACKSPACE: + case keys.BACKSPACE: if (readOnly || hasFocus || focusedStopIndex == null) return; - if (isTargetAThumb(e.target)) { + if (isTargetAThumb(event.target)) { if ( (min == null && focusedStopIndex === 0) || (max == null && focusedStopIndex === sortedStops.length - 1) @@ -319,9 +319,9 @@ export const EuiColorStops: FunctionComponent = ({ } break; - case keyCodes.DOWN: - if (e.target === wrapperRef || isTargetAThumb(e.target)) { - e.preventDefault(); + case keys.ARROW_DOWN: + if (event.target === wrapperRef || isTargetAThumb(event.target)) { + event.preventDefault(); if (focusedStopIndex == null) { onFocusStop(0); } else { @@ -334,9 +334,9 @@ export const EuiColorStops: FunctionComponent = ({ } break; - case keyCodes.UP: - if (e.target === wrapperRef || isTargetAThumb(e.target)) { - e.preventDefault(); + case keys.ARROW_UP: + if (event.target === wrapperRef || isTargetAThumb(event.target)) { + event.preventDefault(); if (focusedStopIndex == null) { onFocusStop(0); } else { diff --git a/src/components/color_picker/saturation.tsx b/src/components/color_picker/saturation.tsx index add0b5cc1ee..2b949e1055a 100644 --- a/src/components/color_picker/saturation.tsx +++ b/src/components/color_picker/saturation.tsx @@ -29,7 +29,7 @@ import classNames from 'classnames'; import { ColorSpaces } from 'chroma-js'; import { CommonProps } from '../common'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { isNil } from '../../services/predicate'; import { EuiScreenReaderOnly } from '../accessibility'; import { EuiI18n } from '../i18n'; @@ -120,7 +120,7 @@ export const EuiSaturation = forwardRef( handleChange, boxRef.current ); - const handleKeyDown = (e: KeyboardEvent) => { + const handleKeyDown = (event: KeyboardEvent) => { if (isNil(boxRef) || isNil(boxRef.current)) { return; } @@ -131,21 +131,21 @@ export const EuiSaturation = forwardRef( let newLeft = left; let newTop = top; - switch (e.keyCode) { - case keyCodes.DOWN: - e.preventDefault(); + switch (event.key) { + case keys.ARROW_DOWN: + event.preventDefault(); newTop = top < height ? top + heightScale : height; break; - case keyCodes.LEFT: - e.preventDefault(); + case keys.ARROW_LEFT: + event.preventDefault(); newLeft = left > 0 ? left - widthScale : 0; break; - case keyCodes.UP: - e.preventDefault(); + case keys.ARROW_UP: + event.preventDefault(); newTop = top > 0 ? top - heightScale : 0; break; - case keyCodes.RIGHT: - e.preventDefault(); + case keys.ARROW_RIGHT: + event.preventDefault(); newLeft = left < width ? left + widthScale : width; break; default: diff --git a/src/components/combo_box/combo_box.test.tsx b/src/components/combo_box/combo_box.test.tsx index c61907cd70c..ec3b4a96770 100644 --- a/src/components/combo_box/combo_box.test.tsx +++ b/src/components/combo_box/combo_box.test.tsx @@ -24,7 +24,7 @@ import { findTestSubject, takeMountedSnapshot, } from '../../test'; -import { comboBoxKeyCodes } from '../../services'; +import { comboBoxKeys } from '../../services'; import { EuiComboBox, EuiComboBoxProps } from './combo_box'; @@ -224,7 +224,7 @@ describe('behavior', () => { component.setState({ searchValue: 'foo' }); const searchInput = findTestSubject(component, 'comboBoxSearchInput'); searchInput.simulate('focus'); - searchInput.simulate('keyDown', { keyCode: comboBoxKeyCodes.ENTER }); + searchInput.simulate('keyDown', { key: comboBoxKeys.ENTER }); expect(onCreateOptionHandler).toHaveBeenCalledTimes(1); expect(onCreateOptionHandler).toHaveBeenNthCalledWith(1, 'foo', options); }); @@ -242,7 +242,7 @@ describe('behavior', () => { const searchInput = findTestSubject(component, 'comboBoxSearchInput'); searchInput.simulate('focus'); - searchInput.simulate('keyDown', { keyCode: comboBoxKeyCodes.ENTER }); + searchInput.simulate('keyDown', { key: comboBoxKeys.ENTER }); expect(onCreateOptionHandler).not.toHaveBeenCalled(); }); }); @@ -264,7 +264,7 @@ describe('behavior', () => { // Tab backwards to take focus off the combo box. searchInput.simulate('keyDown', { - keyCode: comboBoxKeyCodes.TAB, + key: comboBoxKeys.TAB, shiftKey: true, }); @@ -312,11 +312,11 @@ describe('behavior', () => { expect(findTestSubject(component, 'comboBoxOptionsList')).toBeDefined(); // Navigate to an option. - searchInput.simulate('keyDown', { keyCode: comboBoxKeyCodes.DOWN }); + searchInput.simulate('keyDown', { key: comboBoxKeys.ARROW_DOWN }); // Tab backwards to take focus off the combo box. searchInput.simulate('keyDown', { - keyCode: comboBoxKeyCodes.TAB, + key: comboBoxKeys.TAB, shiftKey: true, }); diff --git a/src/components/combo_box/combo_box.tsx b/src/components/combo_box/combo_box.tsx index 9f8dc0197ee..a81c1c0885e 100644 --- a/src/components/combo_box/combo_box.tsx +++ b/src/components/combo_box/combo_box.tsx @@ -32,12 +32,7 @@ import React, { } from 'react'; import classNames from 'classnames'; -import { - comboBoxKeyCodes, - findPopoverPosition, - htmlIdGenerator, -} from '../../services'; -import { BACKSPACE, TAB, ESCAPE } from '../../services/key_codes'; +import { findPopoverPosition, htmlIdGenerator, keys } from '../../services'; import { EuiPortal } from '../portal'; import { EuiComboBoxOptionsList } from './combo_box_options_list'; @@ -587,8 +582,8 @@ export class EuiComboBox extends Component< }; onKeyDown: KeyboardEventHandler = event => { - switch (event.keyCode) { - case comboBoxKeyCodes.UP: + switch (event.key) { + case keys.ARROW_UP: event.preventDefault(); event.stopPropagation(); if (this.state.isListOpen) { @@ -598,7 +593,7 @@ export class EuiComboBox extends Component< } break; - case comboBoxKeyCodes.DOWN: + case keys.ARROW_DOWN: event.preventDefault(); event.stopPropagation(); if (this.state.isListOpen) { @@ -608,17 +603,17 @@ export class EuiComboBox extends Component< } break; - case BACKSPACE: + case keys.BACKSPACE: event.stopPropagation(); this.removeLastOption(); break; - case ESCAPE: + case keys.ESCAPE: event.stopPropagation(); this.closeList(); break; - case comboBoxKeyCodes.ENTER: + case keys.ENTER: event.preventDefault(); event.stopPropagation(); if (this.hasActiveOption()) { @@ -630,7 +625,7 @@ export class EuiComboBox extends Component< } break; - case TAB: + case keys.TAB: // Disallow tabbing when the user is navigating the options. if (this.hasActiveOption() && this.state.isListOpen) { event.preventDefault(); diff --git a/src/components/combo_box/combo_box_options_list/combo_box_option.tsx b/src/components/combo_box/combo_box_options_list/combo_box_option.tsx index 04f91019686..8f09a87ee08 100644 --- a/src/components/combo_box/combo_box_options_list/combo_box_option.tsx +++ b/src/components/combo_box/combo_box_options_list/combo_box_option.tsx @@ -26,7 +26,7 @@ import React, { } from 'react'; import classNames from 'classnames'; -import { ENTER, SPACE } from '../../../services/key_codes'; +import { keys } from '../../../services'; import { EuiComboBoxOptionOption, OptionHandler } from '../types'; import { CommonProps } from '../../common'; @@ -55,7 +55,7 @@ export class EuiComboBoxOption extends Component> { }; onKeyDown: KeyboardEventHandler = event => { - if (event.keyCode === ENTER || event.keyCode === SPACE) { + if (event.key === keys.ENTER || event.key === keys.SPACE) { event.preventDefault(); event.stopPropagation(); const { onEnterKey, option, disabled } = this.props; diff --git a/src/components/context_menu/context_menu_panel.test.tsx b/src/components/context_menu/context_menu_panel.test.tsx index d09f9f80453..780727b61b7 100644 --- a/src/components/context_menu/context_menu_panel.test.tsx +++ b/src/components/context_menu/context_menu_panel.test.tsx @@ -27,7 +27,7 @@ import { EuiContextMenuItem } from './context_menu_item'; import { tick } from './context_menu.test'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; const items = [ @@ -186,7 +186,7 @@ describe('EuiContextMenuPanel', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.UP }); + component.simulate('keydown', { key: keys.ARROW_UP }); expect(onUseKeyboardToNavigateHandler).toHaveBeenCalledTimes(1); }); @@ -200,7 +200,7 @@ describe('EuiContextMenuPanel', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.UP }); + component.simulate('keydown', { key: keys.ARROW_UP }); expect(onUseKeyboardToNavigateHandler).toHaveBeenCalledTimes(1); }); @@ -216,7 +216,7 @@ describe('EuiContextMenuPanel', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.LEFT }); + component.simulate('keydown', { key: keys.ARROW_LEFT }); expect(onUseKeyboardToNavigateHandler).toHaveBeenCalledTimes(1); }); @@ -230,7 +230,7 @@ describe('EuiContextMenuPanel', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.LEFT }); + component.simulate('keydown', { key: keys.ARROW_LEFT }); expect(onUseKeyboardToNavigateHandler).not.toHaveBeenCalled(); }); }); @@ -247,7 +247,7 @@ describe('EuiContextMenuPanel', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.RIGHT }); + component.simulate('keydown', { key: keys.ARROW_RIGHT }); expect(onUseKeyboardToNavigateHandler).toHaveBeenCalledTimes(1); }); @@ -261,7 +261,7 @@ describe('EuiContextMenuPanel', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.RIGHT }); + component.simulate('keydown', { key: keys.ARROW_RIGHT }); expect(onUseKeyboardToNavigateHandler).not.toHaveBeenCalled(); }); }); @@ -322,7 +322,7 @@ describe('EuiContextMenuPanel', () => { }); it('down arrow key focuses the first menu item', async () => { - component.simulate('keydown', { keyCode: keyCodes.DOWN }); + component.simulate('keydown', { key: keys.ARROW_DOWN }); await tick(20); expect(findTestSubject(component, 'itemA').getDOMNode()).toBe( @@ -331,8 +331,8 @@ describe('EuiContextMenuPanel', () => { }); it('subsequently, down arrow key focuses the next menu item', async () => { - component.simulate('keydown', { keyCode: keyCodes.DOWN }); - component.simulate('keydown', { keyCode: keyCodes.DOWN }); + component.simulate('keydown', { key: keys.ARROW_DOWN }); + component.simulate('keydown', { key: keys.ARROW_DOWN }); await tick(20); expect(findTestSubject(component, 'itemB').getDOMNode()).toBe( @@ -341,8 +341,8 @@ describe('EuiContextMenuPanel', () => { }); it('down arrow key wraps to first menu item', async () => { - component.simulate('keydown', { keyCode: keyCodes.UP }); - component.simulate('keydown', { keyCode: keyCodes.DOWN }); + component.simulate('keydown', { key: keys.ARROW_UP }); + component.simulate('keydown', { key: keys.ARROW_DOWN }); await tick(20); expect(findTestSubject(component, 'itemA').getDOMNode()).toBe( @@ -351,7 +351,7 @@ describe('EuiContextMenuPanel', () => { }); it('up arrow key focuses the last menu item', async () => { - component.simulate('keydown', { keyCode: keyCodes.UP }); + component.simulate('keydown', { key: keys.ARROW_UP }); await tick(20); expect(findTestSubject(component, 'itemC').getDOMNode()).toBe( @@ -360,8 +360,8 @@ describe('EuiContextMenuPanel', () => { }); it('subsequently, up arrow key focuses the previous menu item', async () => { - component.simulate('keydown', { keyCode: keyCodes.UP }); - component.simulate('keydown', { keyCode: keyCodes.UP }); + component.simulate('keydown', { key: keys.ARROW_UP }); + component.simulate('keydown', { key: keys.ARROW_UP }); await tick(20); expect(findTestSubject(component, 'itemB').getDOMNode()).toBe( @@ -370,8 +370,8 @@ describe('EuiContextMenuPanel', () => { }); it('up arrow key wraps to last menu item', async () => { - component.simulate('keydown', { keyCode: keyCodes.DOWN }); - component.simulate('keydown', { keyCode: keyCodes.UP }); + component.simulate('keydown', { key: keys.ARROW_DOWN }); + component.simulate('keydown', { key: keys.ARROW_UP }); await tick(20); expect(findTestSubject(component, 'itemC').getDOMNode()).toBe( @@ -380,13 +380,13 @@ describe('EuiContextMenuPanel', () => { }); it("right arrow key shows next panel with focused item's index", () => { - component.simulate('keydown', { keyCode: keyCodes.DOWN }); - component.simulate('keydown', { keyCode: keyCodes.RIGHT }); + component.simulate('keydown', { key: keys.ARROW_DOWN }); + component.simulate('keydown', { key: keys.ARROW_RIGHT }); expect(showNextPanelHandler).toHaveBeenCalledWith(0); }); it('left arrow key shows previous panel', () => { - component.simulate('keydown', { keyCode: keyCodes.LEFT }); + component.simulate('keydown', { key: keys.ARROW_LEFT }); expect(showPreviousPanelHandler).toHaveBeenCalledTimes(1); }); }); diff --git a/src/components/context_menu/context_menu_panel.tsx b/src/components/context_menu/context_menu_panel.tsx index b1a53b387cc..fc12abfab06 100644 --- a/src/components/context_menu/context_menu_panel.tsx +++ b/src/components/context_menu/context_menu_panel.tsx @@ -31,7 +31,7 @@ import { CommonProps, NoArgCallback } from '../common'; import { EuiIcon } from '../icon'; import { EuiPopoverTitle } from '../popover'; import { EuiResizeObserver } from '../observer/resize_observer'; -import { cascadingMenuKeyCodes } from '../../services'; +import { cascadingMenuKeys } from '../../services'; export type EuiContextMenuPanelHeightChangeHandler = (height: number) => void; export type EuiContextMenuPanelTransitionType = 'in' | 'out'; @@ -132,7 +132,7 @@ export class EuiContextMenuPanel extends Component { }); }; - onKeyDown = (e: React.KeyboardEvent) => { + onKeyDown = (event: React.KeyboardEvent) => { // If this panel contains items you can use the left arrow key to go back at any time. // But if it doesn't contain items, then you have to focus on the back button specifically, // since there could be content inside the panel which requires use of the left arrow key, @@ -144,10 +144,10 @@ export class EuiContextMenuPanel extends Component { document.activeElement === this.backButton || document.activeElement === this.panel ) { - if (e.keyCode === cascadingMenuKeyCodes.LEFT) { + if (event.key === cascadingMenuKeys.ARROW_LEFT) { if (showPreviousPanel) { - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); showPreviousPanel(); if (this.props.onUseKeyboardToNavigate) { @@ -158,8 +158,8 @@ export class EuiContextMenuPanel extends Component { } if (this.props.items && this.props.items.length) { - switch (e.keyCode) { - case cascadingMenuKeyCodes.TAB: + switch (event.key) { + case cascadingMenuKeys.TAB: // We need to sync up with the user if s/he is tabbing through the items. const focusedItemIndex = this.state.menuItems.indexOf( document.activeElement as HTMLElement @@ -174,8 +174,8 @@ export class EuiContextMenuPanel extends Component { }); break; - case cascadingMenuKeyCodes.UP: - e.preventDefault(); + case cascadingMenuKeys.ARROW_UP: + event.preventDefault(); this.incrementFocusedItemIndex(-1); if (this.props.onUseKeyboardToNavigate) { @@ -183,8 +183,8 @@ export class EuiContextMenuPanel extends Component { } break; - case cascadingMenuKeyCodes.DOWN: - e.preventDefault(); + case cascadingMenuKeys.ARROW_DOWN: + event.preventDefault(); this.incrementFocusedItemIndex(1); if (this.props.onUseKeyboardToNavigate) { @@ -192,9 +192,9 @@ export class EuiContextMenuPanel extends Component { } break; - case cascadingMenuKeyCodes.RIGHT: + case cascadingMenuKeys.ARROW_RIGHT: if (this.props.showNextPanel) { - e.preventDefault(); + event.preventDefault(); this.props.showNextPanel(this.state.focusedItemIndex); if (this.props.onUseKeyboardToNavigate) { diff --git a/src/components/datagrid/data_grid.test.tsx b/src/components/datagrid/data_grid.test.tsx index 600e6fde471..299b4af1b36 100644 --- a/src/components/datagrid/data_grid.test.tsx +++ b/src/components/datagrid/data_grid.test.tsx @@ -26,7 +26,7 @@ import { takeMountedSnapshot, } from '../../test'; import { EuiDataGridColumnResizer } from './data_grid_column_resizer'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { act } from 'react-dom/test-utils'; import cheerio from 'cheerio'; @@ -1867,41 +1867,41 @@ Array [ // focus should not move when up against the left edge focusableCell .simulate('focus') - .simulate('keydown', { keyCode: keyCodes.LEFT }); + .simulate('keydown', { key: keys.ARROW_LEFT }); focusableCell = getFocusableCell(component); expect( focusableCell.find('[data-test-subj="cell-content"]').text() ).toEqual('0, A'); // focus should not move when up against the top edge - focusableCell.simulate('keydown', { keyCode: keyCodes.UP }); + focusableCell.simulate('keydown', { key: keys.ARROW_UP }); expect( focusableCell.find('[data-test-subj="cell-content"]').text() ).toEqual('0, A'); // move down - focusableCell.simulate('keydown', { keyCode: keyCodes.DOWN }); + focusableCell.simulate('keydown', { key: keys.ARROW_DOWN }); focusableCell = getFocusableCell(component); expect( focusableCell.find('[data-test-subj="cell-content"]').text() ).toEqual('1, A'); // move right - focusableCell.simulate('keydown', { keyCode: keyCodes.RIGHT }); + focusableCell.simulate('keydown', { key: keys.ARROW_RIGHT }); focusableCell = getFocusableCell(component); expect( focusableCell.find('[data-test-subj="cell-content"]').text() ).toEqual('1, B'); // move up - focusableCell.simulate('keydown', { keyCode: keyCodes.UP }); + focusableCell.simulate('keydown', { key: keys.ARROW_UP }); focusableCell = getFocusableCell(component); expect( focusableCell.find('[data-test-subj="cell-content"]').text() ).toEqual('0, B'); // move left - focusableCell.simulate('keydown', { keyCode: keyCodes.LEFT }); + focusableCell.simulate('keydown', { key: keys.ARROW_LEFT }); focusableCell = getFocusableCell(component); expect( focusableCell.find('[data-test-subj="cell-content"]').text() @@ -1909,8 +1909,8 @@ Array [ // move down and to the end of the row focusableCell - .simulate('keydown', { keyCode: keyCodes.DOWN }) - .simulate('keydown', { keyCode: keyCodes.END }); + .simulate('keydown', { key: keys.ARROW_DOWN }) + .simulate('keydown', { key: keys.END }); focusableCell = getFocusableCell(component); expect( focusableCell.find('[data-test-subj="cell-content"]').text() @@ -1918,8 +1918,8 @@ Array [ // move up and to the beginning of the row focusableCell - .simulate('keydown', { keyCode: keyCodes.UP }) - .simulate('keydown', { keyCode: keyCodes.HOME }); + .simulate('keydown', { key: keys.ARROW_UP }) + .simulate('keydown', { key: keys.HOME }); focusableCell = getFocusableCell(component); expect( focusableCell.find('[data-test-subj="cell-content"]').text() @@ -1928,7 +1928,7 @@ Array [ // jump to the last cell focusableCell.simulate('keydown', { ctrlKey: true, - keyCode: keyCodes.END, + key: keys.END, }); focusableCell = getFocusableCell(component); expect( @@ -1938,7 +1938,7 @@ Array [ // jump to the first cell focusableCell.simulate('keydown', { ctrlKey: true, - keyCode: keyCodes.HOME, + key: keys.HOME, }); focusableCell = getFocusableCell(component); expect( @@ -1948,7 +1948,7 @@ Array [ // page should not change when moving before the first entry // but the last row should remain focused focusableCell.simulate('keydown', { - keyCode: keyCodes.PAGE_UP, + key: keys.PAGE_UP, }); focusableCell = getFocusableCell(component); expect( @@ -1957,7 +1957,7 @@ Array [ // advance to the next page focusableCell.simulate('keydown', { - keyCode: keyCodes.PAGE_DOWN, + key: keys.PAGE_DOWN, }); focusableCell = getFocusableCell(component); expect( @@ -1966,9 +1966,9 @@ Array [ // move over one column and advance one more page focusableCell - .simulate('keydown', { keyCode: keyCodes.RIGHT }) // 3, B + .simulate('keydown', { key: keys.ARROW_RIGHT }) // 3, B .simulate('keydown', { - keyCode: keyCodes.PAGE_DOWN, + key: keys.PAGE_DOWN, }); // 6, B focusableCell = getFocusableCell(component); expect( @@ -1977,7 +1977,7 @@ Array [ // does not advance beyond the last page focusableCell.simulate('keydown', { - keyCode: keyCodes.PAGE_DOWN, + key: keys.PAGE_DOWN, }); focusableCell = getFocusableCell(component); expect( @@ -1986,9 +1986,9 @@ Array [ // move left one column, return to the previous page focusableCell - .simulate('keydown', { keyCode: keyCodes.LEFT }) // 6, A + .simulate('keydown', { key: keys.ARROW_LEFT }) // 6, A .simulate('keydown', { - keyCode: keyCodes.PAGE_UP, + key: keys.PAGE_UP, }); // 5, A focusableCell = getFocusableCell(component); expect( @@ -1997,7 +1997,7 @@ Array [ // return to the previous (first) page focusableCell.simulate('keydown', { - keyCode: keyCodes.PAGE_UP, + key: keys.PAGE_UP, }); focusableCell = getFocusableCell(component); expect( @@ -2008,10 +2008,10 @@ Array [ focusableCell .simulate('keydown', { ctrlKey: true, - keyCode: keyCodes.END, + key: keys.END, }) // 2, C (last cell of the first page) .simulate('keydown', { - keyCode: keyCodes.PAGE_DOWN, + key: keys.PAGE_DOWN, }); // 3, C (first cell of the second page, same cell position as previous page) focusableCell = getFocusableCell(component); expect( @@ -2020,7 +2020,7 @@ Array [ // advance to the final page focusableCell.simulate('keydown', { - keyCode: keyCodes.PAGE_DOWN, + key: keys.PAGE_DOWN, }); // 6, C focusableCell = getFocusableCell(component); expect( @@ -2115,7 +2115,7 @@ Array [ expect(focusableCell.text()).toEqual('0, A'); focusableCell .simulate('focus') - .simulate('keydown', { keyCode: keyCodes.DOWN }); + .simulate('keydown', { key: keys.ARROW_DOWN }); /** * On text only cells, the cell receives focus @@ -2124,7 +2124,7 @@ Array [ expect(focusableCell.text()).toEqual('1, A'); // make sure we're on the right cell expect(focusableCell.getDOMNode()).toBe(document.activeElement); - focusableCell.simulate('keydown', { keyCode: keyCodes.RIGHT }); + focusableCell.simulate('keydown', { key: keys.ARROW_RIGHT }); /** * On cells with 1 interactive item, the interactive item receives focus @@ -2135,7 +2135,7 @@ Array [ document.activeElement ); - focusableCell.simulate('keydown', { keyCode: keyCodes.RIGHT }); + focusableCell.simulate('keydown', { key: keys.ARROW_RIGHT }); /** * On cells with multiple interactive items, the cell receives focus @@ -2144,7 +2144,7 @@ Array [ expect(focusableCell.text()).toEqual('1, C'); expect(focusableCell.getDOMNode()).toBe(document.activeElement); - focusableCell.simulate('keydown', { keyCode: keyCodes.RIGHT }); + focusableCell.simulate('keydown', { key: keys.ARROW_RIGHT }); /** * On cells with 1 interactive item and non-interactive item(s), the cell receives focus @@ -2179,7 +2179,7 @@ Array [ expect(focusableCell.text()).toEqual('0, A'); focusableCell .simulate('focus') - .simulate('keydown', { keyCode: keyCodes.DOWN }); + .simulate('keydown', { key: keys.ARROW_DOWN }); focusableCell = getFocusableCell(component); /** @@ -2193,8 +2193,8 @@ Array [ * Disable grid navigation using ENTER */ focusableCell - .simulate('keydown', { keyCode: keyCodes.ENTER }) - .simulate('keydown', { keyCode: keyCodes.DOWN }); + .simulate('keydown', { key: keys.ENTER }) + .simulate('keydown', { key: keys.ARROW_DOWN }); let buttons = focusableCell.find('button'); @@ -2207,11 +2207,11 @@ Array [ /** * Enable grid navigation ESCAPE */ - focusableCell.simulate('keydown', { keyCode: keyCodes.ESCAPE }); + focusableCell.simulate('keydown', { key: keys.ESCAPE }); focusableCell = getFocusableCell(component); expect(focusableCell.getDOMNode()).toBe(document.activeElement); // focus should move back to cell - focusableCell.simulate('keydown', { keyCode: keyCodes.RIGHT }); + focusableCell.simulate('keydown', { key: keys.ARROW_RIGHT }); focusableCell = getFocusableCell(component); expect(focusableCell.text()).toEqual('1, B'); // grid navigation is enabled again, check that we can move expect(takeMountedSnapshot(component)).toMatchSnapshot(); @@ -2221,8 +2221,8 @@ Array [ */ focusableCell = getFocusableCell(component); focusableCell - .simulate('keydown', { keyCode: keyCodes.F2 }) - .simulate('keydown', { keyCode: keyCodes.UP }); + .simulate('keydown', { key: keys.F2 }) + .simulate('keydown', { key: keys.ARROW_UP }); buttons = focusableCell.find('button'); // grid navigation is disabled, location should not move @@ -2234,11 +2234,11 @@ Array [ /** * Enable grid navigation using F2 */ - focusableCell.simulate('keydown', { keyCode: keyCodes.F2 }); + focusableCell.simulate('keydown', { key: keys.F2 }); focusableCell = getFocusableCell(component); expect(focusableCell.getDOMNode()).toBe(document.activeElement); // focus should move back to cell - focusableCell.simulate('keydown', { keyCode: keyCodes.UP }); + focusableCell.simulate('keydown', { key: keys.ARROW_UP }); focusableCell = getFocusableCell(component); expect(focusableCell.text()).toEqual('0, B'); // grid navigation is enabled again, check that we can move expect(takeMountedSnapshot(component)).toMatchSnapshot(); diff --git a/src/components/datagrid/data_grid.tsx b/src/components/datagrid/data_grid.tsx index 9728dbf3b95..4dd101fcd24 100644 --- a/src/components/datagrid/data_grid.tsx +++ b/src/components/datagrid/data_grid.tsx @@ -58,7 +58,7 @@ import { } from './data_grid_types'; import { EuiDataGridCellProps } from './data_grid_cell'; import { EuiButtonEmpty } from '../button'; -import { keyCodes, htmlIdGenerator } from '../../services'; +import { keys, htmlIdGenerator } from '../../services'; import { EuiDataGridBody } from './data_grid_body'; import { useColumnSelector } from './column_selector'; import { useStyleSelector, startingStyles } from './style_selector'; @@ -406,30 +406,30 @@ function createKeyDownHandler( 1; const [x, y] = focusedCell; const rowCount = computeVisibleRows(props); - const { keyCode, ctrlKey } = event; + const { key, ctrlKey } = event; - if (keyCode === keyCodes.DOWN) { + if (key === keys.ARROW_DOWN) { event.preventDefault(); if (y < rowCount - 1) { setFocusedCell([x, y + 1]); } - } else if (keyCode === keyCodes.LEFT) { + } else if (key === keys.ARROW_LEFT) { event.preventDefault(); if (x > 0) { setFocusedCell([x - 1, y]); } - } else if (keyCode === keyCodes.UP) { + } else if (key === keys.ARROW_UP) { event.preventDefault(); const minimumIndex = headerIsInteractive ? -1 : 0; if (y > minimumIndex) { setFocusedCell([x, y - 1]); } - } else if (keyCode === keyCodes.RIGHT) { + } else if (key === keys.ARROW_RIGHT) { event.preventDefault(); if (x < colCount) { setFocusedCell([x + 1, y]); } - } else if (keyCode === keyCodes.PAGE_DOWN) { + } else if (key === keys.PAGE_DOWN) { if (props.pagination) { event.preventDefault(); const rowCount = props.rowCount; @@ -442,7 +442,7 @@ function createKeyDownHandler( setFocusedCell([focusedCell[0], 0]); updateFocus(); } - } else if (keyCode === keyCodes.PAGE_UP) { + } else if (key === keys.PAGE_UP) { if (props.pagination) { event.preventDefault(); const pageIndex = props.pagination.pageIndex; @@ -452,16 +452,16 @@ function createKeyDownHandler( setFocusedCell([focusedCell[0], props.pagination.pageSize - 1]); updateFocus(); } - } else if (keyCode === (ctrlKey && keyCodes.END)) { + } else if (key === (ctrlKey && keys.END)) { event.preventDefault(); setFocusedCell([colCount, rowCount - 1]); - } else if (keyCode === (ctrlKey && keyCodes.HOME)) { + } else if (key === (ctrlKey && keys.HOME)) { event.preventDefault(); setFocusedCell([0, 0]); - } else if (keyCode === keyCodes.END) { + } else if (key === keys.END) { event.preventDefault(); setFocusedCell([colCount, y]); - } else if (keyCode === keyCodes.HOME) { + } else if (key === keys.HOME) { event.preventDefault(); setFocusedCell([0, y]); } @@ -608,11 +608,11 @@ export const EuiDataGrid: FunctionComponent = props => { [headerIsInteractive, setHeaderIsInteractive, focusedCell, setFocusedCell] ); - const handleGridKeyDown = (e: KeyboardEvent) => { - switch (e.keyCode) { - case keyCodes.ESCAPE: + const handleGridKeyDown = (event: KeyboardEvent) => { + switch (event.key) { + case keys.ESCAPE: if (isFullScreen) { - e.preventDefault(); + event.preventDefault(); setIsFullScreen(false); } break; diff --git a/src/components/datagrid/data_grid_cell.tsx b/src/components/datagrid/data_grid_cell.tsx index 2b40a36efac..404d99b9d3c 100644 --- a/src/components/datagrid/data_grid_cell.tsx +++ b/src/components/datagrid/data_grid_cell.tsx @@ -40,6 +40,7 @@ import { EuiDataGridPopoverContent } from './data_grid_types'; import { EuiMutationObserver } from '../observer/mutation_observer'; import { DataGridContext } from './data_grid_context'; import { EuiFocusTrap } from '../focus_trap'; +import { keys } from '../../services'; export interface EuiDataGridCellValueElementProps { /** @@ -302,21 +303,25 @@ export class EuiDataGridCell extends Component< cellProps.style = widthStyle; } - const handleCellKeyDown = (e: KeyboardEvent) => { + const handleCellKeyDown = (event: KeyboardEvent) => { if (isExpandable) { - switch (e.key) { - case 'Enter': - case 'F2': - e.preventDefault(); + switch (event.key) { + case keys.ENTER: + case keys.F2: + event.preventDefault(); this.setState({ popoverIsOpen: true }); break; } } else { - if (e.key === 'Enter' || e.key === 'F2' || e.key === 'Escape') { + if ( + event.key === keys.ENTER || + event.key === keys.F2 || + event.key === keys.ESCAPE + ) { const interactables = this.getInteractables(); if (interactables.length >= 2) { - switch (e.key) { - case 'Enter': + switch (event.key) { + case keys.ENTER: // `Enter` only activates the trap if (this.state.isEntered === false) { this.enableTabbing(); @@ -325,10 +330,10 @@ export class EuiDataGridCell extends Component< // result of this keypress is focus shifts to the first interactive element // and then the browser fires the onClick event because that's how [Enter] works // so we need to prevent that default action otherwise entering the trap triggers the first element - e.preventDefault(); + event.preventDefault(); } break; - case 'F2': + case keys.F2: // toggle interactives' focus trap this.setState(({ isEntered }) => { if (isEntered) { @@ -339,7 +344,7 @@ export class EuiDataGridCell extends Component< return { isEntered: !isEntered }; }); break; - case 'Escape': + case keys.ESCAPE: // `Escape` only de-activates the trap this.preventTabbing(); if (this.state.isEntered === true) { @@ -491,10 +496,10 @@ export class EuiDataGridCell extends Component< zIndex={8001} display="block" closePopover={() => this.setState({ popoverIsOpen: false })} - onKeyDown={e => { - if (e.key === 'F2' || e.key === 'Escape') { - e.preventDefault(); - e.stopPropagation(); + onKeyDown={event => { + if (event.key === keys.F2 || event.key === keys.ESCAPE) { + event.preventDefault(); + event.stopPropagation(); this.setState({ popoverIsOpen: false }); } }} diff --git a/src/components/datagrid/data_grid_control_header_cell.tsx b/src/components/datagrid/data_grid_control_header_cell.tsx index 7188ee83538..8653c273905 100644 --- a/src/components/datagrid/data_grid_control_header_cell.tsx +++ b/src/components/datagrid/data_grid_control_header_cell.tsx @@ -19,7 +19,7 @@ import React, { FunctionComponent, useEffect, useRef, useState } from 'react'; import classnames from 'classnames'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import tabbable from 'tabbable'; import { EuiDataGridControlColumn, @@ -136,22 +136,22 @@ export const EuiDataGridControlHeaderCell: FunctionComponent< }); } - function onKeyUp(e: KeyboardEvent) { - switch (e.keyCode) { - case keyCodes.ENTER: { - e.preventDefault(); + function onKeyUp(event: KeyboardEvent) { + switch (event.key) { + case keys.ENTER: { + event.preventDefault(); setIsCellEntered(true); break; } - case keyCodes.ESCAPE: { - e.preventDefault(); + case keys.ESCAPE: { + event.preventDefault(); // move focus to cell setIsCellEntered(false); headerRef.current!.focus(); break; } - case keyCodes.F2: { - e.preventDefault(); + case keys.F2: { + event.preventDefault(); if (document.activeElement === headerRef.current) { // move focus into cell's interactives setIsCellEntered(true); diff --git a/src/components/datagrid/data_grid_header_cell.tsx b/src/components/datagrid/data_grid_header_cell.tsx index 15373088dd1..22c446d0150 100644 --- a/src/components/datagrid/data_grid_header_cell.tsx +++ b/src/components/datagrid/data_grid_header_cell.tsx @@ -29,7 +29,7 @@ import React, { import { htmlIdGenerator } from '../../services/accessibility'; import classnames from 'classnames'; import { EuiDataGridHeaderRowPropsSpecificProps } from './data_grid_header_row'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { EuiDataGridColumnResizer } from './data_grid_column_resizer'; import { EuiScreenReaderOnly } from '../accessibility'; import tabbable from 'tabbable'; @@ -210,22 +210,22 @@ export const EuiDataGridHeaderCell: FunctionComponent< }); } - function onKeyUp(e: KeyboardEvent) { - switch (e.keyCode) { - case keyCodes.ENTER: { - e.preventDefault(); + function onKeyUp(event: KeyboardEvent) { + switch (event.key) { + case keys.ENTER: { + event.preventDefault(); setIsCellEntered(true); break; } - case keyCodes.ESCAPE: { - e.preventDefault(); + case keys.ESCAPE: { + event.preventDefault(); // move focus to cell setIsCellEntered(false); headerRef.current!.focus(); break; } - case keyCodes.F2: { - e.preventDefault(); + case keys.F2: { + event.preventDefault(); if (document.activeElement === headerRef.current) { // move focus into cell's interactives setIsCellEntered(true); diff --git a/src/components/flyout/flyout.tsx b/src/components/flyout/flyout.tsx index bf0ef6b6e2e..88918718b8d 100644 --- a/src/components/flyout/flyout.tsx +++ b/src/components/flyout/flyout.tsx @@ -26,7 +26,7 @@ import React, { } from 'react'; import classnames from 'classnames'; -import { keyCodes, EuiWindowEvent } from '../../services'; +import { keys, EuiWindowEvent } from '../../services'; import { CommonProps } from '../common'; import { EuiFocusTrap } from '../focus_trap'; @@ -88,7 +88,7 @@ export const EuiFlyout: FunctionComponent = ({ ...rest }) => { const onKeyDown = (event: KeyboardEvent) => { - if (event.keyCode === keyCodes.ESCAPE) { + if (event.key === keys.ESCAPE) { event.preventDefault(); onClose(); } diff --git a/src/components/form/field_search/field_search.tsx b/src/components/form/field_search/field_search.tsx index f90a612967a..c08d6e1234b 100644 --- a/src/components/form/field_search/field_search.tsx +++ b/src/components/form/field_search/field_search.tsx @@ -21,7 +21,7 @@ import React, { Component, InputHTMLAttributes, KeyboardEvent } from 'react'; import classNames from 'classnames'; import { Browser } from '../../../services/browser'; import { CommonProps } from '../../common'; -import { ENTER } from '../../../services/key_codes'; +import { keys } from '../../../services'; import { EuiFormControlLayout, @@ -193,8 +193,8 @@ export class EuiFieldSearch extends Component< if ( onSearch && - ((event.keyCode !== ENTER && incremental) || - (event.keyCode === ENTER && !isSearchSupported)) + ((event.key !== keys.ENTER && incremental) || + (event.key === keys.ENTER && !isSearchSupported)) ) { onSearch((event.target as HTMLInputElement).value); } diff --git a/src/components/form/range/dual_range.tsx b/src/components/form/range/dual_range.tsx index 8a9a411c050..a1ccaf55859 100644 --- a/src/components/form/range/dual_range.tsx +++ b/src/components/form/range/dual_range.tsx @@ -20,7 +20,7 @@ import React, { Component } from 'react'; import classNames from 'classnames'; -import { keyCodes } from '../../../services'; +import { keys } from '../../../services'; import { isWithinRange } from '../../../services/number'; import { EuiInputPopover } from '../../popover'; import { @@ -254,11 +254,14 @@ export class EuiDualRange extends Component { ); }; - _isDirectionalKeyPress = (e: React.KeyboardEvent) => { + _isDirectionalKeyPress = (event: React.KeyboardEvent) => { return ( - [keyCodes.UP, keyCodes.RIGHT, keyCodes.DOWN, keyCodes.LEFT].indexOf( - e.keyCode - ) > -1 + [ + keys.ARROW_UP, + keys.ARROW_RIGHT, + keys.ARROW_DOWN, + keys.ARROW_LEFT, + ].indexOf(event.key) > -1 ); }; @@ -280,24 +283,24 @@ export class EuiDualRange extends Component { _handleKeyDown = ( value: ValueMember, - e: React.KeyboardEvent + event: React.KeyboardEvent ) => { let newVal = Number(value); let stepRemainder = 0; const step = this.props.step || 1; - switch (e.keyCode) { - case keyCodes.UP: - case keyCodes.RIGHT: - e.preventDefault(); + switch (event.key) { + case keys.ARROW_UP: + case keys.ARROW_RIGHT: + event.preventDefault(); newVal += step; stepRemainder = (newVal - this.props.min) % step; if (step !== 1 && stepRemainder > 0) { newVal = newVal - stepRemainder; } break; - case keyCodes.DOWN: - case keyCodes.LEFT: - e.preventDefault(); + case keys.ARROW_DOWN: + case keys.ARROW_LEFT: + event.preventDefault(); newVal -= step; stepRemainder = (newVal - this.props.min) % step; if (step !== 1 && stepRemainder > 0) { @@ -308,40 +311,40 @@ export class EuiDualRange extends Component { return newVal; }; - handleLowerKeyDown = (e: React.KeyboardEvent) => { + handleLowerKeyDown = (event: React.KeyboardEvent) => { let lower = this.lowerValue; - switch (e.keyCode) { - case keyCodes.TAB: + switch (event.key) { + case keys.TAB: return; default: if (!this.lowerValueIsValid) { // Relevant only when initial value is `''` and `showInput` is not set - e.preventDefault(); - this._resetToRangeEnds(e); + event.preventDefault(); + this._resetToRangeEnds(event); return; } - lower = this._handleKeyDown(lower, e); + lower = this._handleKeyDown(lower, event); } if (lower >= this.upperValue || lower < this.props.min) return; - this._handleOnChange(lower, this.upperValue, e); + this._handleOnChange(lower, this.upperValue, event); }; - handleUpperKeyDown = (e: React.KeyboardEvent) => { + handleUpperKeyDown = (event: React.KeyboardEvent) => { let upper = this.upperValue; - switch (e.keyCode) { - case keyCodes.TAB: + switch (event.key) { + case keys.TAB: return; default: if (!this.upperValueIsValid) { // Relevant only when initial value is `''` and `showInput` is not set - e.preventDefault(); - this._resetToRangeEnds(e); + event.preventDefault(); + this._resetToRangeEnds(event); return; } - upper = this._handleKeyDown(upper, e); + upper = this._handleKeyDown(upper, event); } if (upper <= this.lowerValue || upper > this.props.max) return; - this._handleOnChange(this.lowerValue, upper, e); + this._handleOnChange(this.lowerValue, upper, event); }; calculateThumbPositionStyle = (value: number, width?: number) => { diff --git a/src/components/form/super_select/super_select.tsx b/src/components/form/super_select/super_select.tsx index 6962b8dd465..4e177aa3e6a 100644 --- a/src/components/form/super_select/super_select.tsx +++ b/src/components/form/super_select/super_select.tsx @@ -33,7 +33,7 @@ import { EuiContextMenuItem, EuiContextMenuItemLayoutAlignment, } from '../../context_menu'; -import { keyCodes } from '../../../services'; +import { keys } from '../../../services'; import { EuiI18n } from '../../i18n'; enum ShiftDirection { @@ -180,38 +180,38 @@ export class EuiSuperSelect extends Component< } }; - onSelectKeyDown = (e: React.KeyboardEvent) => { - if (e.keyCode === keyCodes.UP || e.keyCode === keyCodes.DOWN) { - e.preventDefault(); - e.stopPropagation(); + onSelectKeyDown = (event: React.KeyboardEvent) => { + if (event.key === keys.ARROW_UP || event.key === keys.ARROW_DOWN) { + event.preventDefault(); + event.stopPropagation(); this.openPopover(); } }; - onItemKeyDown = (e: React.KeyboardEvent) => { - switch (e.keyCode) { - case keyCodes.ESCAPE: + onItemKeyDown = (event: React.KeyboardEvent) => { + switch (event.key) { + case keys.ESCAPE: // close the popover and prevent ancestors from handling - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); this.closePopover(); break; - case keyCodes.TAB: + case keys.TAB: // no-op - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); break; - case keyCodes.UP: - e.preventDefault(); - e.stopPropagation(); + case keys.ARROW_UP: + event.preventDefault(); + event.stopPropagation(); this.shiftFocus(ShiftDirection.BACK); break; - case keyCodes.DOWN: - e.preventDefault(); - e.stopPropagation(); + case keys.ARROW_DOWN: + event.preventDefault(); + event.stopPropagation(); this.shiftFocus(ShiftDirection.FORWARD); break; } diff --git a/src/components/image/image.tsx b/src/components/image/image.tsx index 56e499a265f..6178f175b80 100644 --- a/src/components/image/image.tsx +++ b/src/components/image/image.tsx @@ -34,7 +34,7 @@ import { EuiI18n } from '../i18n'; import { EuiFocusTrap } from '../focus_trap'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { useInnerText } from '../inner_text'; type ImageSize = 's' | 'm' | 'l' | 'xl' | 'fullWidth' | 'original'; @@ -104,7 +104,7 @@ export const EuiImage: FunctionComponent = ({ const [isFullScreenActive, setIsFullScreenActive] = useState(false); const onKeyDown = (event: React.KeyboardEvent) => { - if (event.keyCode === keyCodes.ESCAPE) { + if (event.key === keys.ESCAPE) { event.preventDefault(); event.stopPropagation(); closeFullScreen(); diff --git a/src/components/modal/confirm_modal.test.tsx b/src/components/modal/confirm_modal.test.tsx index 671781293aa..84bad6a0013 100644 --- a/src/components/modal/confirm_modal.test.tsx +++ b/src/components/modal/confirm_modal.test.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { mount, render } from 'enzyme'; import { findTestSubject, requiredProps } from '../../test'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { CANCEL_BUTTON, @@ -126,7 +126,7 @@ describe('EuiConfirmModal', () => { ); findTestSubject(component, 'modal').simulate('keydown', { - keyCode: keyCodes.ESCAPE, + key: keys.ESCAPE, }); expect(onConfirm).toHaveBeenCalledTimes(0); expect(onCancel).toHaveBeenCalledTimes(1); diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx index 036c1d01537..417eef79d32 100644 --- a/src/components/modal/modal.tsx +++ b/src/components/modal/modal.tsx @@ -20,7 +20,7 @@ import React, { FunctionComponent, ReactNode, HTMLAttributes } from 'react'; import classnames from 'classnames'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { EuiButtonIcon } from '../button'; @@ -58,7 +58,7 @@ export const EuiModal: FunctionComponent = ({ ...rest }) => { const onKeyDown = (event: React.KeyboardEvent) => { - if (event.keyCode === keyCodes.ESCAPE) { + if (event.key === keys.ESCAPE) { event.preventDefault(); event.stopPropagation(); onClose(event); diff --git a/src/components/nav_drawer/nav_drawer_flyout.tsx b/src/components/nav_drawer/nav_drawer_flyout.tsx index ab945a2646f..ae21eb366ba 100644 --- a/src/components/nav_drawer/nav_drawer_flyout.tsx +++ b/src/components/nav_drawer/nav_drawer_flyout.tsx @@ -27,7 +27,7 @@ import React, { import classNames from 'classnames'; import tabbable from 'tabbable'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { EuiTitle } from '../title'; import { EuiNavDrawerGroup, FlyoutMenuItem } from './nav_drawer_group'; @@ -84,9 +84,9 @@ export const EuiNavDrawerFlyout: FunctionComponent = ({ ); const handleKeyDown: KeyboardEventHandler = event => { - if (event.keyCode === keyCodes.ESCAPE) { + if (event.key === keys.ESCAPE) { handleClose(); - } else if (event.keyCode === keyCodes.TAB) { + } else if (event.key === keys.TAB) { let tabs = tabbables; if (!tabs && menuElementRef.current) { tabs = tabbable(menuElementRef.current).filter( diff --git a/src/components/popover/input_popover.tsx b/src/components/popover/input_popover.tsx index 91e60fbd0bb..6ca9bae47b0 100644 --- a/src/components/popover/input_popover.tsx +++ b/src/components/popover/input_popover.tsx @@ -31,7 +31,7 @@ import { CommonProps } from '../common'; import { EuiFocusTrap } from '../focus_trap'; import { EuiPopover, EuiPopoverProps } from './popover'; import { EuiResizeObserver } from '../observer/resize_observer'; -import { cascadingMenuKeyCodes } from '../../services'; +import { cascadingMenuKeys } from '../../services'; interface EuiInputPopoverProps extends Omit { @@ -88,8 +88,8 @@ export const EuiInputPopover: FunctionComponent = ({ setPanelWidth(); }, [setPanelWidth]); - const onKeyDown = (e: React.KeyboardEvent) => { - if (e.keyCode === cascadingMenuKeyCodes.TAB) { + const onKeyDown = (event: React.KeyboardEvent) => { + if (event.key === cascadingMenuKeys.TAB) { const tabbableItems = tabbable(panelEl).filter((el: HTMLElement) => { return ( Array.from(el.attributes) diff --git a/src/components/popover/popover.test.tsx b/src/components/popover/popover.test.tsx index 65a2bb206c9..0d4ae1f8914 100644 --- a/src/components/popover/popover.test.tsx +++ b/src/components/popover/popover.test.tsx @@ -28,7 +28,7 @@ import { PopoverAnchorPosition, } from './popover'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; jest.mock('../portal', () => ({ EuiPortal: ({ children }: { children: ReactNode }) => children, @@ -111,7 +111,7 @@ describe('EuiPopover', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.ESCAPE }); + component.simulate('keydown', { key: keys.ESCAPE }); expect(closePopoverHandler).toBeCalledTimes(1); }); @@ -128,7 +128,7 @@ describe('EuiPopover', () => { /> ); - component.simulate('keydown', { keyCode: keyCodes.ESCAPE }); + component.simulate('keydown', { key: keys.ESCAPE }); expect(closePopoverHandler).not.toBeCalled(); }); }); diff --git a/src/components/popover/popover.tsx b/src/components/popover/popover.tsx index 191027128ea..d67f8982af0 100644 --- a/src/components/popover/popover.tsx +++ b/src/components/popover/popover.tsx @@ -33,7 +33,7 @@ import { FocusTarget, EuiFocusTrap } from '../focus_trap'; import { Props as ReactFocusLockProps } from 'react-focus-lock'; // eslint-disable-line import/named import { - cascadingMenuKeyCodes, + cascadingMenuKeys, getTransitionTimings, getWaitDuration, performOnFrame, @@ -336,11 +336,11 @@ export class EuiPopover extends Component { }; } - onKeyDown = (e: React.KeyboardEvent) => { - if (e.keyCode === cascadingMenuKeyCodes.ESCAPE) { + onKeyDown = (event: React.KeyboardEvent) => { + if (event.key === cascadingMenuKeys.ESCAPE) { if (this.state.isOpenStable || this.state.isOpening) { - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); this.props.closePopover(); } } diff --git a/src/components/resizable_container/helpers.ts b/src/components/resizable_container/helpers.ts index 78675862c55..4ff4e3e416b 100644 --- a/src/components/resizable_container/helpers.ts +++ b/src/components/resizable_container/helpers.ts @@ -19,7 +19,7 @@ import { useCallback, MouseEvent, TouchEvent } from 'react'; -import { keyCodes } from '../../services'; +import { keys } from '../../services'; import { EuiResizableButtonMouseEvent, EuiResizableButtonKeyDownEvent, @@ -109,13 +109,12 @@ export const useContainerCallbacks = ({ ); const onKeyDown = useCallback( - (ev: EuiResizableButtonKeyDownEvent) => { - const { keyCode, currentTarget } = ev; + (event: EuiResizableButtonKeyDownEvent) => { + const { key, currentTarget } = event; const shouldResizeHorizontalPanel = - isHorizontal && - (keyCode === keyCodes.LEFT || keyCode === keyCodes.RIGHT); + isHorizontal && (key === keys.ARROW_LEFT || key === keys.ARROW_RIGHT); const shouldResizeVerticalPanel = - !isHorizontal && (keyCode === keyCodes.UP || keyCode === keyCodes.DOWN); + !isHorizontal && (key === keys.ARROW_UP || key === keys.ARROW_DOWN); const prevPanelId = currentTarget.previousElementSibling!.id; const nextPanelId = currentTarget.nextElementSibling!.id; @@ -124,7 +123,7 @@ export const useContainerCallbacks = ({ prevPanelId && nextPanelId ) { - ev.preventDefault(); + event.preventDefault(); const { current: registry } = registryRef; const [prevPanel, nextPanel] = registry.getResizerSiblings( @@ -136,14 +135,12 @@ export const useContainerCallbacks = ({ const prevPanelSize = pxToPercent( prevPanel.getSizePx() - - (keyCode === keyCodes.UP || keyCode === keyCodes.LEFT ? 10 : -10), + (key === keys.ARROW_UP || key === keys.ARROW_LEFT ? 10 : -10), containerSize - resizersSize ); const nextPanelSize = pxToPercent( nextPanel.getSizePx() - - (keyCode === keyCodes.DOWN || keyCode === keyCodes.RIGHT - ? 10 - : -10), + (key === keys.ARROW_DOWN || key === keys.ARROW_RIGHT ? 10 : -10), containerSize - resizersSize ); diff --git a/src/components/search_bar/filters/field_value_selection_filter.tsx b/src/components/search_bar/filters/field_value_selection_filter.tsx index 2bf96a3244d..94f0608104d 100644 --- a/src/components/search_bar/filters/field_value_selection_filter.tsx +++ b/src/components/search_bar/filters/field_value_selection_filter.tsx @@ -19,7 +19,7 @@ import React, { Component, ReactElement, ReactNode } from 'react'; import { isArray, isNil } from '../../../services/predicate'; -import { keyCodes } from '../../../services'; +import { keys } from '../../../services'; import { EuiPopover, EuiPopoverTitle } from '../../popover'; import { EuiFieldSearch } from '../../form/field_search'; import { EuiFilterButton, EuiFilterSelectItem } from '../../filter_group'; @@ -300,15 +300,15 @@ export class FieldValueSelectionFilter extends Component< | React.KeyboardEvent | React.KeyboardEvent ) { - switch (event.keyCode) { - case keyCodes.DOWN: + switch (event.key) { + case keys.ARROW_DOWN: if (index < this.selectItems.length - 1) { event.preventDefault(); this.selectItems[index + 1].focus(); } break; - case keyCodes.UP: + case keys.ARROW_UP: if (index < 0) { return; // it's coming from the search box... nothing to do... nowhere to go } diff --git a/src/components/search_bar/search_bar.test.tsx b/src/components/search_bar/search_bar.test.tsx index 2c03d3701e5..8d1dd964ad1 100644 --- a/src/components/search_bar/search_bar.test.tsx +++ b/src/components/search_bar/search_bar.test.tsx @@ -23,7 +23,7 @@ import { requiredProps } from '../../test'; import { mount, shallow } from 'enzyme'; import { EuiSearchBar } from './search_bar'; import { Query } from './query'; -import { ENTER } from '../../services/key_codes'; +import { keys } from '../../services'; import { SearchFilterConfig } from './search_filters'; describe('SearchBar', () => { @@ -106,7 +106,7 @@ describe('SearchBar', () => { ); component.find('input[data-test-subj="searchbar"]').simulate('keyup', { - keyCode: ENTER, + key: keys.ENTER, target: { value: 'status:inactive' }, }); diff --git a/src/components/selectable/selectable.tsx b/src/components/selectable/selectable.tsx index 51c0fcf5725..61bb338ab84 100644 --- a/src/components/selectable/selectable.tsx +++ b/src/components/selectable/selectable.tsx @@ -24,6 +24,7 @@ import React, { createRef, Fragment, ReactElement, + KeyboardEvent, } from 'react'; import classNames from 'classnames'; import { CommonProps, ExclusiveUnion } from '../common'; @@ -32,8 +33,7 @@ import { EuiSelectableMessage } from './selectable_message'; import { EuiSelectableList } from './selectable_list'; import { EuiLoadingChart } from '../loading'; import { getMatchingOptions } from './matching_options'; -import { comboBoxKeyCodes } from '../../services'; -import { TAB } from '../../services/key_codes'; +import { keys } from '../../services'; import { EuiI18n } from '../i18n'; import { EuiSelectableOption } from './selectable_option'; import { @@ -193,24 +193,24 @@ export class EuiSelectable extends Component< return this.state.activeOptionIndex != null; }; - onKeyDown = (e: any) => { + onKeyDown = (event: KeyboardEvent) => { const optionsList = this.optionsListRef.current; - switch (e.keyCode) { - case comboBoxKeyCodes.UP: - e.preventDefault(); - e.stopPropagation(); + switch (event.key) { + case keys.ARROW_UP: + event.preventDefault(); + event.stopPropagation(); this.incrementActiveOptionIndex(-1); break; - case comboBoxKeyCodes.DOWN: - e.preventDefault(); - e.stopPropagation(); + case keys.ARROW_DOWN: + event.preventDefault(); + event.stopPropagation(); this.incrementActiveOptionIndex(1); break; - case comboBoxKeyCodes.ENTER: - e.stopPropagation(); + case keys.ENTER: + event.stopPropagation(); if (this.state.activeOptionIndex != null && optionsList) { optionsList.onAddOrRemoveOption( this.state.visibleOptions[this.state.activeOptionIndex] @@ -218,18 +218,18 @@ export class EuiSelectable extends Component< } break; - case TAB: + case keys.TAB: // Disallow tabbing when the user is navigating the options. // TODO: Can we force the tab to the next sibling element? if (this.hasActiveOption()) { - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); } break; default: if (this.props.onKeyDown) { - this.props.onKeyDown(e); + this.props.onKeyDown(event); } this.clearActiveOption(); } diff --git a/src/components/tool_tip/tool_tip.tsx b/src/components/tool_tip/tool_tip.tsx index 15f27612721..885cf7ff7de 100644 --- a/src/components/tool_tip/tool_tip.tsx +++ b/src/components/tool_tip/tool_tip.tsx @@ -24,15 +24,14 @@ import React, { ReactElement, ReactNode, MouseEvent as ReactMouseEvent, + KeyboardEvent, } from 'react'; import classNames from 'classnames'; import { keysOf } from '../common'; import { EuiPortal } from '../portal'; import { EuiToolTipPopover } from './tool_tip_popover'; -import { findPopoverPosition, htmlIdGenerator } from '../../services'; - -import { TAB } from '../../services/key_codes'; +import { findPopoverPosition, htmlIdGenerator, keys } from '../../services'; import { EuiResizeObserver } from '../observer/resize_observer'; @@ -243,24 +242,25 @@ export class EuiToolTip extends Component { window.removeEventListener('mousemove', this.hasFocusMouseMoveListener); }; - onKeyUp = (e: { keyCode: number }) => { - if (e.keyCode === TAB) { + onKeyUp = (event: KeyboardEvent) => { + if (event.key === keys.TAB) { window.addEventListener('mousemove', this.hasFocusMouseMoveListener); } }; - onMouseOut = (e: ReactMouseEvent) => { + onMouseOut = (event: ReactMouseEvent) => { // Prevent mousing over children from hiding the tooltip by testing for whether the mouse has // left the anchor for a non-child. if ( - this.anchor === e.relatedTarget || - (this.anchor != null && !this.anchor.contains(e.relatedTarget as Node)) + this.anchor === event.relatedTarget || + (this.anchor != null && + !this.anchor.contains(event.relatedTarget as Node)) ) { this.hideToolTip(); } if (this.props.onMouseOut) { - this.props.onMouseOut(e); + this.props.onMouseOut(event); } }; @@ -315,7 +315,9 @@ export class EuiToolTip extends Component { className={anchorClasses} onMouseOver={this.showToolTip} onMouseOut={this.onMouseOut} - onKeyUp={e => this.onKeyUp(e)}> + onKeyUp={event => { + this.onKeyUp(event); + }}> {/** * Re: jsx-a11y/mouse-events-have-key-events * We apply onFocus, onBlur, etc to the children element because that's the element diff --git a/src/components/tree_view/tree_view.tsx b/src/components/tree_view/tree_view.tsx index 194c89d54aa..4506b588657 100644 --- a/src/components/tree_view/tree_view.tsx +++ b/src/components/tree_view/tree_view.tsx @@ -24,7 +24,7 @@ import { EuiI18n } from '../i18n'; import { EuiIcon } from '../icon'; import { EuiScreenReaderOnly } from '../accessibility'; import { EuiText } from '../text'; -import { keyCodes, htmlIdGenerator } from '../../services'; +import { keys, htmlIdGenerator } from '../../services'; const EuiTreeViewContext = createContext(''); const treeIdGenerator = htmlIdGenerator('euiTreeView'); @@ -169,54 +169,54 @@ export class EuiTreeView extends Component { }; // Enable keyboard navigation - onKeyDown = (e: React.KeyboardEvent, node: Node) => { - switch (e.keyCode) { - case keyCodes.DOWN: { + onKeyDown = (event: React.KeyboardEvent, node: Node) => { + switch (event.key) { + case keys.ARROW_DOWN: { const nodeButtons = Array.from( document.querySelectorAll( `[data-test-subj="euiTreeViewButton-${this.state.treeID}"]` ) ); - const currentIndex = nodeButtons.indexOf(e.currentTarget); + const currentIndex = nodeButtons.indexOf(event.currentTarget); if (currentIndex > -1) { const nextButton = nodeButtons[currentIndex + 1] as HTMLElement; if (nextButton) { - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); nextButton.focus(); } } break; } - case keyCodes.UP: { + case keys.ARROW_UP: { const nodeButtons = Array.from( document.querySelectorAll( `[data-test-subj="euiTreeViewButton-${this.state.treeID}"]` ) ); - const currentIndex = nodeButtons.indexOf(e.currentTarget); + const currentIndex = nodeButtons.indexOf(event.currentTarget); if (currentIndex > -1) { const prevButton = nodeButtons[currentIndex + -1] as HTMLElement; if (prevButton) { - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); prevButton.focus(); } } break; } - case keyCodes.RIGHT: { + case keys.ARROW_RIGHT: { if (!this.isNodeOpen(node)) { - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); this.handleNodeClick(node, true); } break; } - case keyCodes.LEFT: { + case keys.ARROW_LEFT: { if (this.isNodeOpen(node)) { - e.preventDefault(); - e.stopPropagation(); + event.preventDefault(); + event.stopPropagation(); this.handleNodeClick(node, true); } } @@ -225,10 +225,10 @@ export class EuiTreeView extends Component { } }; - onChildrenKeydown = (e: React.KeyboardEvent, index: number) => { - if (e.keyCode === keyCodes.LEFT) { - e.preventDefault(); - e.stopPropagation(); + onChildrenKeydown = (event: React.KeyboardEvent, index: number) => { + if (event.key === keys.ARROW_LEFT) { + event.preventDefault(); + event.stopPropagation(); this.buttonRef[index]!.focus(); } }; diff --git a/src/services/accessibility/accessible_click_keys.ts b/src/services/accessibility/accessible_click_keys.ts index c806bbf1d6b..acf62ebb3ac 100644 --- a/src/services/accessibility/accessible_click_keys.ts +++ b/src/services/accessibility/accessible_click_keys.ts @@ -17,7 +17,7 @@ * under the License. */ -import { ENTER, SPACE } from '../key_codes'; +import { ENTER, SPACE } from '../keys'; // These keys are used to execute click actions on interactive elements like buttons and links. export const accessibleClickKeys = { diff --git a/src/services/accessibility/cascading_menu_key_codes.ts b/src/services/accessibility/cascading_menu_keys.ts similarity index 72% rename from src/services/accessibility/cascading_menu_key_codes.ts rename to src/services/accessibility/cascading_menu_keys.ts index 9c3222eaa8d..b1b16d774f5 100644 --- a/src/services/accessibility/cascading_menu_key_codes.ts +++ b/src/services/accessibility/cascading_menu_keys.ts @@ -20,21 +20,28 @@ /** * These keys are used for navigating cascading menu UI components. * - * UP: Select the previous item in the list. - * DOWN: Select the next item in the list. - * LEFT: Show the previous menu. - * RIGHT: Show the next menu for the selected item. + * ARROW_DOWN: Select the next item in the list. + * ARROW_LEFT: Show the previous menu. + * ARROW_RIGHT: Show the next menu for the selected item. + * ARROW_UP: Select the previous item in the list. * ESC: Deselect the current selection and hide the list. * TAB: Normal tabbing navigation is still supported. */ -import { DOWN, ESCAPE, LEFT, RIGHT, UP, TAB } from '../key_codes'; +import { + ARROW_DOWN, + ARROW_LEFT, + ARROW_RIGHT, + ARROW_UP, + ESCAPE, + TAB, +} from '../keys'; -export const cascadingMenuKeyCodes = { - DOWN, +export const cascadingMenuKeys = { + ARROW_DOWN, + ARROW_LEFT, + ARROW_RIGHT, + ARROW_UP, ESCAPE, - LEFT, - RIGHT, - UP, TAB, }; diff --git a/src/services/accessibility/combo_box_key_codes.ts b/src/services/accessibility/combo_box_keys.ts similarity index 82% rename from src/services/accessibility/combo_box_key_codes.ts rename to src/services/accessibility/combo_box_keys.ts index 4dae7146374..32062191355 100644 --- a/src/services/accessibility/combo_box_key_codes.ts +++ b/src/services/accessibility/combo_box_keys.ts @@ -20,18 +20,18 @@ /** * These keys are used for navigating combobox UI components. * - * UP: Select the previous item in the list. - * DOWN: Select the next item in the list. + * ARROW_UP: Select the previous item in the list. + * ARROW_DOWN: Select the next item in the list. * ENTER / TAB: Complete input with the current selection. * ESC: Deselect the current selection and hide the list. */ -import { DOWN, ENTER, ESCAPE, TAB, UP } from '../key_codes'; +import { ARROW_DOWN, ENTER, ESCAPE, TAB, ARROW_UP } from '../keys'; -export const comboBoxKeyCodes = { - DOWN, +export const comboBoxKeys = { + ARROW_DOWN, + ARROW_UP, ENTER, ESCAPE, TAB, - UP, }; diff --git a/src/services/accessibility/index.ts b/src/services/accessibility/index.ts index 4eb4979d9d6..7c3200a709e 100644 --- a/src/services/accessibility/index.ts +++ b/src/services/accessibility/index.ts @@ -18,6 +18,6 @@ */ export { accessibleClickKeys } from './accessible_click_keys'; -export { cascadingMenuKeyCodes } from './cascading_menu_key_codes'; -export { comboBoxKeyCodes } from './combo_box_key_codes'; +export { cascadingMenuKeys } from './cascading_menu_keys'; +export { comboBoxKeys } from './combo_box_keys'; export { htmlIdGenerator } from './html_id_generator'; diff --git a/src/services/index.ts b/src/services/index.ts index 3637ae9d001..7409ce75601 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -17,14 +17,14 @@ * under the License. */ -// Export all keyCodes under a `keyCodes` named variable -import * as keyCodes from './key_codes'; -export { keyCodes }; +// Export all keys under a `keys` named variable +import * as keys from './keys'; +export { keys }; export { accessibleClickKeys, - cascadingMenuKeyCodes, - comboBoxKeyCodes, + cascadingMenuKeys, + comboBoxKeys, htmlIdGenerator, } from './accessibility'; diff --git a/src/services/key_codes.ts b/src/services/keys.ts similarity index 51% rename from src/services/key_codes.ts rename to src/services/keys.ts index 366174fbbab..1774262f83c 100644 --- a/src/services/key_codes.ts +++ b/src/services/keys.ts @@ -17,39 +17,36 @@ * under the License. */ -export const ENTER = 13; -export const SPACE = 32; -export const ESCAPE = 27; -export const TAB = 9; -export const BACKSPACE = 8; -export const F2 = 113; +export const ENTER = 'Enter'; +export const SPACE = ' '; +export const ESCAPE = 'Escape'; +export const TAB = 'Tab'; +export const BACKSPACE = 'Backspace'; +export const F2 = 'F2'; -// Arrow keys -export const DOWN = 40; -export const UP = 38; -export const LEFT = 37; -export const RIGHT = 39; +export const ARROW_DOWN = 'ArrowDown'; +export const ARROW_UP = 'ArrowUp'; +export const ARROW_LEFT = 'ArrowLeft'; +export const ARROW_RIGHT = 'ArrowRight'; -export const PAGE_UP = 33; -export const PAGE_DOWN = 34; -export const END = 35; -export const HOME = 36; +export const PAGE_UP = 'PageUp'; +export const PAGE_DOWN = 'PageDown'; +export const END = 'End'; +export const HOME = 'Home'; -export enum keyCodes { - ENTER = 13, - SPACE = 32, - ESCAPE = 27, - TAB = 9, - BACKSPACE = 8, - F2 = 113, - - DOWN = 40, - UP = 38, - LEFT = 37, - RIGHT = 39, - - PAGE_UP = 33, - PAGE_DOWN = 34, - END = 35, - HOME = 36, +export enum keys { + ENTER = 'Enter', + SPACE = ' ', + ESCAPE = 'Escape', + TAB = 'Tab', + BACKSPACE = 'Backspace', + F2 = 'F2', + ARROW_DOWN = 'ArrowDown', + ARROW_UP = 'ArrowUp', + ARROW_LEFT = 'ArrowLeft', + ARROW_RIGHT = 'ArrowRight', + PAGE_UP = 'PageUp', + PAGE_DOWN = 'PageDown', + END = 'End', + HOME = 'Home', } diff --git a/wiki/consuming.md b/wiki/consuming.md index 794c58431fc..5f2cdf2e97a 100644 --- a/wiki/consuming.md +++ b/wiki/consuming.md @@ -25,7 +25,7 @@ import { Most services are published from the `lib/services` directory. Some are published from their module directories in this directory. ```js -import { keyCodes } from '@elastic/eui/lib/services'; +import { keys } from '@elastic/eui/lib/services'; import { Timer } from '@elastic/eui/lib/services/time'; ```