64 lines
1.8 KiB
TypeScript

import { useEventListener } from "@vueuse/core";
import type { Directive, DirectiveBinding } from "vue";
import { subBefore, subAfter, isFunction } from "@pureadmin/utils";
export const longpress: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding<Function>) {
const cb = binding.value;
if (cb && isFunction(cb)) {
let timer = null;
let interTimer = null;
let num = 500;
let interNum = null;
const isInter = binding?.arg?.includes(":") ?? false;
if (isInter) {
num = Number(subBefore(binding.arg, ":"));
interNum = Number(subAfter(binding.arg, ":"));
} else if (binding.arg) {
num = Number(binding.arg);
}
const clear = () => {
if (timer) {
clearTimeout(timer);
timer = null;
}
if (interTimer) {
clearInterval(interTimer);
interTimer = null;
}
};
const onDownInter = (ev: PointerEvent) => {
ev.preventDefault();
if (interTimer === null) {
interTimer = setInterval(() => cb(), interNum);
}
};
const onDown = (ev: PointerEvent) => {
clear();
ev.preventDefault();
if (timer === null) {
timer = isInter
? setTimeout(() => {
cb();
onDownInter(ev);
}, num)
: setTimeout(() => cb(), num);
}
};
// Register using addEventListener on mounted, and removeEventListener automatically on unmounted
useEventListener(el, "pointerdown", onDown);
useEventListener(el, "pointerup", clear);
useEventListener(el, "pointerleave", clear);
} else {
throw new Error(
'[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"'
);
}
}
};