react-edge-dock 1.0.9 → 1.0.11
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/LICENSE +1 -1
- package/dist/EdgeDock.d.ts.map +1 -1
- package/dist/EdgeDock.js +2 -1
- package/dist/types.d.ts +27 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/useEdgeDock.d.ts.map +1 -1
- package/dist/useEdgeDock.js +137 -15
- package/package.json +2 -3
package/LICENSE
CHANGED
package/dist/EdgeDock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EdgeDock.d.ts","sourceRoot":"","sources":["../src/EdgeDock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"EdgeDock.d.ts","sourceRoot":"","sources":["../src/EdgeDock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,qBAwF5C"}
|
package/dist/EdgeDock.js
CHANGED
|
@@ -14,7 +14,7 @@ import { useEdgeDock } from './useEdgeDock';
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
export function EdgeDock(props) {
|
|
17
|
-
const { button, popup, className, style, dockMode, dockEdge, allowedEdges, position, animation, popupGap, edgeOffset, zIndex, onDockChange, isPopupOpen, onPopupChange, } = props;
|
|
17
|
+
const { button, popup, className, style, dockMode, dockEdge, allowedEdges, position, animation, popupGap, edgeOffset, zIndex, onDockChange, isPopupOpen, onPopupChange, draggable, } = props;
|
|
18
18
|
const { state, buttonRef, popupRef, closePopup, buttonStyles, popupStyles, buttonProps, } = useEdgeDock({
|
|
19
19
|
dockMode,
|
|
20
20
|
dockEdge,
|
|
@@ -27,6 +27,7 @@ export function EdgeDock(props) {
|
|
|
27
27
|
onDockChange,
|
|
28
28
|
isPopupOpen,
|
|
29
29
|
onPopupChange,
|
|
30
|
+
draggable,
|
|
30
31
|
});
|
|
31
32
|
// Render button content
|
|
32
33
|
const renderButton = () => {
|
package/dist/types.d.ts
CHANGED
|
@@ -62,7 +62,34 @@ export interface EdgeDockConfig {
|
|
|
62
62
|
isPopupOpen?: boolean;
|
|
63
63
|
/** Callback when popup state changes */
|
|
64
64
|
onPopupChange?: (isOpen: boolean) => void;
|
|
65
|
+
/** Whether the button is draggable. Defaults to true. */
|
|
66
|
+
draggable?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Sticky position configuration for non-draggable mode.
|
|
69
|
+
* Can be a single position, an array of positions (for responsive),
|
|
70
|
+
* or an object with named breakpoints.
|
|
71
|
+
*/
|
|
72
|
+
sticky?: StickyConfig;
|
|
65
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Sticky position coordinates.
|
|
76
|
+
* Values can be numbers (pixels) or strings (percentage/css units).
|
|
77
|
+
*/
|
|
78
|
+
export interface StickyPosition {
|
|
79
|
+
top?: number | string;
|
|
80
|
+
bottom?: number | string;
|
|
81
|
+
left?: number | string;
|
|
82
|
+
right?: number | string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sticky configuration supporting responsive breakpoints.
|
|
86
|
+
*/
|
|
87
|
+
export type StickyConfig = StickyPosition | StickyPosition[] | {
|
|
88
|
+
mobile?: StickyPosition;
|
|
89
|
+
tablet?: StickyPosition;
|
|
90
|
+
desktop?: StickyPosition;
|
|
91
|
+
largeDesktop?: StickyPosition;
|
|
92
|
+
};
|
|
66
93
|
/**
|
|
67
94
|
* Props for EdgeDock component
|
|
68
95
|
*/
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,iDAAiD;IACjD,UAAU,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC5B,oDAAoD;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,0CAA0C;IAC1C,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,kCAAkC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEdgeDock.d.ts","sourceRoot":"","sources":["../src/useEdgeDock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EAId,iBAAiB,
|
|
1
|
+
{"version":3,"file":"useEdgeDock.d.ts","sourceRoot":"","sources":["../src/useEdgeDock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EAId,iBAAiB,EAMlB,MAAM,SAAS,CAAC;AAuQjB;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,cAAmB,GAAG,iBAAiB,CAsa1E"}
|
package/dist/useEdgeDock.js
CHANGED
|
@@ -139,11 +139,81 @@ function calculatePopupPosition(buttonPos, buttonDimensions, popupDimensions, vi
|
|
|
139
139
|
origin,
|
|
140
140
|
};
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Resolve sticky position based on viewport width
|
|
144
|
+
*/
|
|
145
|
+
function resolveStickyConfig(config, viewportWidth) {
|
|
146
|
+
if (!config)
|
|
147
|
+
return undefined;
|
|
148
|
+
// Single position object
|
|
149
|
+
if ('top' in config || 'bottom' in config || 'left' in config || 'right' in config) {
|
|
150
|
+
return config;
|
|
151
|
+
}
|
|
152
|
+
// Array format: [mobile, tablet, desktop, largeDesktop]
|
|
153
|
+
if (Array.isArray(config)) {
|
|
154
|
+
if (viewportWidth < 768)
|
|
155
|
+
return config[0];
|
|
156
|
+
if (viewportWidth < 1024)
|
|
157
|
+
return config[1] ?? config[0];
|
|
158
|
+
if (viewportWidth < 1440)
|
|
159
|
+
return config[2] ?? config[1] ?? config[0];
|
|
160
|
+
return config[3] ?? config[2] ?? config[1] ?? config[0];
|
|
161
|
+
}
|
|
162
|
+
// Object format with named breakpoints
|
|
163
|
+
const breakpoints = config;
|
|
164
|
+
if (viewportWidth < 768)
|
|
165
|
+
return breakpoints.mobile;
|
|
166
|
+
if (viewportWidth < 1024)
|
|
167
|
+
return breakpoints.tablet ?? breakpoints.mobile;
|
|
168
|
+
if (viewportWidth < 1440)
|
|
169
|
+
return breakpoints.desktop ?? breakpoints.tablet ?? breakpoints.mobile;
|
|
170
|
+
return breakpoints.largeDesktop ?? breakpoints.desktop ?? breakpoints.tablet ?? breakpoints.mobile;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Calculate absolute coordinates from sticky position
|
|
174
|
+
*/
|
|
175
|
+
function calculateStickyCoordinates(stickyPos, viewport) {
|
|
176
|
+
let x = 0;
|
|
177
|
+
let y = 0;
|
|
178
|
+
// Helper to resolve value (number or percentage string)
|
|
179
|
+
const resolveVal = (val, dimension) => {
|
|
180
|
+
if (typeof val === 'number')
|
|
181
|
+
return val;
|
|
182
|
+
if (typeof val === 'string' && val.endsWith('%')) {
|
|
183
|
+
return (parseFloat(val) / 100) * dimension;
|
|
184
|
+
}
|
|
185
|
+
return parseFloat(val) || 0;
|
|
186
|
+
};
|
|
187
|
+
// Horizontal
|
|
188
|
+
if (stickyPos.left !== undefined) {
|
|
189
|
+
x = resolveVal(stickyPos.left, viewport.width);
|
|
190
|
+
}
|
|
191
|
+
else if (stickyPos.right !== undefined) {
|
|
192
|
+
x = viewport.width - resolveVal(stickyPos.right, viewport.width);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// Default to center if neither specified? Or default to checking dockMode...
|
|
196
|
+
// For sticky, let's assume if omitted, it stays current or 0.
|
|
197
|
+
// But returning 0 might jump. Let's assume left: 0 if nothing.
|
|
198
|
+
x = 0;
|
|
199
|
+
}
|
|
200
|
+
// Vertical
|
|
201
|
+
if (stickyPos.top !== undefined) {
|
|
202
|
+
y = resolveVal(stickyPos.top, viewport.height);
|
|
203
|
+
}
|
|
204
|
+
else if (stickyPos.bottom !== undefined) {
|
|
205
|
+
y = viewport.height - resolveVal(stickyPos.bottom, viewport.height);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
y = 0;
|
|
209
|
+
}
|
|
210
|
+
return { x, y };
|
|
211
|
+
}
|
|
142
212
|
/**
|
|
143
213
|
* Main hook for edge dock functionality
|
|
144
214
|
*/
|
|
145
215
|
export function useEdgeDock(config = {}) {
|
|
146
|
-
const { dockMode = 'auto', dockEdge, allowedEdges, position: controlledPosition, animation = true, popupGap = 12, edgeOffset, zIndex = 9999, onDockChange, isPopupOpen: controlledPopupOpen, onPopupChange, } = config;
|
|
216
|
+
const { dockMode = 'auto', dockEdge, allowedEdges, position: controlledPosition, animation = true, popupGap = 12, edgeOffset, zIndex = 9999, onDockChange, isPopupOpen: controlledPopupOpen, onPopupChange, draggable = true, sticky, } = config;
|
|
147
217
|
const buttonRef = useRef(null);
|
|
148
218
|
const popupRef = useRef(null);
|
|
149
219
|
const isMountedRef = useRef(false);
|
|
@@ -183,19 +253,49 @@ export function useEdgeDock(config = {}) {
|
|
|
183
253
|
const buttonDimensions = { width: buttonRect.width, height: buttonRect.height };
|
|
184
254
|
// Set initial position on client after mount
|
|
185
255
|
let initialPos = { x: viewport.width - 60, y: viewport.height - 60 };
|
|
186
|
-
|
|
187
|
-
if (
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
256
|
+
// Check for sticky config first if not draggable
|
|
257
|
+
if (!draggable && sticky) {
|
|
258
|
+
const stickyPos = resolveStickyConfig(sticky, viewport.width);
|
|
259
|
+
if (stickyPos) {
|
|
260
|
+
initialPos = calculateStickyCoordinates(stickyPos, viewport);
|
|
261
|
+
// Adjust for center origin point of the button
|
|
262
|
+
// The button is positioned with transform: translate(-50%, -50%)
|
|
263
|
+
// So if sticky says left: 20, right now x=20.
|
|
264
|
+
// However, calculateStickyCoordinates returns the exact point for left/top.
|
|
265
|
+
// If we use that directly with translate(-50%, -50%), the center of button is at that point.
|
|
266
|
+
// Usually sticky means "distance from edge to edge of element".
|
|
267
|
+
// If left: 20, we want left edge of button at 20.
|
|
268
|
+
// So center should be 20 + width/2.
|
|
269
|
+
if (stickyPos.left !== undefined) {
|
|
270
|
+
initialPos.x += buttonDimensions.width / 2;
|
|
271
|
+
}
|
|
272
|
+
else if (stickyPos.right !== undefined) {
|
|
273
|
+
initialPos.x -= buttonDimensions.width / 2;
|
|
274
|
+
}
|
|
275
|
+
if (stickyPos.top !== undefined) {
|
|
276
|
+
initialPos.y += buttonDimensions.height / 2;
|
|
277
|
+
}
|
|
278
|
+
else if (stickyPos.bottom !== undefined) {
|
|
279
|
+
initialPos.y -= buttonDimensions.height / 2;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
191
282
|
}
|
|
192
|
-
else
|
|
193
|
-
|
|
194
|
-
|
|
283
|
+
else {
|
|
284
|
+
// Normal dock logic
|
|
285
|
+
initialPos = constrainToViewport(initialPos, viewport, buttonDimensions, edgeOffset);
|
|
286
|
+
if (dockMode === 'auto') {
|
|
287
|
+
const edge = getClosestEdge(initialPos, viewport, allowedEdges);
|
|
288
|
+
initialPos = snapToEdge(initialPos, edge, viewport, buttonDimensions, edgeOffset);
|
|
289
|
+
setDockedEdge(edge);
|
|
290
|
+
}
|
|
291
|
+
else if (dockMode === 'manual' && dockEdge) {
|
|
292
|
+
initialPos = snapToEdge(initialPos, dockEdge, viewport, buttonDimensions, edgeOffset);
|
|
293
|
+
setDockedEdge(dockEdge);
|
|
294
|
+
}
|
|
195
295
|
}
|
|
196
296
|
setPositionInternal(initialPos);
|
|
197
297
|
}
|
|
198
|
-
}, [controlledPosition, dockMode, dockEdge, allowedEdges, edgeOffset]);
|
|
298
|
+
}, [controlledPosition, dockMode, dockEdge, allowedEdges, edgeOffset, draggable, sticky]);
|
|
199
299
|
// Update controlled position
|
|
200
300
|
useEffect(() => {
|
|
201
301
|
if (controlledPosition) {
|
|
@@ -284,7 +384,7 @@ export function useEdgeDock(config = {}) {
|
|
|
284
384
|
}, [dockMode, dockEdge, allowedEdges, edgeOffset]);
|
|
285
385
|
// Pointer down handler
|
|
286
386
|
const handlePointerDown = useCallback((e) => {
|
|
287
|
-
if (!buttonRef.current)
|
|
387
|
+
if (!buttonRef.current || !draggable)
|
|
288
388
|
return;
|
|
289
389
|
e.preventDefault();
|
|
290
390
|
e.stopPropagation();
|
|
@@ -301,7 +401,7 @@ export function useEdgeDock(config = {}) {
|
|
|
301
401
|
};
|
|
302
402
|
setIsDragging(true);
|
|
303
403
|
setIsAnimating(false);
|
|
304
|
-
}, [position, isPopupOpen]);
|
|
404
|
+
}, [position, isPopupOpen, draggable]);
|
|
305
405
|
// Pointer move handler
|
|
306
406
|
useEffect(() => {
|
|
307
407
|
const handlePointerMove = (e) => {
|
|
@@ -382,7 +482,29 @@ export function useEdgeDock(config = {}) {
|
|
|
382
482
|
const buttonRect = buttonRef.current.getBoundingClientRect();
|
|
383
483
|
const viewport = getViewport();
|
|
384
484
|
const buttonDimensions = { width: buttonRect.width, height: buttonRect.height };
|
|
385
|
-
let newPos =
|
|
485
|
+
let newPos = position;
|
|
486
|
+
if (!draggable && sticky) {
|
|
487
|
+
const stickyPos = resolveStickyConfig(sticky, viewport.width);
|
|
488
|
+
if (stickyPos) {
|
|
489
|
+
newPos = calculateStickyCoordinates(stickyPos, viewport);
|
|
490
|
+
// Adjust for center origin
|
|
491
|
+
if (stickyPos.left !== undefined) {
|
|
492
|
+
newPos.x += buttonDimensions.width / 2;
|
|
493
|
+
}
|
|
494
|
+
else if (stickyPos.right !== undefined) {
|
|
495
|
+
newPos.x -= buttonDimensions.width / 2;
|
|
496
|
+
}
|
|
497
|
+
if (stickyPos.top !== undefined) {
|
|
498
|
+
newPos.y += buttonDimensions.height / 2;
|
|
499
|
+
}
|
|
500
|
+
else if (stickyPos.bottom !== undefined) {
|
|
501
|
+
newPos.y -= buttonDimensions.height / 2;
|
|
502
|
+
}
|
|
503
|
+
setPositionInternal(newPos);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
newPos = constrainToViewport(position, viewport, buttonDimensions, edgeOffset);
|
|
386
508
|
if (dockMode === 'auto') {
|
|
387
509
|
const edge = getClosestEdge(newPos, viewport, allowedEdges);
|
|
388
510
|
newPos = snapToEdge(newPos, edge, viewport, buttonDimensions, edgeOffset);
|
|
@@ -396,7 +518,7 @@ export function useEdgeDock(config = {}) {
|
|
|
396
518
|
};
|
|
397
519
|
window.addEventListener('resize', handleResize);
|
|
398
520
|
return () => window.removeEventListener('resize', handleResize);
|
|
399
|
-
}, [position, dockMode, dockEdge, edgeOffset, allowedEdges]);
|
|
521
|
+
}, [position, dockMode, dockEdge, edgeOffset, allowedEdges, draggable, sticky]);
|
|
400
522
|
// Button styles
|
|
401
523
|
const buttonStyles = {
|
|
402
524
|
position: 'fixed',
|
|
@@ -404,7 +526,7 @@ export function useEdgeDock(config = {}) {
|
|
|
404
526
|
top: 0,
|
|
405
527
|
transform: `translate3d(${position.x}px, ${position.y}px, 0) translate(-50%, -50%)`,
|
|
406
528
|
transition: isAnimating && animation ? 'transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)' : 'none',
|
|
407
|
-
cursor: isDragging ? 'grabbing' : 'grab',
|
|
529
|
+
cursor: draggable ? (isDragging ? 'grabbing' : 'grab') : 'pointer',
|
|
408
530
|
touchAction: 'none',
|
|
409
531
|
userSelect: 'none',
|
|
410
532
|
zIndex,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-edge-dock",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
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",
|
|
@@ -22,8 +22,7 @@
|
|
|
22
22
|
"dev": "tsc --watch",
|
|
23
23
|
"clean": "rm -rf dist",
|
|
24
24
|
"prepublishOnly": "npm run clean && npm run build",
|
|
25
|
-
"prepack": "npm run build"
|
|
26
|
-
"publish": "npm publish --access public"
|
|
25
|
+
"prepack": "npm run build"
|
|
27
26
|
},
|
|
28
27
|
"keywords": [
|
|
29
28
|
"react",
|