@yafh/use-tinykeys
Version:
Vue composition API for listen keyboard event.
175 lines (169 loc) • 4.82 kB
JavaScript
;
var tinykeys = require('tinykeys');
var vue = require('vue');
var uaParserJs = require('ua-parser-js');
// src/index.ts
var ua = new uaParserJs.UAParser().getResult();
function isWindows() {
return ua.os.name === "Windows";
}
function isMac() {
return ua.os.name === "Mac OS" || ua.os.name === "iOS";
}
// src/util.ts
function callWithAsyncErrorHandling(fn, args) {
if (typeof fn === "function") {
const res = callWithErrorHandling(fn, args);
if (res instanceof Promise) {
res.catch((err) => {
console.error(err);
});
}
return res;
}
const values = [];
for (let i = 0; i < fn.length; i++) {
values.push(callWithAsyncErrorHandling(fn[i], args));
}
return values;
}
function callWithErrorHandling(fn, args) {
let res;
try {
res = args ? fn(...args) : fn();
} catch (err) {
console.error(err);
}
return res;
}
// src/index.ts
function useKeyStroke(key, handler, option = { target: window, eventType: "keydown" }) {
const instance = vue.getCurrentInstance();
if (!instance) {
throw new Error("onKeyStroke must be called inside a setup function");
}
if (!instance.__utk_enabled) {
instance.__utk_enabled = vue.ref(true);
}
let enable;
if (option.customEnable) {
enable = option.customEnable;
enable.__is_sustom_enabled = true;
} else {
enable = vue.ref(true);
}
const enableActivated = vue.ref(true);
const enableInstance = instance.__utk_enabled;
const { target, eventType, timeout, listenOnkeepAlive } = option;
const _key = filterKeyBinding(key);
const _eventType = eventType ? Array.isArray(eventType) ? eventType : [eventType] : ["keydown"];
const _target = target || window;
let keyupListener;
let keydownListener;
let keypressListener;
function registerEvent() {
if (!_target)
return;
keyupListener && _target.addEventListener("keyup", keyupListener);
keydownListener && _target.addEventListener("keydown", keydownListener);
keypressListener && _target.addEventListener("keypress", keypressListener);
}
function unregisterEvent() {
if (!_target)
return;
keyupListener && _target.removeEventListener("keyup", keyupListener);
keydownListener && _target.removeEventListener("keydown", keydownListener);
keypressListener && _target.removeEventListener("keypress", keypressListener);
}
vue.onBeforeUnmount(() => {
unregisterEvent();
});
if (!listenOnkeepAlive) {
vue.onActivated(() => {
enableActivated.value = true;
if (!enable.__is_sustom_enabled) {
enable.value = true;
}
});
vue.onDeactivated(() => {
enableActivated.value = false;
if (!enable.__is_sustom_enabled) {
enable.value = false;
}
});
}
const stopWatchHandle = vue.watchEffect(() => {
unregisterEvent();
if (!enableInstance.value || !enable.value || !enableActivated.value)
return;
if (typeof handler === "function") {
const keyBindingHandler = wrapKeyBindingHandler(handler, _key, timeout);
if (_eventType.includes("keydown")) {
keydownListener = keyBindingHandler;
}
if (_eventType.includes("keyup")) {
keyupListener = keyBindingHandler;
}
if (_eventType.includes("keypress")) {
keypressListener = keyBindingHandler;
}
} else {
if (handler.keydown) {
keydownListener = wrapKeyBindingHandler(handler.keydown, _key, timeout);
}
if (handler.keyup) {
keyupListener = wrapKeyBindingHandler(handler.keyup, _key, timeout);
}
if (handler.keypress) {
keypressListener = wrapKeyBindingHandler(
handler.keypress,
_key,
timeout
);
}
}
registerEvent();
});
const clearup = () => {
stopWatchHandle();
unregisterEvent();
};
return {
enable,
enableInstance,
clearup
};
}
function filterKeyBinding(key) {
if (typeof key === "string") {
return [key];
} else if (Array.isArray(key)) {
return key;
} else if (isWindows()) {
return Array.isArray(key.windows) ? key.windows : key.windows ? [key.windows] : [];
} else if (isMac()) {
return Array.isArray(key.mac) ? key.mac : key.mac ? [key.mac] : [];
} else {
return [];
}
}
function wrapEventListener(fn) {
if (!fn.__wel) {
fn.__wel = (event) => {
callWithAsyncErrorHandling(fn, [event]);
};
}
return fn.__wel;
}
function wrapKeyBindingHandler(handler, key, timeout) {
const _handler = wrapEventListener(handler);
return tinykeys.createKeybindingsHandler(
key.reduce((acc, type) => {
acc[type] = _handler;
return acc;
}, {}),
{ timeout }
);
}
exports.useKeyStroke = useKeyStroke;
exports.wrapKeyBindingHandler = wrapKeyBindingHandler;