@orca-fe/hooks
Version:
React Hooks Collections
146 lines (141 loc) • 5.24 kB
JavaScript
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;