From 58fc650f7507425a252e6e817b6ac596b7c489ef Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 1 May 2023 16:37:09 -0400 Subject: [PATCH 01/11] [v5] feat: use named keys instead of key codes --- packages/core/src/common/keys.ts | 24 ++- .../core/src/components/button/buttons.tsx | 18 +-- .../components/editable-text/editableText.tsx | 10 +- .../src/components/forms/numericInput.tsx | 12 +- .../src/components/hotkeys/hotkeyParser.ts | 148 +++--------------- .../core/src/components/overlay/overlay.tsx | 6 +- .../core/src/components/popover/popover.tsx | 6 +- .../core/src/components/slider/handle.tsx | 12 +- packages/core/src/components/tabs/tabs.tsx | 16 +- .../src/components/tag-input/tagInput.tsx | 15 +- .../src/components/toast/overlayToaster.tsx | 5 +- packages/datetime/src/dateInput.tsx | 12 +- packages/datetime/src/dateRangeInput.tsx | 6 +- packages/datetime/src/timePicker.tsx | 16 +- .../date-range-input2/dateRangeInput2.tsx | 7 +- .../docs-app/src/components/clickToCopy.tsx | 4 +- .../docs-app/src/components/colorSchemes.tsx | 4 +- .../numericInputExtendedExample.tsx | 3 +- .../src/common/eventHandlerUtils.ts | 17 +- .../components/multi-select/multiSelect.tsx | 9 +- .../src/components/query-list/queryList.tsx | 14 +- .../select/src/components/select/select.tsx | 7 +- .../select/src/components/suggest/suggest.tsx | 19 +-- 23 files changed, 125 insertions(+), 265 deletions(-) diff --git a/packages/core/src/common/keys.ts b/packages/core/src/common/keys.ts index fa5936f996..0c04b3db8f 100644 --- a/packages/core/src/common/keys.ts +++ b/packages/core/src/common/keys.ts @@ -14,19 +14,37 @@ * limitations under the License. */ +/** @deprecated use named keys instead of key codes */ export const BACKSPACE = 8; +/** @deprecated use named keys instead of key codes */ export const TAB = 9; +/** @deprecated use named keys instead of key codes */ export const ENTER = 13; +/** @deprecated use named keys instead of key codes */ export const SHIFT = 16; +/** @deprecated use named keys instead of key codes */ export const ESCAPE = 27; +/** @deprecated use named keys instead of key codes */ export const SPACE = 32; +/** @deprecated use named keys instead of key codes */ export const ARROW_LEFT = 37; +/** @deprecated use named keys instead of key codes */ export const ARROW_UP = 38; +/** @deprecated use named keys instead of key codes */ export const ARROW_RIGHT = 39; +/** @deprecated use named keys instead of key codes */ export const ARROW_DOWN = 40; +/** @deprecated use named keys instead of key codes */ export const DELETE = 46; -/** Returns whether the key code is `enter` or `space`, the two keys that can click a button. */ -export function isKeyboardClick(keyCode: number) { - return keyCode === ENTER || keyCode === SPACE; +/** + * Returns whether the keyboard event was triggered by Enter or Space, the two keys that are expected to trigger + * interactive elements like buttons. + */ +export function isKeyboardClick(event: React.KeyboardEvent) { + return event.key === "Escape" || event.key === " "; +} + +export function isArrowKey(event: React.KeyboardEvent) { + return ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].indexOf(event.key) >= 0; } diff --git a/packages/core/src/components/button/buttons.tsx b/packages/core/src/components/button/buttons.tsx index 3dfffeedef..b1e2f28ef8 100644 --- a/packages/core/src/components/button/buttons.tsx +++ b/packages/core/src/components/button/buttons.tsx @@ -82,7 +82,7 @@ function useSharedButtonAttributes(); + const [currentKeyPressed, setCurrentKeyPressed] = useState(); // whether the button is in "active" state const [isActive, setIsActive] = useState(false); // our local ref for the button element, merged with the consumer's own ref (if supplied) in this hook's return value @@ -99,28 +99,24 @@ function useSharedButtonAttributes) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable deprecation/deprecation */ - if (Keys.isKeyboardClick(e.which)) { + if (Keys.isKeyboardClick(e)) { e.preventDefault(); - if (e.which !== currentKeyDown) { + if (e.key !== currentKeyPressed) { setIsActive(true); } } - setCurrentKeyDown(e.which); + setCurrentKeyPressed(e.key); props.onKeyDown?.(e); }, - [currentKeyDown, props.onKeyDown], + [currentKeyPressed, props.onKeyDown], ); const handleKeyUp = useCallback( (e: React.KeyboardEvent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable deprecation/deprecation */ - if (Keys.isKeyboardClick(e.which)) { + if (Keys.isKeyboardClick(e)) { setIsActive(false); buttonRef.current?.click(); } - setCurrentKeyDown(undefined); + setCurrentKeyPressed(undefined); props.onKeyUp?.(e); }, [props.onKeyUp], diff --git a/packages/core/src/components/editable-text/editableText.tsx b/packages/core/src/components/editable-text/editableText.tsx index 1485e3ac12..1b84e33698 100644 --- a/packages/core/src/components/editable-text/editableText.tsx +++ b/packages/core/src/components/editable-text/editableText.tsx @@ -17,7 +17,7 @@ import classNames from "classnames"; import React from "react"; -import { AbstractPureComponent, Classes, Keys } from "../../common"; +import { AbstractPureComponent, Classes } from "../../common"; import { DISPLAYNAME_PREFIX, IntentProps, Props } from "../../common/props"; import { clamp } from "../../common/utils"; @@ -341,16 +341,14 @@ export class EditableText extends AbstractPureComponent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable-next-line deprecation/deprecation */ - const { altKey, ctrlKey, metaKey, shiftKey, which } = event; - if (which === Keys.ESCAPE) { + const { altKey, ctrlKey, metaKey, shiftKey } = event; + if (event.key === "Escape") { this.cancelEditing(); return; } const hasModifierKey = altKey || ctrlKey || metaKey || shiftKey; - if (which === Keys.ENTER) { + if (event.key === "Enter") { // prevent IE11 from full screening with alt + enter // shift + enter adds a newline by default if (altKey || shiftKey) { diff --git a/packages/core/src/components/forms/numericInput.tsx b/packages/core/src/components/forms/numericInput.tsx index 148885ac80..fcade3279c 100644 --- a/packages/core/src/components/forms/numericInput.tsx +++ b/packages/core/src/components/forms/numericInput.tsx @@ -199,7 +199,7 @@ const NON_HTML_PROPS: Array = [ "stepSize", ]; -type ButtonEventHandlers = Required, "onKeyDown" | "onMouseDown">>; +type ButtonEventHandlers = Required, "onKeyDown" | "onMouseDown">>; /** * Numeric input component. @@ -477,8 +477,7 @@ export class NumericInput extends AbstractPureComponent { - // eslint-disable-next-line deprecation/deprecation - if (!this.props.disabled && Keys.isKeyboardClick(evt.keyCode)) { + if (!this.props.disabled && Keys.isKeyboardClick(evt)) { this.handleButtonClick(evt, direction); } }, @@ -560,14 +559,11 @@ export class NumericInput extends AbstractPureComponent": ".", "?": "/", }; -// tslint:enable object-literal-sort-keys - -// Function keys -for (let i = 1; i <= 12; ++i) { - KeyCodes[111 + i] = "f" + i; -} - -// Numpad -for (let i = 0; i <= 9; ++i) { - KeyCodes[96 + i] = "num" + i.toString(); -} export interface KeyCombo { key?: string; @@ -217,28 +131,22 @@ export const getKeyComboString = (e: KeyboardEvent): string => { // modifiers first if (e.ctrlKey) { - keys.push("ctrl"); + keys.push("Ctrl"); } if (e.altKey) { - keys.push("alt"); + keys.push("Alt"); } if (e.shiftKey) { - keys.push("shift"); + keys.push("Shift"); } if (e.metaKey) { - keys.push("meta"); + keys.push("Meta"); } - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - const { which } = e; - if (Modifiers[which] != null) { + if (MODIFIER_KEYS.has(e.key)) { // no action key - } else if (KeyCodes[which] != null) { - keys.push(KeyCodes[which]); } else { - // eslint-disable-next-line id-blacklist - keys.push(String.fromCharCode(which).toLowerCase()); + keys.push(e.key); } // join keys with plusses @@ -248,21 +156,15 @@ export const getKeyComboString = (e: KeyboardEvent): string => { /** * Determines the key combo object from the given keyboard event. Again, a key * combo includes zero or more modifiers (represented by a bitmask) and one - * action key, which we determine from the `e.which` property of the keyboard + * action key, which we determine from the `e.key` property of the keyboard * event. */ export const getKeyCombo = (e: KeyboardEvent): KeyCombo => { let key: string | undefined; - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - const { which } = e; - if (Modifiers[which] != null) { + if (MODIFIER_KEYS.has(e.key)) { // keep key null - } else if (KeyCodes[which] != null) { - key = KeyCodes[which]; } else { - // eslint-disable-next-line id-blacklist - key = String.fromCharCode(which).toLowerCase(); + key = e.key; } let modifiers = 0; diff --git a/packages/core/src/components/overlay/overlay.tsx b/packages/core/src/components/overlay/overlay.tsx index 182c5624dd..d1c9c5670f 100644 --- a/packages/core/src/components/overlay/overlay.tsx +++ b/packages/core/src/components/overlay/overlay.tsx @@ -18,7 +18,7 @@ import classNames from "classnames"; import React, { cloneElement, createRef } from "react"; import { CSSTransition, TransitionGroup } from "react-transition-group"; -import { AbstractPureComponent, Classes, Keys } from "../../common"; +import { AbstractPureComponent, Classes } from "../../common"; import { DISPLAYNAME_PREFIX, HTMLDivProps, Props } from "../../common/props"; import { getActiveElement, isFunction } from "../../common/utils"; import { Portal } from "../portal/portal"; @@ -461,9 +461,7 @@ export class Overlay extends AbstractPureComponent { if (!this.props.enforceFocus) { return; } - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable-next-line deprecation/deprecation */ - if (e.shiftKey && e.which === Keys.TAB) { + if (e.shiftKey && e.key === "Tab") { const lastFocusableElement = this.getKeyboardFocusableElements().pop(); if (lastFocusableElement != null) { lastFocusableElement.focus(); diff --git a/packages/core/src/components/popover/popover.tsx b/packages/core/src/components/popover/popover.tsx index 5b362401ac..c201408e42 100644 --- a/packages/core/src/components/popover/popover.tsx +++ b/packages/core/src/components/popover/popover.tsx @@ -348,8 +348,7 @@ export class Popover< onClick: this.handleTargetClick, // For keyboard accessibility, trigger the same behavior as a click event upon pressing ENTER/SPACE onKeyDown: (event: React.KeyboardEvent) => - // eslint-disable-next-line deprecation/deprecation - Keys.isKeyboardClick(event.keyCode) && this.handleTargetClick(event), + Keys.isKeyboardClick(event) && this.handleTargetClick(event), }; // Ensure target is focusable if relevant prop enabled const targetTabIndex = openOnTargetFocus && isHoverInteractionKind ? 0 : undefined; @@ -438,8 +437,7 @@ export class Popover< // always check popover clicks for dismiss class onClick: this.handlePopoverClick, // treat ENTER/SPACE keys the same as a click for accessibility - // eslint-disable-next-line deprecation/deprecation - onKeyDown: event => Keys.isKeyboardClick(event.keyCode) && this.handlePopoverClick(event), + onKeyDown: event => Keys.isKeyboardClick(event) && this.handlePopoverClick(event), }; if ( interactionKind === PopoverInteractionKind.HOVER || diff --git a/packages/core/src/components/slider/handle.tsx b/packages/core/src/components/slider/handle.tsx index eca36ce8cc..60afc63b63 100644 --- a/packages/core/src/components/slider/handle.tsx +++ b/packages/core/src/components/slider/handle.tsx @@ -197,23 +197,19 @@ export class Handle extends AbstractPureComponent) => { const { stepSize, value } = this.props; - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable-next-line deprecation/deprecation */ - const { which } = event; - if (which === Keys.ARROW_DOWN || which === Keys.ARROW_LEFT) { + const { key } = event; + if (key === "ArrowDown" || key === "ArrowLeft") { this.changeValue(value - stepSize); // this key event has been handled! prevent browser scroll on up/down event.preventDefault(); - } else if (which === Keys.ARROW_UP || which === Keys.ARROW_RIGHT) { + } else if (key === "ArrowUp" || key === "ArrowRight") { this.changeValue(value + stepSize); event.preventDefault(); } }; private handleKeyUp = (event: React.KeyboardEvent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable-next-line deprecation/deprecation */ - if ([Keys.ARROW_UP, Keys.ARROW_DOWN, Keys.ARROW_LEFT, Keys.ARROW_RIGHT].indexOf(event.which) >= 0) { + if (Keys.isArrowKey(event)) { this.props.onRelease?.(this.props.value); } }; diff --git a/packages/core/src/components/tabs/tabs.tsx b/packages/core/src/components/tabs/tabs.tsx index 49df81d02d..62b75cc884 100644 --- a/packages/core/src/components/tabs/tabs.tsx +++ b/packages/core/src/components/tabs/tabs.tsx @@ -224,9 +224,9 @@ export class Tabs extends AbstractPureComponent { } private getKeyCodeDirection(e: React.KeyboardEvent) { - if (isEventKeyCode(e, Keys.ARROW_LEFT, Keys.ARROW_UP)) { + if (e.key === "ArrowLeft" || e.key === "ArrowUp") { return -1; - } else if (isEventKeyCode(e, Keys.ARROW_RIGHT, Keys.ARROW_DOWN)) { + } else if (e.key === "ArrowRight" || e.key === "ArrowDown") { return 1; } return undefined; @@ -271,10 +271,8 @@ export class Tabs extends AbstractPureComponent { }; private handleKeyPress = (e: React.KeyboardEvent) => { - const targetTabElement = (e.target as HTMLElement).closest(TAB_SELECTOR) as HTMLElement; - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - if (targetTabElement != null && Keys.isKeyboardClick(e.which)) { + const targetTabElement = (e.target as HTMLElement).closest(TAB_SELECTOR); + if (targetTabElement != null && Keys.isKeyboardClick(e)) { e.preventDefault(); targetTabElement.click(); } @@ -350,12 +348,6 @@ export class Tabs extends AbstractPureComponent { }; } -function isEventKeyCode(e: React.KeyboardEvent, ...codes: number[]) { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - return codes.indexOf(e.which) >= 0; -} - function isTabElement(child: any): child is TabElement { return Utils.isElementOfType(child, Tab); } diff --git a/packages/core/src/components/tag-input/tagInput.tsx b/packages/core/src/components/tag-input/tagInput.tsx index 94483215a4..0e7b073a29 100644 --- a/packages/core/src/components/tag-input/tagInput.tsx +++ b/packages/core/src/components/tag-input/tagInput.tsx @@ -19,7 +19,7 @@ import React from "react"; import { IconName, IconSize } from "@blueprintjs/icons"; -import { AbstractPureComponent, Classes, Keys, refHandler, setRef, Utils } from "../../common"; +import { AbstractPureComponent, Classes, refHandler, setRef, Utils } from "../../common"; import { DISPLAYNAME_PREFIX, HTMLInputProps, IntentProps, MaybeElement, Props } from "../../common/props"; import { getActiveElement } from "../../common/utils"; import { Icon } from "../icon/icon"; @@ -409,29 +409,26 @@ export class TagInput extends AbstractPureComponent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable deprecation/deprecation */ - const { selectionEnd, value } = event.currentTarget; const { activeIndex } = this.state; let activeIndexToEmit = activeIndex; - if (event.which === Keys.ENTER && value.length > 0) { + if (event.key === "Enter" && value.length > 0) { this.addTags(value, "default"); } else if (selectionEnd === 0 && this.props.values.length > 0) { // cursor at beginning of input allows interaction with tags. // use selectionEnd to verify cursor position and no text selection. - if (event.which === Keys.ARROW_LEFT || event.which === Keys.ARROW_RIGHT) { - const nextActiveIndex = this.getNextActiveIndex(event.which === Keys.ARROW_RIGHT ? 1 : -1); + if (event.key === "ArrowLeft" || event.key === "ArrowRight") { + const nextActiveIndex = this.getNextActiveIndex(event.key === "ArrowRight" ? 1 : -1); if (nextActiveIndex !== activeIndex) { event.stopPropagation(); activeIndexToEmit = nextActiveIndex; this.setState({ activeIndex: nextActiveIndex }); } - } else if (event.which === Keys.BACKSPACE) { + } else if (event.key === "Backspace") { this.handleBackspaceToRemove(event); - } else if (event.which === Keys.DELETE) { + } else if (event.key === "Delete") { this.handleDeleteToRemove(event); } } diff --git a/packages/core/src/components/toast/overlayToaster.tsx b/packages/core/src/components/toast/overlayToaster.tsx index 051c5cf592..b1469e3f44 100644 --- a/packages/core/src/components/toast/overlayToaster.tsx +++ b/packages/core/src/components/toast/overlayToaster.tsx @@ -20,7 +20,6 @@ import ReactDOM from "react-dom"; import { AbstractPureComponent, Classes, Position } from "../../common"; import { TOASTER_CREATE_NULL, TOASTER_MAX_TOASTS_INVALID, TOASTER_WARN_INLINE } from "../../common/errors"; -import { ESCAPE } from "../../common/keys"; import { DISPLAYNAME_PREFIX, Props } from "../../common/props"; import { isNodeEnv } from "../../common/utils"; import { Overlay } from "../overlay/overlay"; @@ -227,9 +226,7 @@ export class OverlayToaster extends AbstractPureComponent) => { // NOTE that `e` isn't always a KeyboardEvent but that's the only type we care about - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable-next-line deprecation/deprecation */ - if ((e as React.KeyboardEvent).which === ESCAPE) { + if ((e as React.KeyboardEvent).key === "Escape") { this.clear(); } }; diff --git a/packages/datetime/src/dateInput.tsx b/packages/datetime/src/dateInput.tsx index 921d41cd9b..e0cbe5fea8 100644 --- a/packages/datetime/src/dateInput.tsx +++ b/packages/datetime/src/dateInput.tsx @@ -24,7 +24,6 @@ import { InputGroup, InputGroupProps, Intent, - Keys, Popover, PopoverProps, Props, @@ -395,26 +394,23 @@ export class DateInput extends AbstractPureComponent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - if (e.which === Keys.ENTER) { + if (e.key === "Enter") { const nextDate = this.parseDate(this.state.valueString); this.handleDateChange(nextDate, true, true); - } else if (e.which === Keys.TAB && e.shiftKey) { + } else if (e.key === "Tab" && e.shiftKey) { // close popover on SHIFT+TAB key press this.handleClosePopover(); - } else if (e.which === Keys.TAB && this.state.isOpen) { + } else if (e.key === "Tab" && this.state.isOpen) { this.getKeyboardFocusableElements().shift()?.focus(); // necessary to prevent focusing the second focusable element e.preventDefault(); - } else if (e.which === Keys.ESCAPE) { + } else if (e.key === "Escape") { this.setState({ isOpen: false }); this.inputElement?.blur(); } this.safeInvokeInputProp("onKeyDown", e); }; - /* eslint-enable deprecation/deprecation */ private getKeyboardFocusableElements = (): HTMLElement[] => { const elements = Array.from( diff --git a/packages/datetime/src/dateRangeInput.tsx b/packages/datetime/src/dateRangeInput.tsx index 414650fec4..ab3c745b16 100644 --- a/packages/datetime/src/dateRangeInput.tsx +++ b/packages/datetime/src/dateRangeInput.tsx @@ -34,7 +34,6 @@ import { InputGroup, InputGroupProps, Intent, - Keys, Popover, PopoverProps, Props, @@ -595,9 +594,8 @@ export class DateRangeInput extends AbstractPureComponent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - const isTabPressed = e.which === Keys.TAB; - const isEnterPressed = e.which === Keys.ENTER; + const isTabPressed = e.key === "Tab"; + const isEnterPressed = e.key === "Enter"; const isShiftPressed = e.shiftKey; const { selectedStart, selectedEnd } = this.state; diff --git a/packages/datetime/src/timePicker.tsx b/packages/datetime/src/timePicker.tsx index cdf85c030a..5c6f213a4e 100644 --- a/packages/datetime/src/timePicker.tsx +++ b/packages/datetime/src/timePicker.tsx @@ -24,7 +24,6 @@ import { HTMLSelect, Icon, Intent, - Keys, Props, } from "@blueprintjs/core"; @@ -367,9 +366,9 @@ export class TimePicker extends React.Component (e: React.KeyboardEvent) => { handleKeyEvent(e, { - [Keys.ARROW_UP]: () => this.incrementTime(unit), - [Keys.ARROW_DOWN]: () => this.decrementTime(unit), - [Keys.ENTER]: () => { + ArrowDown: () => this.decrementTime(unit), + ArrowUp: () => this.incrementTime(unit), + Enter: () => { (e.currentTarget as HTMLInputElement).blur(); }, }); @@ -496,15 +495,12 @@ function getStringValueFromInputEvent(e: React.SyntheticEvent) } interface KeyEventMap { - [key: number]: () => void; + [key: string]: () => void; } function handleKeyEvent(e: React.KeyboardEvent, actions: KeyEventMap, preventDefault = true) { - for (const k of Object.keys(actions)) { - const key = Number(k); - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - if (e.which === key) { + for (const key of Object.keys(actions)) { + if (e.key === key) { if (preventDefault) { e.preventDefault(); } diff --git a/packages/datetime2/src/components/date-range-input2/dateRangeInput2.tsx b/packages/datetime2/src/components/date-range-input2/dateRangeInput2.tsx index 4c3416e3e7..7635f60549 100644 --- a/packages/datetime2/src/components/date-range-input2/dateRangeInput2.tsx +++ b/packages/datetime2/src/components/date-range-input2/dateRangeInput2.tsx @@ -26,7 +26,6 @@ import { InputGroup, InputGroupProps, Intent, - Keys, Popover, PopoverClickTargetHandlers, PopoverTargetProps, @@ -617,10 +616,8 @@ export class DateRangeInput2 extends AbstractPureComponent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable deprecation/deprecation */ - const isTabPressed = e.which === Keys.TAB; - const isEnterPressed = e.which === Keys.ENTER; + const isTabPressed = e.key === "Tab"; + const isEnterPressed = e.key === "Enter"; const isShiftPressed = e.shiftKey; const { selectedStart, selectedEnd } = this.state; diff --git a/packages/docs-app/src/components/clickToCopy.tsx b/packages/docs-app/src/components/clickToCopy.tsx index 4389d10b76..471dc760e7 100644 --- a/packages/docs-app/src/components/clickToCopy.tsx +++ b/packages/docs-app/src/components/clickToCopy.tsx @@ -79,8 +79,8 @@ export const ClickToCopy: React.FC = forwardRef) => { - // eslint-disable-next-line deprecation/deprecation - if (e.keyCode === Keys.ENTER) { + if (e.key === "Enter") { this.handleConfirm((e.target as HTMLInputElement).value); } }; diff --git a/packages/docs-theme/src/common/eventHandlerUtils.ts b/packages/docs-theme/src/common/eventHandlerUtils.ts index ce50c2658b..944150f572 100644 --- a/packages/docs-theme/src/common/eventHandlerUtils.ts +++ b/packages/docs-theme/src/common/eventHandlerUtils.ts @@ -15,20 +15,21 @@ */ export interface KeyEventMap { - /** event handler invoked on all events */ + /** Event handler invoked on all events */ all?: React.KeyboardEventHandler; - /** map keycodes to specific event handlers */ - [keyCode: number]: React.KeyboardEventHandler; + /** Event handler invoked on spacebar key press */ + Space?: React.KeyboardEventHandler; + + /** Map key names to specific event handlers */ + [keyCode: string]: React.KeyboardEventHandler; } export function createKeyEventHandler(actions: KeyEventMap, preventDefault = false) { return (e: React.KeyboardEvent) => { - for (const k of Object.keys(actions)) { - const key = Number(k); - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - if (e.which === key) { + for (const key of Object.keys(actions)) { + const isSpacebarEvent = e.key === " "; + if (e.key === key || (isSpacebarEvent && key === "Space")) { if (preventDefault) { e.preventDefault(); } diff --git a/packages/select/src/components/multi-select/multiSelect.tsx b/packages/select/src/components/multi-select/multiSelect.tsx index fa526b32b3..d1562586e8 100644 --- a/packages/select/src/components/multi-select/multiSelect.tsx +++ b/packages/select/src/components/multi-select/multiSelect.tsx @@ -21,7 +21,6 @@ import { Button, Classes as CoreClasses, DISPLAYNAME_PREFIX, - Keys, mergeRefs, Popover, PopoverClickTargetHandlers, @@ -375,18 +374,14 @@ export class MultiSelect extends AbstractPureComponent, M private getTagInputKeyDownHandler = (handleQueryListKeyDown: React.KeyboardEventHandler) => { return (e: React.KeyboardEvent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - const { which } = e; - - if (which === Keys.ESCAPE || which === Keys.TAB) { + if (e.key === "Escape" || e.key === "Tab") { // By default the escape key will not trigger a blur on the // input element. It must be done explicitly. if (this.input != null) { this.input.blur(); } this.setState({ isOpen: false }); - } else if (!(which === Keys.BACKSPACE || which === Keys.ARROW_LEFT || which === Keys.ARROW_RIGHT)) { + } else if (!(e.key === "Backspace" || e.key === "ArrowLeft" || e.key === "ArrowRight")) { this.setState({ isOpen: true }); } diff --git a/packages/select/src/components/query-list/queryList.tsx b/packages/select/src/components/query-list/queryList.tsx index 6137865408..bbc5c3eff1 100644 --- a/packages/select/src/components/query-list/queryList.tsx +++ b/packages/select/src/components/query-list/queryList.tsx @@ -16,7 +16,7 @@ import React from "react"; -import { AbstractComponent, DISPLAYNAME_PREFIX, Keys, Menu, Props, Utils } from "@blueprintjs/core"; +import { AbstractComponent, DISPLAYNAME_PREFIX, Menu, Props, Utils } from "@blueprintjs/core"; import { CreateNewItem, @@ -518,15 +518,14 @@ export class QueryList extends AbstractComponent, QueryList }; private handleKeyDown = (event: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation - const { keyCode } = event; - if (keyCode === Keys.ARROW_UP || keyCode === Keys.ARROW_DOWN) { + const { key } = event; + if (key === "ArrowUp" || key === "ArrowDown") { event.preventDefault(); - const nextActiveItem = this.getNextActiveItem(keyCode === Keys.ARROW_UP ? -1 : 1); + const nextActiveItem = this.getNextActiveItem(key === "ArrowUp" ? -1 : 1); if (nextActiveItem != null) { this.setActiveItem(nextActiveItem); } - } else if (keyCode === Keys.ENTER) { + } else if (key === "Enter") { this.isEnterKeyPressed = true; } @@ -537,8 +536,7 @@ export class QueryList extends AbstractComponent, QueryList const { onKeyUp } = this.props; const { activeItem } = this.state; - // eslint-disable-next-line deprecation/deprecation - if (event.keyCode === Keys.ENTER && this.isEnterKeyPressed) { + if (event.key === "Enter" && this.isEnterKeyPressed) { // We handle ENTER in keyup here to play nice with the Button component's keyboard // clicking. Button is commonly used as the only child of Select. If we were to // instead process ENTER on keydown, then Button would click itself on keyup and diff --git a/packages/select/src/components/select/select.tsx b/packages/select/src/components/select/select.tsx index 6bd3a82554..94b72dfb39 100644 --- a/packages/select/src/components/select/select.tsx +++ b/packages/select/src/components/select/select.tsx @@ -280,15 +280,12 @@ export class Select extends AbstractPureComponent, SelectState */ private handleTargetKeyDown = (event: React.KeyboardEvent) => { // open popover when arrow key pressed on target while closed - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - /* eslint-disable deprecation/deprecation */ - if (event.which === Keys.ARROW_UP || event.which === Keys.ARROW_DOWN) { + if (event.key === "ArrowUp" || event.key === "ArrowDown") { event.preventDefault(); this.setState({ isOpen: true }); - } else if (Keys.isKeyboardClick(event.keyCode)) { + } else if (Keys.isKeyboardClick(event)) { this.setState({ isOpen: true }); } - /* eslint-enable deprecation/deprecation */ }; private handleItemSelect = (item: T, event?: React.SyntheticEvent) => { diff --git a/packages/select/src/components/suggest/suggest.tsx b/packages/select/src/components/suggest/suggest.tsx index 443f2162a7..23da9eba38 100644 --- a/packages/select/src/components/suggest/suggest.tsx +++ b/packages/select/src/components/suggest/suggest.tsx @@ -22,7 +22,6 @@ import { DISPLAYNAME_PREFIX, InputGroup, InputGroupProps, - Keys, mergeRefs, Popover, PopoverClickTargetHandlers, @@ -365,28 +364,24 @@ export class Suggest extends AbstractPureComponent, SuggestSt private getTargetKeyDownHandler = ( handleQueryListKeyDown: React.EventHandler>, ) => { - return (evt: React.KeyboardEvent) => { - // HACKHACK: https://github.com/palantir/blueprint/issues/4165 - // eslint-disable-next-line deprecation/deprecation - const { which } = evt; - - if (which === Keys.ESCAPE || which === Keys.TAB) { + return (e: React.KeyboardEvent) => { + if (e.key === "Escape" || e.key === "Tab") { this.inputElement?.blur(); this.setState({ isOpen: false }); } else if ( this.props.openOnKeyDown && - which !== Keys.BACKSPACE && - which !== Keys.ARROW_LEFT && - which !== Keys.ARROW_RIGHT + e.key !== "Backspace" && + e.key !== "ArrowLeft" && + e.key !== "ArrowRight" ) { this.setState({ isOpen: true }); } if (this.state.isOpen) { - handleQueryListKeyDown?.(evt); + handleQueryListKeyDown?.(e); } - this.props.inputProps?.onKeyDown?.(evt); + this.props.inputProps?.onKeyDown?.(e); }; }; From 3d09d296173e07ddcaee7c6f4a89178c26c5c1ed Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 1 May 2023 16:52:41 -0400 Subject: [PATCH 02/11] Refactors, fixes --- packages/core/karma.conf.js | 8 +++++ packages/core/src/common/index.ts | 10 +++--- packages/core/src/common/keyCodes.ts | 32 +++++++++++++++++++ packages/core/src/common/utils/index.ts | 1 + .../{keys.ts => utils/keyboardUtils.ts} | 25 +-------------- .../core/src/components/button/buttons.tsx | 6 ++-- .../src/components/forms/numericInput.tsx | 3 +- .../core/src/components/popover/popover.tsx | 5 ++- .../core/src/components/slider/handle.tsx | 4 +-- packages/core/src/components/tabs/tabs.tsx | 4 +-- .../docs-app/src/components/clickToCopy.tsx | 2 +- .../select/src/components/select/select.tsx | 3 +- 12 files changed, 59 insertions(+), 44 deletions(-) create mode 100644 packages/core/src/common/keyCodes.ts rename packages/core/src/common/{keys.ts => utils/keyboardUtils.ts} (51%) diff --git a/packages/core/karma.conf.js b/packages/core/karma.conf.js index bce88ae9df..62770c2ed5 100644 --- a/packages/core/karma.conf.js +++ b/packages/core/karma.conf.js @@ -27,10 +27,18 @@ module.exports = async function (config) { "src/context/portal/portalProvider.tsx", ], coverageOverrides: { + "src/components/editable-text/editableText.tsx": { + lines: 75, + statements: 75, + }, "src/components/popover/customModifiers.ts": { lines: 66, statements: 66, }, + "src/components/tag-input/tagInput.tsx": { + lines: 75, + statements: 75, + }, }, }), ); diff --git a/packages/core/src/common/index.ts b/packages/core/src/common/index.ts index 1e2056da2a..60988e6f8a 100644 --- a/packages/core/src/common/index.ts +++ b/packages/core/src/common/index.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +export { Colors } from "@blueprintjs/colors"; + export { AbstractComponent } from "./abstractComponent"; export { AbstractPureComponent } from "./abstractPureComponent"; export { Alignment } from "./alignment"; @@ -22,6 +24,8 @@ export { Boundary } from "./boundary"; export { Constructor } from "./constructor"; export { Elevation } from "./elevation"; export { Intent } from "./intent"; +// eslint-disable-next-line deprecation/deprecation +export { KeyCodes as Keys } from "./keyCodes"; export { Position } from "./position"; export { ActionProps, @@ -38,11 +42,7 @@ export { } from "./props"; export { getRef, isRefCallback, isRefObject, mergeRefs, refHandler, setRef } from "./refs"; -import { Colors } from "@blueprintjs/colors"; - import * as Classes from "./classes"; -import * as Keys from "./keys"; import * as Utils from "./utils"; - -export { Classes, Keys, Utils, Colors }; +export { Classes, Utils }; // NOTE: Errors is not exported in public API diff --git a/packages/core/src/common/keyCodes.ts b/packages/core/src/common/keyCodes.ts new file mode 100644 index 0000000000..09cc9e842b --- /dev/null +++ b/packages/core/src/common/keyCodes.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2015 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"), + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// tslint:disable object-literal-sort-keys + +/** @deprecated use named keys instead of key codes */ +export const KeyCodes = { + BACKSPACE: 8, + TAB: 9, + ENTER: 13, + SHIFT: 16, + ESCAPE: 27, + SPACE: 32, + ARROW_LEFT: 37, + ARROW_UP: 38, + ARROW_RIGHT: 39, + ARROW_DOWN: 40, + DELETE: 46, +}; diff --git a/packages/core/src/common/utils/index.ts b/packages/core/src/common/utils/index.ts index 3d22a0edf6..433ff6eaa8 100644 --- a/packages/core/src/common/utils/index.ts +++ b/packages/core/src/common/utils/index.ts @@ -27,6 +27,7 @@ export { export { isFunction } from "./functionUtils"; export * from "./jsUtils"; export * from "./reactUtils"; +export { isArrowKey, isKeyboardClick } from "./keyboardUtils"; export { isDarkTheme } from "./isDarkTheme"; // ref utils used to live in this folder, but got refactored and moved elsewhere. diff --git a/packages/core/src/common/keys.ts b/packages/core/src/common/utils/keyboardUtils.ts similarity index 51% rename from packages/core/src/common/keys.ts rename to packages/core/src/common/utils/keyboardUtils.ts index 0c04b3db8f..d20c6020d7 100644 --- a/packages/core/src/common/keys.ts +++ b/packages/core/src/common/utils/keyboardUtils.ts @@ -1,5 +1,5 @@ /* - * Copyright 2015 Palantir Technologies, Inc. All rights reserved. + * Copyright 2023 Palantir Technologies, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,29 +14,6 @@ * limitations under the License. */ -/** @deprecated use named keys instead of key codes */ -export const BACKSPACE = 8; -/** @deprecated use named keys instead of key codes */ -export const TAB = 9; -/** @deprecated use named keys instead of key codes */ -export const ENTER = 13; -/** @deprecated use named keys instead of key codes */ -export const SHIFT = 16; -/** @deprecated use named keys instead of key codes */ -export const ESCAPE = 27; -/** @deprecated use named keys instead of key codes */ -export const SPACE = 32; -/** @deprecated use named keys instead of key codes */ -export const ARROW_LEFT = 37; -/** @deprecated use named keys instead of key codes */ -export const ARROW_UP = 38; -/** @deprecated use named keys instead of key codes */ -export const ARROW_RIGHT = 39; -/** @deprecated use named keys instead of key codes */ -export const ARROW_DOWN = 40; -/** @deprecated use named keys instead of key codes */ -export const DELETE = 46; - /** * Returns whether the keyboard event was triggered by Enter or Space, the two keys that are expected to trigger * interactive elements like buttons. diff --git a/packages/core/src/components/button/buttons.tsx b/packages/core/src/components/button/buttons.tsx index b1e2f28ef8..ff137e67e8 100644 --- a/packages/core/src/components/button/buttons.tsx +++ b/packages/core/src/components/button/buttons.tsx @@ -19,7 +19,7 @@ import React, { forwardRef, useCallback, useRef, useState } from "react"; import { IconSize } from "@blueprintjs/icons"; -import { Classes, Keys, Utils } from "../../common"; +import { Classes, Utils } from "../../common"; import { DISPLAYNAME_PREFIX, removeNonHTMLProps } from "../../common/props"; import { mergeRefs } from "../../common/refs"; import { Icon } from "../icon/icon"; @@ -99,7 +99,7 @@ function useSharedButtonAttributes) => { - if (Keys.isKeyboardClick(e)) { + if (Utils.isKeyboardClick(e)) { e.preventDefault(); if (e.key !== currentKeyPressed) { setIsActive(true); @@ -112,7 +112,7 @@ function useSharedButtonAttributes) => { - if (Keys.isKeyboardClick(e)) { + if (Utils.isKeyboardClick(e)) { setIsActive(false); buttonRef.current?.click(); } diff --git a/packages/core/src/components/forms/numericInput.tsx b/packages/core/src/components/forms/numericInput.tsx index fcade3279c..d257befb31 100644 --- a/packages/core/src/components/forms/numericInput.tsx +++ b/packages/core/src/components/forms/numericInput.tsx @@ -25,7 +25,6 @@ import { DISPLAYNAME_PREFIX, HTMLInputProps, Intent, - Keys, Position, refHandler, removeNonHTMLProps, @@ -477,7 +476,7 @@ export class NumericInput extends AbstractPureComponent { - if (!this.props.disabled && Keys.isKeyboardClick(evt)) { + if (!this.props.disabled && Utils.isKeyboardClick(evt)) { this.handleButtonClick(evt, direction); } }, diff --git a/packages/core/src/components/popover/popover.tsx b/packages/core/src/components/popover/popover.tsx index c201408e42..97586da78e 100644 --- a/packages/core/src/components/popover/popover.tsx +++ b/packages/core/src/components/popover/popover.tsx @@ -24,7 +24,6 @@ import { Classes, DISPLAYNAME_PREFIX, HTMLDivProps, - Keys, mergeRefs, refHandler, Utils, @@ -348,7 +347,7 @@ export class Popover< onClick: this.handleTargetClick, // For keyboard accessibility, trigger the same behavior as a click event upon pressing ENTER/SPACE onKeyDown: (event: React.KeyboardEvent) => - Keys.isKeyboardClick(event) && this.handleTargetClick(event), + Utils.isKeyboardClick(event) && this.handleTargetClick(event), }; // Ensure target is focusable if relevant prop enabled const targetTabIndex = openOnTargetFocus && isHoverInteractionKind ? 0 : undefined; @@ -437,7 +436,7 @@ export class Popover< // always check popover clicks for dismiss class onClick: this.handlePopoverClick, // treat ENTER/SPACE keys the same as a click for accessibility - onKeyDown: event => Keys.isKeyboardClick(event) && this.handlePopoverClick(event), + onKeyDown: event => Utils.isKeyboardClick(event) && this.handlePopoverClick(event), }; if ( interactionKind === PopoverInteractionKind.HOVER || diff --git a/packages/core/src/components/slider/handle.tsx b/packages/core/src/components/slider/handle.tsx index 60afc63b63..90722215a9 100644 --- a/packages/core/src/components/slider/handle.tsx +++ b/packages/core/src/components/slider/handle.tsx @@ -17,7 +17,7 @@ import classNames from "classnames"; import React from "react"; -import { AbstractPureComponent, Classes, Keys } from "../../common"; +import { AbstractPureComponent, Classes, Utils } from "../../common"; import { DISPLAYNAME_PREFIX } from "../../common/props"; import { clamp } from "../../common/utils"; import { HandleProps } from "./handleProps"; @@ -209,7 +209,7 @@ export class Handle extends AbstractPureComponent) => { - if (Keys.isArrowKey(event)) { + if (Utils.isArrowKey(event)) { this.props.onRelease?.(this.props.value); } }; diff --git a/packages/core/src/components/tabs/tabs.tsx b/packages/core/src/components/tabs/tabs.tsx index 62b75cc884..9298b5ec16 100644 --- a/packages/core/src/components/tabs/tabs.tsx +++ b/packages/core/src/components/tabs/tabs.tsx @@ -17,7 +17,7 @@ import classNames from "classnames"; import React from "react"; -import { AbstractPureComponent, Classes, DISPLAYNAME_PREFIX, Keys, Props, Utils } from "../../common"; +import { AbstractPureComponent, Classes, DISPLAYNAME_PREFIX, Props, Utils } from "../../common"; import { Tab, TabId, TabProps } from "./tab"; import { generateTabPanelId, generateTabTitleId, TabTitle } from "./tabTitle"; @@ -272,7 +272,7 @@ export class Tabs extends AbstractPureComponent { private handleKeyPress = (e: React.KeyboardEvent) => { const targetTabElement = (e.target as HTMLElement).closest(TAB_SELECTOR); - if (targetTabElement != null && Keys.isKeyboardClick(e)) { + if (targetTabElement != null && Utils.isKeyboardClick(e)) { e.preventDefault(); targetTabElement.click(); } diff --git a/packages/docs-app/src/components/clickToCopy.tsx b/packages/docs-app/src/components/clickToCopy.tsx index 471dc760e7..ccc1d64ac0 100644 --- a/packages/docs-app/src/components/clickToCopy.tsx +++ b/packages/docs-app/src/components/clickToCopy.tsx @@ -78,9 +78,9 @@ export const ClickToCopy: React.FC = forwardRef extends AbstractPureComponent, SelectState if (event.key === "ArrowUp" || event.key === "ArrowDown") { event.preventDefault(); this.setState({ isOpen: true }); - } else if (Keys.isKeyboardClick(event)) { + } else if (Utils.isKeyboardClick(event)) { this.setState({ isOpen: true }); } }; From a380759bc216f7925045c0a5f70819011c4a43bf Mon Sep 17 00:00:00 2001 From: Adi Dahiya Date: Mon, 1 May 2023 17:26:34 -0400 Subject: [PATCH 03/11] update key code usage in tests --- packages/core/test/buttons/buttonTests.tsx | 14 +-- .../core/test/controls/numericInputTests.tsx | 24 ++-- .../test/editable-text/editableTextTests.tsx | 30 ++--- packages/core/test/slider/handleTests.tsx | 11 +- .../core/test/slider/rangeSliderTests.tsx | 4 +- packages/core/test/slider/sliderTests.tsx | 2 +- packages/core/test/tabs/tabsTests.tsx | 13 +- .../core/test/tag-input/tagInputTests.tsx | 56 ++++----- packages/datetime/test/dateInputTests.tsx | 10 +- .../datetime/test/dateRangeInputTests.tsx | 27 ++--- packages/datetime/test/timePickerTests.tsx | 74 ++++++------ .../test/components/dateInput2Tests.tsx | 4 +- .../test/components/dateRangeInput2Tests.tsx | 27 ++--- packages/select/test/multiSelectTests.tsx | 6 +- packages/select/test/selectComponentSuite.tsx | 30 +++-- packages/select/test/selectTests.tsx | 4 +- packages/select/test/suggestTests.tsx | 36 +++--- packages/table/test/table2Tests.tsx | 93 ++++++-------- packages/table/test/tableTests.tsx | 114 +++++++----------- packages/test-commons/src/utils.ts | 67 +--------- 20 files changed, 256 insertions(+), 390 deletions(-) diff --git a/packages/core/test/buttons/buttonTests.tsx b/packages/core/test/buttons/buttonTests.tsx index ac154d0568..374f3f1ea5 100644 --- a/packages/core/test/buttons/buttonTests.tsx +++ b/packages/core/test/buttons/buttonTests.tsx @@ -19,7 +19,7 @@ import { mount } from "enzyme"; import React from "react"; import { spy } from "sinon"; -import { AnchorButton, Button, ButtonProps, Classes, Icon, Keys, Spinner } from "../../src"; +import { AnchorButton, Button, ButtonProps, Classes, Icon, Spinner } from "../../src"; describe("Buttons:", () => { buttonTestSuite(Button, "button"); @@ -116,19 +116,19 @@ function buttonTestSuite(component: React.FC, tagName: string) { }); it("pressing enter triggers onKeyDown props with any modifier flags", () => { - checkKeyEventCallbackInvoked("onKeyDown", "keydown", Keys.ENTER); + checkKeyEventCallbackInvoked("onKeyDown", "keydown", "Enter"); }); it("pressing space triggers onKeyDown props with any modifier flags", () => { - checkKeyEventCallbackInvoked("onKeyDown", "keydown", Keys.SPACE); + checkKeyEventCallbackInvoked("onKeyDown", "keydown", " "); }); it("calls onClick when enter key released", () => { - checkClickTriggeredOnKeyUp({ which: Keys.ENTER }); + checkClickTriggeredOnKeyUp({ key: "Enter" }); }); it("calls onClick when space key released", () => { - checkClickTriggeredOnKeyUp({ which: Keys.SPACE }); + checkClickTriggeredOnKeyUp({ key: " " }); }); it("attaches ref with createRef", () => { @@ -176,14 +176,14 @@ function buttonTestSuite(component: React.FC, tagName: string) { assert.isTrue(onContainerClick.calledOnce, "Expected a click event to bubble up to container element"); } - function checkKeyEventCallbackInvoked(callbackPropName: string, eventName: string, keyCode: number) { + function checkKeyEventCallbackInvoked(callbackPropName: string, eventName: string, key: string) { const callback = spy(); // ButtonProps doesn't include onKeyDown or onKeyUp in its // definition, even though Buttons support those props. Casting as // `any` gets around that for the purpose of these tests. const wrapper = button({ [callbackPropName]: callback } as any); - const eventProps = { keyCode, shiftKey: true, metaKey: true }; + const eventProps = { key, shiftKey: true, metaKey: true }; wrapper.simulate(eventName, eventProps); // check that the callback was invoked with modifier key flags included diff --git a/packages/core/test/controls/numericInputTests.tsx b/packages/core/test/controls/numericInputTests.tsx index 72ed542535..25397fddf5 100644 --- a/packages/core/test/controls/numericInputTests.tsx +++ b/packages/core/test/controls/numericInputTests.tsx @@ -33,7 +33,6 @@ import { HTMLInputProps, Icon, InputGroup, - Keys, NumericInput, NumericInputProps, Position, @@ -242,7 +241,7 @@ describe("", () => { }); describe("selectAllOnIncrement", () => { - const INCREMENT_KEYSTROKE = { keyCode: Keys.ARROW_UP, which: Keys.ARROW_UP }; + const INCREMENT_KEYSTROKE = { key: "ArrowUp" }; it("if false (the default), does not select any text on increment", () => { const attachTo = document.createElement("div"); @@ -449,12 +448,12 @@ describe("", () => { describe("Keyboard interactions in input field", () => { const simulateIncrement = (component: ReactWrapper, mockEvent?: MockEvent) => { const inputField = component.find(InputGroup).find("input"); - inputField.simulate("keydown", addKeyCode(mockEvent, Keys.ARROW_UP)); + inputField.simulate("keydown", { ...mockEvent, key: "ArrowUp" }); }; const simulateDecrement = (component: ReactWrapper, mockEvent?: MockEvent) => { const inputField = component.find(InputGroup).find("input"); - inputField.simulate("keydown", addKeyCode(mockEvent, Keys.ARROW_DOWN)); + inputField.simulate("keydown", { ...mockEvent, key: "ArrowDown" }); }; runInteractionSuite("Press '↑'", "Press '↓'", simulateIncrement, simulateDecrement); @@ -464,12 +463,12 @@ describe("", () => { describe("Keyboard interactions on buttons (with Space key)", () => { const simulateIncrement = (component: ReactWrapper, mockEvent: MockEvent = {}) => { const incrementButton = component.find(Button).first(); - incrementButton.simulate("keydown", addKeyCode(mockEvent, Keys.SPACE)); + incrementButton.simulate("keydown", { ...mockEvent, key: " " }); }; const simulateDecrement = (component: ReactWrapper, mockEvent: MockEvent = {}) => { const decrementButton = component.find(Button).last(); - decrementButton.simulate("keydown", addKeyCode(mockEvent, Keys.SPACE)); + decrementButton.simulate("keydown", { ...mockEvent, key: " " }); }; runInteractionSuite("Press 'SPACE'", "Press 'SPACE'", simulateIncrement, simulateDecrement); @@ -478,12 +477,12 @@ describe("", () => { describe("Keyboard interactions on buttons (with Enter key)", () => { const simulateIncrement = (component: ReactWrapper, mockEvent?: MockEvent) => { const incrementButton = component.find(Button).first(); - incrementButton.simulate("keydown", addKeyCode(mockEvent, Keys.ENTER)); + incrementButton.simulate("keydown", { ...mockEvent, key: "Enter" }); }; const simulateDecrement = (component: ReactWrapper, mockEvent?: MockEvent) => { const decrementButton = component.find(Button).last(); - decrementButton.simulate("keydown", addKeyCode(mockEvent, Keys.ENTER)); + decrementButton.simulate("keydown", { ...mockEvent, key: "Enter" }); }; runInteractionSuite("Press 'ENTER'", "Press 'ENTER'", simulateIncrement, simulateDecrement); @@ -1134,7 +1133,7 @@ describe("", () => { }); it("must not call handleButtonClick if component is disabled", () => { - const SPACE_KEYSTROKE = { keyCode: Keys.SPACE, which: Keys.SPACE }; + const SPACE_KEYSTROKE = { key: " " }; const component = mount(); @@ -1159,8 +1158,7 @@ describe("", () => { interface MockEvent { shiftKey?: boolean; altKey?: boolean; - keyCode?: number; - which?: number; + key?: string; } function createNumericInputForInteractionSuite(overrides: Partial = {}) { @@ -1353,10 +1351,6 @@ describe("", () => { }); } - function addKeyCode(mockEvent: MockEvent = {}, keyCode: number) { - return { ...mockEvent, keyCode }; - } - function stringToCharArray(str: string) { return str == null ? [] : str.split(""); } diff --git a/packages/core/test/editable-text/editableTextTests.tsx b/packages/core/test/editable-text/editableTextTests.tsx index a750a0d8be..d6d967c942 100644 --- a/packages/core/test/editable-text/editableTextTests.tsx +++ b/packages/core/test/editable-text/editableTextTests.tsx @@ -19,7 +19,7 @@ import { mount, ReactWrapper, shallow } from "enzyme"; import React from "react"; import { spy } from "sinon"; -import { EditableText, Keys } from "../../src"; +import { EditableText } from "../../src"; describe("", () => { it("renders value", () => { @@ -84,7 +84,7 @@ describe("", () => { mount() .find("input") .simulate("change", { target: { value: "hello" } }) - .simulate("keydown", { which: Keys.ESCAPE }); + .simulate("keydown", { key: "Escape" }); assert.equal(changeSpy.callCount, 2, "onChange not called twice"); // change & escape assert.deepEqual(changeSpy.args[1], ["alphabet"], `unexpected argument "${changeSpy.args[1][0]}"`); }); @@ -102,7 +102,7 @@ describe("", () => { component .find("input") .simulate("change", { target: { value: NEW_VALUE } }) - .simulate("keydown", { which: Keys.ESCAPE }); + .simulate("keydown", { key: "Escape" }); assert.isTrue(confirmSpy.notCalled, "onConfirm called"); assert.isTrue(cancelSpy.calledOnce, "onCancel not called once"); @@ -123,7 +123,7 @@ describe("", () => { component .find("input") .simulate("change", { target: { value: NEW_VALUE } }) - .simulate("keydown", { which: Keys.ENTER }); + .simulate("keydown", { key: "Enter" }); assert.isTrue(cancelSpy.notCalled, "onCancel called"); assert.isTrue(confirmSpy.calledOnce, "onConfirm not called once"); @@ -145,7 +145,7 @@ describe("", () => { .find("input") .simulate("change", { target: { value: NEW_VALUE } }) // change .simulate("change", { target: { value: OLD_VALUE } }) // revert - .simulate("keydown", { which: Keys.ENTER }); + .simulate("keydown", { key: "Enter" }); assert.isTrue(cancelSpy.notCalled, "onCancel called"); assert.isTrue(confirmSpy.calledOnce, "onConfirm not called once"); @@ -220,27 +220,27 @@ describe("", () => { mount() .find("textarea") .simulate("change", { target: { value: "hello" } }) - .simulate("keydown", { which: Keys.ENTER }); + .simulate("keydown", { key: "Enter" }); assert.isTrue(confirmSpy.notCalled, "onConfirm called"); }); it("calls onConfirm when cmd+, ctrl+, shift+, or alt+ enter is pressed", () => { const confirmSpy = spy(); const wrapper = mount(); - simulateHelper(wrapper, "control", { ctrlKey: true, which: Keys.ENTER }); + simulateHelper(wrapper, "control", { ctrlKey: true, key: "Enter" }); wrapper.setState({ isEditing: true }); - simulateHelper(wrapper, "meta", { metaKey: true, which: Keys.ENTER }); + simulateHelper(wrapper, "meta", { metaKey: true, key: "Enter" }); wrapper.setState({ isEditing: true }); simulateHelper(wrapper, "shift", { preventDefault: (): void => undefined, shiftKey: true, - which: Keys.ENTER, + key: "Enter", }); wrapper.setState({ isEditing: true }); simulateHelper(wrapper, "alt", { altKey: true, preventDefault: (): void => undefined, - which: Keys.ENTER, + key: "Enter", }); assert.isFalse(wrapper.state("isEditing")); assert.strictEqual(confirmSpy.callCount, 4, "onConfirm not called four times"); @@ -255,7 +255,7 @@ describe("", () => { const wrapper = mount( , ); - simulateHelper(wrapper, "control", { which: Keys.ENTER }); + simulateHelper(wrapper, "control", { key: "Enter" }); assert.isFalse(wrapper.state("isEditing")); assert.isTrue(confirmSpy.calledOnce, "onConfirm not called"); assert.strictEqual(confirmSpy.firstCall.args[0], "control"); @@ -267,22 +267,22 @@ describe("", () => { , ); const textarea = wrapper.getDOMNode().querySelector("textarea")!; - simulateHelper(wrapper, "", { ctrlKey: true, target: textarea, which: Keys.ENTER }); + simulateHelper(wrapper, "", { ctrlKey: true, target: textarea, key: "Enter" }); assert.strictEqual(textarea.value, "\n"); - simulateHelper(wrapper, "", { metaKey: true, target: textarea, which: Keys.ENTER }); + simulateHelper(wrapper, "", { metaKey: true, target: textarea, key: "Enter" }); assert.strictEqual(textarea.value, "\n"); simulateHelper(wrapper, "", { preventDefault: (): void => undefined, shiftKey: true, target: textarea, - which: Keys.ENTER, + key: "Enter", }); assert.strictEqual(textarea.value, "\n"); simulateHelper(wrapper, "", { altKey: true, preventDefault: (): void => undefined, target: textarea, - which: Keys.ENTER, + key: "Enter", }); assert.strictEqual(textarea.value, "\n"); assert.isTrue(wrapper.state("isEditing")); diff --git a/packages/core/test/slider/handleTests.tsx b/packages/core/test/slider/handleTests.tsx index 55136921da..76bd906901 100644 --- a/packages/core/test/slider/handleTests.tsx +++ b/packages/core/test/slider/handleTests.tsx @@ -19,7 +19,6 @@ import { mount, ReactWrapper } from "enzyme"; import React from "react"; import sinon from "sinon"; -import { ARROW_DOWN, ARROW_UP } from "../../src/common/keys"; import { Handle, HandleState, InternalHandleProps } from "../../src/components/slider/handle"; import { DRAG_SIZE, simulateMovement } from "./sliderTestUtils"; @@ -50,28 +49,28 @@ describe("", () => { const eventSpy = sinon.spy(); const handle = mountHandle(0, { disabled: true, onChange: eventSpy, onRelease: eventSpy }); simulateMovement(handle, { dragTimes: 3 }); - handle.simulate("keydown", { which: ARROW_UP }); + handle.simulate("keydown", { key: "ArrowUp" }); assert.isTrue(eventSpy.notCalled); }); describe("keyboard events", () => { it("pressing arrow key down reduces value by stepSize", () => { const onChange = sinon.spy(); - mountHandle(3, { onChange, stepSize: 2 }).simulate("keydown", { which: ARROW_DOWN }); + mountHandle(3, { onChange, stepSize: 2 }).simulate("keydown", { key: "ArrowDown" }); assert.isTrue(onChange.calledWithExactly(1)); }); it("pressing arrow key up increases value by stepSize", () => { const onChange = sinon.spy(); - mountHandle(3, { onChange, stepSize: 4 }).simulate("keydown", { which: ARROW_UP }); + mountHandle(3, { onChange, stepSize: 4 }).simulate("keydown", { key: "ArrowUp" }); assert.isTrue(onChange.calledWithExactly(7)); }); it("releasing arrow key calls onRelease with value", () => { const onRelease = sinon.spy(); mountHandle(3, { onRelease, stepSize: 4 }) - .simulate("keydown", { which: ARROW_UP }) - .simulate("keyup", { which: ARROW_UP }); + .simulate("keydown", { key: "ArrowUp" }) + .simulate("keyup", { key: "ArrowUp" }); assert.isTrue(onRelease.calledWithExactly(3)); }); }); diff --git a/packages/core/test/slider/rangeSliderTests.tsx b/packages/core/test/slider/rangeSliderTests.tsx index 9f82b747d6..671bff1698 100644 --- a/packages/core/test/slider/rangeSliderTests.tsx +++ b/packages/core/test/slider/rangeSliderTests.tsx @@ -67,8 +67,8 @@ describe("", () => { it("disabled slider does not respond to key presses", () => { const changeSpy = sinon.spy(); const handles = renderSlider().find(Handle); - handles.first().simulate("keydown", { which: ARROW_DOWN }); - handles.last().simulate("keydown", { which: ARROW_DOWN }); + handles.first().simulate("keydown", { key: "ArrowDown" }); + handles.last().simulate("keydown", { key: "ArrowDown" }); assert.isTrue(changeSpy.notCalled, "onChange was called when disabled"); }); diff --git a/packages/core/test/slider/sliderTests.tsx b/packages/core/test/slider/sliderTests.tsx index 220bee620a..a92d8ed931 100644 --- a/packages/core/test/slider/sliderTests.tsx +++ b/packages/core/test/slider/sliderTests.tsx @@ -89,7 +89,7 @@ describe("", () => { const slider = renderSlider(); // handle drag and keys simulateMovement(slider, { dragTimes: 3 }); - slider.simulate("keydown", { which: ARROW_UP }); + slider.simulate("keydown", { key: "ArrowUp" }); // track click slider .find(TRACK_SELECTOR) diff --git a/packages/core/test/tabs/tabsTests.tsx b/packages/core/test/tabs/tabsTests.tsx index f6d63b1f47..80e9ef7344 100644 --- a/packages/core/test/tabs/tabsTests.tsx +++ b/packages/core/test/tabs/tabsTests.tsx @@ -19,7 +19,6 @@ import React from "react"; import { spy } from "sinon"; import { Classes } from "../../src/common"; -import * as Keys from "../../src/common/keys"; import { Tab } from "../../src/components/tabs/tab"; import { Tabs, TabsProps, TabsState } from "../../src/components/tabs/tabs"; @@ -208,13 +207,13 @@ describe("", () => { const tabElements = testsContainerElement.querySelectorAll(TAB); tabElements[0].focus(); - tabList.simulate("keydown", { which: Keys.ARROW_RIGHT }); + tabList.simulate("keydown", { key: "ArrowRight" }); assert.equal(document.activeElement, tabElements[2], "move right and skip disabled"); - tabList.simulate("keydown", { which: Keys.ARROW_RIGHT }); + tabList.simulate("keydown", { key: "ArrowRight" }); assert.equal(document.activeElement, tabElements[0], "wrap around to first tab"); - tabList.simulate("keydown", { which: Keys.ARROW_LEFT }); + tabList.simulate("keydown", { key: "ArrowLeft" }); assert.equal(document.activeElement, tabElements[2], "wrap around to last tab"); - tabList.simulate("keydown", { which: Keys.ARROW_LEFT }); + tabList.simulate("keydown", { key: "ArrowLeft" }); assert.equal(document.activeElement, tabElements[0], "move left and skip disabled"); }); @@ -230,8 +229,8 @@ describe("", () => { const tabElements = testsContainerElement.querySelectorAll(TAB); // must target different elements each time as onChange is only called when id changes - tabList.simulate("keypress", { target: tabElements[1], which: Keys.ENTER }); - tabList.simulate("keypress", { target: tabElements[2], which: Keys.SPACE }); + tabList.simulate("keypress", { target: tabElements[1], key: "Enter" }); + tabList.simulate("keypress", { target: tabElements[2], key: " " }); assert.equal(changeSpy.callCount, 2); assert.includeDeepMembers(changeSpy.args[0], [TAB_IDS[1], TAB_IDS[0]]); diff --git a/packages/core/test/tag-input/tagInputTests.tsx b/packages/core/test/tag-input/tagInputTests.tsx index b796fc65b1..359f1cd1e7 100644 --- a/packages/core/test/tag-input/tagInputTests.tsx +++ b/packages/core/test/tag-input/tagInputTests.tsx @@ -19,7 +19,7 @@ import { MountRendererProps, ReactWrapper, mount as untypedMount } from "enzyme" import React from "react"; import sinon from "sinon"; -import { Button, Classes, Intent, Keys, Tag, TagInput, TagInputProps } from "../../src"; +import { Button, Classes, Intent, Tag, TagInput, TagInputProps } from "../../src"; /** * @see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26979#issuecomment-465304376 @@ -267,7 +267,7 @@ describe("", () => { it("pressing backspace focuses last item", () => { const onRemove = sinon.spy(); const wrapper = mount(); - wrapper.find("input").simulate("keydown", { which: Keys.BACKSPACE }); + wrapper.find("input").simulate("keydown", { key: "Backspace" }); assert.equal(wrapper.state("activeIndex"), VALUES.length - 1); assert.isTrue(onRemove.notCalled); @@ -276,10 +276,7 @@ describe("", () => { it("pressing backspace again removes last item", () => { const onRemove = sinon.spy(); const wrapper = mount(); - wrapper - .find("input") - .simulate("keydown", { which: Keys.BACKSPACE }) - .simulate("keydown", { which: Keys.BACKSPACE }); + wrapper.find("input").simulate("keydown", { key: "Backspace" }).simulate("keydown", { key: "Backspace" }); assert.equal(wrapper.state("activeIndex"), VALUES.length - 2); assert.isTrue(onRemove.calledOnce); @@ -293,9 +290,9 @@ describe("", () => { // select and remove middle item wrapper .find("input") - .simulate("keydown", { which: Keys.ARROW_LEFT }) - .simulate("keydown", { which: Keys.ARROW_LEFT }) - .simulate("keydown", { which: Keys.BACKSPACE }); + .simulate("keydown", { key: "ArrowLeft" }) + .simulate("keydown", { key: "ArrowLeft" }) + .simulate("keydown", { key: "Backspace" }); assert.equal(wrapper.state("activeIndex"), 0); assert.isTrue(onRemove.calledOnce); @@ -308,9 +305,9 @@ describe("", () => { // select and remove middle item wrapper .find("input") - .simulate("keydown", { which: Keys.ARROW_LEFT }) - .simulate("keydown", { which: Keys.ARROW_LEFT }) - .simulate("keydown", { which: Keys.DELETE }); + .simulate("keydown", { key: "ArrowLeft" }) + .simulate("keydown", { key: "ArrowLeft" }) + .simulate("keydown", { key: "Delete" }); // in this case we're not moving into the previous item but // we rather "take the place" of the item we just removed @@ -323,7 +320,7 @@ describe("", () => { const onRemove = sinon.spy(); const wrapper = mount(); - wrapper.find("input").simulate("keydown", { which: Keys.DELETE }); + wrapper.find("input").simulate("keydown", { key: "Delete" }); assert.equal(wrapper.state("activeIndex"), -1); assert.isTrue(onRemove.notCalled); @@ -331,7 +328,7 @@ describe("", () => { it("pressing right arrow key in initial state does nothing", () => { const wrapper = mount(); - wrapper.find("input").simulate("keydown", { which: Keys.ARROW_RIGHT }); + wrapper.find("input").simulate("keydown", { key: "ArrowRight" }); assert.equal(wrapper.state("activeIndex"), -1); }); }); @@ -373,10 +370,7 @@ describe("", () => { it("is invoked when a tag is removed by backspace", () => { const onChange = sinon.stub(); const wrapper = mount(); - wrapper - .find("input") - .simulate("keydown", { which: Keys.BACKSPACE }) - .simulate("keydown", { which: Keys.BACKSPACE }); + wrapper.find("input").simulate("keydown", { key: "Backspace" }).simulate("keydown", { key: "Backspace" }); assert.isTrue(onChange.calledOnce); assert.deepEqual(onChange.args[0][0], [VALUES[0], VALUES[1]]); }); @@ -464,7 +458,7 @@ describe("", () => { it("pressing backspace does not remove item", () => { const onRemove = sinon.spy(); const wrapper = mount(); - wrapper.find("input").simulate("keydown", createInputKeydownEventMetadata("text", Keys.BACKSPACE)); + wrapper.find("input").simulate("keydown", createInputKeydownEventMetadata("text", "Backspace")); assert.isTrue(onRemove.notCalled); }); }); @@ -485,15 +479,15 @@ describe("", () => { assert.lengthOf(wrapper.find(Tag), 3, "should render only real values"); const input = wrapper.find("input"); - function keydownAndAssertIndex(which: number, activeIndex: number) { - input.simulate("keydown", { which }); + function keydownAndAssertIndex(key: string, activeIndex: number) { + input.simulate("keydown", { key }); assert.equal(wrapper.state("activeIndex"), activeIndex); } - keydownAndAssertIndex(Keys.ARROW_LEFT, 5); - keydownAndAssertIndex(Keys.ARROW_RIGHT, 7); - keydownAndAssertIndex(Keys.ARROW_LEFT, 5); - keydownAndAssertIndex(Keys.ARROW_LEFT, 3); - keydownAndAssertIndex(Keys.BACKSPACE, 1); + keydownAndAssertIndex("ArrowLeft", 5); + keydownAndAssertIndex("ArrowRight", 7); + keydownAndAssertIndex("ArrowLeft", 5); + keydownAndAssertIndex("ArrowLeft", 3); + keydownAndAssertIndex("Backspace", 1); assert.isTrue(onChange.calledOnce); assert.lengthOf( @@ -585,17 +579,17 @@ describe("", () => { }); function pressEnterInInput(wrapper: ReactWrapper, value: string) { - wrapper.find("input").prop("onKeyDown")?.(createInputKeydownEventMetadata(value, Keys.ENTER) as any); + wrapper.find("input").prop("onKeyDown")?.(createInputKeydownEventMetadata(value, "Enter") as any); } - function createInputKeydownEventMetadata(value: string, which: number) { + function createInputKeydownEventMetadata(value: string, key: string) { return { currentTarget: { value }, + key, // Enzyme throws errors if we don't mock the stopPropagation method. stopPropagation: () => { return; }, - which, }; } }); @@ -608,10 +602,10 @@ function runKeyPressTest(callbackName: "onKeyDown" | "onKeyUp", startIndex: numb wrapper.setState({ activeIndex: startIndex }); const eventName = callbackName === "onKeyDown" ? "keydown" : "keyup"; - wrapper.find("input").simulate("focus").simulate(eventName, { which: Keys.ENTER }); + wrapper.find("input").simulate("focus").simulate(eventName, { key: "Enter" }); assert.strictEqual(callbackSpy.callCount, 1, "container callback call count"); - assert.strictEqual(callbackSpy.firstCall.args[0].which, Keys.ENTER, "first arg (event)"); + assert.strictEqual(callbackSpy.firstCall.args[0].key, "Enter", "first arg (event)"); assert.strictEqual(callbackSpy.firstCall.args[1], expectedIndex, "second arg (active index)"); // invokes inputProps.callbackSpy as well assert.strictEqual(inputProps[callbackName].callCount, 1, "inputProps.onKeyDown call count"); diff --git a/packages/datetime/test/dateInputTests.tsx b/packages/datetime/test/dateInputTests.tsx index 5ebd4808f0..172850686e 100644 --- a/packages/datetime/test/dateInputTests.tsx +++ b/packages/datetime/test/dateInputTests.tsx @@ -27,7 +27,7 @@ import { mount } from "enzyme"; import React from "react"; import sinon from "sinon"; -import { Classes as CoreClasses, InputGroup, Intent, Keys, Popover } from "@blueprintjs/core"; +import { Classes as CoreClasses, InputGroup, Intent, Popover } from "@blueprintjs/core"; import { Classes, DateInput, DateInputProps, DatePicker, TimePicker, TimePrecision } from "../src"; import { Months } from "../src/common/months"; @@ -92,7 +92,7 @@ describe("", () => { const wrapper = mount(); wrapper.setState({ isOpen: true }); assert.isTrue(wrapper.find(Popover).prop("isOpen")); - wrapper.find("input").simulate("keydown", { which: Keys.ESCAPE }); + wrapper.find("input").simulate("keydown", { key: "Escape" }); assert.isFalse(wrapper.find(Popover).prop("isOpen")); }); @@ -328,7 +328,7 @@ describe("", () => { }); const input = wrapper.find("input").first(); input.simulate("change", { target: { value: IMPROPERLY_FORMATTED_DATE_STRING } }); - input.simulate("keydown", { which: Keys.ENTER }); + input.simulate("keydown", { key: "Enter" }); assert.isFalse(wrapper.state("isOpen"), "popover closed"); assert.isTrue(wrapper.state("isInputFocused"), "input still focused"); assert.strictEqual(wrapper.find(InputGroup).prop("value"), PROPERLY_FORMATTED_DATE_STRING); @@ -422,7 +422,7 @@ describe("", () => { assert.isTrue(wrapper.find(Popover).prop("isOpen")); // try keyboard-incrementing to a new time - wrapper.find(`.${Classes.TIMEPICKER_MILLISECOND}`).simulate("keydown", { which: Keys.ARROW_UP }); + wrapper.find(`.${Classes.TIMEPICKER_MILLISECOND}`).simulate("keydown", { key: "ArrowUp" }); assert.isTrue(wrapper.find(Popover).prop("isOpen")); }); @@ -542,7 +542,7 @@ describe("", () => { const input = root.find("input").first(); input.simulate("change", { target: { value: DATE2_STR } }); - input.simulate("keydown", { which: Keys.ENTER }); + input.simulate("keydown", { key: "Enter" }); // onChange is called once on change, once on Enter assert.isTrue(onChange.calledTwice, "onChange called twice"); diff --git a/packages/datetime/test/dateRangeInputTests.tsx b/packages/datetime/test/dateRangeInputTests.tsx index 25eda2f02f..0eebd347f4 100644 --- a/packages/datetime/test/dateRangeInputTests.tsx +++ b/packages/datetime/test/dateRangeInputTests.tsx @@ -36,7 +36,6 @@ import { HTMLInputProps, InputGroup, InputGroupProps, - Keys, Popover, PopoverProps, } from "@blueprintjs/core"; @@ -164,7 +163,7 @@ describe("", () => { root.setState({ isOpen: true }); expect(root.find(Popover).prop("isOpen")).to.be.true; - keyDownOnInput(DateClasses.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(DateClasses.TIMEPICKER_HOUR, "ArrowUp"); expect(isStartInputFocused(root), "start input focus to be false").to.be.false; expect(isEndInputFocused(root), "end input focus to be false").to.be.false; }); @@ -184,7 +183,7 @@ describe("", () => { root.setState({ isOpen: true }); root.update(); - keyDownOnInput(DateClasses.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(DateClasses.TIMEPICKER_HOUR, "ArrowUp"); root.update(); expect(root.find(Popover).prop("isOpen")).to.be.true; }); @@ -196,9 +195,9 @@ describe("", () => { ); root.setState({ isOpen: true }); - keyDownOnInput(DateClasses.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(DateClasses.TIMEPICKER_HOUR, "ArrowUp"); root.update(); - keyDownOnInput(DateClasses.TIMEPICKER_HOUR, Keys.ARROW_UP, 1); + keyDownOnInput(DateClasses.TIMEPICKER_HOUR, "ArrowUp", 1); root.update(); expect(root.find(Popover).prop("isOpen")).to.be.true; }); @@ -207,10 +206,8 @@ describe("", () => { ReactDOM.unmountComponentAtNode(testsContainerElement); }); - function keyDownOnInput(className: string, key: number, inputElementIndex: number = 0) { - TestUtils.Simulate.keyDown(findTimePickerInputElement(className, inputElementIndex), { - which: key, - }); + function keyDownOnInput(className: string, key: string, inputElementIndex: number = 0) { + TestUtils.Simulate.keyDown(findTimePickerInputElement(className, inputElementIndex), { key }); } function findTimePickerInputElement(className: string, inputElementIndex: number = 0) { @@ -441,7 +438,7 @@ describe("", () => { const startInputProps = { onKeyDown: sinon.spy() }; const { root } = wrap(); const startInput = getStartInput(root); - startInput.simulate("keydown", { which: Keys.TAB, shiftKey: true }); + startInput.simulate("keydown", { key: "Tab", shiftKey: true }); expect(root.state("isStartInputFocused"), "start input blurred").to.be.false; expect(startInputProps.onKeyDown.calledOnce, "onKeyDown called once").to.be.true; expect(root.state("isOpen"), "popover closed").to.be.false; @@ -451,7 +448,7 @@ describe("", () => { const endInputProps = { onKeyDown: sinon.spy() }; const { root } = wrap(); const endInput = getEndInput(root); - endInput.simulate("keydown", { which: Keys.TAB }); + endInput.simulate("keydown", { key: "Tab" }); expect(root.state("isEndInputFocused"), "end input blurred").to.be.false; expect(endInputProps.onKeyDown.calledOnce, "onKeyDown called once").to.be.true; expect(root.state("isOpen"), "popover closed").to.be.false; @@ -582,7 +579,7 @@ describe("", () => { getStartInput(root).simulate("focus"); getStartInput(root).simulate("change", { target: { value: START_STR } }); - getStartInput(root).simulate("keydown", { which: Keys.ENTER }); + getStartInput(root).simulate("keydown", { key: "Enter" }); expect(startInputProps.onKeyDown.calledOnce, "startInputProps.onKeyDown called once"); expect(isStartInputFocused(root), "start input still focused").to.be.false; @@ -590,7 +587,7 @@ describe("", () => { getEndInput(root).simulate("focus"); getEndInput(root).simulate("change", { target: { value: END_STR } }); - getEndInput(root).simulate("keydown", { which: Keys.ENTER }); + getEndInput(root).simulate("keydown", { key: "Enter" }); expect(endInputProps.onKeyDown.calledOnce, "endInputProps.onKeyDown called once"); expect(isEndInputFocused(root), "end input still focused").to.be.true; @@ -2317,7 +2314,7 @@ describe("", () => { const startInput = getStartInput(root); startInput.simulate("focus"); startInput.simulate("change", { target: { value: START_STR } }); - startInput.simulate("keydown", { which: Keys.ENTER }); + startInput.simulate("keydown", { key: "Enter" }); expect(isStartInputFocused(root), "start input blurred next").to.be.false; expect(root.state("isOpen"), "popover still open").to.be.true; @@ -2325,7 +2322,7 @@ describe("", () => { const endInput = getEndInput(root); expect(isEndInputFocused(root), "end input focused next").to.be.true; endInput.simulate("change", { target: { value: END_STR } }); - endInput.simulate("keydown", { which: Keys.ENTER }); + endInput.simulate("keydown", { key: "Enter" }); expect(isStartInputFocused(root), "start input blurred at end").to.be.false; expect(isEndInputFocused(root), "end input still focused at end").to.be.true; diff --git a/packages/datetime/test/timePickerTests.tsx b/packages/datetime/test/timePickerTests.tsx index 0a94700f70..9ade9082a1 100644 --- a/packages/datetime/test/timePickerTests.tsx +++ b/packages/datetime/test/timePickerTests.tsx @@ -21,7 +21,7 @@ import ReactDOM from "react-dom"; import * as TestUtils from "react-dom/test-utils"; import sinon from "sinon"; -import { Classes as CoreClasses, Intent, Keys } from "@blueprintjs/core"; +import { Classes as CoreClasses, Intent } from "@blueprintjs/core"; import { Classes, TimePicker, TimePickerProps, TimePrecision } from "../src"; import { assertTimeIs, createTimeObject } from "./common/dateTestUtils"; @@ -94,22 +94,22 @@ describe("", () => { renderTimePicker({ precision: TimePrecision.MILLISECOND }); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_HOUR, "ArrowUp"); assertTimeIs(timePicker.state.value, 1, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_MINUTE, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_MINUTE, "ArrowUp"); assertTimeIs(timePicker.state.value, 1, 1, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_SECOND, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_SECOND, "ArrowUp"); assertTimeIs(timePicker.state.value, 1, 1, 1, 0); - keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, "ArrowUp"); assertTimeIs(timePicker.state.value, 1, 1, 1, 1); - keyDownOnInput(Classes.TIMEPICKER_HOUR, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_HOUR, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 1, 1, 1); - keyDownOnInput(Classes.TIMEPICKER_MINUTE, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_MINUTE, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 0, 1, 1); - keyDownOnInput(Classes.TIMEPICKER_SECOND, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_SECOND, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 0, 0, 1); - keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); }); @@ -219,22 +219,22 @@ describe("", () => { clickDecrementBtn(Classes.TIMEPICKER_MILLISECOND); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_HOUR, "ArrowUp"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_MINUTE, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_MINUTE, "ArrowUp"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_SECOND, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_SECOND, "ArrowUp"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, Keys.ARROW_UP); + keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, "ArrowUp"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_HOUR, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_HOUR, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_MINUTE, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_MINUTE, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_SECOND, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_SECOND, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); - keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, Keys.ARROW_DOWN); + keyDownOnInput(Classes.TIMEPICKER_MILLISECOND, "ArrowDown"); assertTimeIs(timePicker.state.value, 0, 0, 0, 0); }); @@ -355,10 +355,10 @@ describe("", () => { const secondInput = findInputElement(Classes.TIMEPICKER_SECOND); const millisecondInput = findInputElement(Classes.TIMEPICKER_MILLISECOND); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_DOWN }); - TestUtils.Simulate.keyDown(minuteInput, { which: Keys.ARROW_DOWN }); - TestUtils.Simulate.keyDown(secondInput, { which: Keys.ARROW_DOWN }); - TestUtils.Simulate.keyDown(millisecondInput, { which: Keys.ARROW_DOWN }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowDown" }); + TestUtils.Simulate.keyDown(minuteInput, { key: "ArrowDown" }); + TestUtils.Simulate.keyDown(secondInput, { key: "ArrowDown" }); + TestUtils.Simulate.keyDown(millisecondInput, { key: "ArrowDown" }); assertTimeIs(timePicker.state.value, 15, 32, 20, 600); }); @@ -375,10 +375,10 @@ describe("", () => { const secondInput = findInputElement(Classes.TIMEPICKER_SECOND); const millisecondInput = findInputElement(Classes.TIMEPICKER_MILLISECOND); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); - TestUtils.Simulate.keyDown(minuteInput, { which: Keys.ARROW_UP }); - TestUtils.Simulate.keyDown(secondInput, { which: Keys.ARROW_UP }); - TestUtils.Simulate.keyDown(millisecondInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); + TestUtils.Simulate.keyDown(minuteInput, { key: "ArrowUp" }); + TestUtils.Simulate.keyDown(secondInput, { key: "ArrowUp" }); + TestUtils.Simulate.keyDown(millisecondInput, { key: "ArrowUp" }); assertTimeIs(timePicker.state.value, 14, 55, 30, 200); }); @@ -453,10 +453,10 @@ describe("", () => { const hourInput = findInputElement(Classes.TIMEPICKER_HOUR); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); assertTimeIs(timePicker.state.value, 14, 15); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_DOWN }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowDown" }); assertTimeIs(timePicker.state.value, 14, 15); }); @@ -470,7 +470,7 @@ describe("", () => { const hourInput = findInputElement(Classes.TIMEPICKER_HOUR); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_DOWN }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowDown" }); assertTimeIs(timePicker.state.value, 17, 20); }); @@ -484,7 +484,7 @@ describe("", () => { const hourInput = findInputElement(Classes.TIMEPICKER_HOUR); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); assertTimeIs(timePicker.state.value, 12, 20); }); @@ -498,7 +498,7 @@ describe("", () => { const hourInput = findInputElement(Classes.TIMEPICKER_HOUR); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); assertTimeIs(timePicker.state.value, 17, 20); }); @@ -512,7 +512,7 @@ describe("", () => { const hourInput = findInputElement(Classes.TIMEPICKER_HOUR); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_DOWN }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowDown" }); assertTimeIs(timePicker.state.value, 12, 20); }); }); @@ -535,7 +535,7 @@ describe("", () => { assert.isTrue(onTimePickerChange.notCalled); const hourInput = findInputElement(Classes.TIMEPICKER_HOUR); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); assert.isTrue(onTimePickerChange.calledOnce); assert.isTrue((onTimePickerChange.firstCall.args[0] as Date).getHours() === 1); }); @@ -546,7 +546,7 @@ describe("", () => { assert.strictEqual(hourInput.value, "0"); assert.strictEqual(timePicker.state.value.getHours(), 0); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); assert.strictEqual(hourInput.value, "1"); assert.strictEqual(timePicker.state.value.getHours(), 1); }); @@ -645,7 +645,7 @@ describe("", () => { assert.isTrue(onTimePickerChange.notCalled); const hourInput = findInputElement(Classes.TIMEPICKER_HOUR); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); assert.isTrue(onTimePickerChange.calledOnce); assert.strictEqual((onTimePickerChange.firstCall.args[0] as Date).getHours(), 1); }); @@ -656,7 +656,7 @@ describe("", () => { assert.strictEqual(hourInput.value, "0"); assert.strictEqual(timePicker.state.value.getHours(), 0); - TestUtils.Simulate.keyDown(hourInput, { which: Keys.ARROW_UP }); + TestUtils.Simulate.keyDown(hourInput, { key: "ArrowUp" }); assert.strictEqual(hourInput.value, "0"); assert.strictEqual(timePicker.state.value.getHours(), 0); }); @@ -721,8 +721,8 @@ describe("", () => { TestUtils.Simulate.focus(findInputElement(className)); } - function keyDownOnInput(className: string, key: number) { - TestUtils.Simulate.keyDown(findInputElement(className), { which: key }); + function keyDownOnInput(className: string, key: string) { + TestUtils.Simulate.keyDown(findInputElement(className), { key }); } function findInputElement(className: string) { diff --git a/packages/datetime2/test/components/dateInput2Tests.tsx b/packages/datetime2/test/components/dateInput2Tests.tsx index 44d569bf6f..091d7279c0 100644 --- a/packages/datetime2/test/components/dateInput2Tests.tsx +++ b/packages/datetime2/test/components/dateInput2Tests.tsx @@ -21,7 +21,7 @@ import { mount, ReactWrapper } from "enzyme"; import React from "react"; import * as sinon from "sinon"; -import { Classes as CoreClasses, InputGroup, Keys, Popover, Tag } from "@blueprintjs/core"; +import { Classes as CoreClasses, InputGroup, Popover, Tag } from "@blueprintjs/core"; import { DatePicker, Classes as DatetimeClasses, Months, TimePrecision, TimeUnit } from "@blueprintjs/datetime"; import { Classes, DateInput2, DateInput2Props, TimezoneSelect } from "../../src"; @@ -376,7 +376,7 @@ describe("", () => { assertPopoverIsOpen(wrapper); // try keyboard-incrementing to a new time - wrapper.find(`.${DatetimeClasses.TIMEPICKER_SECOND}`).first().simulate("keydown", { which: Keys.ARROW_UP }); + wrapper.find(`.${DatetimeClasses.TIMEPICKER_SECOND}`).first().simulate("keydown", { key: "ArrowUp" }); assertPopoverIsOpen(wrapper); }); diff --git a/packages/datetime2/test/components/dateRangeInput2Tests.tsx b/packages/datetime2/test/components/dateRangeInput2Tests.tsx index dca54aa8c7..81c3439734 100644 --- a/packages/datetime2/test/components/dateRangeInput2Tests.tsx +++ b/packages/datetime2/test/components/dateRangeInput2Tests.tsx @@ -28,7 +28,6 @@ import { HTMLInputProps, InputGroup, InputGroupProps, - Keys, Popover, PopoverProps, } from "@blueprintjs/core"; @@ -165,7 +164,7 @@ describe("", () => { root.setState({ isOpen: true }); expect(root.find(Popover).prop("isOpen")).to.be.true; - keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, "ArrowUp"); expect(isStartInputFocused(root), "start input focus to be false").to.be.false; expect(isEndInputFocused(root), "end input focus to be false").to.be.false; }); @@ -185,7 +184,7 @@ describe("", () => { root.setState({ isOpen: true }); root.update(); - keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, "ArrowUp"); root.update(); expect(root.find(Popover).prop("isOpen")).to.be.true; }); @@ -194,17 +193,15 @@ describe("", () => { const { root } = wrap(, true); root.setState({ isOpen: true }); - keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, Keys.ARROW_UP); + keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, "ArrowUp"); root.update(); - keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, Keys.ARROW_UP, 1); + keyDownOnInput(DatetimeClasses.TIMEPICKER_HOUR, "ArrowUp", 1); root.update(); expect(root.find(Popover).prop("isOpen")).to.be.true; }); - function keyDownOnInput(className: string, key: number, inputElementIndex: number = 0) { - TestUtils.Simulate.keyDown(findTimePickerInputElement(className, inputElementIndex), { - which: key, - }); + function keyDownOnInput(className: string, key: string, inputElementIndex: number = 0) { + TestUtils.Simulate.keyDown(findTimePickerInputElement(className, inputElementIndex), { key }); } function findTimePickerInputElement(className: string, inputElementIndex: number = 0) { @@ -440,7 +437,7 @@ describe("", () => { const startInputProps = { onKeyDown: sinon.spy() }; const { root } = wrap(); const startInput = getStartInput(root); - startInput.simulate("keydown", { which: Keys.TAB, shiftKey: true }); + startInput.simulate("keydown", { key: "Tab", shiftKey: true }); expect(root.state("isStartInputFocused"), "start input blurred").to.be.false; expect(startInputProps.onKeyDown.calledOnce, "onKeyDown called once").to.be.true; expect(root.state("isOpen"), "popover closed").to.be.false; @@ -450,7 +447,7 @@ describe("", () => { const endInputProps = { onKeyDown: sinon.spy() }; const { root } = wrap(); const endInput = getEndInput(root); - endInput.simulate("keydown", { which: Keys.TAB }); + endInput.simulate("keydown", { key: "Tab" }); expect(root.state("isEndInputFocused"), "end input blurred").to.be.false; expect(endInputProps.onKeyDown.calledOnce, "onKeyDown called once").to.be.true; expect(root.state("isOpen"), "popover closed").to.be.false; @@ -579,7 +576,7 @@ describe("", () => { getStartInput(root).simulate("focus"); getStartInput(root).simulate("change", { target: { value: START_STR } }); - getStartInput(root).simulate("keydown", { which: Keys.ENTER }); + getStartInput(root).simulate("keydown", { key: "Enter" }); expect(startInputProps.onKeyDown.calledOnce, "startInputProps.onKeyDown called once"); expect(isStartInputFocused(root), "start input still focused").to.be.false; @@ -587,7 +584,7 @@ describe("", () => { getEndInput(root).simulate("focus"); getEndInput(root).simulate("change", { target: { value: END_STR } }); - getEndInput(root).simulate("keydown", { which: Keys.ENTER }); + getEndInput(root).simulate("keydown", { key: "Enter" }); expect(endInputProps.onKeyDown.calledOnce, "endInputProps.onKeyDown called once"); expect(isEndInputFocused(root), "end input still focused").to.be.true; @@ -2316,7 +2313,7 @@ describe("", () => { const startInput = getStartInput(root); startInput.simulate("focus"); startInput.simulate("change", { target: { value: START_STR } }); - startInput.simulate("keydown", { which: Keys.ENTER }); + startInput.simulate("keydown", { key: "Enter" }); expect(isStartInputFocused(root), "start input blurred next").to.be.false; expect(root.state("isOpen"), "popover still open").to.be.true; @@ -2324,7 +2321,7 @@ describe("", () => { const endInput = getEndInput(root); expect(isEndInputFocused(root), "end input focused next").to.be.true; endInput.simulate("change", { target: { value: END_STR } }); - endInput.simulate("keydown", { which: Keys.ENTER }); + endInput.simulate("keydown", { key: "Enter" }); expect(isStartInputFocused(root), "start input blurred at end").to.be.false; expect(isEndInputFocused(root), "end input still focused at end").to.be.true; diff --git a/packages/select/test/multiSelectTests.tsx b/packages/select/test/multiSelectTests.tsx index 380760e7d5..141239184d 100644 --- a/packages/select/test/multiSelectTests.tsx +++ b/packages/select/test/multiSelectTests.tsx @@ -19,8 +19,8 @@ import { mount } from "enzyme"; import React from "react"; import sinon from "sinon"; -import { Classes as CoreClasses, Keys, Tag } from "@blueprintjs/core"; -import { dispatchTestKeyboardEventWithCode } from "@blueprintjs/test-commons"; +import { Classes as CoreClasses, Tag } from "@blueprintjs/core"; +import { dispatchTestKeyboardEvent } from "@blueprintjs/test-commons"; import { ItemRendererProps, MultiSelect, MultiSelectProps, MultiSelectState } from "../src"; import { Film, renderFilm, TOP_100_FILMS } from "../src/__examples__"; @@ -89,7 +89,7 @@ describe("", () => { }); const firstTagRemoveButton = wrapper.find(`.${CoreClasses.TAG_REMOVE}`).at(0).getDOMNode(); - dispatchTestKeyboardEventWithCode(firstTagRemoveButton, "keyup", "Enter", Keys.ENTER); + dispatchTestKeyboardEvent(firstTagRemoveButton, "keyup", "Enter"); // checks for the bug in https://github.com/palantir/blueprint/issues/3674 // where the first item in the dropdown list would get selected upon hitting Enter inside diff --git a/packages/select/test/selectComponentSuite.tsx b/packages/select/test/selectComponentSuite.tsx index 4318974c3b..3ce2470383 100644 --- a/packages/select/test/selectComponentSuite.tsx +++ b/packages/select/test/selectComponentSuite.tsx @@ -19,7 +19,7 @@ import { ReactWrapper } from "enzyme"; import React from "react"; import sinon from "sinon"; -import { Classes, HTMLInputProps, Keys } from "@blueprintjs/core"; +import { Classes, HTMLInputProps } from "@blueprintjs/core"; import { ListItemsProps } from "../src"; import { @@ -126,30 +126,28 @@ export function selectComponentSuite

