vue-hooks-plus
Version:
Vue hooks library
194 lines (193 loc) • 4.23 kB
JavaScript
import { ref } from "vue";
import { getTargetElement } from "../utils/domTarget";
import useDeepCompareEffectWithTarget from "../utils/useDeepCompareWithTarget";
import { isFunction, isString, isNumber } from "../utils";
const aliasKeyCodeMap = {
"0": 48,
"1": 49,
"2": 50,
"3": 51,
"4": 52,
"5": 53,
"6": 54,
"7": 55,
"8": 56,
"9": 57,
backspace: 8,
tab: 9,
enter: 13,
shift: 16,
ctrl: 17,
alt: 18,
pausebreak: 19,
capslock: 20,
esc: 27,
space: 32,
pageup: 33,
pagedown: 34,
end: 35,
home: 36,
leftarrow: 37,
uparrow: 38,
rightarrow: 39,
downarrow: 40,
insert: 45,
delete: 46,
a: 65,
b: 66,
c: 67,
d: 68,
e: 69,
f: 70,
g: 71,
h: 72,
i: 73,
j: 74,
k: 75,
l: 76,
m: 77,
n: 78,
o: 79,
p: 80,
q: 81,
r: 82,
s: 83,
t: 84,
u: 85,
v: 86,
w: 87,
x: 88,
y: 89,
z: 90,
leftwindowkey: 91,
rightwindowkey: 92,
selectkey: 93,
numpad0: 96,
numpad1: 97,
numpad2: 98,
numpad3: 99,
numpad4: 100,
numpad5: 101,
numpad6: 102,
numpad7: 103,
numpad8: 104,
numpad9: 105,
multiply: 106,
add: 107,
subtract: 109,
decimalpoint: 110,
divide: 111,
f1: 112,
f2: 113,
f3: 114,
f4: 115,
f5: 116,
f6: 117,
f7: 118,
f8: 119,
f9: 120,
f10: 121,
f11: 122,
f12: 123,
numlock: 144,
scrolllock: 145,
semicolon: 186,
equalsign: 187,
comma: 188,
dash: 189,
period: 190,
forwardslash: 191,
graveaccent: 192,
openbracket: 219,
backslash: 220,
closebracket: 221,
singlequote: 222
};
const modifierKey = {
ctrl: (event) => event.ctrlKey,
shift: (event) => event.shiftKey,
alt: (event) => event.altKey,
meta: (event) => event.metaKey
};
function countKeyByEvent(event) {
const countOfModifier = Object.keys(modifierKey).reduce((total, key) => {
if (modifierKey[key](event)) {
return total + 1;
}
return total;
}, 0);
return [16, 17, 18, 91, 92].includes(event.keyCode) ? countOfModifier : countOfModifier + 1;
}
function genFilterKey(event, keyFilter, exactMatch) {
if (!event.key) {
return false;
}
if (isNumber(keyFilter)) {
return event.keyCode === keyFilter;
}
const genArr = keyFilter.split(".");
let genLen = 0;
for (const key of genArr) {
const genModifier = modifierKey[key];
const aliasKeyCode = aliasKeyCodeMap[key.toLowerCase()];
if (genModifier && genModifier(event) || aliasKeyCode && aliasKeyCode === event.keyCode) {
genLen++;
}
}
if (exactMatch) {
return genLen === genArr.length && countKeyByEvent(event) === genArr.length;
}
return genLen === genArr.length;
}
function genKeyFormatter(keyFilter, exactMatch) {
if (isFunction(keyFilter)) {
return keyFilter;
}
if (isString(keyFilter) || isNumber(keyFilter)) {
return (event) => genFilterKey(event, keyFilter, exactMatch);
}
if (Array.isArray(keyFilter)) {
return (event) => keyFilter.some((item) => genFilterKey(event, item, exactMatch));
}
return keyFilter ? () => true : () => false;
}
const defaultEvents = ["keydown"];
function useKeyPress(keyFilter, eventHandler, option) {
const { events = defaultEvents, target, exactMatch = false } = option || {};
const eventHandlerRef = ref(eventHandler);
const keyFilterRef = ref(keyFilter);
useDeepCompareEffectWithTarget(
() => {
var _a;
const el = getTargetElement(target, window);
if (!el) {
return;
}
const callbackHandler = (event) => {
var _a2;
const genGuard = genKeyFormatter(keyFilterRef.value, exactMatch);
if (genGuard(event)) {
return (_a2 = eventHandlerRef.value) == null ? void 0 : _a2.call(eventHandlerRef, event);
}
};
for (const eventName of events) {
(_a = el == null ? void 0 : el.addEventListener) == null ? void 0 : _a.call(el, eventName, callbackHandler);
}
return () => {
var _a2;
for (const eventName of events) {
(_a2 = el == null ? void 0 : el.removeEventListener) == null ? void 0 : _a2.call(
el,
eventName,
callbackHandler
);
}
};
},
[events],
target
);
}
export {
useKeyPress as default
};