@re-flex/ui
Version:
Re-Flex ui library
103 lines (102 loc) • 3.32 kB
JavaScript
import React, { useState, useLayoutEffect } from "react";
const initialState = {
startX: 0,
startY: 0,
endX: 0,
endY: 0,
isSwiping: false,
};
const useSwipeable = ({ axis = "x", onSwipe, onSwipeEnd, }) => {
const [element, ref] = useState();
const [count, setCount] = useState(0);
let state = React.useRef({ ...initialState }).current;
const setState = (next) => {
state = Object.assign({}, state, next);
setCount(count + 1);
};
const swipeStart = (e) => {
e.preventDefault();
e.stopPropagation();
if (!element)
return;
if ("touches" in e) {
const touch = e.touches[0];
setState({
...state,
startX: touch.screenX,
startY: touch.screenY,
isSwiping: true,
});
element.addEventListener("touchmove", onSwipeHandler);
}
else {
setState({
...state,
startX: e.screenX,
startY: e.screenY,
isSwiping: true,
});
element.addEventListener("mousemove", onSwipeHandler);
}
};
const swipeEnd = (e) => {
e.preventDefault();
e.stopPropagation();
if (!element)
return;
if ("touches" in e) {
const touch = e.touches[0];
setState({
...state,
endX: touch.screenX,
endY: touch.screenY,
isSwiping: false,
});
element.removeEventListener("touchmove", onSwipeHandler);
onSwipeEnd(element, state.startX - touch.screenX, state.startY - touch.screenY);
}
else {
setState({
...state,
endX: e.screenX,
endY: e.screenY,
isSwiping: false,
});
element.removeEventListener("mousemove", onSwipeHandler);
onSwipeEnd(element, state.startX - e.screenX, state.startY - e.screenY);
}
};
const onSwipeHandler = (e) => {
e.preventDefault();
e.stopPropagation();
if (!element)
return;
if (state.startX === 0 || state.startY === 0)
return;
if ("touches" in e) {
const touch = e.touches[0];
if (onSwipe)
onSwipe(element, state.startX - touch.screenX, state.startY - touch.screenY);
}
else {
if (onSwipe)
onSwipe(element, state.startX - e.screenX, state.startY - e.screenY);
}
};
useLayoutEffect(() => {
if (!element)
return;
element.addEventListener("touchstart", swipeStart);
element.addEventListener("mousedown", swipeStart);
element.addEventListener("mouseup", swipeEnd);
element.addEventListener("touchend", swipeEnd);
return () => {
element.removeEventListener("touchstart", swipeStart);
element.removeEventListener("touchend", swipeEnd);
element.removeEventListener("mousedown", swipeStart);
element.removeEventListener("mouseup", swipeEnd);
};
}, [element]);
return [ref, element];
};
export default useSwipeable;