UNPKG

reakeys

Version:
120 lines (119 loc) 5.28 kB
(function(global, factory) { typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react"), require("ctrl-keys")) : typeof define === "function" && define.amd ? define(["exports", "react", "ctrl-keys"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.reakeys = {}, global.react, global.ctrlKeys)); })(this, function(exports2, react, ctrlKeys) { "use strict"; function isMac() { try { return navigator.platform.toUpperCase().indexOf("MAC") >= 0; } catch { return false; } } function getModifierKey() { return isMac() ? "⌘" : "CTRL"; } const MODIFIER_KEY = getModifierKey(); function getHotkeyText(hotkey) { return hotkey.toLowerCase().replace("modifier", getModifierKey()).replace("mod", getModifierKey()).replace("shift", "⇧"); } let isGlobalListenersBinded = false; const keypressGlobalHandler = ctrlKeys.keys(); const keyupGlobalHandler = ctrlKeys.keys(); const keydownGlobalHandler = ctrlKeys.keys(); const handlers = /* @__PURE__ */ new Map(); let hotkeys = []; const extractKeys = (keys2) => { const normalizedKeys = Array.isArray(keys2) ? keys2.map((key) => key.toLowerCase()) : [keys2.toLowerCase()]; const modKey = isMac() ? "meta" : "ctrl"; return normalizedKeys.map((key) => key.replace("modifier", modKey).replace("mod", modKey)); }; const focusInputWrapper = (callback) => (event) => { const target = event.target; const isInput = target.tagName === "INPUT" && !["checkbox", "radio", "range", "button", "file", "reset", "submit", "color"].includes(target.type); if (target.isContentEditable || (isInput || target.tagName === "TEXTAREA" || target.tagName === "SELECT") && !target.readOnly) { return; } return callback(event); }; const registerGlobalShortcut = (shortcut) => { if (!shortcut.action || shortcut.action === "keypress") { keypressGlobalHandler.add(...extractKeys(shortcut.keys), shortcut.callback); } if (shortcut.action === "keyup") { keyupGlobalHandler.add(...extractKeys(shortcut.keys), shortcut.callback); } if (shortcut.action === "keydown") { keydownGlobalHandler.add(...extractKeys(shortcut.keys), shortcut.callback); } }; const removeGlobalShortcut = (shortcut) => { if (!shortcut.action || shortcut.action === "keypress") { keypressGlobalHandler.remove(...extractKeys(shortcut.keys), shortcut.callback); } if (shortcut.action === "keyup") { keyupGlobalHandler.remove(...extractKeys(shortcut.keys), shortcut.callback); } if (shortcut.action === "keydown") { keydownGlobalHandler.remove(...extractKeys(shortcut.keys), shortcut.callback); } }; const registerElementShortcut = (shortcut) => { var _a, _b, _c; const handler = ctrlKeys.keys(); handler.add(...extractKeys(shortcut.keys), shortcut.callback); (_b = (_a = shortcut.ref) == null ? void 0 : _a.current) == null ? void 0 : _b.addEventListener(shortcut.action ?? "keypress", handler.handle); handlers.set((_c = shortcut.ref) == null ? void 0 : _c.current, handler); }; const removeElementShortcut = (shortcut) => { var _a, _b, _c, _d; if (((_a = shortcut.ref) == null ? void 0 : _a.current) && !shortcut.disabled) { const handler = handlers.get((_b = shortcut.ref) == null ? void 0 : _b.current); handler == null ? void 0 : handler.remove(...extractKeys(shortcut.keys), shortcut.callback); (_d = (_c = shortcut.ref) == null ? void 0 : _c.current) == null ? void 0 : _d.removeEventListener(shortcut.action ?? "keypress", handler.handle); } }; const useHotkeys = (shortcuts = []) => { const [registered, setRegistered] = react.useState([]); react.useLayoutEffect(() => { if (!isGlobalListenersBinded && window !== void 0) { window.addEventListener("keypress", keypressGlobalHandler.handle); window.addEventListener("keyup", keyupGlobalHandler.handle); window.addEventListener("keydown", keydownGlobalHandler.handle); isGlobalListenersBinded = true; } }, []); react.useLayoutEffect(() => { shortcuts.map((shortcut) => { var _a; if (shortcut.disabled) { return; } shortcut.callback = focusInputWrapper(shortcut.callback); if ((_a = shortcut.ref) == null ? void 0 : _a.current) { registerElementShortcut(shortcut); hotkeys = [...hotkeys, shortcut]; } else if (!shortcut.ref) { registerGlobalShortcut(shortcut); hotkeys = [...hotkeys, shortcut]; } }); return () => { shortcuts.map((shortcut) => { removeElementShortcut(shortcut); removeGlobalShortcut(shortcut); hotkeys = hotkeys.filter((hotkey) => shortcut !== hotkey); }); }; }, [shortcuts]); react.useEffect(() => { setRegistered(hotkeys); }, []); return registered; }; exports2.MODIFIER_KEY = MODIFIER_KEY; exports2.getHotkeyText = getHotkeyText; exports2.isMac = isMac; exports2.useHotkeys = useHotkeys; Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" }); }); //# sourceMappingURL=index.umd.cjs.map