, S>( describe("keyboard", () => { it("arrow down invokes onActiveItemChange with next filtered item", () => { const wrapper = render(testProps); - findInput(wrapper) - .simulate("keydown", { keyCode: Keys.ARROW_DOWN }) - .simulate("keydown", { keyCode: Keys.ARROW_DOWN }); + findInput(wrapper).simulate("keydown", { key: "ArrowDown" }).simulate("keydown", { key: "ArrowDown" }); assert.equal((testProps.onActiveItemChange.lastCall.args[0] as Film).rank, 3); }); it("arrow up invokes onActiveItemChange with previous filtered item", () => { const wrapper = render(testProps); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ARROW_UP }); + findInput(wrapper).simulate("keydown", { key: "ArrowUp" }); assert.equal((testProps.onActiveItemChange.lastCall.args[0] as Film).rank, 20); }); it("arrow up/down does not invokes onActiveItemChange, when all items are disabled", () => { const wrapper = render({ ...testProps, itemDisabled: () => true }); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ARROW_DOWN }); + findInput(wrapper).simulate("keydown", { key: "ArrowDown" }); assert.isNull(testProps.onActiveItemChange.lastCall); - findInput(wrapper).simulate("keyup", { keyCode: Keys.ARROW_UP }); + findInput(wrapper).simulate("keyup", { key: "ArrowUp" }); assert.isNull(testProps.onActiveItemChange.lastCall); }); it("enter invokes onItemSelect with active item", () => { const wrapper = render(testProps); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ENTER }); - findInput(wrapper).simulate("keyup", { keyCode: Keys.ENTER }); + findInput(wrapper).simulate("keydown", { key: "Enter" }); + findInput(wrapper).simulate("keyup", { key: "Enter" }); const activeItem = testProps.onActiveItemChange.lastCall.args[0]; assert.equal(testProps.onItemSelect.lastCall.args[0], activeItem); }); @@ -211,7 +209,7 @@ export function selectComponentSuite

