UNPKG

rooks

Version:

Essential React custom hooks ⚓ to super charge your components!

145 lines (144 loc) 5.82 kB
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 };