useDragToClose.tsx 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import React, { useCallback } from 'react'
  2. /**
  3. * Custom hook to enable closing bottom drawers by dragging down.
  4. */
  5. const useDragToClose = ({
  6. onClose,
  7. threshold = 100,
  8. }: {
  9. onClose: Function
  10. threshold?: number
  11. }) => {
  12. const [startY, setStartY] = React.useState(0)
  13. const [currentY, setCurrentY] = React.useState(0)
  14. const ref = React.useRef<HTMLDivElement>(null)
  15. const handleTouchStart = useCallback(
  16. (e: React.TouchEvent<HTMLDivElement>) => {
  17. setStartY(e.touches[0].clientY)
  18. },
  19. [setStartY]
  20. )
  21. const handleTouchMove = useCallback(
  22. (e: React.TouchEvent<HTMLDivElement>) => {
  23. setCurrentY(e.touches[0].clientY)
  24. const translateY = currentY - startY
  25. if (translateY > 0 && ref.current) {
  26. ref.current.style.transform = `translateY(${translateY}px)`
  27. }
  28. },
  29. [setCurrentY, startY, currentY]
  30. )
  31. const handleTouchEnd = useCallback(() => {
  32. if (currentY - startY > threshold) {
  33. onClose()
  34. } else if (ref.current) {
  35. ref.current.style.transform = 'translateY(0)'
  36. }
  37. setStartY(0)
  38. setCurrentY(0)
  39. }, [setStartY, setCurrentY, startY, currentY])
  40. return { ref, handleTouchStart, handleTouchMove, handleTouchEnd }
  41. }
  42. export default useDragToClose