Files
standardnotes-app-web/packages/web/src/javascripts/Hooks/useLongPress.tsx
2023-02-08 18:23:14 +05:30

64 lines
1.9 KiB
TypeScript

import { RefObject, useCallback, useMemo, useRef } from 'react'
// According to https://reactnative.dev/docs/touchablewithoutfeedback#onlongpress
const ReactNativeLongpressDelay = 370
export const useLongPressEvent = (
elementRef: RefObject<HTMLElement>,
listener: (x: number, y: number) => void,
delay = ReactNativeLongpressDelay,
) => {
const longPressTimeout = useRef<number>()
const clearLongPressTimeout = useCallback(() => {
if (longPressTimeout.current) {
clearTimeout(longPressTimeout.current)
}
}, [])
const createLongPressTimeout = useCallback(
(event: PointerEvent) => {
clearLongPressTimeout()
longPressTimeout.current = window.setTimeout(() => {
const x = event.clientX
const y = event.clientY
listener(x, y)
}, delay)
},
[clearLongPressTimeout, delay, listener],
)
const attachEvents = useCallback(() => {
if (!elementRef.current) {
return
}
elementRef.current.addEventListener('pointerdown', createLongPressTimeout)
elementRef.current.addEventListener('pointermove', clearLongPressTimeout)
elementRef.current.addEventListener('pointercancel', clearLongPressTimeout)
elementRef.current.addEventListener('pointerup', clearLongPressTimeout)
}, [clearLongPressTimeout, createLongPressTimeout, elementRef])
const cleanupEvents = useCallback(() => {
if (!elementRef.current) {
return
}
elementRef.current.removeEventListener('pointerdown', createLongPressTimeout)
elementRef.current.removeEventListener('pointermove', clearLongPressTimeout)
elementRef.current.removeEventListener('pointercancel', clearLongPressTimeout)
elementRef.current.removeEventListener('pointerup', clearLongPressTimeout)
}, [clearLongPressTimeout, createLongPressTimeout, elementRef])
const memoizedReturn = useMemo(
() => ({
attachEvents,
cleanupEvents,
}),
[attachEvents, cleanupEvents],
)
return memoizedReturn
}