UNPKG

@re-flex/ui

Version:
103 lines (102 loc) 3.32 kB
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;