create a react hook to deal with long presses on buttons
This commit is contained in:
parent
3d3412a3a6
commit
0a38b0cd27
64
src/components/hooks/useLongPress.js
Normal file
64
src/components/hooks/useLongPress.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* check for long presses of element
|
||||
* return a function that can be attacked as ref to an element
|
||||
*/
|
||||
|
||||
import { useState, useRef, useCallback } from 'react';
|
||||
|
||||
function useLongPress(shortPressCallback, longPressCallback) {
|
||||
const [pressTimeout, setPressTimeout] = useState(null);
|
||||
const btnRef = useRef();
|
||||
|
||||
const press = useCallback((event) => {
|
||||
event.preventDefault();
|
||||
setPressTimeout(setTimeout(() => {
|
||||
longPressCallback(event);
|
||||
setPressTimeout(null);
|
||||
}, 600));
|
||||
}, [longPressCallback]);
|
||||
|
||||
const release = useCallback((event) => {
|
||||
event.preventDefault();
|
||||
if (!pressTimeout) {
|
||||
// long press already occured
|
||||
return;
|
||||
}
|
||||
clearTimeout(pressTimeout);
|
||||
shortPressCallback(event);
|
||||
setPressTimeout(null);
|
||||
}, [pressTimeout, shortPressCallback]);
|
||||
|
||||
const cancel = useCallback((event) => {
|
||||
event.preventDefault();
|
||||
clearTimeout(pressTimeout);
|
||||
setPressTimeout(null);
|
||||
}, [pressTimeout]);
|
||||
|
||||
const refCallback = useCallback((node) => {
|
||||
if (!node) {
|
||||
if (btnRef.current) {
|
||||
const oldNode = btnRef.current;
|
||||
// remove event listeners, happens on detach
|
||||
oldNode.removeEventListener('mousedown', press, { passive: false });
|
||||
oldNode.removeEventListener('mouseup', release, { passive: false });
|
||||
oldNode.removeEventListener('touchstart', press, { passive: false });
|
||||
oldNode.removeEventListener('touchend', release, { passive: false });
|
||||
oldNode.removeEventListener('mouseleave', cancel, { passive: false });
|
||||
oldNode.removeEventListener('touchcancel', cancel, { passive: false });
|
||||
}
|
||||
} else {
|
||||
btnRef.current = node;
|
||||
// add event listeners
|
||||
node.addEventListener('mousedown', press, { passive: false });
|
||||
node.addEventListener('mouseup', release, { passive: false });
|
||||
node.addEventListener('touchstart', press, { passive: false });
|
||||
node.addEventListener('touchend', release, { passive: false });
|
||||
node.addEventListener('mouseleave', cancel, { passive: false });
|
||||
node.addEventListener('touchcancel', cancel, { passive: false });
|
||||
}
|
||||
}, [cancel, press, release]);
|
||||
|
||||
return refCallback;
|
||||
}
|
||||
|
||||
export default useLongPress;
|
Loading…
Reference in New Issue
Block a user