Press and hold me
Is pressed done: no
Enable precise control of long-press interactions for both touch and mouse events with useLongPress.
Is pressed done: no
type LongPressEvent = TouchEvent | MouseEvent;
type LongPressOptions = {
threshold?: number;
onStart?: (event: LongPressEvent) => void;
onFinish?: (event: LongPressEvent) => void;
onCancel?: (event: LongPressEvent) => void;
};
export function useLongPress(
node: HTMLElement,
callback: (event: LongPressEvent) => void,
options: LongPressOptions = {}
) {
const { threshold = 400, onStart, onFinish, onCancel } = options;
let timerId: ReturnType<typeof setTimeout> | null = null;
let isLongPress = false;
let isPressed = false;
function isTouch(event: any): event is TouchEvent {
return typeof TouchEvent !== 'undefined'
? event instanceof TouchEvent
: 'touches' in event;
}
function isMouse(event: any): event is MouseEvent {
return typeof MouseEvent !== 'undefined'
? event instanceof MouseEvent
: 'button' in event;
}
function start(event: LongPressEvent) {
if (!isTouch(event) && !isMouse(event)) return;
onStart?.(event);
isPressed = true;
timerId = setTimeout(() => {
callback(event);
isLongPress = true;
}, threshold);
}
function cancel(event: LongPressEvent) {
if (!isTouch(event) && !isMouse(event)) return;
if (isLongPress) {
onFinish?.(event);
} else if (isPressed) {
onCancel?.(event);
}
isLongPress = false;
isPressed = false;
if (timerId !== null) {
clearTimeout(timerId);
timerId = null;
}
}
node.addEventListener('mousedown', start);
node.addEventListener('mouseup', cancel);
node.addEventListener('mouseleave', cancel);
node.addEventListener('touchstart', start);
node.addEventListener('touchend', cancel);
return {
destroy() {
node.removeEventListener('mousedown', start);
node.removeEventListener('mouseup', cancel);
node.removeEventListener('mouseleave', cancel);
node.removeEventListener('touchstart', start);
node.removeEventListener('touchend', cancel);
}
};
} <!-- javascript -->
<script lang="ts">
import { writable } from 'svelte/store';
import { useLongPress } from "@dimaslz/svelteuse";
const longPressDone = writable<boolean>(false);
function handleLongPress(event) {
console.log('Long press fired', event);
longPressDone.update(() => true);
}
</script>
<!-- html -->
<div>
<div
use:useLongPress={handleLongPress}
style="padding: 2rem; border: 1px solid;"
class={$longPressDone ? 'bg-green-900': ''}
>
Press and hold me
</div>
<p>Is pressed done: {$longPressDone ? 'yes' : 'no'}</p>
</div>