UNPKG

@orca-fe/hooks

Version:

React Hooks Collections

146 lines (141 loc) 5.24 kB
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import { useMemoizedFn } from 'ahooks'; import { useEffect, useMemo, useState } from 'react'; import { createHotkeyCache, formatHotKeyStr, isInput, isMac, toHotkeyStr } from "./hotkey-manager/utils"; import { registerGlobal } from "./utils/syncGlobal"; /** * 快捷键对象 */ /** * 热键库 */ export var defaultHotkeyDef = { copy: ['Ctrl+C', 'Command+C'], paste: ['Ctrl+V', 'Command+V'], cut: ['Ctrl+X', 'Command+X'], undo: ['Ctrl+Z', 'Command+Z'], save: ['Ctrl+S', 'Command+S'], redo: [['Ctrl+Shift+Z', 'Ctrl+Y'], ['Command+Shift+Z', 'Command+Y']], confirm: ['Ctrl+Enter', 'Command+Enter'], delete: ['Delete', ['Delete', 'Backspace']], escape: ['Escape'] }; var mapping = createHotkeyCache(defaultHotkeyDef); export var actionStack = []; var handleKeyDown = e => { var hotkeyStr = toHotkeyStr(e); if (!hotkeyStr) return; var keyMapping = isMac() ? mapping.macHotkeyMapping : mapping.hotkeyMapping; var hotkeyName = keyMapping.get(hotkeyStr); if (window.sessionStorage.useHotkeyListenerDebug) { console.warn('hotkeyStr', hotkeyStr); console.warn('hotkeyName', hotkeyName); } // 在监听器中查找 action for (var _i = 0, _actionStack = actionStack; _i < _actionStack.length; _i++) { var action = _actionStack[_i]; // 禁用的监听器,跳过 if (action.disabled) continue; // 匹配事件名称(允许直接匹配) if (hotkeyName === action.hotkeyName || hotkeyStr === action.hotkeyName) { var _action$target, _ref, _action$action; var triggerTarget = e.target; if (action.input === false) { // 不对 input 内的快捷键进行响应,不做处理,继续/退出 if (isInput(triggerTarget)) { if (action.through) { continue; } else { break; } } } // 事件监听有限制父节点 var parentNode = (_action$target = action.target) === null || _action$target === void 0 ? void 0 : _action$target.call(action); if (parentNode) { // 有指定父节点,但触发目标节点不在范围内,不做处理,继续/退出 if (!parentNode.contains(e.target)) { if (action.through) { continue; } else { break; } } } var through = (_ref = (_action$action = action.action(e)) !== null && _action$action !== void 0 ? _action$action : action.through) !== null && _ref !== void 0 ? _ref : true; if (!through) { // 不传递事件,中断,并标记事件已被触发 break; } } } }; var unregisterHotkeyAction = action => { var index = actionStack.findIndex(item => item === action); if (index >= 0) { actionStack.splice(index, 1); } if (actionStack.length <= 0) { window.removeEventListener('keydown', handleKeyDown); } }; var registerHotkeyAction = action => { if (actionStack.length <= 0) { window.addEventListener('keydown', handleKeyDown); } actionStack.unshift(action); actionStack.sort((a, b) => { var _b$priority, _a$priority; return ((_b$priority = b.priority) !== null && _b$priority !== void 0 ? _b$priority : 0) - ((_a$priority = a.priority) !== null && _a$priority !== void 0 ? _a$priority : 0); }); return () => { unregisterHotkeyAction(action); }; }; // 将内容挂载到 window 上,避免多个包重复,导致无法共享,重复触发等问题 var globalObj = registerGlobal('__orca-hooks-useHotkeyListener-global', { mapping, unregisterHotkeyAction, registerHotkeyAction }); var useHotkeyListener = (_hotkeyName, action, options = {}) => { var getOptionTarget = useMemoizedFn(() => { var _options$target; return (_options$target = options.target) === null || _options$target === void 0 ? void 0 : _options$target.call(options); }); var memoAction = useMemoizedFn(action); var _useState = useState(() => isMac()), _useState2 = _slicedToArray(_useState, 1), isMacEnv = _useState2[0]; var _useState3 = useState({ action: memoAction, hotkeyName: '', target: getOptionTarget }), _useState4 = _slicedToArray(_useState3, 1), actionObject = _useState4[0]; var hotkeyName = (Array.isArray(_hotkeyName) ? _hotkeyName : [_hotkeyName, _hotkeyName])[isMacEnv ? 1 : 0]; actionObject.hotkeyName = useMemo(() => formatHotKeyStr(hotkeyName), [hotkeyName]); actionObject.input = options.input; actionObject.through = options.through; actionObject.disabled = options.disabled; actionObject.priority = options.priority; useEffect(() => { globalObj.registerHotkeyAction(actionObject); return () => { globalObj.unregisterHotkeyAction(actionObject); }; }, [actionObject.priority]); }; /** * 更新预设快捷键 * @param hotkeys */ useHotkeyListener.updateHotkeyDefs = hotkeys => { var _createHotkeyCache = createHotkeyCache(hotkeys), hotkeyMapping = _createHotkeyCache.hotkeyMapping, macHotkeyMapping = _createHotkeyCache.macHotkeyMapping; globalObj.mapping.hotkeyMapping = hotkeyMapping; globalObj.mapping.macHotkeyMapping = macHotkeyMapping; }; export default useHotkeyListener;