{"version":3,"file":"use-move.cjs","names":["clamp"],"sources":["../../src/use-move/use-move.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { clamp } from '../utils';\n\nexport interface UseMovePosition {\n  x: number;\n  y: number;\n}\n\nexport function clampUseMovePosition(position: UseMovePosition) {\n  return {\n    x: clamp(position.x, 0, 1),\n    y: clamp(position.y, 0, 1),\n  };\n}\n\nexport interface UseMoveHandlers {\n  onScrubStart?: () => void;\n  onScrubEnd?: () => void;\n}\n\nexport interface UseMoveReturnValue<T extends HTMLElement = any> {\n  ref: React.RefCallback<T | null>;\n  active: boolean;\n}\n\nexport function useMove<T extends HTMLElement = any>(\n  onChange: (value: UseMovePosition) => void,\n  handlers?: UseMoveHandlers,\n  dir: 'ltr' | 'rtl' = 'ltr'\n): UseMoveReturnValue<T> {\n  const mounted = useRef<boolean>(false);\n  const isSliding = useRef(false);\n  const frame = useRef(0);\n  const cleanupRef = useRef<(() => void) | null>(null);\n  const [active, setActive] = useState(false);\n\n  useEffect(() => {\n    mounted.current = true;\n    return () => {\n      cleanupRef.current?.();\n    };\n  }, []);\n\n  const refCallback: React.RefCallback<T | null> = useCallback(\n    (node) => {\n      const onScrub = ({ x, y }: UseMovePosition) => {\n        cancelAnimationFrame(frame.current);\n\n        frame.current = requestAnimationFrame(() => {\n          if (mounted.current && node) {\n            node.style.userSelect = 'none';\n            const rect = node.getBoundingClientRect();\n\n            if (rect.width && rect.height) {\n              const _x = clamp((x - rect.left) / rect.width, 0, 1);\n              onChange({\n                x: dir === 'ltr' ? _x : 1 - _x,\n                y: clamp((y - rect.top) / rect.height, 0, 1),\n              });\n            }\n          }\n        });\n      };\n\n      const bindEvents = () => {\n        document.addEventListener('mousemove', onMouseMove);\n        document.addEventListener('mouseup', stopScrubbing);\n        document.addEventListener('touchmove', onTouchMove, { passive: false });\n        document.addEventListener('touchend', stopScrubbing);\n      };\n\n      const unbindEvents = () => {\n        document.removeEventListener('mousemove', onMouseMove);\n        document.removeEventListener('mouseup', stopScrubbing);\n        document.removeEventListener('touchmove', onTouchMove);\n        document.removeEventListener('touchend', stopScrubbing);\n      };\n\n      const startScrubbing = () => {\n        if (!isSliding.current && mounted.current) {\n          isSliding.current = true;\n          typeof handlers?.onScrubStart === 'function' && handlers.onScrubStart();\n          setActive(true);\n          bindEvents();\n        }\n      };\n\n      const stopScrubbing = () => {\n        if (isSliding.current && mounted.current) {\n          isSliding.current = false;\n          setActive(false);\n          unbindEvents();\n          setTimeout(() => {\n            typeof handlers?.onScrubEnd === 'function' && handlers.onScrubEnd();\n          }, 0);\n        }\n      };\n\n      const onMouseDown = (event: MouseEvent) => {\n        startScrubbing();\n        event.preventDefault();\n        onMouseMove(event);\n      };\n\n      const onMouseMove = (event: MouseEvent) => onScrub({ x: event.clientX, y: event.clientY });\n\n      const onTouchStart = (event: TouchEvent) => {\n        if (event.cancelable) {\n          event.preventDefault();\n        }\n\n        startScrubbing();\n        onTouchMove(event);\n      };\n\n      const onTouchMove = (event: TouchEvent) => {\n        if (event.cancelable) {\n          event.preventDefault();\n        }\n\n        onScrub({ x: event.changedTouches[0].clientX, y: event.changedTouches[0].clientY });\n      };\n\n      node?.addEventListener('mousedown', onMouseDown);\n      node?.addEventListener('touchstart', onTouchStart, { passive: false });\n\n      cleanupRef.current = () => {\n        unbindEvents();\n        cancelAnimationFrame(frame.current);\n      };\n\n      return () => {\n        if (node) {\n          node.removeEventListener('mousedown', onMouseDown);\n          node.removeEventListener('touchstart', onTouchStart);\n        }\n      };\n    },\n    [dir, onChange]\n  );\n\n  return { ref: refCallback, active };\n}\n\nexport namespace useMove {\n  export type Handlers = UseMoveHandlers;\n  export type ReturnValue<T extends HTMLElement> = UseMoveReturnValue<T>;\n}\n"],"mappings":"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"}