Skip to content

Commit 660b75f

Browse files
committedApr 28, 2021
Fix dependency
1 parent 1918492 commit 660b75f

16 files changed

+2711
-2742
lines changed
 

‎.babelrc

+4-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
{ "presets": ["@babel/preset-env", "@babel/preset-react"] }
1+
2+
{
3+
"presets": ["@babel/preset-env", "@babel/preset-react"]
4+
}

‎.eslintrc.json

+9-29
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,14 @@
11
{
2-
"extends": "airbnb",
2+
"parser": "@typescript-eslint/parser", // Specifies the ESLint parser
33
"parserOptions": {
4-
"sourceType": "module",
5-
"parser": "babel-eslint"
4+
"ecmaVersion": 2020, // Allows for the parsing of modern ECMAScript features
5+
"sourceType": "module" // Allows for the use of imports
66
},
7+
"extends": [
8+
"plugin:@typescript-eslint/recommended" // Uses the recommended rules from the @typescript-eslint/eslint-plugin
9+
],
710
"rules": {
8-
"arrow-parens": ["off"],
9-
"prefer-template": "off",
10-
"no-console": "off",
11-
"compat/compat": 2,
12-
"consistent-return": "off",
13-
"comma-dangle": "off",
14-
"generator-star-spacing": "off",
15-
"import/no-unresolved": "off",
16-
"import/no-extraneous-dependencies": "off",
17-
"no-use-before-define": "off",
18-
"promise/param-names": 2,
19-
"promise/always-return": 2,
20-
"promise/catch-or-return": 2,
21-
"promise/no-native": 0,
22-
"react/jsx-no-bind": "off",
23-
"react/jsx-filename-extension": ["error", { "extensions": [".js", ".jsx"] }],
24-
"react/prefer-stateless-function": "off",
25-
"rules": {
26-
"curly": ["error", "all"]
27-
}
28-
},
29-
"plugins": ["promise", "compat", "react"],
30-
"env": {
31-
"jest": true,
32-
"browser": true
11+
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
12+
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
3313
}
34-
}
14+
}

‎.prettierrc

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{
22
"printWidth": 120,
3-
"singleQuote": true,
4-
"useTabs": false,
5-
"tabWidth": 2,
6-
"semi": true,
7-
"bracketSpacing": true,
8-
"brace_style": "collapse,preserve-inline"
9-
}
3+
"singleQuote": true,
4+
"useTabs": false,
5+
"tabWidth": 2,
6+
"semi": true,
7+
"bracketSpacing": true,
8+
"brace_style": "collapse,preserve-inline"
9+
}
10+

‎babel.config.js

-11
This file was deleted.

‎build/index.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
interface IParamType {
2+
detectKeys: Array<string | number>;
3+
keyevent: string;
4+
}
5+
declare const useKey: (callback: (currentKeyCode: number, event: Event) => unknown, { detectKeys, keyevent }?: IParamType, { dependencies }?: {
6+
dependencies?: never[] | undefined;
7+
}) => any;
8+
export { useKey };

‎build/index.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
exports.useKey = void 0;
7+
const react_1 = require("react");
8+
const invariant_1 = __importDefault(require("invariant"));
9+
const keys_js_1 = require("./keys.js");
10+
const VALID_KEY_EVENTS = ['keydown', 'keyup', 'keypress'];
11+
const useKey = (callback, { detectKeys, keyevent } = { detectKeys: [], keyevent: 'keydown' }, { dependencies = [] } = {}) => {
12+
const isKeyeventValid = VALID_KEY_EVENTS.indexOf(keyevent) > -1;
13+
invariant_1.default(isKeyeventValid, 'keyevent is not valid: ' + keyevent);
14+
invariant_1.default(callback != null, 'callback needs to be defined');
15+
invariant_1.default(Array.isArray(dependencies), 'dependencies need to be an array');
16+
let allowedKeys = detectKeys;
17+
if (!Array.isArray(detectKeys)) {
18+
allowedKeys = [];
19+
// eslint-disable-next-line no-console
20+
console.warn('Keys should be array!');
21+
}
22+
allowedKeys = keys_js_1.convertToAsciiEquivalent(allowedKeys);
23+
const handleEvent = (event) => {
24+
const asciiCode = keys_js_1.getAsciiCode(event);
25+
return keys_js_1.onKeyPress(asciiCode, callback, allowedKeys, event);
26+
};
27+
react_1.useEffect(() => {
28+
const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
29+
if (!canUseDOM) {
30+
console.error('Window is not defined');
31+
return () => {
32+
// returning null
33+
};
34+
}
35+
window.document.addEventListener(keyevent, handleEvent);
36+
return () => {
37+
window.document.removeEventListener(keyevent, handleEvent);
38+
};
39+
}, dependencies);
40+
};
41+
exports.useKey = useKey;

