rooks
Version:
Essential React custom hooks ⚓ to super charge your components!
145 lines (144 loc) • 5.82 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { useEffect, useRef, useCallback } from "react";
import { doesIdentifierMatchKeyboardEvent } from "../utils/doesIdentifierMatchKeyboardEvent";
import { noop } from "../utils/noop";
/**
* defaultOptions which will be merged with passed in options
*/
var defaultOptions = {
continuous: false,
when: true,
};
/**
* useKeys hook
*
* @param keysList - list of keys to listen to
* @param callback - callback to be called when a key is pressed
* @param options - options to be passed to the event listener
* @see https://react-hooks.org/docs/useKeys
*/
function useKeys(keysList, callback, options) {
var internalOptions = __assign(__assign({}, defaultOptions), options);
var target = internalOptions.target, when = internalOptions.when, continuous = internalOptions.continuous, preventLostKeyup = internalOptions.preventLostKeyup;
var savedCallback = useRef(callback);
/**
* PressedKeyMapping will do the bookkeeping the pressed keys
*/
var pressedKeyMappingRef = useRef({});
var PressedKeyMapping = pressedKeyMappingRef.current;
/**
* First useEffect is to remember the latest callback
*/
useEffect(function () {
savedCallback.current = callback;
});
/**
* handleKeyDown
*
* @param {KeyboardEvent} event
* KeyDown event handler which will wrap the passed in callback
*/
var handleKeyDown = useCallback(function (event) {
var pressedKeyIdentifier = null;
var areAllKeysFromListPressed = false;
// First detect the key that was pressed;
for (var _i = 0, keysList_1 = keysList; _i < keysList_1.length; _i++) {
var identifier = keysList_1[_i];
if (doesIdentifierMatchKeyboardEvent(event, identifier)) {
PressedKeyMapping[identifier] = true;
pressedKeyIdentifier = identifier;
}
}
if (keysList.every(function (identifier) { return Boolean(PressedKeyMapping[identifier]); })) {
areAllKeysFromListPressed = true;
}
if (areAllKeysFromListPressed) {
savedCallback.current(event);
/**
* If not continuous
* disable identifier immediately
*/
if (!continuous && pressedKeyIdentifier !== null) {
PressedKeyMapping[pressedKeyIdentifier] = false;
}
}
}, [keysList, PressedKeyMapping, continuous]);
/**
* [handleKeyUp]
*
* @param {KeyboardEvent} event
*
* KeyUp event handler which will update the keys pressed state in PressedKeyMapping
*/
var handleKeyUp = useCallback(function (event) {
for (var _i = 0, keysList_2 = keysList; _i < keysList_2.length; _i++) {
var identifier = keysList_2[_i];
if (doesIdentifierMatchKeyboardEvent(event, identifier)) {
PressedKeyMapping[identifier] = undefined;
}
}
}, [PressedKeyMapping, keysList]);
/**
* Responsible for setting up the event listener and removing event listeners
*/
useEffect(function () {
if (when && typeof window !== "undefined") {
var targetNode_1 = (target === null || target === void 0 ? void 0 : target.current) ? target.current : document;
targetNode_1.addEventListener("keydown", handleKeyDown);
targetNode_1.addEventListener("keyup", handleKeyUp);
return function () {
targetNode_1.removeEventListener("keydown", handleKeyDown);
targetNode_1.removeEventListener("keyup", handleKeyUp);
};
}
return noop;
}, [when, target, keysList, handleKeyDown, handleKeyUp]);
useEffect(function () {
if (preventLostKeyup !== true)
return noop;
if (typeof window !== "undefined") {
var originalAlert_1 = window.alert;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
window.alert = function (message) {
for (var _i = 0, keysList_3 = keysList; _i < keysList_3.length; _i++) {
var identifier = keysList_3[_i];
PressedKeyMapping[identifier] = undefined;
}
return originalAlert_1(message);
};
var originalConfirm_1 = window.confirm;
window.confirm = function (message) {
for (var _i = 0, keysList_4 = keysList; _i < keysList_4.length; _i++) {
var identifier = keysList_4[_i];
PressedKeyMapping[identifier] = undefined;
}
return originalConfirm_1(message);
};
var originalPrompt_1 = window.prompt;
window.prompt = function (message, _default) {
for (var _i = 0, keysList_5 = keysList; _i < keysList_5.length; _i++) {
var identifier = keysList_5[_i];
PressedKeyMapping[identifier] = undefined;
}
return originalPrompt_1(message, _default);
};
return function () {
window.alert = originalAlert_1;
window.confirm = originalConfirm_1;
window.prompt = originalPrompt_1;
};
}
return noop;
}, [PressedKeyMapping, keysList, preventLostKeyup]);
}
export { useKeys };