@kiwicom/orbit-components
Version:
Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.
65 lines (60 loc) • 2.89 kB
JavaScript
import { useCallback, useEffect, useState } from "react";
import { SWIPE_DISMISS_DELAY } from "../consts";
export default function useSwipeToDismiss(ref, onDismiss, distanceBeforeDismiss, direction) {
const node = ref.current;
const [removing, setRemoving] = useState(false);
const [pressedPosition, setPressedPosition] = useState(false);
const [positionLeft, setPositionLeft] = useState(0);
const [opacity, setOpacity] = useState(1);
const remove = useCallback(() => {
setTimeout(() => {
onDismiss();
}, SWIPE_DISMISS_DELAY);
}, [onDismiss]);
const onMouseUp = useCallback(() => {
if (!removing) {
setPressedPosition(false);
setPositionLeft(0);
setOpacity(1);
}
}, [removing]);
const onMouseMove = useCallback(ev => {
if (removing) return;
if (pressedPosition && node) {
let newPositionLeft = ev.screenX - pressedPosition;
const directionValue = direction === "right" ? 1 : -1;
if (direction === "right" && newPositionLeft >= node.offsetWidth * distanceBeforeDismiss / 100 || direction === "left" && newPositionLeft * directionValue >= node.offsetWidth * distanceBeforeDismiss / 100) {
newPositionLeft += node.offsetWidth * directionValue;
setRemoving(true);
remove();
} else if (direction === "right") {
newPositionLeft = newPositionLeft < 0 ? 0 : newPositionLeft;
} else {
newPositionLeft = newPositionLeft > 0 ? 0 : newPositionLeft;
}
setPositionLeft(newPositionLeft);
setOpacity((100 - newPositionLeft * directionValue * 100 / (node.offsetWidth * 2)) / 100);
}
}, [removing, pressedPosition, direction, distanceBeforeDismiss, node, remove]);
const onMouseDown = useCallback(ev => setPressedPosition(ev.screenX), [setPressedPosition]);
useEffect(() => {
if (!node) setOpacity(1.1);else node.addEventListener("mousedown", onMouseDown);
return () => {
if (node) node.removeEventListener("mousedown", onMouseDown);
};
}, [node, onMouseDown, setOpacity]);
useEffect(() => {
var _document$body, _document$body2;
(_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.addEventListener("mouseup", onMouseUp);
(_document$body2 = document.body) === null || _document$body2 === void 0 ? void 0 : _document$body2.addEventListener("mousemove", onMouseMove);
return () => {
var _document$body3, _document$body4;
(_document$body3 = document.body) === null || _document$body3 === void 0 ? void 0 : _document$body3.removeEventListener("mouseup", onMouseUp);
(_document$body4 = document.body) === null || _document$body4 === void 0 ? void 0 : _document$body4.removeEventListener("mousemove", onMouseMove);
};
}, [onMouseUp, onMouseDown, onMouseMove]);
return {
swipeOffset: positionLeft,
swipeOpacity: opacity
};
}