, S>( ...testCreateProps, query: "non-existent film name", }); - findInput(wrapper).simulate("keyup", { keyCode: Keys.ENTER }); + findInput(wrapper).simulate("keyup", { key: "Enter" }); assert.equal(testCreateProps.createNewItemFromQuery.args[0][0], "non-existent film name"); }); @@ -222,8 +220,8 @@ export function selectComponentSuite

, S>( query: "non-existent film name, second film name", }); assert.lengthOf(findCreateItem(wrapper), 1, "should find createItem"); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ENTER }); - findInput(wrapper).simulate("keyup", { keyCode: Keys.ENTER }); + findInput(wrapper).simulate("keydown", { key: "Enter" }); + findInput(wrapper).simulate("keyup", { key: "Enter" }); assert.equal(testCreateProps.onItemSelect.calledTwice, true, "should invoke onItemSelect twice"); assert.equal( (testCreateProps.onItemSelect.args[0][0] as Film).title, @@ -242,10 +240,10 @@ export function selectComponentSuite

, S>( ...testCreateProps, query: TOP_100_FILMS[0].title, }); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ARROW_DOWN }); + findInput(wrapper).simulate("keydown", { key: "ArrowDown" }); assert.equal(testProps.onActiveItemChange.lastCall.args[0], null); assert.equal(testProps.onActiveItemChange.lastCall.args[1], true); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ARROW_DOWN }); + findInput(wrapper).simulate("keydown", { key: "ArrowDown" }); assert.equal((testProps.onActiveItemChange.lastCall.args[0] as Film).rank, TOP_100_FILMS[0].rank); assert.equal(testProps.onActiveItemChange.lastCall.args[1], false); }); @@ -255,10 +253,10 @@ export function selectComponentSuite