‎build/keys.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { EffectCallback } from 'react';
2+
declare const isKeyFromGivenList: (keyCode: number, allowedKeys?: Array<string | number>) => boolean;
3+
declare const onKeyPress: (currentKeyCode: number, callback: (currentKeyCode: number, event: Event) => unknown, allowedKeys: Array<string | number>, event: Event) => ReturnType<EffectCallback>;
4+
declare function getAsciiCode(event: Event): number;
5+
declare function convertToAsciiEquivalent(inputArray: Array<string | number>): Array<string | number>;
6+
export { isKeyFromGivenList, onKeyPress, convertToAsciiEquivalent, getAsciiCode };

‎build/keys.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
exports.getAsciiCode = exports.convertToAsciiEquivalent = exports.onKeyPress = exports.isKeyFromGivenList = void 0;
4+
const codeLowerCaseA = 65;
5+
const codeUpperCaseZ = 122;
6+
const isKeyFromGivenList = (keyCode, allowedKeys = []) => {
7+
if (allowedKeys === null || allowedKeys.includes(keyCode) || allowedKeys.length === 0) {
8+
return true;
9+
}
10+
return false;
11+
};
12+
exports.isKeyFromGivenList = isKeyFromGivenList;
13+
const onKeyPress = (currentKeyCode, callback, allowedKeys, event) => {
14+
if (isKeyFromGivenList(currentKeyCode, allowedKeys)) {
15+
callback(currentKeyCode, event);
16+
}
17+
};
18+
exports.onKeyPress = onKeyPress;
19+
function getAsciiCode(event) {
20+
let keyCode = event.which;
21+
if (keyCode >= codeLowerCaseA && keyCode <= codeUpperCaseZ) {
22+
keyCode = event.key.charCodeAt(0);
23+
}
24+
return keyCode;
25+
}
26+
exports.getAsciiCode = getAsciiCode;
27+
function convertToAsciiEquivalent(inputArray) {
28+
return inputArray.map((item) => {
29+
const finalVal = item;
30+
if (typeof finalVal === 'string') {
31+
return finalVal.charCodeAt(0);
32+
}
33+
return finalVal;
34+
});
35+
}
36+
exports.convertToAsciiEquivalent = convertToAsciiEquivalent;

‎dist/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var useKey = function useKey(callback) {
4242
return onKeyPress(asciiCode, callback, allowedKeys, event);
4343
};
4444

