{"version":3,"sources":["../../src/use-mouse/index.ts"],"sourcesContent":["import { useRef } from 'react'\nimport { useEventListener } from '../use-event-listener'\nimport { useLatest } from '../use-latest'\nimport { usePausable } from '../use-pausable'\nimport { useSafeState } from '../use-safe-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { isDefined, isFunction } from '../utils/basic'\n\nimport type { Pausable } from '../use-pausable'\nimport type { Position } from '../utils/basic'\n\nexport type UseMouseCoordType = 'page' | 'client' | 'screen' | 'movement'\nexport type UseMouseSourceType = 'mouse' | 'touch' | null\nexport type UseMouseEventExtractor = (event: MouseEvent | Touch) => [x: number, y: number] | null | undefined\n\nexport interface UseMouseOptions {\n  /**\n   * Type of coordinates to extract from the event.\n   *\n   * @defaultValue 'page'\n   */\n  type?: UseMouseCoordType | UseMouseEventExtractor\n  /**\n   * Target element to attach the event listeners.\n   *\n   * @defaultValue window\n   */\n  target?: Window | EventTarget | null | undefined\n  /**\n   * Whether to enable touch events.\n   *\n   * @defaultValue true\n   */\n  touch?: boolean\n  /**\n   * Whether to enable scroll events.\n   *\n   * @defaultValue true\n   */\n  scroll?: boolean\n  /**\n   * Whether to reset the position when touch ends.\n   *\n   * @defaultValue false\n   */\n  resetOnTouchEnds?: boolean\n  /**\n   * Initial position.\n   *\n   * @defaultValue { x: 0, y: 0 }\n   */\n  initialValue?: Position\n  /**\n   * Whether to start to update position immediately.\n   *\n   * @defaultValue false\n   */\n  immediate?: boolean\n}\n\nconst UseMouseBuiltinExtractors: Record<UseMouseCoordType, UseMouseEventExtractor> = {\n  page: (event) => [event.pageX, event.pageY],\n  client: (event) => [event.clientX, event.clientY],\n  screen: (event) => [event.screenX, event.screenY],\n  movement: (event) => {\n    if (!isDefined(Touch)) {\n      return 'movementX' in event ? [event.movementX, event.movementY] : null\n    }\n    return event instanceof Touch ? null : [event.movementX, event.movementY]\n  },\n}\n\nexport interface UseMouseReturns extends Position, Pausable {\n  /**\n   * mouse event position.\n   */\n  position: Position\n  /**\n   * Source type of the event.\n   */\n  sourceType: UseMouseSourceType\n  /**\n   * stop the mouse event listener immediately.\n   */\n  stop(): void\n}\n\n/**\n * A React Hook that tracks mouse position.\n *\n * @param {UseMouseOptions} options - `UseMouseOptions`, options to configure the hook, see {@link UseMouseOptions}\n * @returns {UseMouseReturns} `UseMouseReturns`, see {@link UseMouseReturns}\n */\nexport function useMouse(options: UseMouseOptions = {}): UseMouseReturns {\n  const {\n    type = 'page',\n    touch = true,\n    immediate = true,\n    resetOnTouchEnds = false,\n    initialValue = { x: 0, y: 0 },\n    target = () => window,\n    scroll = true,\n  } = options\n\n  const pausable = usePausable(immediate)\n  const preMouseEventRef = useRef<MouseEvent | null>(null)\n  const [position, setPosition] = useSafeState(initialValue)\n  const [sourceType, setSourceType] = useSafeState<UseMouseSourceType>(null)\n\n  const extractor = isFunction(type) ? type : UseMouseBuiltinExtractors[type]\n\n  function mouseHandler(event: MouseEvent) {\n    const result = extractor(event)\n    preMouseEventRef.current = event\n\n    if (result && pausable.isActive()) {\n      setPosition({ x: result[0], y: result[1] })\n      setSourceType('mouse')\n    }\n  }\n\n  function touchHandler(event: TouchEvent) {\n    if (!event.touches.length) return\n    const result = extractor(event.touches[0])\n    if (result && pausable.isActive()) {\n      setPosition({ x: result[0], y: result[1] })\n      setSourceType('touch')\n    }\n  }\n\n  function scrollHandler() {\n    if (!preMouseEventRef.current) return\n\n    const position = extractor(preMouseEventRef.current)\n    const isMouseEvent = preMouseEventRef.current instanceof MouseEvent\n\n    if (isMouseEvent && position && pausable.isActive()) {\n      setPosition({ x: position[0] + window.scrollX, y: position[1] + window.scrollY })\n    }\n  }\n\n  const isTouch = touch && type !== 'movement'\n  const isScroll = scroll && type === 'page'\n  const resetOnEnds = isTouch && resetOnTouchEnds\n  const evtOptions = { passive: true }\n\n  const cleanups = useLatest([\n    useEventListener(target, ['mousemove', 'dragover'], mouseHandler, evtOptions),\n    useEventListener(target, isTouch ? ['touchstart', 'touchmove'] : [], touchHandler, evtOptions),\n    useEventListener(\n      target,\n      resetOnEnds ? 'touchend' : [],\n      () => {\n        pausable.isActive() && setPosition(initialValue)\n      },\n      evtOptions,\n    ),\n    useEventListener(() => window, isScroll ? 'scroll' : [], scrollHandler, evtOptions),\n  ])\n\n  const stop = useStableFn(() => {\n    for (const cleanup of cleanups.current) cleanup()\n  })\n\n  return {\n    ...position,\n    ...pausable,\n    position,\n    sourceType,\n    stop,\n  }\n}\n"],"names":["useMouse","UseMouseBuiltinExtractors","page","event","pageX","pageY","client","clientX","clientY","screen","screenX","screenY","movement","isDefined","Touch","movementX","movementY","options","type","touch","immediate","resetOnTouchEnds","initialValue","x","y","target","window","scroll","pausable","usePausable","preMouseEventRef","useRef","useSafeState","position","setPosition","sourceType","setSourceType","extractor","isFunction","mouseHandler","result","current","isActive","touchHandler","touches","length","scrollHandler","isMouseEvent","MouseEvent","scrollX","scrollY","isTouch","isScroll","resetOnEnds","evtOptions","passive","cleanups","useLatest","useEventListener","stop","useStableFn","cleanup"],"mappings":"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"}