{"version":3,"sources":["../../src/use-draggable/index.ts"],"sourcesContent":["import { useEventListener } from '../use-event-listener'\nimport { useLatest } from '../use-latest'\nimport { useSafeState } from '../use-safe-state'\nimport { useTargetElement } from '../use-target-element'\n\nimport type { CSSProperties } from 'react'\nimport type { ElementTarget, GlobalTarget } from '../use-target-element'\nimport type { PointerType, Position } from '../utils/basic'\n\nexport interface UseDraggableOptions {\n  /**\n   * Whether to drag the element only when the pointer is exactly on the target element.\n   *\n   * @defaultValue false\n   */\n  exact?: boolean\n  /**\n   * Whether to prevent the default behavior of the pointer event.\n   *\n   * @defaultValue false\n   */\n  preventDefault?: boolean\n  /**\n   * Whether to stop the propagation of the pointer event.\n   *\n   * @defaultValue false\n   */\n  stopPropagation?: boolean\n  /**\n   * Whether to capture the pointer event.\n   *\n   * @defaultValue true\n   */\n  capture?: boolean\n  /**\n   * The element that should be dragged.\n   *\n   * @defaultValue target\n   */\n  handle?: ElementTarget\n  /**\n   * The element that should be dragged.\n   *\n   * @defaultValue window\n   */\n  draggingElement?: ElementTarget | GlobalTarget\n  /**\n   * The element that should contain the draggable element.\n   *\n   * @defaultValue undefined\n   */\n  containerElement?: ElementTarget\n  /**\n   * The types of pointer events that should be handled.\n   *\n   * @defaultValue ['mouse', 'touch', 'pen']\n   */\n  pointerTypes?: PointerType[]\n  /**\n   * The initial position of the draggable element.\n   *\n   * @defaultValue { x: 0; y: 0 }\n   */\n  initialValue?: Position\n  /**\n   * The callback that is called when the dragging starts.\n   */\n  onStart?: (position: Position, event: PointerEvent) => undefined | false\n  /**\n   * The callback that is called when the dragging moves.\n   */\n  onMove?: (position: Position, event: PointerEvent) => void\n  /**\n   * The callback that is called when the dragging ends.\n   */\n  onEnd?: (position: Position, event: PointerEvent) => void\n  /**\n   * The axis that the draggable element can be moved along.\n   *\n   * @defaultValue 'both'\n   */\n  axis?: 'x' | 'y' | 'both'\n  /**\n   * Whether the draggable element is disabled.\n   *\n   * @defaultValue false\n   */\n  disabled?: boolean\n}\n\nexport interface UseDraggableReturns {\n  /**\n   * The x-coordinate of the draggable element.\n   */\n  x: number\n  /**\n   * The y-coordinate of the draggable element.\n   */\n  y: number\n  /**\n   * The style that should be applied to the draggable element.\n   */\n  style: CSSProperties\n  /**\n   * The style that should be applied to the container element if it exists.\n   */\n  containerStyle: CSSProperties\n  /**\n   * The position of the draggable element.\n   */\n  position: Position\n  /**\n   * Whether the draggable element is being dragged.\n   */\n  isDragging: boolean\n}\n\n/** @see {@link https://developer.mozilla.org/zh-CN/docs/Web/API/MouseEvent/button MDN} */\nconst MAIN_MOUSE_BUTTON_TYPE = 0\n\n/**\n * A React Hook that helps to make element draggable.\n */\nexport function useDraggable(target: ElementTarget, options: UseDraggableOptions = {}): UseDraggableReturns {\n  const {\n    exact = false,\n    preventDefault = false,\n    stopPropagation = false,\n    capture = true,\n    handle = target,\n    draggingElement = () => window,\n    containerElement,\n    pointerTypes: types = ['mouse', 'touch', 'pen'],\n    initialValue = { x: 0, y: 0 },\n    axis = 'both',\n    disabled = false,\n    onStart,\n    onMove,\n    onEnd,\n  } = options\n\n  const [delta, setDelta] = useSafeState<Position | null>(null)\n  const [position, setPosition] = useSafeState(initialValue)\n\n  const targetEl = useTargetElement(target)\n  const handleEl = useTargetElement(handle)\n  const containerEl = useTargetElement(containerElement)\n  const draggingEl = useTargetElement(draggingElement)\n\n  const latest = useLatest({\n    ...position,\n    position,\n    onStart,\n    onMove,\n    onEnd,\n    types,\n    preventDefault,\n    stopPropagation,\n    disabled,\n    exact,\n    delta,\n  })\n\n  function filterEvent(e: PointerEvent) {\n    const { types } = latest.current\n    return !types || types.includes(e.pointerType as PointerType)\n  }\n\n  function handleEvent(e: PointerEvent) {\n    const { preventDefault, stopPropagation } = latest.current\n    preventDefault && e.preventDefault()\n    stopPropagation && e.stopPropagation()\n  }\n\n  function start(e: PointerEvent) {\n    const { onStart, disabled, exact } = latest.current\n\n    if (!targetEl.current || e.button !== MAIN_MOUSE_BUTTON_TYPE || disabled || !filterEvent(e)) return\n    if (exact && e.target !== targetEl.current) return\n\n    const containerRect = containerEl.current?.getBoundingClientRect?.()\n    const targetRect = targetEl.current.getBoundingClientRect()\n\n    const pos = {\n      x:\n        e.clientX -\n        (containerEl.current && containerRect\n          ? targetRect.left - containerRect.left + containerEl.current.scrollLeft\n          : targetRect.left),\n      y:\n        e.clientY -\n        (containerEl.current && containerRect\n          ? targetRect.top - containerRect.top + containerEl.current.scrollTop\n          : targetRect.top),\n    }\n\n    if (onStart?.({ ...pos }, e) === false) return\n\n    setDelta({ ...pos })\n    handleEvent(e)\n  }\n\n  function move(e: PointerEvent) {\n    const { x, y, onMove, disabled, delta } = latest.current\n    if (!targetEl.current || disabled) return\n    if (!filterEvent(e) || !delta) return\n\n    const targetRect = targetEl.current.getBoundingClientRect()\n\n    const pos = { x, y }\n\n    if (axis === 'x' || axis === 'both') {\n      pos.x = e.clientX - delta.x\n\n      if (containerEl.current) {\n        pos.x = Math.min(Math.max(0, pos.x), containerEl.current.scrollWidth - targetRect.width)\n      }\n    }\n\n    if (axis === 'y' || axis === 'both') {\n      pos.y = e.clientY - delta.y\n\n      if (containerEl.current) {\n        pos.y = Math.min(Math.max(0, pos.y), containerEl.current.scrollHeight - targetRect.height)\n      }\n    }\n\n    setPosition({ ...pos })\n    onMove?.({ ...pos }, e)\n    handleEvent(e)\n  }\n\n  function end(e: PointerEvent) {\n    const { position, onEnd, disabled, delta } = latest.current\n\n    if (disabled || !filterEvent(e) || !delta) return\n\n    setDelta(null)\n    onEnd?.({ ...position }, e)\n    handleEvent(e)\n  }\n\n  useEventListener(handleEl, 'pointerdown', start, { capture })\n  useEventListener(draggingEl, 'pointermove', move, { capture })\n  useEventListener(draggingEl, 'pointerup', end, { capture })\n\n  return {\n    ...position,\n    style: {\n      position: containerElement ? 'absolute' : 'fixed',\n      top: position.y,\n      left: position.x,\n    } as CSSProperties,\n    containerStyle: {\n      position: 'relative',\n    } as CSSProperties,\n    position,\n    isDragging: !!delta,\n  }\n}\n"],"names":["useDraggable","MAIN_MOUSE_BUTTON_TYPE","target","options","exact","preventDefault","stopPropagation","capture","handle","draggingElement","window","containerElement","types","pointerTypes","initialValue","x","y","axis","disabled","onStart","onMove","onEnd","useSafeState","delta","setDelta","position","setPosition","targetEl","useTargetElement","handleEl","containerEl","draggingEl","latest","useLatest","filterEvent","e","current","includes","pointerType","handleEvent","start","button","containerRect","getBoundingClientRect","targetRect","pos","clientX","left","scrollLeft","clientY","top","scrollTop","move","Math","min","max","scrollWidth","width","scrollHeight","height","end","useEventListener","style","containerStyle","isDragging"],"mappings":"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"}