45-
useEffect(function() {
45+
useEffect(function () {
4646
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
4747

4848
if (!canUseDOM) {
@@ -51,7 +51,7 @@ var useKey = function useKey(callback) {
5151
}
5252

5353
window.document.addEventListener(keyevent, handleEvent);
54-
return function() {
54+
return function () {
5555
window.document.removeEventListener(keyevent, handleEvent);
5656
};
5757
}, dependencies);

‎package-lock.json

+2,537-2,642
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+16-12
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,41 @@
1818
},
1919
"scripts": {
2020
"build:lib": "cross-env NODE_ENV='production' babel src --out-dir dist --ignore '**/__test__/**'",
21-
"test": "jest --coverage",
21+
"test": "npm run build && jest --coverage",
2222
"test-watch": "jest --watchAll --coverage",
2323
"lint": "./node_modules/eslint/bin/eslint.js --ext js,jsx src",
2424
"lint-fix": "./node_modules/eslint/bin/eslint.js --ext js,jsx src --fix",
2525
"format:check": "prettier --config ./.prettierrc --list-different \"src/**/*{.ts,.js,.json,.css,.scss}\"",
26-
"format:fix": "pretty-quick --staged"
26+
"format:fix": "pretty-quick --staged",
27+
"build": "tsc"
2728
},
2829
"license": "MIT",
2930
"peerDependencies": {
3031
"react": "^16.7.0-alpha.2"
3132
},
3233
"devDependencies": {
34+
"@types/invariant": "^2.2.34",
35+
"@types/jest": "^26.0.19",
36+
"@types/react": "^17.0.3",
37+
"@typescript-eslint/eslint-plugin": "^4.22.0",
38+
"@typescript-eslint/parser": "^4.22.0",
3339
"cross-env": "^5.2.0",
34-
"eslint": "^5.8.0",
35-
"eslint-config-airbnb": "^17.1.0",
36-
"eslint-plugin-compat": "^2.6.2",
37-
"eslint-plugin-import": "^2.14.0",
38-
"eslint-plugin-jsx-a11y": "^6.1.2",
39-
"eslint-plugin-promise": "^4.0.1",
40-
"eslint-plugin-react": "^7.11.1",
40+
"eslint": "^7.25.0",
41+
"eslint-config-prettier": "^8.3.0",
42+
"eslint-plugin-prettier": "^3.4.0",
4143
"husky": "1.1.2",
4244
"jest": "^26.6.3",
43-
"prettier": "1.14.3",
45+
"prettier": "^2.2.1",
4446
"pretty-quick": "^1.8.0",
4547
"react": "^16.7.0-alpha.2",
4648
"react-dom": "^16.7.0-alpha.2",
47-
"react-test-renderer": "^16.7.0-alpha.2",
49+
"react-test-renderer": "^16.14.0",
4850
"react-testing-library": "5.9.0",
4951
"regenerator-runtime": "^0.12.1",
5052
"typescript": "^4.1.3",
51-
"@types/jest": "^26.0.19"
53+
"@babel/preset-env": "^7.13.15",
54+
"@babel/preset-react": "^7.13.13",
55+
"babel-jest": "^26.6.3"
5256
},
5357
"files": [
5458
"dist/index.js",

‎src/__tests__/index.test.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import React from 'react';
33
// eslint-disable-next-line object-curly-newline
44
import { render, cleanup, fireEvent } from 'react-testing-library';
55

6-
const useKey = require('../');
6+
import { useKey } from '../../build/index';
77

8-
// eslint-disable-next-line react/prop-types
98
const TestComponent = ({ callback, detectKeys, keyevent }) => {
109
useKey(callback, { detectKeys, keyevent });
1110
return <div />;
@@ -38,7 +37,7 @@ describe('events', () => {
3837
key: 'ArrowUp',
3938
bubbles: true,
4039
which: 38,
41-
code: 'ArrowUp'
40+
code: 'ArrowUp',
4241
});
4342
fireEvent(container, keyDownEvent);
4443
expect(callback).toHaveBeenCalledWith(38, keyDownEvent);
@@ -52,7 +51,7 @@ describe('events', () => {
5251
key: 'ArrowUp',
5352
bubbles: true,
5453
which: 38,
55-
code: 'ArrowUp'
54+
code: 'ArrowUp',
5655
});
5756
fireEvent(container, keyUpEvent);
5857
expect(callback).toHaveBeenCalledWith(38, keyUpEvent);
@@ -66,7 +65,7 @@ describe('events', () => {
6665
key: 'ArrowUp',
6766
bubbles: true,
6867
which: 38,
69-
code: 'ArrowUp'
68+
code: 'ArrowUp',
7069
});
7170
fireEvent(container, keyPressEvent);
7271
expect(callback).toHaveBeenCalledWith(38, keyPressEvent);
@@ -80,7 +79,7 @@ describe('events', () => {
8079
key: 'ArrowUp',
8180
bubbles: true,
8281
which: 38,
83-
code: 'ArrowUp'
82+
code: 'ArrowUp',
8483
});
8584
fireEvent(container, keyDownEvent);
8685
expect(callback).not.toHaveBeenCalledWith(38, keyDownEvent);

‎src/__tests__/keys.test.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
const {
2-
isKeyFromGivenList,
3-
onKeyPress,
4-
convertToAsciiEquivalent,
5-
getAsciiCode,
6-
} = require('../keys');
1+
import { isKeyFromGivenList, onKeyPress, convertToAsciiEquivalent, getAsciiCode } from '../../build/keys';
72

83
describe('keys utils', () => {
94
test('isKeyFromGivenList returns true when current key belong to allowed list', () => {

‎src/index.ts

+19-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
const { useEffect } = require('react');
2-
const invariant = require('invariant');
3-
const { onKeyPress, convertToAsciiEquivalent, getAsciiCode } = require('./keys.js');
1+
import { EffectCallback, useEffect } from 'react';
42

5-
const VALID_KEY_EVENTS = ['keydown', 'keyup', 'keypress'];
3+
import invariant from 'invariant';
4+
import { onKeyPress, convertToAsciiEquivalent, getAsciiCode } from './keys.js';
65

7-
const useKey = (callback: unknown, { detectKeys = [], keyevent = 'keydown' } = {}, { dependencies = [] } = {}) => {
6+
const VALID_KEY_EVENTS = ['keydown', 'keyup', 'keypress'];
7+
interface IParamType {
8+
detectKeys: Array<string | number>;
9+
keyevent: string;
10+
}
11+
const useKey = (
12+
callback: (currentKeyCode: number, event: Event) => unknown,
13+
{ detectKeys, keyevent }: IParamType = { detectKeys: [], keyevent: 'keydown' },
14+
{ dependencies = [] } = {}
15+
): any => {
816
const isKeyeventValid = VALID_KEY_EVENTS.indexOf(keyevent) > -1;
917

1018
invariant(isKeyeventValid, 'keyevent is not valid: ' + keyevent);
@@ -21,16 +29,18 @@ const useKey = (callback: unknown, { detectKeys = [], keyevent = 'keydown' } = {
2129

2230
allowedKeys = convertToAsciiEquivalent(allowedKeys);
2331

24-
const handleEvent = (event: any) => {
32+
const handleEvent = (event: Event) => {
2533
const asciiCode = getAsciiCode(event);
2634
return onKeyPress(asciiCode, callback, allowedKeys, event);
2735
};
2836

29-
useEffect(() => {
37+
useEffect((): ReturnType<EffectCallback> => {
3038
const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
3139
if (!canUseDOM) {
3240
console.error('Window is not defined');
33-
return null;
41+
return (): void => {
42+
// returning null
43+
};
3444
}
3545
window.document.addEventListener(keyevent, handleEvent);
3646
return () => {
@@ -39,4 +49,4 @@ const useKey = (callback: unknown, { detectKeys = [], keyevent = 'keydown' } = {
3949
}, dependencies);
4050
};
4151

42-
module.exports = useKey;
52+
export { useKey };

‎src/keys.ts

+18-16
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,40 @@
1+
import { EffectCallback } from 'react';
2+
13
const codeLowerCaseA = 65;
24
const codeUpperCaseZ = 122;
3-
const isKeyFromGivenList = (keyCode: never, allowedKeys = []) => {
5+
const isKeyFromGivenList = (keyCode: number, allowedKeys: Array<string | number> = []): boolean => {
46
if (allowedKeys === null || allowedKeys.includes(keyCode) || allowedKeys.length === 0) {
57
return true;
68
}
79
return false;
810
};
9-
const onKeyPress = (currentKeyCode: never, callback: Function, allowedKeys: any, event: any) => {
11+
const onKeyPress = (
12+
currentKeyCode: number,
13+
callback: (currentKeyCode: number, event: Event) => unknown,
14+
allowedKeys: Array<string | number>,
15+
event: Event
16+
): ReturnType<EffectCallback> => {
1017
if (isKeyFromGivenList(currentKeyCode, allowedKeys)) {
1118
callback(currentKeyCode, event);
1219
}
1320
};
1421

15-
function getAsciiCode(event) {
16-
let keyCode = event.which;
22+
function getAsciiCode(event: Event): number {
23+
let keyCode = (event as KeyboardEvent).which;
1724
if (keyCode >= codeLowerCaseA && keyCode <= codeUpperCaseZ) {
18-
keyCode = event.key.charCodeAt(0);
25+
keyCode = (event as KeyboardEvent).key.charCodeAt(0);
1926
}
2027
return keyCode;
2128
}
2229

23-
function convertToAsciiEquivalent(inputArray) {
24-
return inputArray.map(item => {
25-
let finalVal = item;
26-
if (typeof item === 'string') {
27-
finalVal = finalVal.charCodeAt(0);
30+
function convertToAsciiEquivalent(inputArray: Array<string | number>): Array<string | number> {
31+
return inputArray.map((item) => {
32+
const finalVal = item;
33+
if (typeof finalVal === 'string') {
34+
return finalVal.charCodeAt(0);
2835
}
2936
return finalVal;
3037
});
3138
}
3239

33-
module.exports = {
34-
isKeyFromGivenList,
35-
onKeyPress,
36-
convertToAsciiEquivalent,
37-
getAsciiCode
38-
};
40+
export { isKeyFromGivenList, onKeyPress, convertToAsciiEquivalent, getAsciiCode };

‎tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"removeComments": false,
99
"declaration": true,
1010
"outDir": "build",
11-
"lib": ["es6"]
11+
"lib": ["es6", "DOM"]
1212
},
1313
"include": ["src", "src/index.ts"],
1414
"exclude": ["node_modules", "**/__tests__/*"]

0 commit comments

Comments
 (0)
Please sign in to comment.