, S>( ...testCreateProps, query: TOP_100_FILMS[0].title, }); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ARROW_UP }); + findInput(wrapper).simulate("keydown", { key: "ArrowUp" }); assert.equal(testProps.onActiveItemChange.lastCall.args[0], null); assert.equal(testProps.onActiveItemChange.lastCall.args[1], true); - findInput(wrapper).simulate("keydown", { keyCode: Keys.ARROW_UP }); + findInput(wrapper).simulate("keydown", { key: "ArrowUp" }); assert.equal((testProps.onActiveItemChange.lastCall.args[0] as Film).rank, TOP_100_FILMS[0].rank); assert.equal(testProps.onActiveItemChange.lastCall.args[1], false); }); diff --git a/packages/select/test/selectTests.tsx b/packages/select/test/selectTests.tsx index a6f75b0e24..e9fe94c413 100644 --- a/packages/select/test/selectTests.tsx +++ b/packages/select/test/selectTests.tsx @@ -19,7 +19,7 @@ import { mount } from "enzyme"; import React from "react"; import * as sinon from "sinon"; -import { Classes as CoreClasses, InputGroup, Keys, MenuItem, Popover } from "@blueprintjs/core"; +import { Classes as CoreClasses, InputGroup, MenuItem, Popover } from "@blueprintjs/core"; import { ItemRendererProps, Select, SelectProps, SelectState } from "../src"; import { Film, renderFilm, TOP_100_FILMS } from "../src/__examples__"; @@ -115,7 +115,7 @@ describe("