@tamagui/floating 2.7.7 → 3.0.0-beta.637.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/cjs/Floating.cjs +10 -11
  2. package/dist/cjs/Floating.native.cjs +37 -0
  3. package/dist/cjs/Floating.native.js +20 -20
  4. package/dist/cjs/Floating.native.js.map +1 -1
  5. package/dist/cjs/index.cjs +45 -46
  6. package/dist/cjs/index.native.cjs +74 -0
  7. package/dist/cjs/index.native.js +45 -45
  8. package/dist/cjs/index.native.js.map +1 -1
  9. package/dist/cjs/interactions/PopupTriggerMap.cjs +36 -39
  10. package/dist/cjs/interactions/PopupTriggerMap.native.cjs +96 -0
  11. package/dist/cjs/interactions/PopupTriggerMap.native.js +76 -75
  12. package/dist/cjs/interactions/PopupTriggerMap.native.js.map +1 -1
  13. package/dist/cjs/interactions/createFloatingEvents.cjs +36 -39
  14. package/dist/cjs/interactions/createFloatingEvents.native.cjs +52 -0
  15. package/dist/cjs/interactions/createFloatingEvents.native.js +39 -41
  16. package/dist/cjs/interactions/createFloatingEvents.native.js.map +1 -1
  17. package/dist/cjs/interactions/safePolygon.cjs +263 -252
  18. package/dist/cjs/interactions/safePolygon.native.cjs +294 -0
  19. package/dist/cjs/interactions/safePolygon.native.js +271 -259
  20. package/dist/cjs/interactions/safePolygon.native.js.map +1 -1
  21. package/dist/cjs/interactions/types.cjs +10 -11
  22. package/dist/cjs/interactions/types.native.cjs +19 -0
  23. package/dist/cjs/interactions/types.native.js +10 -10
  24. package/dist/cjs/interactions/types.native.js.map +1 -1
  25. package/dist/cjs/interactions/useClick.cjs +96 -105
  26. package/dist/cjs/interactions/useClick.native.cjs +122 -0
  27. package/dist/cjs/interactions/useClick.native.js +101 -109
  28. package/dist/cjs/interactions/useClick.native.js.map +1 -1
  29. package/dist/cjs/interactions/useDelayGroup.cjs +86 -91
  30. package/dist/cjs/interactions/useDelayGroup.native.cjs +119 -0
  31. package/dist/cjs/interactions/useDelayGroup.native.js +92 -96
  32. package/dist/cjs/interactions/useDelayGroup.native.js.map +1 -1
  33. package/dist/cjs/interactions/useFocus.cjs +108 -115
  34. package/dist/cjs/interactions/useFocus.native.cjs +131 -0
  35. package/dist/cjs/interactions/useFocus.native.js +114 -120
  36. package/dist/cjs/interactions/useFocus.native.js.map +1 -1
  37. package/dist/cjs/interactions/useHover.cjs +321 -335
  38. package/dist/cjs/interactions/useHover.native.cjs +357 -0
  39. package/dist/cjs/interactions/useHover.native.js +333 -347
  40. package/dist/cjs/interactions/useHover.native.js.map +1 -1
  41. package/dist/cjs/interactions/useInnerOffset.cjs +103 -111
  42. package/dist/cjs/interactions/useInnerOffset.native.cjs +132 -0
  43. package/dist/cjs/interactions/useInnerOffset.native.js +113 -120
  44. package/dist/cjs/interactions/useInnerOffset.native.js.map +1 -1
  45. package/dist/cjs/interactions/useInteractions.cjs +85 -90
  46. package/dist/cjs/interactions/useInteractions.native.cjs +199 -0
  47. package/dist/cjs/interactions/useInteractions.native.js +180 -195
  48. package/dist/cjs/interactions/useInteractions.native.js.map +1 -1
  49. package/dist/cjs/interactions/useListNavigation.cjs +404 -390
  50. package/dist/cjs/interactions/useListNavigation.native.cjs +446 -0
  51. package/dist/cjs/interactions/useListNavigation.native.js +416 -401
  52. package/dist/cjs/interactions/useListNavigation.native.js.map +1 -1
  53. package/dist/cjs/interactions/useRole.cjs +92 -106
  54. package/dist/cjs/interactions/useRole.native.cjs +121 -0
  55. package/dist/cjs/interactions/useRole.native.js +103 -116
  56. package/dist/cjs/interactions/useRole.native.js.map +1 -1
  57. package/dist/cjs/interactions/useTypeahead.cjs +115 -129
  58. package/dist/cjs/interactions/useTypeahead.native.cjs +144 -0
  59. package/dist/cjs/interactions/useTypeahead.native.js +128 -141
  60. package/dist/cjs/interactions/useTypeahead.native.js.map +1 -1
  61. package/dist/cjs/interactions/utils.cjs +126 -143
  62. package/dist/cjs/interactions/utils.native.cjs +209 -0
  63. package/dist/cjs/interactions/utils.native.js +138 -154
  64. package/dist/cjs/interactions/utils.native.js.map +1 -1
  65. package/dist/cjs/middleware/inner.cjs +74 -101
  66. package/dist/cjs/middleware/inner.native.cjs +102 -0
  67. package/dist/cjs/middleware/inner.native.js +83 -109
  68. package/dist/cjs/middleware/inner.native.js.map +1 -1
  69. package/dist/cjs/useFloating.cjs +34 -46
  70. package/dist/cjs/useFloating.native.cjs +56 -0
  71. package/dist/cjs/useFloating.native.js +37 -48
  72. package/dist/cjs/useFloating.native.js.map +1 -1
  73. package/dist/esm/Floating.mjs +1 -2
  74. package/dist/esm/Floating.native.js +6 -4
  75. package/dist/esm/Floating.native.js.map +1 -1
  76. package/dist/esm/index.js +4 -5
  77. package/dist/esm/index.mjs +4 -5
  78. package/dist/esm/index.native.js +4 -5
  79. package/dist/esm/interactions/PopupTriggerMap.mjs +23 -22
  80. package/dist/esm/interactions/PopupTriggerMap.mjs.map +1 -1
  81. package/dist/esm/interactions/PopupTriggerMap.native.js +62 -58
  82. package/dist/esm/interactions/PopupTriggerMap.native.js.map +1 -1
  83. package/dist/esm/interactions/createFloatingEvents.mjs +22 -21
  84. package/dist/esm/interactions/createFloatingEvents.mjs.map +1 -1
  85. package/dist/esm/interactions/createFloatingEvents.native.js +25 -24
  86. package/dist/esm/interactions/createFloatingEvents.native.js.map +1 -1
  87. package/dist/esm/interactions/safePolygon.mjs +250 -234
  88. package/dist/esm/interactions/safePolygon.mjs.map +1 -1
  89. package/dist/esm/interactions/safePolygon.native.js +258 -242
  90. package/dist/esm/interactions/safePolygon.native.js.map +1 -1
  91. package/dist/esm/interactions/types.mjs +0 -2
  92. package/dist/esm/interactions/types.native.js +0 -2
  93. package/dist/esm/interactions/useClick.mjs +83 -87
  94. package/dist/esm/interactions/useClick.mjs.map +1 -1
  95. package/dist/esm/interactions/useClick.native.js +88 -92
  96. package/dist/esm/interactions/useClick.native.js.map +1 -1
  97. package/dist/esm/interactions/useDelayGroup.mjs +68 -65
  98. package/dist/esm/interactions/useDelayGroup.mjs.map +1 -1
  99. package/dist/esm/interactions/useDelayGroup.native.js +74 -71
  100. package/dist/esm/interactions/useDelayGroup.native.js.map +1 -1
  101. package/dist/esm/interactions/useFocus.mjs +95 -97
  102. package/dist/esm/interactions/useFocus.mjs.map +1 -1
  103. package/dist/esm/interactions/useFocus.native.js +101 -103
  104. package/dist/esm/interactions/useFocus.native.js.map +1 -1
  105. package/dist/esm/interactions/useHover.mjs +304 -310
  106. package/dist/esm/interactions/useHover.mjs.map +1 -1
  107. package/dist/esm/interactions/useHover.native.js +316 -323
  108. package/dist/esm/interactions/useHover.native.js.map +1 -1
  109. package/dist/esm/interactions/useInnerOffset.mjs +87 -85
  110. package/dist/esm/interactions/useInnerOffset.mjs.map +1 -1
  111. package/dist/esm/interactions/useInnerOffset.native.js +97 -95
  112. package/dist/esm/interactions/useInnerOffset.native.js.map +1 -1
  113. package/dist/esm/interactions/useInteractions.mjs +71 -72
  114. package/dist/esm/interactions/useInteractions.mjs.map +1 -1
  115. package/dist/esm/interactions/useInteractions.native.js +166 -178
  116. package/dist/esm/interactions/useInteractions.native.js.map +1 -1
  117. package/dist/esm/interactions/useListNavigation.mjs +392 -373
  118. package/dist/esm/interactions/useListNavigation.mjs.map +1 -1
  119. package/dist/esm/interactions/useListNavigation.native.js +404 -385
  120. package/dist/esm/interactions/useListNavigation.native.js.map +1 -1
  121. package/dist/esm/interactions/useRole.mjs +76 -80
  122. package/dist/esm/interactions/useRole.mjs.map +1 -1
  123. package/dist/esm/interactions/useRole.native.js +87 -91
  124. package/dist/esm/interactions/useRole.native.js.map +1 -1
  125. package/dist/esm/interactions/useTypeahead.mjs +102 -111
  126. package/dist/esm/interactions/useTypeahead.mjs.map +1 -1
  127. package/dist/esm/interactions/useTypeahead.native.js +115 -124
  128. package/dist/esm/interactions/useTypeahead.native.js.map +1 -1
  129. package/dist/esm/interactions/utils.mjs +91 -106
  130. package/dist/esm/interactions/utils.mjs.map +1 -1
  131. package/dist/esm/interactions/utils.native.js +103 -118
  132. package/dist/esm/interactions/utils.native.js.map +1 -1
  133. package/dist/esm/middleware/inner.mjs +58 -75
  134. package/dist/esm/middleware/inner.mjs.map +1 -1
  135. package/dist/esm/middleware/inner.native.js +67 -84
  136. package/dist/esm/middleware/inner.native.js.map +1 -1
  137. package/dist/esm/useFloating.mjs +17 -21
  138. package/dist/esm/useFloating.mjs.map +1 -1
  139. package/dist/esm/useFloating.native.js +19 -23
  140. package/dist/esm/useFloating.native.js.map +1 -1
  141. package/package.json +6 -5
  142. package/types/interactions/PopupTriggerMap.d.ts.map +1 -1
  143. package/types/interactions/useInteractions.d.ts.map +1 -1
  144. package/types/middleware/inner.d.ts.map +1 -1
  145. package/types/useFloating.d.ts.map +1 -1
  146. package/dist/esm/Floating.mjs.map +0 -1
  147. package/dist/esm/index.js.map +0 -1
  148. package/dist/esm/index.mjs.map +0 -1
  149. package/dist/esm/index.native.js.map +0 -1
  150. package/dist/esm/interactions/types.mjs.map +0 -1
  151. package/dist/esm/interactions/types.native.js.map +0 -1
