{"version":3,"file":"use-floating-window.cjs","names":[],"sources":["../../src/use-floating-window/use-floating-window.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\nimport { RefCallback, useCallback, useEffect, useRef, useState } from 'react';\n\nfunction useRefValue<T>(value: T) {\n  const ref = useRef(value);\n  ref.current = value;\n  return ref;\n}\n\ninterface FloatingWindowPositionConfig {\n  top?: number;\n  left?: number;\n  right?: number;\n  bottom?: number;\n}\n\ninterface FloatingWindowPosition {\n  /** Element offset from the left side of the viewport */\n  x: number;\n\n  /** Element offset from the top side of the viewport */\n  y: number;\n}\n\nexport interface UseFloatingWindowOptions {\n  /** If `false`, the element can not be dragged. */\n  enabled?: boolean;\n\n  /** If `true`, the element can only move within the current viewport boundaries. */\n  constrainToViewport?: boolean;\n\n  /** The offset from the viewport edges when constraining the element. Requires `constrainToViewport: true`. */\n  constrainOffset?: number;\n\n  /** Selector of an element that should be used to drag floating window. If not specified, the entire root element is used as a drag target. */\n  dragHandleSelector?: string;\n\n  /** Selector of an element within `dragHandleSelector` that should be excluded from the drag event. */\n  excludeDragHandleSelector?: string;\n\n  /** If set, restricts movement to the specified axis */\n  axis?: 'x' | 'y';\n\n  /** Initial position. If not set, calculated from element styles. */\n  initialPosition?: FloatingWindowPositionConfig;\n\n  /** Called when the element position changes */\n  onPositionChange?: (pos: FloatingWindowPosition) => void;\n\n  /** Called when the drag starts */\n  onDragStart?: () => void;\n\n  /** Called when the drag stops */\n  onDragEnd?: () => void;\n}\n\nexport type SetFloatingWindowPosition = (position: FloatingWindowPositionConfig) => void;\n\nexport interface UseFloatingWindowReturnValue<T extends HTMLElement> {\n  /** Ref to the element that should be draggable */\n  ref: RefCallback<T | null>;\n\n  /** Function to set the position of the element */\n  setPosition: SetFloatingWindowPosition;\n\n  /** `true` if the element is currently being dragged */\n  isDragging: boolean;\n}\n\nexport function useFloatingWindow<T extends HTMLElement>(\n  options: UseFloatingWindowOptions = {}\n): UseFloatingWindowReturnValue<T> {\n  const [element, setElement] = useState<T | null>(null);\n  const ref = useRef<T>(null);\n  const pos = useRef({ x: 0, y: 0 });\n  const offset = useRef({ x: 0, y: 0 });\n  const [isDragging, setIsDragging] = useState(false);\n  const isDraggingRef = useRef(false);\n  const initialized = useRef(false);\n  const enabledRef = useRefValue(options.enabled);\n\n  const setDragging = useCallback((value: boolean) => {\n    setIsDragging(value);\n    isDraggingRef.current = value;\n  }, []);\n\n  const assignRef = useCallback((node: T | null) => {\n    if (node) {\n      ref.current = node;\n      setElement(node);\n    } else {\n      ref.current = null;\n      setElement(null);\n    }\n  }, []);\n\n  useEffect(() => {\n    const el = ref.current;\n    if (!initialized.current && el) {\n      initialized.current = true;\n      pos.current = calculateInitialPosition(el, options);\n      el.style.left = `${pos.current.x}px`;\n      el.style.top = `${pos.current.y}px`;\n      el.style.right = 'unset';\n      el.style.bottom = 'unset';\n    }\n\n    return () => {\n      initialized.current = false;\n    };\n  }, [\n    element,\n    options.constrainOffset,\n    options.initialPosition?.top,\n    options.initialPosition?.left,\n    options.initialPosition?.right,\n    options.initialPosition?.bottom,\n    options.constrainToViewport,\n  ]);\n\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) {\n      return;\n    }\n\n    const controller = new AbortController();\n    const signal = controller.signal;\n\n    const onStart = (e: MouseEvent | TouchEvent) => {\n      if (enabledRef.current === false) {\n        return;\n      }\n\n      const point = 'touches' in e ? e.touches[0] : e;\n\n      if ('button' in e && e.button !== 0) {\n        return;\n      }\n\n      if (!getHandle(el, e.target, options)) {\n        return;\n      }\n\n      setDragging(true);\n      document.body.style.userSelect = 'none';\n      document.body.style.webkitUserSelect = 'none';\n\n      const rect = el.getBoundingClientRect();\n\n      offset.current = {\n        x: point.clientX - rect.left,\n        y: point.clientY - rect.top,\n      };\n\n      options.onDragStart?.();\n\n      document.addEventListener('mousemove', onMove, { signal });\n      document.addEventListener('mouseup', onEnd, { signal });\n      document.addEventListener('touchmove', onMove, { signal, passive: false });\n      document.addEventListener('touchend', onEnd, { signal });\n    };\n\n    const onMove = (e: MouseEvent | TouchEvent) => {\n      if (!isDraggingRef.current) {\n        return;\n      }\n\n      const point = 'touches' in e ? e.touches[0] : e;\n      e.preventDefault();\n\n      let x = point.clientX - offset.current.x;\n      let y = point.clientY - offset.current.y;\n\n      const constrained = getConstrainedPosition(el, { x, y }, options);\n      if (options.axis === 'x') {\n        x = constrained.x;\n        y = pos.current.y;\n      } else if (options.axis === 'y') {\n        x = pos.current.x;\n        y = constrained.y;\n      } else {\n        x = constrained.x;\n        y = constrained.y;\n      }\n\n      pos.current = { x, y };\n\n      if (ref.current) {\n        ref.current.style.left = `${x}px`;\n        ref.current.style.top = `${y}px`;\n      }\n\n      options.onPositionChange?.({ x, y });\n    };\n\n    const onEnd = () => {\n      if (isDraggingRef.current) {\n        setDragging(false);\n        document.body.style.userSelect = '';\n        document.body.style.webkitUserSelect = '';\n        options.onDragEnd?.();\n      }\n    };\n\n    el.addEventListener('mousedown', onStart, { signal });\n    el.addEventListener('touchstart', onStart, { signal, passive: false });\n\n    return () => {\n      controller.abort();\n    };\n  }, [\n    options.constrainToViewport,\n    options.constrainOffset,\n    options.dragHandleSelector,\n    options.axis,\n    options.onPositionChange,\n    options.onDragStart,\n    options.onDragEnd,\n    options.initialPosition?.top,\n    options.initialPosition?.left,\n    options.initialPosition?.right,\n    options.initialPosition?.bottom,\n    element,\n  ]);\n\n  useEffect(() => {\n    const el = ref.current;\n    if (!el) {\n      return;\n    }\n\n    const observer = new ResizeObserver(() => {\n      // Re-clamp current position if element size changes\n      const constrained = getConstrainedPosition(el, pos.current, options);\n      pos.current = constrained;\n      el.style.left = `${constrained.x}px`;\n      el.style.top = `${constrained.y}px`;\n    });\n\n    observer.observe(el);\n\n    return () => {\n      observer.disconnect();\n    };\n  }, [options.constrainToViewport, options.constrainOffset]);\n\n  const setPosition = useCallback(\n    (position: FloatingWindowPositionConfig) => {\n      const el = ref.current;\n      if (!el) {\n        return;\n      }\n\n      const offset = options.constrainOffset ?? 0;\n      const rect = el.getBoundingClientRect();\n\n      let x: number | undefined;\n      let y: number | undefined;\n\n      if (position.left != null) {\n        x = position.left;\n      } else if (position.right != null) {\n        x = window.innerWidth - rect.width - position.right;\n      }\n\n      if (position.top != null) {\n        y = position.top;\n      } else if (position.bottom != null) {\n        y = window.innerHeight - rect.height - position.bottom;\n      }\n\n      x = x ?? pos.current.x;\n      y = y ?? pos.current.y;\n\n      if (options.constrainToViewport) {\n        const clamped = clampToViewport(x, y, el, offset);\n        x = clamped.x;\n        y = clamped.y;\n      }\n\n      pos.current = { x, y };\n      el.style.left = `${x}px`;\n      el.style.top = `${y}px`;\n      options.onPositionChange?.({ x, y });\n    },\n    [options.constrainToViewport, options.constrainOffset, options.onPositionChange]\n  );\n\n  return {\n    ref: assignRef,\n    setPosition,\n    isDragging,\n  };\n}\n\n// -------------------------------------------------------\n// Helper functions\n// -------------------------------------------------------\n\nfunction px(v: string) {\n  return v.endsWith('px') ? parseFloat(v) : 0;\n}\n\nfunction calculateInitialPosition(\n  el: HTMLElement,\n  options: UseFloatingWindowOptions\n): { x: number; y: number } {\n  const rect = el.getBoundingClientRect();\n  const offset = options.constrainOffset ?? 0;\n  const winW = window.innerWidth;\n  const winH = window.innerHeight;\n  const style = window.getComputedStyle(el);\n  const top = options.initialPosition?.top;\n  const left = options.initialPosition?.left;\n  const right = options.initialPosition?.right;\n  const bottom = options.initialPosition?.bottom;\n\n  let x = offset;\n  let y = offset;\n\n  if (left != null) {\n    x = left;\n  } else if (right != null) {\n    x = winW - rect.width - right;\n  } else {\n    x = px(style.left) || winW - rect.width - px(style.right) || offset;\n  }\n\n  if (top != null) {\n    y = top;\n  } else if (bottom != null) {\n    y = winH - rect.height - bottom;\n  } else {\n    y = px(style.top) || winH - rect.height - px(style.bottom) || offset;\n  }\n\n  return options.constrainToViewport\n    ? clampToViewport(x, y, el, options.constrainOffset)\n    : { x, y };\n}\n\nfunction getConstrainedPosition(\n  el: HTMLElement,\n  pos: FloatingWindowPosition,\n  options: UseFloatingWindowOptions\n) {\n  if (!options.constrainToViewport || !el) {\n    return pos;\n  }\n\n  const rect = el.getBoundingClientRect();\n  const offset = options.constrainOffset ?? 0;\n  const maxX = window.innerWidth - rect.width - offset;\n  const maxY = window.innerHeight - rect.height - offset;\n\n  return {\n    x: Math.min(Math.max(offset, pos.x), maxX),\n    y: Math.min(Math.max(offset, pos.y), maxY),\n  };\n}\n\nfunction matchesExcludeSelector(target: Node, excludeSelector?: string): boolean {\n  if (!excludeSelector) {\n    return false;\n  }\n  if (!(target instanceof Element)) {\n    return false;\n  }\n\n  return Boolean(target.closest(excludeSelector));\n}\n\nfunction getHandle(\n  el: HTMLElement,\n  target: EventTarget | null,\n  options: UseFloatingWindowOptions\n): boolean {\n  if (!(target instanceof Node)) {\n    return false;\n  }\n\n  // If no drag handle selector, allow dragging from entire element\n  if (!options.dragHandleSelector) {\n    return !matchesExcludeSelector(target, options.excludeDragHandleSelector);\n  }\n\n  const handles = Array.from(el.querySelectorAll(options.dragHandleSelector));\n  return handles.some(\n    (handle) =>\n      handle.contains(target) && !matchesExcludeSelector(target, options.excludeDragHandleSelector)\n  );\n}\n\nfunction clampToViewport(\n  x: number,\n  y: number,\n  el: HTMLElement,\n  offset: number = 0\n): { x: number; y: number } {\n  const rect = el.getBoundingClientRect();\n  const maxX = window.innerWidth - rect.width - offset;\n  const maxY = window.innerHeight - rect.height - offset;\n\n  return {\n    x: Math.min(Math.max(offset, x), maxX),\n    y: Math.min(Math.max(offset, y), maxY),\n  };\n}\n\nexport namespace useFloatingWindow {\n  export type Options = UseFloatingWindowOptions;\n  export type Position = FloatingWindowPosition;\n  export type SetPosition = SetFloatingWindowPosition;\n  export type ReturnValue<T extends HTMLElement> = UseFloatingWindowReturnValue<T>;\n}\n"],"mappings":"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"}