Simplify key codes expression in Tags component (#4248)

* Simplifying this key codes expression in Tags component

* Refactor KeyboardEvent keyCode to key

* Simplify cyrillic letter regexp

* Wrap condition in 2 lines
This commit is contained in:
Leonid Trofymchuk 2019-10-09 23:50:48 +03:00 committed by Ben Halpern
parent ae22dc93a9
commit 5e347a6f94
2 changed files with 78 additions and 21 deletions

View file

@ -0,0 +1,52 @@
import { h } from 'preact';
import { deep } from 'preact-render-spy';
import Tags from '../tags';
describe('<Tags />', () => {
beforeAll(() => {
const publicId = document.createElement('meta');
publicId.setAttribute('name', 'algolia-public-id');
const publicKey = document.createElement('meta');
publicKey.setAttribute('name', 'algolia-public-key');
const environment = document.createElement('meta');
environment.setAttribute('name', 'environment');
document.body.appendChild(publicId);
document.body.appendChild(publicKey);
document.body.appendChild(environment);
global.algoliasearch = () => ({
initIndex: () => 'initIndex',
});
});
let tags;
beforeEach(() => {
tags = deep(<Tags defaultValue="defaultValue" listing />);
});
describe('handleKeyDown', () => {
const preventDefaultMock = jest.fn();
const createKeyDown = key => ({
key,
preventDefault: preventDefaultMock,
});
beforeEach(() => {
preventDefaultMock.mockClear();
});
test('calls preventDefault on unused keyCode', () => {
tags.find('#tag-input').simulate('keydown', createKeyDown('§'));
tags.find('#tag-input').simulate('keydown', createKeyDown('1'));
tags.find('#tag-input').simulate('keydown', createKeyDown('\\'));
expect(preventDefaultMock).toHaveBeenCalledTimes(3);
});
test('does not call preventDefault on used keyCode', () => {
tags.find('#tag-input').simulate('keypress', createKeyDown('a'));
tags.find('#tag-input').simulate('keypress', createKeyDown(','));
tags.find('#tag-input').simulate('keypress', createKeyDown('Enter'));
expect(preventDefaultMock).not.toHaveBeenCalled();
});
});
});

View file

@ -2,16 +2,26 @@ import { h, Component } from 'preact';
import PropTypes from 'prop-types';
const KEYS = {
UP: 38,
DOWN: 40,
LEFT: 37,
RIGHT: 39,
TAB: 9,
RETURN: 13,
COMMA: 188,
DELETE: 8,
UP: 'ArrowUp',
DOWN: 'ArrowDown',
LEFT: 'ArrowLeft',
RIGHT: 'ArrowRight',
TAB: 'Tab',
RETURN: 'Enter',
COMMA: ',',
DELETE: 'Backspace',
};
const NAVIGATION_KEYS = [
KEYS.COMMA,
KEYS.DELETE,
KEYS.LEFT,
KEYS.RIGHT,
KEYS.TAB,
];
const LETTERS = /[a-z]/i;
/* TODO: Remove all instances of this.props.listing
and refactor this component to be more generic */
@ -218,23 +228,23 @@ class Tags extends Component {
if (
component.selected.length === this.props.maxTags &&
e.keyCode === KEYS.COMMA
e.key === KEYS.COMMA
) {
e.preventDefault();
return;
}
if (
(e.keyCode === KEYS.DOWN || e.keyCode === KEYS.TAB) &&
(e.key === KEYS.DOWN || e.key === KEYS.TAB) &&
!this.isBottomOfSearchResults &&
component.props.defaultValue !== ''
) {
e.preventDefault();
this.moveDownInSearchResults();
} else if (e.keyCode === KEYS.UP && !this.isTopOfSearchResults) {
} else if (e.key === KEYS.UP && !this.isTopOfSearchResults) {
e.preventDefault();
this.moveUpInSearchResults();
} else if (e.keyCode === KEYS.RETURN && this.isSearchResultSelected) {
} else if (e.key === KEYS.RETURN && this.isSearchResultSelected) {
e.preventDefault();
this.insertTag(
component.state.searchResults[component.state.selectedIndex].name,
@ -243,10 +253,10 @@ class Tags extends Component {
setTimeout(() => {
document.getElementById('tag-input').focus();
}, 10);
} else if (e.keyCode === KEYS.COMMA && !this.isSearchResultSelected) {
} else if (e.key === KEYS.COMMA && !this.isSearchResultSelected) {
this.resetSearchResults();
this.clearSelectedSearchResult();
} else if (e.keyCode === KEYS.DELETE) {
} else if (e.key === KEYS.DELETE) {
if (
component.props.defaultValue[
component.props.defaultValue.length - 1
@ -255,13 +265,8 @@ class Tags extends Component {
this.clearSelectedSearchResult();
}
} else if (
(e.keyCode < 65 || e.keyCode > 90) &&
e.keyCode != KEYS.COMMA &&
e.keyCode != KEYS.DELETE &&
e.keyCode != KEYS.LEFT &&
e.keyCode != KEYS.RIGHT &&
e.keyCode != KEYS.TAB
) {
!LETTERS.test(e.key) &&
!NAVIGATION_KEYS.includes(e.key)) {
e.preventDefault();
}
};