Skip to content

Commit

Permalink
✨ Custom directive for long-press events (#586)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lissy93 committed Mar 31, 2022
1 parent 83ce9b8 commit d077b1b
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/directives/LongPress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* A Vue directive to call event when element is long-pressed
* Used to open context menus on touch-enabled devices
* Inspired by: FeliciousX/vue-directive-long-press
* Dashy: Licensed under MIT - (C) Alicia Sykes 2022
*/

const LONG_PRESS_DEFAULT_DELAY = 750;
const longPressEvent = new CustomEvent('long-press');

export default {
bind(element, binding, vnode) {
const el = element;
el.dataset.longPressTimeout = null;

const swallowClick = (e) => {
el.removeEventListener('click', swallowClick);
if (!el.dataset.elapsed) return true;
e.preventDefault();
e.stopPropagation();
return false;
};

const complete = () => {
if (vnode.componentInstance) vnode.componentInstance.$emit('long-press');
else el.dispatchEvent(longPressEvent);
el.dataset.elapsed = true;
};

const onPointerUp = () => {
clearTimeout(parseInt(el.dataset.longPressTimeout, 10));
document.removeEventListener('pointerup', onPointerUp);
};

const onPointerDown = () => {
document.addEventListener('pointerup', onPointerUp);
el.addEventListener('click', swallowClick);
const timeoutDuration = binding.value || LONG_PRESS_DEFAULT_DELAY;
const timeout = setTimeout(complete, timeoutDuration);
el.dataset.elapsed = false;
el.dataset.longPressTimeout = timeout;
};

el.$longPressHandler = onPointerDown;
el.addEventListener('pointerdown', onPointerDown);
},
unbind(el) {
clearTimeout(parseInt(el.dataset.longPressTimeout, 10));
el.removeEventListener('pointerdown', el.$longPressHandler);
},
};

0 comments on commit d077b1b

Please sign in to comment.