@@ -1,320 +1,314 @@
1
1
  import * as React from "react";
2
2
  import { useEvent } from "@tamagui/use-event";
3
3
  import { clearTimeoutIfSet, contains, getDocument, isElement, isMouseLikePointerType } from "./utils.mjs";
4
+
4
5
  const safePolygonIdentifier = "data-floating-ui-safe-polygon";
5
6
  function getDelay(value, prop, pointerType) {
6
- if (pointerType && !isMouseLikePointerType(pointerType)) {
7
- return 0;
8
- }
9
- if (typeof value === "number") {
10
- return value;
11
- }
12
- return value?.[prop];
7
+ if (pointerType && !isMouseLikePointerType(pointerType)) {
8
+ return 0;
9
+ }
10
+ if (typeof value === "number") {
11
+ return value;
12
+ }
13
+ return value?.[prop];
13
14
  }
14
15
  function useHover(context, props = {}) {
15
- const {
16
- open,
17
- onOpenChange,
18
- dataRef,
19
- events,
20
- elements
21
- } = context;
22
- const {
23
- enabled = true,
24
- delay = 0,
25
- handleClose = null,
26
- mouseOnly = false,
27
- restMs = 0,
28
- move = true
29
- } = props;
30
- const handleCloseRef = React.useRef(handleClose);
31
- handleCloseRef.current = handleClose;
32
- const delayRef = React.useRef(delay);
33
- delayRef.current = delay;
34
- const openRef = React.useRef(open);
35
- openRef.current = open;
36
- const restMsRef = React.useRef(restMs);
37
- restMsRef.current = restMs;
38
- const stableOnOpenChange = useEvent(onOpenChange);
39
- const pointerTypeRef = React.useRef(void 0);
40
- const timeoutRef = React.useRef(-1);
41
- const handlerRef = React.useRef(void 0);
42
- const restTimeoutRef = React.useRef(-1);
43
- const blockMouseMoveRef = React.useRef(true);
44
- const performedPointerEventsMutationRef = React.useRef(false);
45
- const unbindMouseMoveRef = React.useRef(() => {});
46
- const restTimeoutPendingRef = React.useRef(false);
47
- const isHoverOpen = useEvent(() => {
48
- const type = dataRef.current.openEvent?.type;
49
- return type?.includes("mouse") && type !== "mousedown";
50
- });
51
- React.useEffect(() => {
52
- if (!enabled) return;
53
- if (!events) return;
54
- function onOpenChange2({
55
- open: open2
56
- }) {
57
- if (!open2) {
58
- clearTimeoutIfSet(timeoutRef);
59
- clearTimeoutIfSet(restTimeoutRef);
60
- blockMouseMoveRef.current = true;
61
- restTimeoutPendingRef.current = false;
62
- }
63
- }
64
- events.on("openchange", onOpenChange2);
65
- return () => {
66
- events.off("openchange", onOpenChange2);
67
- };
68
- }, [enabled, events]);
69
- const closeWithDelay = useEvent((event, runElseBranch = true, reason = "hover") => {
70
- const closeDelay = getDelay(delayRef.current, "close", pointerTypeRef.current);
71
- if (closeDelay && !handlerRef.current) {
72
- clearTimeoutIfSet(timeoutRef);
73
- timeoutRef.current = window.setTimeout(() => stableOnOpenChange(false, event, reason), closeDelay);
74
- } else if (runElseBranch) {
75
- clearTimeoutIfSet(timeoutRef);
76
- stableOnOpenChange(false, event, reason);
77
- }
78
- });
79
- const cleanupMouseMoveHandler = useEvent(() => {
80
- unbindMouseMoveRef.current();
81
- handlerRef.current = void 0;
82
- if (context.handleCloseActiveRef) {
83
- context.handleCloseActiveRef.current = false;
84
- }
85
- });
86
- const clearPointerEvents = useEvent(() => {
87
- if (performedPointerEventsMutationRef.current) {
88
- const body = getDocument(elements.floating).body;
89
- body.style.pointerEvents = "";
90
- body.removeAttribute(safePolygonIdentifier);
91
- performedPointerEventsMutationRef.current = false;
92
- }
93
- });
94
- const isClickLikeOpenEvent = useEvent(() => {
95
- return dataRef.current.openEvent ? ["click", "mousedown"].includes(dataRef.current.openEvent.type) : false;
96
- });
97
- React.useEffect(() => {
98
- if (!enabled) return;
99
- function onReferenceMouseEnter(event) {
100
- clearTimeoutIfSet(timeoutRef);
101
- blockMouseMoveRef.current = false;
102
- if (mouseOnly && !isMouseLikePointerType(pointerTypeRef.current) || restMsRef.current > 0 && !getDelay(delayRef.current, "open")) {
103
- return;
104
- }
105
- const openDelay = getDelay(delayRef.current, "open", pointerTypeRef.current);
106
- if (openDelay) {
107
- timeoutRef.current = window.setTimeout(() => {
108
- if (!openRef.current) {
109
- stableOnOpenChange(true, event, "hover");
110
- }
111
- }, openDelay);
112
- } else if (!open) {
113
- stableOnOpenChange(true, event, "hover");
114
- }
115
- }
116
- function onReferenceMouseLeave(event) {
117
- if (isClickLikeOpenEvent()) {
118
- clearPointerEvents();
119
- return;
120
- }
121
- if (context.triggerElements?.hasElement(event.relatedTarget)) {
122
- return;
123
- }
124
- unbindMouseMoveRef.current();
125
- const doc = getDocument(elements.floating);
126
- clearTimeoutIfSet(restTimeoutRef);
127
- restTimeoutPendingRef.current = false;
128
- if (handleCloseRef.current) {
129
- if (!open) {
130
- clearTimeoutIfSet(timeoutRef);
131
- }
132
- const placement = dataRef.current.placement || "bottom";
133
- const reference2 = elements.domReference;
134
- const floating = elements.floating;
135
- if (!reference2 || !floating) return;
136
- handlerRef.current = handleCloseRef.current({
137
- x: event.clientX,
138
- y: event.clientY,
139
- placement,
140
- elements: {
141
- reference: reference2,
142
- floating,
143
- domReference: reference2
144
- },
145
- onClose() {
146
- if (context.handleCloseActiveRef) {
147
- context.handleCloseActiveRef.current = false;
148
- }
149
- clearPointerEvents();
150
- cleanupMouseMoveHandler();
151
- if (!isClickLikeOpenEvent()) {
152
- closeWithDelay(event, true, "safe-polygon");
153
- }
154
- }
155
- });
156
- if (context.handleCloseActiveRef) {
157
- context.handleCloseActiveRef.current = true;
158
- }
159
- const handler = handlerRef.current;
160
- doc.addEventListener("mousemove", handler);
161
- unbindMouseMoveRef.current = () => {
162
- doc.removeEventListener("mousemove", handler);
163
- };
164
- return;
165
- }
166
- const shouldClose = pointerTypeRef.current === "touch" ? !contains(elements.floating, event.relatedTarget) : true;
167
- if (shouldClose) {
168
- closeWithDelay(event);
169
- }
170
- }
171
- function onScrollMouseLeave(event) {
172
- if (isClickLikeOpenEvent()) return;
173
- if (context.triggerElements?.hasElement(event.relatedTarget)) {
174
- return;
175
- }
176
- const placement = dataRef.current.placement || "bottom";
177
- const reference2 = elements.domReference;
178
- const floating = elements.floating;
179
- if (!reference2 || !floating) return;
180
- handleCloseRef.current?.({
181
- x: event.clientX,
182
- y: event.clientY,
183
- placement,
184
- elements: {
185
- reference: reference2,
186
- floating,
187
- domReference: reference2
188
- },
189
- onClose() {
190
- clearPointerEvents();
191
- cleanupMouseMoveHandler();
192
- if (!isClickLikeOpenEvent()) {
193
- closeWithDelay(event);
194
- }
195
- }
196
- })(event);
197
- }
198
- function onFloatingMouseEnter() {
199
- clearTimeoutIfSet(timeoutRef);
200
- }
201
- function onFloatingMouseLeave(event) {
202
- if (isClickLikeOpenEvent()) return;
203
- if (context.triggerElements?.hasElement(event.relatedTarget)) {
204
- return;
205
- }
206
- closeWithDelay(event, false);
207
- }
208
- if (isElement(elements.domReference)) {
209
- const reference2 = elements.domReference;
210
- const floating = elements.floating;
211
- if (open) {
212
- reference2.addEventListener("mouseleave", onScrollMouseLeave);
213
- }
214
- if (move) {
215
- reference2.addEventListener("mousemove", onReferenceMouseEnter, {
216
- once: true
217
- });
218
- }
219
- reference2.addEventListener("mouseenter", onReferenceMouseEnter);
220
- reference2.addEventListener("mouseleave", onReferenceMouseLeave);
221
- if (floating) {
222
- floating.addEventListener("mouseleave", onScrollMouseLeave);
223
- floating.addEventListener("mouseenter", onFloatingMouseEnter);
224
- floating.addEventListener("mouseleave", onFloatingMouseLeave);
225
- }
226
- return () => {
227
- if (open) {
228
- reference2.removeEventListener("mouseleave", onScrollMouseLeave);
229
- }
230
- if (move) {
231
- reference2.removeEventListener("mousemove", onReferenceMouseEnter);
232
- }
233
- reference2.removeEventListener("mouseenter", onReferenceMouseEnter);
234
- reference2.removeEventListener("mouseleave", onReferenceMouseLeave);
235
- if (floating) {
236
- floating.removeEventListener("mouseleave", onScrollMouseLeave);
237
- floating.removeEventListener("mouseenter", onFloatingMouseEnter);
238
- floating.removeEventListener("mouseleave", onFloatingMouseLeave);
239
- }
240
- cleanupMouseMoveHandler();
241
- };
242
- }
243
- }, [elements, enabled, context, mouseOnly, move, open, dataRef]);
244
- React.useLayoutEffect(() => {
245
- if (!enabled) return;
246
- if (open && handleCloseRef.current?.__options?.blockPointerEvents && isHoverOpen()) {
247
- performedPointerEventsMutationRef.current = true;
248
- const floatingEl = elements.floating;
249
- if (isElement(elements.domReference) && floatingEl) {
250
- const body = getDocument(elements.floating).body;
251
- body.setAttribute(safePolygonIdentifier, "");
252
- const ref = elements.domReference;
253
- body.style.pointerEvents = "none";
254
- ref.style.pointerEvents = "auto";
255
- floatingEl.style.pointerEvents = "auto";
256
- return () => {
257
- body.style.pointerEvents = "";
258
- ref.style.pointerEvents = "";
259
- floatingEl.style.pointerEvents = "";
260
- };
261
- }
262
- }
263
- }, [enabled, open, elements, isHoverOpen]);
264
- React.useLayoutEffect(() => {
265
- if (!open) {
266
- pointerTypeRef.current = void 0;
267
- restTimeoutPendingRef.current = false;
268
- cleanupMouseMoveHandler();
269
- clearPointerEvents();
270
- }
271
- }, [open]);
272
- React.useEffect(() => {
273
- return () => {
274
- cleanupMouseMoveHandler();
275
- clearTimeoutIfSet(timeoutRef);
276
- clearTimeoutIfSet(restTimeoutRef);
277
- clearPointerEvents();
278
- };
279
- }, [enabled, elements.domReference]);
280
- const reference = React.useMemo(() => {
281
- function setPointerRef(event) {
282
- pointerTypeRef.current = event.pointerType;
283
- }
284
- return {
285
- onPointerDown: setPointerRef,
286
- onPointerEnter: setPointerRef,
287
- onMouseMove(event) {
288
- const {
289
- nativeEvent
290
- } = event;
291
- function handleMouseMove() {
292
- if (!blockMouseMoveRef.current && !openRef.current) {
293
- stableOnOpenChange(true, nativeEvent, "hover");
294
- }
295
- }
296
- if (mouseOnly && !isMouseLikePointerType(pointerTypeRef.current)) {
297
- return;
298
- }
299
- if (open || restMsRef.current === 0) {
300
- return;
301
- }
302
- if (restTimeoutPendingRef.current && event.movementX ** 2 + event.movementY ** 2 < 2) {
303
- return;
304
- }
305
- clearTimeoutIfSet(restTimeoutRef);
306
- if (pointerTypeRef.current === "touch") {
307
- handleMouseMove();
308
- } else {
309
- restTimeoutPendingRef.current = true;
310
- restTimeoutRef.current = window.setTimeout(handleMouseMove, restMsRef.current);
311
- }
312
- }
313
- };
314
- }, [mouseOnly, open]);
315
- return React.useMemo(() => enabled ? {
316
- reference
317
- } : {}, [enabled, reference]);
16
+ const { open, onOpenChange, dataRef, events, elements } = context;
17
+ const { enabled = true, delay = 0, handleClose = null, mouseOnly = false, restMs = 0, move = true } = props;
18
+ const handleCloseRef = React.useRef(handleClose);
19
+ handleCloseRef.current = handleClose;
20
+ const delayRef = React.useRef(delay);
21
+ delayRef.current = delay;
22
+ const openRef = React.useRef(open);
23
+ openRef.current = open;
24
+ const restMsRef = React.useRef(restMs);
25
+ restMsRef.current = restMs;
26
+ const stableOnOpenChange = useEvent(onOpenChange);
27
+ const pointerTypeRef = React.useRef(void 0);
28
+ const timeoutRef = React.useRef(-1);
29
+ const handlerRef = React.useRef(void 0);
30
+ const restTimeoutRef = React.useRef(-1);
31
+ const blockMouseMoveRef = React.useRef(true);
32
+ const performedPointerEventsMutationRef = React.useRef(false);
33
+ const unbindMouseMoveRef = React.useRef(() => {});
34
+ const restTimeoutPendingRef = React.useRef(false);
35
+ const isHoverOpen = useEvent(() => {
36
+ const type = dataRef.current.openEvent?.type;
37
+ return type?.includes("mouse") && type !== "mousedown";
38
+ });
39
+ React.useEffect(() => {
40
+ if (!enabled) return;
41
+ if (!events) return;
42
+ function onOpenChange2({ open: open2 }) {
43
+ if (!open2) {
44
+ clearTimeoutIfSet(timeoutRef);
45
+ clearTimeoutIfSet(restTimeoutRef);
46
+ blockMouseMoveRef.current = true;
47
+ restTimeoutPendingRef.current = false;
48
+ }
49
+ }
50
+ events.on("openchange", onOpenChange2);
51
+ return () => {
52
+ events.off("openchange", onOpenChange2);
53
+ };
54
+ }, [enabled, events]);
55
+ const closeWithDelay = useEvent((event, runElseBranch = true, reason = "hover") => {
56
+ const closeDelay = getDelay(delayRef.current, "close", pointerTypeRef.current);
57
+ if (closeDelay && !handlerRef.current) {
58
+ clearTimeoutIfSet(timeoutRef);
59
+ timeoutRef.current = window.setTimeout(() => stableOnOpenChange(false, event, reason), closeDelay);
60
+ } else if (runElseBranch) {
61
+ clearTimeoutIfSet(timeoutRef);
62
+ stableOnOpenChange(false, event, reason);
63
+ }
64
+ });
65
+ const cleanupMouseMoveHandler = useEvent(() => {
66
+ unbindMouseMoveRef.current();
67
+ handlerRef.current = void 0;
68
+ if (context.handleCloseActiveRef) {
69
+ context.handleCloseActiveRef.current = false;
70
+ }
71
+ });
72
+ const clearPointerEvents = useEvent(() => {
73
+ if (performedPointerEventsMutationRef.current) {
74
+ const body = getDocument(elements.floating).body;
75
+ body.style.pointerEvents = "";
76
+ body.removeAttribute(safePolygonIdentifier);
77
+ performedPointerEventsMutationRef.current = false;
78
+ }
79
+ });
80
+ const isClickLikeOpenEvent = useEvent(() => {
81
+ return dataRef.current.openEvent ? ["click", "mousedown"].includes(dataRef.current.openEvent.type) : false;
82
+ });
83
+ React.useEffect(() => {
84
+ if (!enabled) return;
85
+ function onReferenceMouseEnter(event) {
86
+ clearTimeoutIfSet(timeoutRef);
87
+ blockMouseMoveRef.current = false;
88
+ if (mouseOnly && !isMouseLikePointerType(pointerTypeRef.current) || restMsRef.current > 0 && !getDelay(delayRef.current, "open")) {
89
+ return;
90
+ }
91
+ const openDelay = getDelay(delayRef.current, "open", pointerTypeRef.current);
92
+ if (openDelay) {
93
+ timeoutRef.current = window.setTimeout(() => {
94
+ if (!openRef.current) {
95
+ stableOnOpenChange(true, event, "hover");
96
+ }
97
+ }, openDelay);
98
+ } else if (!open) {
99
+ stableOnOpenChange(true, event, "hover");
100
+ }
101
+ }
102
+ function onReferenceMouseLeave(event) {
103
+ if (isClickLikeOpenEvent()) {
104
+ clearPointerEvents();
105
+ return;
106
+ }
107
+ if (context.triggerElements?.hasElement(event.relatedTarget)) {
108
+ return;
109
+ }
110
+ unbindMouseMoveRef.current();
111
+ const doc = getDocument(elements.floating);
112
+ clearTimeoutIfSet(restTimeoutRef);
113
+ restTimeoutPendingRef.current = false;
114
+ if (handleCloseRef.current) {
115
+ if (!open) {
116
+ clearTimeoutIfSet(timeoutRef);
117
+ }
118
+ const placement = dataRef.current.placement || "bottom";
119
+ const reference2 = elements.domReference;
120
+ const floating = elements.floating;
121
+ if (!reference2 || !floating) return;
122
+ handlerRef.current = handleCloseRef.current({
123
+ x: event.clientX,
124
+ y: event.clientY,
125
+ placement,
126
+ elements: {
127
+ reference: reference2,
128
+ floating,
129
+ domReference: reference2
130
+ },
131
+ onClose() {
132
+ if (context.handleCloseActiveRef) {
133
+ context.handleCloseActiveRef.current = false;
134
+ }
135
+ clearPointerEvents();
136
+ cleanupMouseMoveHandler();
137
+ if (!isClickLikeOpenEvent()) {
138
+ closeWithDelay(event, true, "safe-polygon");
139
+ }
140
+ }
141
+ });
142
+ if (context.handleCloseActiveRef) {
143
+ context.handleCloseActiveRef.current = true;
144
+ }
145
+ const handler = handlerRef.current;
146
+ doc.addEventListener("mousemove", handler);
147
+ unbindMouseMoveRef.current = () => {
148
+ doc.removeEventListener("mousemove", handler);
149
+ };
150
+ return;
151
+ }
152
+ const shouldClose = pointerTypeRef.current === "touch" ? !contains(elements.floating, event.relatedTarget) : true;
153
+ if (shouldClose) {
154
+ closeWithDelay(event);
155
+ }
156
+ }
157
+ function onScrollMouseLeave(event) {
158
+ if (isClickLikeOpenEvent()) return;
159
+ if (context.triggerElements?.hasElement(event.relatedTarget)) {
160
+ return;
161
+ }
162
+ const placement = dataRef.current.placement || "bottom";
163
+ const reference2 = elements.domReference;
164
+ const floating = elements.floating;
165
+ if (!reference2 || !floating) return;
166
+ handleCloseRef.current?.({
167
+ x: event.clientX,
168
+ y: event.clientY,
169
+ placement,
170
+ elements: {
171
+ reference: reference2,
172
+ floating,
173
+ domReference: reference2
174
+ },
175
+ onClose() {
176
+ clearPointerEvents();
177
+ cleanupMouseMoveHandler();
178
+ if (!isClickLikeOpenEvent()) {
179
+ closeWithDelay(event);
180
+ }
181
+ }
182
+ })(event);
183
+ }
184
+ function onFloatingMouseEnter() {
185
+ clearTimeoutIfSet(timeoutRef);
186
+ }
187
+ function onFloatingMouseLeave(event) {
188
+ if (isClickLikeOpenEvent()) return;
189
+ if (context.triggerElements?.hasElement(event.relatedTarget)) {
190
+ return;
191
+ }
192
+ closeWithDelay(event, false);
193
+ }
194
+ if (isElement(elements.domReference)) {
195
+ const reference2 = elements.domReference;
196
+ const floating = elements.floating;
197
+ if (open) {
198
+ reference2.addEventListener("mouseleave", onScrollMouseLeave);
199
+ }
200
+ if (move) {
201
+ reference2.addEventListener("mousemove", onReferenceMouseEnter, { once: true });
202
+ }
203
+ reference2.addEventListener("mouseenter", onReferenceMouseEnter);
204
+ reference2.addEventListener("mouseleave", onReferenceMouseLeave);
205
+ if (floating) {
206
+ floating.addEventListener("mouseleave", onScrollMouseLeave);
207
+ floating.addEventListener("mouseenter", onFloatingMouseEnter);
208
+ floating.addEventListener("mouseleave", onFloatingMouseLeave);
209
+ }
210
+ return () => {
211
+ if (open) {
212
+ reference2.removeEventListener("mouseleave", onScrollMouseLeave);
213
+ }
214
+ if (move) {
215
+ reference2.removeEventListener("mousemove", onReferenceMouseEnter);
216
+ }
217
+ reference2.removeEventListener("mouseenter", onReferenceMouseEnter);
218
+ reference2.removeEventListener("mouseleave", onReferenceMouseLeave);
219
+ if (floating) {
220
+ floating.removeEventListener("mouseleave", onScrollMouseLeave);
221
+ floating.removeEventListener("mouseenter", onFloatingMouseEnter);
222
+ floating.removeEventListener("mouseleave", onFloatingMouseLeave);
223
+ }
224
+ cleanupMouseMoveHandler();
225
+ };
226
+ }
227
+ }, [
228
+ elements,
229
+ enabled,
230
+ context,
231
+ mouseOnly,
232
+ move,
233
+ open,
234
+ dataRef
235
+ ]);
236
+ React.useLayoutEffect(() => {
237
+ if (!enabled) return;
238
+ if (open && handleCloseRef.current?.__options?.blockPointerEvents && isHoverOpen()) {
239
+ performedPointerEventsMutationRef.current = true;
240
+ const floatingEl = elements.floating;
241
+ if (isElement(elements.domReference) && floatingEl) {
242
+ const body = getDocument(elements.floating).body;
243
+ body.setAttribute(safePolygonIdentifier, "");
244
+ const ref = elements.domReference;
245
+ body.style.pointerEvents = "none";
246
+ ref.style.pointerEvents = "auto";
247
+ floatingEl.style.pointerEvents = "auto";
248
+ return () => {
249
+ body.style.pointerEvents = "";
250
+ ref.style.pointerEvents = "";
251
+ floatingEl.style.pointerEvents = "";
252
+ };
253
+ }
254
+ }
255
+ }, [
256
+ enabled,
257
+ open,
258
+ elements,
259
+ isHoverOpen
260
+ ]);
261
+ React.useLayoutEffect(() => {
262
+ if (!open) {
263
+ pointerTypeRef.current = void 0;
264
+ restTimeoutPendingRef.current = false;
265
+ cleanupMouseMoveHandler();
266
+ clearPointerEvents();
267
+ }
268
+ }, [open]);
269
+ React.useEffect(() => {
270
+ return () => {
271
+ cleanupMouseMoveHandler();
272
+ clearTimeoutIfSet(timeoutRef);
273
+ clearTimeoutIfSet(restTimeoutRef);
274
+ clearPointerEvents();
275
+ };
276
+ }, [enabled, elements.domReference]);
277
+ const reference = React.useMemo(() => {
278
+ function setPointerRef(event) {
279
+ pointerTypeRef.current = event.pointerType;
280
+ }
281
+ return {
282
+ onPointerDown: setPointerRef,
283
+ onPointerEnter: setPointerRef,
284
+ onMouseMove(event) {
285
+ const { nativeEvent } = event;
286
+ function handleMouseMove() {
287
+ if (!blockMouseMoveRef.current && !openRef.current) {
288
+ stableOnOpenChange(true, nativeEvent, "hover");
289
+ }
290
+ }
291
+ if (mouseOnly && !isMouseLikePointerType(pointerTypeRef.current)) {
292
+ return;
293
+ }
294
+ if (open || restMsRef.current === 0) {
295
+ return;
296
+ }
297
+ if (restTimeoutPendingRef.current && event.movementX ** 2 + event.movementY ** 2 < 2) {
298
+ return;
299
+ }
300
+ clearTimeoutIfSet(restTimeoutRef);
301
+ if (pointerTypeRef.current === "touch") {
302
+ handleMouseMove();
303
+ } else {
304
+ restTimeoutPendingRef.current = true;
305
+ restTimeoutRef.current = window.setTimeout(handleMouseMove, restMsRef.current);
306
+ }
307
+ }
308
+ };
309
+ }, [mouseOnly, open]);
310
+ return React.useMemo(() => enabled ? { reference } : {}, [enabled, reference]);
318
311
  }
312
+
319
313
  export { getDelay, useHover };
320
314
  //# sourceMappingURL=useHover.mjs.map