{"mappings":"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","sources":["packages/react-aria/src/tooltip/useSafeArea.ts"],"sourcesContent":["/*\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {getOwnerDocument, getOwnerWindow} from '../utils/domHelpers';\nimport {RefObject} from '@react-types/shared';\nimport {useEffect} from 'react';\nimport {useEffectEvent} from '../utils/useEffectEvent';\n\ninterface Point {\n  x: number;\n  y: number;\n}\n\ninterface SafeAreaOptions {\n  /** Ref for the trigger element. */\n  triggerRef: RefObject<Element | null>;\n  /** Ref for the overlay element. */\n  overlayRef: RefObject<Element | null>;\n  /** Whether the overlay is open. */\n  isOpen: boolean;\n  /** Whether this feature is disabled. */\n  isDisabled?: boolean;\n  /**\n   * Called on pointer move (and when the pointer leaves the document) with whether the pointer is\n   * currently within the \"safe area\" — the trigger, the overlay, or the region between them. This\n   * lets an overlay stay open while the pointer travels from the trigger to the overlay, even\n   * diagonally and regardless of placement.\n   */\n  onSafeAreaChange: (isInSafeArea: boolean) => void;\n}\n\n// A small amount of padding (in pixels) added around the trigger and overlay so the safe area is\n// slightly forgiving of sub-pixel jitter and the gap between the elements.\nconst PADDING = 8;\n\n/**\n * Tracks whether the pointer is within a \"safe area\" connecting a trigger and its overlay, so the\n * overlay can stay open while the pointer moves between them. The safe area is the union of the\n * trigger rect, the overlay rect, and the convex hull connecting the two (a polygon), which works\n * for any placement of the overlay relative to the trigger.\n */\nexport function useSafeArea(options: SafeAreaOptions): void {\n  let {triggerRef, overlayRef, isOpen, isDisabled} = options;\n  let onSafeAreaChange = useEffectEvent(options.onSafeAreaChange);\n\n  useEffect(() => {\n    let trigger = triggerRef.current;\n    if (isDisabled || !isOpen || !trigger) {\n      return;\n    }\n\n    let onPointerMove = (e: PointerEvent) => {\n      if (e.pointerType === 'touch') {\n        return;\n      }\n      let point = {x: e.clientX, y: e.clientY};\n      let triggerRect = trigger!.getBoundingClientRect();\n      let overlayRect = overlayRef.current?.getBoundingClientRect();\n      onSafeAreaChange(isPointInSafeArea(point, triggerRect, overlayRect));\n    };\n\n    // If the pointer leaves the document entirely, it is no longer in the safe area.\n    let onPointerLeave = () => onSafeAreaChange(false);\n\n    let win = getOwnerWindow(trigger);\n    let doc = getOwnerDocument(trigger);\n    win.addEventListener('pointermove', onPointerMove);\n    doc.documentElement.addEventListener('pointerleave', onPointerLeave);\n    return () => {\n      win.removeEventListener('pointermove', onPointerMove);\n      doc.documentElement.removeEventListener('pointerleave', onPointerLeave);\n    };\n  }, [isDisabled, isOpen, triggerRef, overlayRef]);\n}\n\nfunction isPointInSafeArea(point: Point, triggerRect: DOMRect, overlayRect?: DOMRect): boolean {\n  if (rectContains(triggerRect, point)) {\n    return true;\n  }\n  if (!overlayRect) {\n    return false;\n  }\n  if (rectContains(overlayRect, point)) {\n    return true;\n  }\n  // Otherwise, check whether the point is within the convex hull connecting the two rects.\n  let hull = convexHull([...rectCorners(triggerRect), ...rectCorners(overlayRect)]);\n  return hull.length >= 3 && isPointInPolygon(point, hull);\n}\n\nfunction rectContains(rect: DOMRect, point: Point): boolean {\n  return (\n    point.x >= rect.left - PADDING &&\n    point.x <= rect.right + PADDING &&\n    point.y >= rect.top - PADDING &&\n    point.y <= rect.bottom + PADDING\n  );\n}\n\nfunction rectCorners(rect: DOMRect): Point[] {\n  let left = rect.left - PADDING;\n  let right = rect.right + PADDING;\n  let top = rect.top - PADDING;\n  let bottom = rect.bottom + PADDING;\n  return [\n    {x: left, y: top},\n    {x: right, y: top},\n    {x: right, y: bottom},\n    {x: left, y: bottom}\n  ];\n}\n\n// Computes the convex hull of a set of points using the monotone chain algorithm.\nfunction convexHull(points: Point[]): Point[] {\n  let sorted = points.slice().sort((a, b) => a.x - b.x || a.y - b.y);\n  if (sorted.length < 3) {\n    return sorted;\n  }\n\n  let cross = (o: Point, a: Point, b: Point) =>\n    (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);\n\n  let lower: Point[] = [];\n  for (let p of sorted) {\n    while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {\n      lower.pop();\n    }\n    lower.push(p);\n  }\n\n  let upper: Point[] = [];\n  for (let i = sorted.length - 1; i >= 0; i--) {\n    let p = sorted[i];\n    while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {\n      upper.pop();\n    }\n    upper.push(p);\n  }\n\n  lower.pop();\n  upper.pop();\n  return lower.concat(upper);\n}\n\n// Ray casting point-in-polygon test.\nfunction isPointInPolygon(point: Point, polygon: Point[]): boolean {\n  let {x, y} = point;\n  let inside = false;\n  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n    let xi = polygon[i].x;\n    let yi = polygon[i].y;\n    let xj = polygon[j].x;\n    let yj = polygon[j].y;\n    let intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\n    if (intersect) {\n      inside = !inside;\n    }\n  }\n  return inside;\n}\n"],"names":[],"version":3,"file":"useSafeArea.mjs.map"}