@punch-in/buffet-modern-hooks 3.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Buffet.js Hooks
2
+
3
+ ## Getting Started
4
+
5
+ ### Installation
6
+
7
+ Using yarn
8
+
9
+ ```bash
10
+ yarn add @punch-in/buffet-modern-hooks
11
+ # Install the required dependencies
12
+ yarn add react
13
+ ```
14
+
15
+ or npm
16
+
17
+ ```bash
18
+ npm install @punch-in/buffet-modern-hooks --save
19
+ # Install the required dependencies
20
+ npm install react --save
21
+ ```
22
+
23
+ ### Available commands
24
+
25
+ - **build**<br/>
26
+ Builds the library for production
27
+ - **build:analyze**<br/>
28
+ Analyse the generated build
29
+ - **build:watch**<br/>
30
+ Whatch the files with webpack
31
+ - **build:watch:esm**<br/>
32
+ Whatch the files with babel
33
+ - **create:index**<br/>
34
+ Create the `build/index.js` file
35
+ - **test**<br/>
36
+ Runs the entire set of test: lint, style and jest
37
+ - **test:jest**<br/>
38
+ Runs the unit tests
39
+ - **test:jest:watch**<br/>
40
+ Runs the unit tests in watch mode
41
+ - **test:lint**<br/>
42
+ Runs the lint tests
43
+ - **test:lint:quiet**<br/>
44
+ Runs the lint tests without displaying the warnings
45
+ - **test:style**<br/>
46
+ Runs the stylelint tests
47
+ - **test:style:quiet**<br/>
48
+ Runs the stylelint tests without displaying the warnings
49
+ - **lint:fix**<br/>
50
+ Fixes the lint
@@ -0,0 +1,18 @@
1
+ const defaultPresets = [
2
+ [
3
+ '@babel/preset-env',
4
+ {
5
+ modules: process.env.BABEL_ENV === 'esm' ? false : 'auto',
6
+ },
7
+ ],
8
+ ];
9
+
10
+ module.exports = {
11
+ presets: defaultPresets.concat(['@babel/preset-react', '@babel/preset-flow']),
12
+ plugins: [
13
+ '@babel/plugin-proposal-class-properties',
14
+ '@babel/plugin-proposal-export-default-from',
15
+ '@babel/plugin-proposal-export-namespace-from',
16
+ '@babel/plugin-proposal-function-bind',
17
+ ],
18
+ };
@@ -0,0 +1,195 @@
1
+ (function webpackUniversalModuleDefinition(root, factory) {
2
+ if(typeof exports === 'object' && typeof module === 'object')
3
+ module.exports = factory(require("react"));
4
+ else if(typeof define === 'function' && define.amd)
5
+ define("@punch-in/buffet-modern-hooks", ["react"], factory);
6
+ else if(typeof exports === 'object')
7
+ exports["@punch-in/buffet-modern-hooks"] = factory(require("react"));
8
+ else
9
+ root["@punch-in/buffet-modern-hooks"] = factory(root["react"]);
10
+ })(window, function(__WEBPACK_EXTERNAL_MODULE_react__) {
11
+ return /******/ (function(modules) { // webpackBootstrap
12
+ /******/ // The module cache
13
+ /******/ var installedModules = {};
14
+ /******/
15
+ /******/ // The require function
16
+ /******/ function __webpack_require__(moduleId) {
17
+ /******/
18
+ /******/ // Check if module is in cache
19
+ /******/ if(installedModules[moduleId]) {
20
+ /******/ return installedModules[moduleId].exports;
21
+ /******/ }
22
+ /******/ // Create a new module (and put it into the cache)
23
+ /******/ var module = installedModules[moduleId] = {
24
+ /******/ i: moduleId,
25
+ /******/ l: false,
26
+ /******/ exports: {}
27
+ /******/ };
28
+ /******/
29
+ /******/ // Execute the module function
30
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31
+ /******/
32
+ /******/ // Flag the module as loaded
33
+ /******/ module.l = true;
34
+ /******/
35
+ /******/ // Return the exports of the module
36
+ /******/ return module.exports;
37
+ /******/ }
38
+ /******/
39
+ /******/
40
+ /******/ // expose the modules object (__webpack_modules__)
41
+ /******/ __webpack_require__.m = modules;
42
+ /******/
43
+ /******/ // expose the module cache
44
+ /******/ __webpack_require__.c = installedModules;
45
+ /******/
46
+ /******/ // define getter function for harmony exports
47
+ /******/ __webpack_require__.d = function(exports, name, getter) {
48
+ /******/ if(!__webpack_require__.o(exports, name)) {
49
+ /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
50
+ /******/ }
51
+ /******/ };
52
+ /******/
53
+ /******/ // define __esModule on exports
54
+ /******/ __webpack_require__.r = function(exports) {
55
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
56
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
57
+ /******/ }
58
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
59
+ /******/ };
60
+ /******/
61
+ /******/ // create a fake namespace object
62
+ /******/ // mode & 1: value is a module id, require it
63
+ /******/ // mode & 2: merge all properties of value into the ns
64
+ /******/ // mode & 4: return value when already ns object
65
+ /******/ // mode & 8|1: behave like require
66
+ /******/ __webpack_require__.t = function(value, mode) {
67
+ /******/ if(mode & 1) value = __webpack_require__(value);
68
+ /******/ if(mode & 8) return value;
69
+ /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
70
+ /******/ var ns = Object.create(null);
71
+ /******/ __webpack_require__.r(ns);
72
+ /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
73
+ /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
74
+ /******/ return ns;
75
+ /******/ };
76
+ /******/
77
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
78
+ /******/ __webpack_require__.n = function(module) {
79
+ /******/ var getter = module && module.__esModule ?
80
+ /******/ function getDefault() { return module['default']; } :
81
+ /******/ function getModuleExports() { return module; };
82
+ /******/ __webpack_require__.d(getter, 'a', getter);
83
+ /******/ return getter;
84
+ /******/ };
85
+ /******/
86
+ /******/ // Object.prototype.hasOwnProperty.call
87
+ /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
88
+ /******/
89
+ /******/ // __webpack_public_path__
90
+ /******/ __webpack_require__.p = "";
91
+ /******/
92
+ /******/
93
+ /******/ // Load entry module and return exports
94
+ /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js");
95
+ /******/ })
96
+ /************************************************************************/
97
+ /******/ ({
98
+
99
+ /***/ "./src/index.js":
100
+ /*!**********************!*\
101
+ !*** ./src/index.js ***!
102
+ \**********************/
103
+ /*! exports provided: useActiveKeys, useClickAwayListener, useDebounce, useEventListener, useIsMounted, useShortcutEffect */
104
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
105
+
106
+ "use strict";
107
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _useActiveKeys__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./useActiveKeys */ \"./src/useActiveKeys/index.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"useActiveKeys\", function() { return _useActiveKeys__WEBPACK_IMPORTED_MODULE_0__[\"default\"]; });\n\n/* harmony import */ var _useClickAwayListener__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./useClickAwayListener */ \"./src/useClickAwayListener/index.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"useClickAwayListener\", function() { return _useClickAwayListener__WEBPACK_IMPORTED_MODULE_1__[\"default\"]; });\n\n/* harmony import */ var _useDebounce__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./useDebounce */ \"./src/useDebounce/index.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"useDebounce\", function() { return _useDebounce__WEBPACK_IMPORTED_MODULE_2__[\"default\"]; });\n\n/* harmony import */ var _useEventListener__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./useEventListener */ \"./src/useEventListener/index.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"useEventListener\", function() { return _useEventListener__WEBPACK_IMPORTED_MODULE_3__[\"default\"]; });\n\n/* harmony import */ var _useIsMounted__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./useIsMounted */ \"./src/useIsMounted/index.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"useIsMounted\", function() { return _useIsMounted__WEBPACK_IMPORTED_MODULE_4__[\"default\"]; });\n\n/* harmony import */ var _useShortcutEffect__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./useShortcutEffect */ \"./src/useShortcutEffect/index.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"useShortcutEffect\", function() { return _useShortcutEffect__WEBPACK_IMPORTED_MODULE_5__[\"default\"]; });\n\n\n\n\n\n\n\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/./src/index.js?");
108
+
109
+ /***/ }),
110
+
111
+ /***/ "./src/useActiveKeys/index.js":
112
+ /*!************************************!*\
113
+ !*** ./src/useActiveKeys/index.js ***!
114
+ \************************************/
115
+ /*! exports provided: default */
116
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
117
+
118
+ "use strict";
119
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _useEventListener__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../useEventListener */ \"./src/useEventListener/index.js\");\nfunction _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _iterableToArray(r) { if (\"undefined\" != typeof Symbol && null != r[Symbol.iterator] || null != r[\"@@iterator\"]) return Array.from(r); }\nfunction _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }\nfunction _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(r, a) { if (r) { if (\"string\" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }\nfunction _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(r) { if (Array.isArray(r)) return r; }\n\n\nfunction useActiveKeys() {\n var isEnabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])([]),\n _useState2 = _slicedToArray(_useState, 2),\n activeKeys = _useState2[0],\n setActiveKeys = _useState2[1];\n\n // Add keys to the array on down\n Object(_useEventListener__WEBPACK_IMPORTED_MODULE_1__[\"default\"])('keydown', function (e) {\n if (!activeKeys.includes(e.keyCode)) {\n setActiveKeys(function (prevKeys) {\n return [].concat(_toConsumableArray(prevKeys), [e.keyCode]);\n });\n }\n }, isEnabled);\n\n // Remove keys on up\n Object(_useEventListener__WEBPACK_IMPORTED_MODULE_1__[\"default\"])('keyup', function (e) {\n setActiveKeys(function (prevKeys) {\n return prevKeys.filter(function (key) {\n return key !== e.keyCode;\n });\n });\n }, isEnabled);\n return activeKeys;\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (useActiveKeys);\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/./src/useActiveKeys/index.js?");
120
+
121
+ /***/ }),
122
+
123
+ /***/ "./src/useClickAwayListener/index.js":
124
+ /*!*******************************************!*\
125
+ !*** ./src/useClickAwayListener/index.js ***!
126
+ \*******************************************/
127
+ /*! exports provided: default */
128
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
129
+
130
+ "use strict";
131
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n\nvar useClickAwayListener = function useClickAwayListener(ref, callback) {\n // Call the callback function if clicked on outside of element\n var handleClickOutside = function handleClickOutside(event) {\n if (ref.current && !ref.current.contains(event.target)) {\n callback();\n }\n };\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n // Bind the event listener\n document.addEventListener('mousedown', handleClickOutside);\n return function () {\n // Unbind the event listener on clean up\n document.removeEventListener('mousedown', handleClickOutside);\n };\n });\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (useClickAwayListener);\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/./src/useClickAwayListener/index.js?");
132
+
133
+ /***/ }),
134
+
135
+ /***/ "./src/useDebounce/index.js":
136
+ /*!**********************************!*\
137
+ !*** ./src/useDebounce/index.js ***!
138
+ \**********************************/
139
+ /*! exports provided: default */
140
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
141
+
142
+ "use strict";
143
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\nfunction _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(r, a) { if (r) { if (\"string\" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }\nfunction _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(r) { if (Array.isArray(r)) return r; }\n\n\n// A simple hook to debounce value.\nvar useDebounce = function useDebounce(value, delay) {\n var _useState = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useState\"])(value),\n _useState2 = _slicedToArray(_useState, 2),\n debouncedValue = _useState2[0],\n setDebouncedValue = _useState2[1];\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n var handler = setTimeout(function () {\n setDebouncedValue(value);\n }, delay);\n return function () {\n clearTimeout(handler);\n };\n }, [value, delay]);\n return debouncedValue;\n};\n/* harmony default export */ __webpack_exports__[\"default\"] = (useDebounce);\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/./src/useDebounce/index.js?");
144
+
145
+ /***/ }),
146
+
147
+ /***/ "./src/useEventListener/index.js":
148
+ /*!***************************************!*\
149
+ !*** ./src/useEventListener/index.js ***!
150
+ \***************************************/
151
+ /*! exports provided: default */
152
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
153
+
154
+ "use strict";
155
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n\nfunction useEventListener(event, eventListener) {\n var isEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n var listenerRef = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useRef\"])();\n listenerRef.current = eventListener;\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n function handleEvent(e) {\n listenerRef.current(e);\n }\n if (isEnabled) {\n window.addEventListener(event, handleEvent);\n } else {\n window.removeEventListener(event, handleEvent);\n }\n return function () {\n window.removeEventListener(event, handleEvent);\n };\n }, [event, isEnabled]);\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (useEventListener);\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/./src/useEventListener/index.js?");
156
+
157
+ /***/ }),
158
+
159
+ /***/ "./src/useIsMounted/index.js":
160
+ /*!***********************************!*\
161
+ !*** ./src/useIsMounted/index.js ***!
162
+ \***********************************/
163
+ /*! exports provided: default */
164
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
165
+
166
+ "use strict";
167
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n\n\n// Hook taken from https://github.com/hupe1980/react-is-mounted-hook\n\nfunction useIsMounted() {\n var ref = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useRef\"])(true);\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n ref.current = true;\n return function () {\n ref.current = false;\n };\n }, []);\n return ref.current;\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (useIsMounted);\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/./src/useIsMounted/index.js?");
168
+
169
+ /***/ }),
170
+
171
+ /***/ "./src/useShortcutEffect/index.js":
172
+ /*!****************************************!*\
173
+ !*** ./src/useShortcutEffect/index.js ***!
174
+ \****************************************/
175
+ /*! exports provided: default */
176
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
177
+
178
+ "use strict";
179
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"react\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _useActiveKeys__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../useActiveKeys */ \"./src/useActiveKeys/index.js\");\n\n\nvar keyCodes = {\n alt: 18,\n arrowup: 38,\n arrowdown: 40,\n enter: 13,\n f: 70,\n tab: 9\n};\nfunction getShortcutKeys(keys) {\n return keys.split('+').map(function (value) {\n return keyCodes[value.toLowerCase()];\n });\n}\nfunction useShortcutEffect(shortcut, listener) {\n var isEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n var activeKeys = Object(_useActiveKeys__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(isEnabled);\n var listenerRef = Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useRef\"])();\n listenerRef.current = listener;\n Object(react__WEBPACK_IMPORTED_MODULE_0__[\"useEffect\"])(function () {\n var match = getShortcutKeys(shortcut).every(function (key) {\n return activeKeys.includes(key);\n });\n if (match) {\n listenerRef.current();\n }\n }, [activeKeys, shortcut]);\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (useShortcutEffect);\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/./src/useShortcutEffect/index.js?");
180
+
181
+ /***/ }),
182
+
183
+ /***/ "react":
184
+ /*!************************!*\
185
+ !*** external "react" ***!
186
+ \************************/
187
+ /*! no static exports found */
188
+ /***/ (function(module, exports) {
189
+
190
+ eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react__;\n\n//# sourceURL=webpack://@punch-in/buffet-modern-hooks/external_%22react%22?");
191
+
192
+ /***/ })
193
+
194
+ /******/ });
195
+ });
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define("@punch-in/buffet-modern-hooks",["react"],t):"object"==typeof exports?exports["@punch-in/buffet-modern-hooks"]=t(require("react")):e["@punch-in/buffet-modern-hooks"]=t(e.react)}(window,(function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(t,n){t.exports=e},function(e,t,n){"use strict";n.r(t),n.d(t,"useActiveKeys",(function(){return a})),n.d(t,"useClickAwayListener",(function(){return l})),n.d(t,"useDebounce",(function(){return y})),n.d(t,"useEventListener",(function(){return o})),n.d(t,"useIsMounted",(function(){return b})),n.d(t,"useShortcutEffect",(function(){return m}));var r=n(0);var o=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],o=Object(r.useRef)();o.current=t,Object(r.useEffect)((function(){function t(e){o.current(e)}return n?window.addEventListener(e,t):window.removeEventListener(e,t),function(){window.removeEventListener(e,t)}}),[e,n])};function u(e){return function(e){if(Array.isArray(e))return f(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||c(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,u,i,c=[],f=!0,a=!1;try{if(u=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;f=!1}else for(;!(f=(r=u.call(n)).done)&&(c.push(r.value),c.length!==t);f=!0);}catch(e){a=!0,o=e}finally{try{if(!f&&null!=n.return&&(i=n.return(),Object(i)!==i))return}finally{if(a)throw o}}return c}}(e,t)||c(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e,t){if(e){if("string"==typeof e)return f(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?f(e,t):void 0}}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var a=function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=Object(r.useState)([]),n=i(t,2),c=n[0],f=n[1];return o("keydown",(function(e){c.includes(e.keyCode)||f((function(t){return[].concat(u(t),[e.keyCode])}))}),e),o("keyup",(function(e){f((function(t){return t.filter((function(t){return t!==e.keyCode}))}))}),e),c},l=function(e,t){var n=function(n){e.current&&!e.current.contains(n.target)&&t()};Object(r.useEffect)((function(){return document.addEventListener("mousedown",n),function(){document.removeEventListener("mousedown",n)}}))};function s(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,u,i,c=[],f=!0,a=!1;try{if(u=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;f=!1}else for(;!(f=(r=u.call(n)).done)&&(c.push(r.value),c.length!==t);f=!0);}catch(e){a=!0,o=e}finally{try{if(!f&&null!=n.return&&(i=n.return(),Object(i)!==i))return}finally{if(a)throw o}}return c}}(e,t)||function(e,t){if(e){if("string"==typeof e)return d(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?d(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var y=function(e,t){var n=s(Object(r.useState)(e),2),o=n[0],u=n[1];return Object(r.useEffect)((function(){var n=setTimeout((function(){u(e)}),t);return function(){clearTimeout(n)}}),[e,t]),o};var b=function(){var e=Object(r.useRef)(!0);return Object(r.useEffect)((function(){return e.current=!0,function(){e.current=!1}}),[]),e.current},v={alt:18,arrowup:38,arrowdown:40,enter:13,f:70,tab:9};function p(e){return e.split("+").map((function(e){return v[e.toLowerCase()]}))}var m=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],o=a(n),u=Object(r.useRef)();u.current=t,Object(r.useEffect)((function(){p(e).every((function(e){return o.includes(e)}))&&u.current()}),[o,e])}}])}));
@@ -0,0 +1,6 @@
1
+ export { default as useActiveKeys } from './useActiveKeys';
2
+ export { default as useClickAwayListener } from './useClickAwayListener';
3
+ export { default as useDebounce } from './useDebounce';
4
+ export { default as useEventListener } from './useEventListener';
5
+ export { default as useIsMounted } from './useIsMounted';
6
+ export { default as useShortcutEffect } from './useShortcutEffect';
@@ -0,0 +1,39 @@
1
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
4
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
5
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
6
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
8
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
9
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
11
+ import { useState } from 'react';
12
+ import useEventListener from '../useEventListener';
13
+ function useActiveKeys() {
14
+ var isEnabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
15
+ var _useState = useState([]),
16
+ _useState2 = _slicedToArray(_useState, 2),
17
+ activeKeys = _useState2[0],
18
+ setActiveKeys = _useState2[1];
19
+
20
+ // Add keys to the array on down
21
+ useEventListener('keydown', function (e) {
22
+ if (!activeKeys.includes(e.keyCode)) {
23
+ setActiveKeys(function (prevKeys) {
24
+ return [].concat(_toConsumableArray(prevKeys), [e.keyCode]);
25
+ });
26
+ }
27
+ }, isEnabled);
28
+
29
+ // Remove keys on up
30
+ useEventListener('keyup', function (e) {
31
+ setActiveKeys(function (prevKeys) {
32
+ return prevKeys.filter(function (key) {
33
+ return key !== e.keyCode;
34
+ });
35
+ });
36
+ }, isEnabled);
37
+ return activeKeys;
38
+ }
39
+ export default useActiveKeys;
@@ -0,0 +1,18 @@
1
+ import { useEffect } from 'react';
2
+ var useClickAwayListener = function useClickAwayListener(ref, callback) {
3
+ // Call the callback function if clicked on outside of element
4
+ var handleClickOutside = function handleClickOutside(event) {
5
+ if (ref.current && !ref.current.contains(event.target)) {
6
+ callback();
7
+ }
8
+ };
9
+ useEffect(function () {
10
+ // Bind the event listener
11
+ document.addEventListener('mousedown', handleClickOutside);
12
+ return function () {
13
+ // Unbind the event listener on clean up
14
+ document.removeEventListener('mousedown', handleClickOutside);
15
+ };
16
+ });
17
+ };
18
+ export default useClickAwayListener;
@@ -0,0 +1,25 @@
1
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
7
+ import { useState, useEffect } from 'react';
8
+
9
+ // A simple hook to debounce value.
10
+ var useDebounce = function useDebounce(value, delay) {
11
+ var _useState = useState(value),
12
+ _useState2 = _slicedToArray(_useState, 2),
13
+ debouncedValue = _useState2[0],
14
+ setDebouncedValue = _useState2[1];
15
+ useEffect(function () {
16
+ var handler = setTimeout(function () {
17
+ setDebouncedValue(value);
18
+ }, delay);
19
+ return function () {
20
+ clearTimeout(handler);
21
+ };
22
+ }, [value, delay]);
23
+ return debouncedValue;
24
+ };
25
+ export default useDebounce;
@@ -0,0 +1,20 @@
1
+ import { useEffect, useRef } from 'react';
2
+ function useEventListener(event, eventListener) {
3
+ var isEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
4
+ var listenerRef = useRef();
5
+ listenerRef.current = eventListener;
6
+ useEffect(function () {
7
+ function handleEvent(e) {
8
+ listenerRef.current(e);
9
+ }
10
+ if (isEnabled) {
11
+ window.addEventListener(event, handleEvent);
12
+ } else {
13
+ window.removeEventListener(event, handleEvent);
14
+ }
15
+ return function () {
16
+ window.removeEventListener(event, handleEvent);
17
+ };
18
+ }, [event, isEnabled]);
19
+ }
20
+ export default useEventListener;
@@ -0,0 +1,15 @@
1
+ import { useRef, useEffect } from 'react';
2
+
3
+ // Hook taken from https://github.com/hupe1980/react-is-mounted-hook
4
+
5
+ function useIsMounted() {
6
+ var ref = useRef(true);
7
+ useEffect(function () {
8
+ ref.current = true;
9
+ return function () {
10
+ ref.current = false;
11
+ };
12
+ }, []);
13
+ return ref.current;
14
+ }
15
+ export default useIsMounted;
@@ -0,0 +1,30 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import useActiveKeys from '../useActiveKeys';
3
+ var keyCodes = {
4
+ alt: 18,
5
+ arrowup: 38,
6
+ arrowdown: 40,
7
+ enter: 13,
8
+ f: 70,
9
+ tab: 9
10
+ };
11
+ function getShortcutKeys(keys) {
12
+ return keys.split('+').map(function (value) {
13
+ return keyCodes[value.toLowerCase()];
14
+ });
15
+ }
16
+ function useShortcutEffect(shortcut, listener) {
17
+ var isEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
18
+ var activeKeys = useActiveKeys(isEnabled);
19
+ var listenerRef = useRef();
20
+ listenerRef.current = listener;
21
+ useEffect(function () {
22
+ var match = getShortcutKeys(shortcut).every(function (key) {
23
+ return activeKeys.includes(key);
24
+ });
25
+ if (match) {
26
+ listenerRef.current();
27
+ }
28
+ }, [activeKeys, shortcut]);
29
+ }
30
+ export default useShortcutEffect;
package/build/index.js ADDED
@@ -0,0 +1,8 @@
1
+
2
+ 'use strict';
3
+
4
+ if (process.env.NODE_ENV === "production") {
5
+ module.exports = require("./bundle.production.js");
6
+ } else {
7
+ module.exports = require("./bundle.development.js");
8
+ }
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@punch-in/buffet-modern-hooks",
3
+ "version": "3.3.10",
4
+ "description": "Buffetjs react-hooks",
5
+ "main": "build",
6
+ "module": "build/esm/index.js",
7
+ "sideEffects": [
8
+ "*.css"
9
+ ],
10
+ "scripts": {
11
+ "prebuild": "rimraf build",
12
+ "build": "npm run build:development && npm run build:production && npm run build:esm && npm run create:index",
13
+ "build:analyze": "cross-env NODE_ENV=production webpack-cli --json > build/stats.production.json && webpack-bundle-analyzer build/stats.production.json",
14
+ "build:development": "cross-env NODE_ENV=development webpack-cli",
15
+ "build:esm": "cross-env BABEL_ENV=esm babel ./src --out-dir ./build/esm --ignore \"**/*.test.js\" --ignore \"**/test.js\" ",
16
+ "build:production": "cross-env NODE_ENV=production webpack-cli",
17
+ "build:watch": "npm run create:index && cross-env NODE_ENV=development webpack-cli -w",
18
+ "build:watch:esm": "cross-env BABEL_ENV=esm babel ./src --out-dir ./build/esm --ignore \"**/*.test.js\" --ignore \"**/test.js\" --watch",
19
+ "create:index": "node ./createBuildIndex.js",
20
+ "test": "npm run test:lint",
21
+ "test:lint": "eslint .",
22
+ "test:lint:quiet": "eslint . --quiet",
23
+ "lint:fix": "eslint . --fix",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "license": "MIT",
27
+ "private": false,
28
+ "devDependencies": {
29
+ "@babel/cli": "^7.1.5",
30
+ "@babel/core": "^7.1.6",
31
+ "@babel/plugin-proposal-class-properties": "^7.1.0",
32
+ "@babel/plugin-proposal-export-default-from": "^7.0.0",
33
+ "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
34
+ "@babel/plugin-proposal-function-bind": "^7.0.0",
35
+ "@babel/plugin-transform-flow-strip-types": "^7.1.6",
36
+ "@babel/polyfill": "^7.0.0",
37
+ "@babel/preset-env": "^7.1.6",
38
+ "@babel/preset-flow": "^7.0.0",
39
+ "@babel/preset-react": "^7.0.0",
40
+ "babel-eslint": "^10.0.1",
41
+ "babel-jest": "^23.6.0",
42
+ "babel-loader": "^8.0.4",
43
+ "babel-plugin-module-resolver": "3.0.0",
44
+ "bundlesize": "^0.17.0",
45
+ "cross-env": "^5.1.4",
46
+ "enzyme": "^3.10.0",
47
+ "eslint": "^7.5.0",
48
+ "eslint-config-airbnb": "^18.2.0",
49
+ "eslint-config-prettier": "^6.11.0",
50
+ "eslint-import-resolver-lerna": "^1.1.0",
51
+ "eslint-import-resolver-webpack": "^0.12.2",
52
+ "eslint-plugin-import": "^2.22.0",
53
+ "eslint-plugin-jest": "^23.19.0",
54
+ "eslint-plugin-jsx-a11y": "^6.3.1",
55
+ "eslint-plugin-react": "^7.20.5",
56
+ "eslint-plugin-react-hooks": "^4.0.8",
57
+ "rimraf": "^3.0.2",
58
+ "url-loader": "^1.0.1",
59
+ "webpack": "~4.44.0",
60
+ "webpack-bundle-analyzer": "^3.8.0",
61
+ "webpack-cli": "~3.3.12"
62
+ },
63
+ "peerDependencies": {
64
+ "react": "^16.8.6"
65
+ },
66
+ "keywords": [
67
+ "Buffetjs",
68
+ "React",
69
+ "react-hooks",
70
+ "hooks"
71
+ ],
72
+ "author": "Strapi team",
73
+ "publishConfig": {
74
+ "access": "public"
75
+ },
76
+ "repository": {
77
+ "type": "git",
78
+ "url": "https://github.com/strapi/buffet"
79
+ },
80
+ "gitHead": "fa862df858d9729b31171d540a2ae8c4b25ce4d2"
81
+ }
package/src/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { default as useActiveKeys } from './useActiveKeys';
2
+ export { default as useClickAwayListener } from './useClickAwayListener';
3
+ export { default as useDebounce } from './useDebounce';
4
+ export { default as useEventListener } from './useEventListener';
5
+ export { default as useIsMounted } from './useIsMounted';
6
+ export { default as useShortcutEffect } from './useShortcutEffect';
@@ -0,0 +1,30 @@
1
+ import { useState } from 'react';
2
+ import useEventListener from '../useEventListener';
3
+
4
+ function useActiveKeys(isEnabled = true) {
5
+ const [activeKeys, setActiveKeys] = useState([]);
6
+
7
+ // Add keys to the array on down
8
+ useEventListener(
9
+ 'keydown',
10
+ e => {
11
+ if (!activeKeys.includes(e.keyCode)) {
12
+ setActiveKeys(prevKeys => [...prevKeys, e.keyCode]);
13
+ }
14
+ },
15
+ isEnabled
16
+ );
17
+
18
+ // Remove keys on up
19
+ useEventListener(
20
+ 'keyup',
21
+ e => {
22
+ setActiveKeys(prevKeys => prevKeys.filter(key => key !== e.keyCode));
23
+ },
24
+ isEnabled
25
+ );
26
+
27
+ return activeKeys;
28
+ }
29
+
30
+ export default useActiveKeys;
@@ -0,0 +1,22 @@
1
+ import { useEffect } from 'react';
2
+
3
+ const useClickAwayListener = (ref, callback) => {
4
+ // Call the callback function if clicked on outside of element
5
+ const handleClickOutside = event => {
6
+ if (ref.current && !ref.current.contains(event.target)) {
7
+ callback();
8
+ }
9
+ };
10
+
11
+ useEffect(() => {
12
+ // Bind the event listener
13
+ document.addEventListener('mousedown', handleClickOutside);
14
+
15
+ return () => {
16
+ // Unbind the event listener on clean up
17
+ document.removeEventListener('mousedown', handleClickOutside);
18
+ };
19
+ });
20
+ };
21
+
22
+ export default useClickAwayListener;
@@ -0,0 +1,20 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ // A simple hook to debounce value.
4
+ const useDebounce = (value, delay) => {
5
+ const [debouncedValue, setDebouncedValue] = useState(value);
6
+
7
+ useEffect(() => {
8
+ const handler = setTimeout(() => {
9
+ setDebouncedValue(value);
10
+ }, delay);
11
+
12
+ return () => {
13
+ clearTimeout(handler);
14
+ };
15
+ }, [value, delay]);
16
+
17
+ return debouncedValue;
18
+ };
19
+
20
+ export default useDebounce;
@@ -0,0 +1,24 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ function useEventListener(event, eventListener, isEnabled = true) {
4
+ const listenerRef = useRef();
5
+ listenerRef.current = eventListener;
6
+
7
+ useEffect(() => {
8
+ function handleEvent(e) {
9
+ listenerRef.current(e);
10
+ }
11
+
12
+ if (isEnabled) {
13
+ window.addEventListener(event, handleEvent);
14
+ } else {
15
+ window.removeEventListener(event, handleEvent);
16
+ }
17
+
18
+ return () => {
19
+ window.removeEventListener(event, handleEvent);
20
+ };
21
+ }, [event, isEnabled]);
22
+ }
23
+
24
+ export default useEventListener;
@@ -0,0 +1,19 @@
1
+ import { useRef, useEffect } from 'react';
2
+
3
+ // Hook taken from https://github.com/hupe1980/react-is-mounted-hook
4
+
5
+ function useIsMounted() {
6
+ const ref = useRef(true);
7
+
8
+ useEffect(() => {
9
+ ref.current = true;
10
+
11
+ return () => {
12
+ ref.current = false;
13
+ };
14
+ }, []);
15
+
16
+ return ref.current;
17
+ }
18
+
19
+ export default useIsMounted;
@@ -0,0 +1,34 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ import useActiveKeys from '../useActiveKeys';
4
+
5
+ const keyCodes = {
6
+ alt: 18,
7
+ arrowup: 38,
8
+ arrowdown: 40,
9
+ enter: 13,
10
+ f: 70,
11
+ tab: 9,
12
+ };
13
+
14
+ function getShortcutKeys(keys) {
15
+ return keys.split('+').map(value => keyCodes[value.toLowerCase()]);
16
+ }
17
+
18
+ function useShortcutEffect(shortcut, listener, isEnabled = true) {
19
+ const activeKeys = useActiveKeys(isEnabled);
20
+ const listenerRef = useRef();
21
+ listenerRef.current = listener;
22
+
23
+ useEffect(() => {
24
+ const match = getShortcutKeys(shortcut).every(key =>
25
+ activeKeys.includes(key)
26
+ );
27
+
28
+ if (match) {
29
+ listenerRef.current();
30
+ }
31
+ }, [activeKeys, shortcut]);
32
+ }
33
+
34
+ export default useShortcutEffect;