react-edge-dock 1.0.6 → 1.0.8
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.
- package/dist/useEdgeDock.d.ts.map +1 -1
- package/dist/useEdgeDock.js +52 -26
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEdgeDock.d.ts","sourceRoot":"","sources":["../src/useEdgeDock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EAId,iBAAiB,EAIlB,MAAM,SAAS,CAAC;AAwLjB;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,cAAmB,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"useEdgeDock.d.ts","sourceRoot":"","sources":["../src/useEdgeDock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EAId,iBAAiB,EAIlB,MAAM,SAAS,CAAC;AAwLjB;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,cAAmB,GAAG,iBAAiB,CA8W1E"}
|
package/dist/useEdgeDock.js
CHANGED
|
@@ -164,6 +164,7 @@ export function useEdgeDock(config = {}) {
|
|
|
164
164
|
startPosX: 0,
|
|
165
165
|
startPosY: 0,
|
|
166
166
|
hasMoved: false,
|
|
167
|
+
popupWasOpen: false,
|
|
167
168
|
});
|
|
168
169
|
const isPopupOpen = controlledPopupOpen ?? isPopupOpenInternal;
|
|
169
170
|
// Get current state
|
|
@@ -201,6 +202,26 @@ export function useEdgeDock(config = {}) {
|
|
|
201
202
|
setPositionInternal(controlledPosition);
|
|
202
203
|
}
|
|
203
204
|
}, [controlledPosition]);
|
|
205
|
+
// Toggle popup
|
|
206
|
+
const togglePopup = useCallback(() => {
|
|
207
|
+
const newState = !isPopupOpen;
|
|
208
|
+
if (controlledPopupOpen === undefined) {
|
|
209
|
+
setIsPopupOpenInternal(newState);
|
|
210
|
+
}
|
|
211
|
+
onPopupChange?.(newState);
|
|
212
|
+
}, [isPopupOpen, controlledPopupOpen, onPopupChange]);
|
|
213
|
+
const closePopup = useCallback(() => {
|
|
214
|
+
if (controlledPopupOpen === undefined) {
|
|
215
|
+
setIsPopupOpenInternal(false);
|
|
216
|
+
}
|
|
217
|
+
onPopupChange?.(false);
|
|
218
|
+
}, [controlledPopupOpen, onPopupChange]);
|
|
219
|
+
const openPopup = useCallback(() => {
|
|
220
|
+
if (controlledPopupOpen === undefined) {
|
|
221
|
+
setIsPopupOpenInternal(true);
|
|
222
|
+
}
|
|
223
|
+
onPopupChange?.(true);
|
|
224
|
+
}, [controlledPopupOpen, onPopupChange]);
|
|
204
225
|
// Calculate popup position when it opens or button moves
|
|
205
226
|
useEffect(() => {
|
|
206
227
|
if (isPopupOpen && buttonRef.current && popupRef.current) {
|
|
@@ -211,6 +232,28 @@ export function useEdgeDock(config = {}) {
|
|
|
211
232
|
setPopupOrigin(result.origin);
|
|
212
233
|
}
|
|
213
234
|
}, [isPopupOpen, position, popupGap]);
|
|
235
|
+
// Close popup when clicking outside
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
if (!isPopupOpen || !isBrowser)
|
|
238
|
+
return;
|
|
239
|
+
const handleClickOutside = (e) => {
|
|
240
|
+
const target = e.target;
|
|
241
|
+
// Check if click is outside both button and popup
|
|
242
|
+
const isOutsideButton = buttonRef.current && !buttonRef.current.contains(target);
|
|
243
|
+
const isOutsidePopup = popupRef.current && !popupRef.current.contains(target);
|
|
244
|
+
if (isOutsideButton && isOutsidePopup) {
|
|
245
|
+
closePopup();
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
// Use setTimeout to avoid closing immediately on the same click that opened it
|
|
249
|
+
const timeoutId = setTimeout(() => {
|
|
250
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
251
|
+
}, 0);
|
|
252
|
+
return () => {
|
|
253
|
+
clearTimeout(timeoutId);
|
|
254
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
255
|
+
};
|
|
256
|
+
}, [isPopupOpen, closePopup]);
|
|
214
257
|
// Notify state changes
|
|
215
258
|
useEffect(() => {
|
|
216
259
|
if (onDockChange) {
|
|
@@ -239,26 +282,6 @@ export function useEdgeDock(config = {}) {
|
|
|
239
282
|
}
|
|
240
283
|
setPositionInternal(finalPos);
|
|
241
284
|
}, [dockMode, dockEdge, allowedEdges, edgeOffset]);
|
|
242
|
-
// Toggle popup
|
|
243
|
-
const togglePopup = useCallback(() => {
|
|
244
|
-
const newState = !isPopupOpen;
|
|
245
|
-
if (controlledPopupOpen === undefined) {
|
|
246
|
-
setIsPopupOpenInternal(newState);
|
|
247
|
-
}
|
|
248
|
-
onPopupChange?.(newState);
|
|
249
|
-
}, [isPopupOpen, controlledPopupOpen, onPopupChange]);
|
|
250
|
-
const closePopup = useCallback(() => {
|
|
251
|
-
if (controlledPopupOpen === undefined) {
|
|
252
|
-
setIsPopupOpenInternal(false);
|
|
253
|
-
}
|
|
254
|
-
onPopupChange?.(false);
|
|
255
|
-
}, [controlledPopupOpen, onPopupChange]);
|
|
256
|
-
const openPopup = useCallback(() => {
|
|
257
|
-
if (controlledPopupOpen === undefined) {
|
|
258
|
-
setIsPopupOpenInternal(true);
|
|
259
|
-
}
|
|
260
|
-
onPopupChange?.(true);
|
|
261
|
-
}, [controlledPopupOpen, onPopupChange]);
|
|
262
285
|
// Pointer down handler
|
|
263
286
|
const handlePointerDown = useCallback((e) => {
|
|
264
287
|
if (!buttonRef.current)
|
|
@@ -274,14 +297,11 @@ export function useEdgeDock(config = {}) {
|
|
|
274
297
|
startPosX: position.x,
|
|
275
298
|
startPosY: position.y,
|
|
276
299
|
hasMoved: false,
|
|
300
|
+
popupWasOpen: isPopupOpen,
|
|
277
301
|
};
|
|
278
302
|
setIsDragging(true);
|
|
279
303
|
setIsAnimating(false);
|
|
280
|
-
|
|
281
|
-
if (isPopupOpen) {
|
|
282
|
-
closePopup();
|
|
283
|
-
}
|
|
284
|
-
}, [position, isPopupOpen, closePopup]);
|
|
304
|
+
}, [position, isPopupOpen]);
|
|
285
305
|
// Pointer move handler
|
|
286
306
|
useEffect(() => {
|
|
287
307
|
const handlePointerMove = (e) => {
|
|
@@ -291,6 +311,12 @@ export function useEdgeDock(config = {}) {
|
|
|
291
311
|
const deltaY = e.clientY - dragStateRef.current.startY;
|
|
292
312
|
// Mark as moved if dragged more than 5px
|
|
293
313
|
if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) {
|
|
314
|
+
if (!dragStateRef.current.hasMoved) {
|
|
315
|
+
// First time detecting movement - close popup if it was open
|
|
316
|
+
if (dragStateRef.current.popupWasOpen) {
|
|
317
|
+
closePopup();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
294
320
|
dragStateRef.current.hasMoved = true;
|
|
295
321
|
}
|
|
296
322
|
const newPos = {
|
|
@@ -337,7 +363,7 @@ export function useEdgeDock(config = {}) {
|
|
|
337
363
|
document.removeEventListener('pointermove', handlePointerMove);
|
|
338
364
|
document.removeEventListener('pointerup', handlePointerUp);
|
|
339
365
|
};
|
|
340
|
-
}, [position, dockMode, dockEdge, animation, edgeOffset, allowedEdges]);
|
|
366
|
+
}, [position, dockMode, dockEdge, animation, edgeOffset, allowedEdges, closePopup]);
|
|
341
367
|
// Click handler (only trigger if not dragged)
|
|
342
368
|
const handleClick = useCallback((e) => {
|
|
343
369
|
if (dragStateRef.current.hasMoved) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-edge-dock",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "A zero-dependency React TypeScript library for customizable draggable edge-docked floating buttons with popup support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|