@buoy-gg/floating-tools-core 2.1.11 → 2.1.13

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 (108) hide show
  1. package/LICENSE +58 -0
  2. package/lib/commonjs/FloatingToolsStore.js +1 -501
  3. package/lib/commonjs/colors.js +1 -54
  4. package/lib/commonjs/constants.js +1 -31
  5. package/lib/commonjs/devToolsState.js +1 -325
  6. package/lib/commonjs/dial.js +1 -617
  7. package/lib/commonjs/easing.js +1 -69
  8. package/lib/commonjs/icons/benchmark-icon.js +1 -24
  9. package/lib/commonjs/icons/env-icon.js +1 -24
  10. package/lib/commonjs/icons/events-icon.js +1 -24
  11. package/lib/commonjs/icons/highlight-icon.js +1 -24
  12. package/lib/commonjs/icons/icon-data.js +1 -2268
  13. package/lib/commonjs/icons/icon-factories.js +1 -173
  14. package/lib/commonjs/icons/icon-primitives.js +1 -559
  15. package/lib/commonjs/icons/icon-primitives.native.js +1 -779
  16. package/lib/commonjs/icons/icon-renderer.js +1 -260
  17. package/lib/commonjs/icons/network-icon.js +1 -24
  18. package/lib/commonjs/icons/query-icon.js +1 -24
  19. package/lib/commonjs/icons/redux-icon.js +1 -85
  20. package/lib/commonjs/icons/renders-icon.js +1 -33
  21. package/lib/commonjs/icons/routes-icon.js +1 -49
  22. package/lib/commonjs/icons/sentry-icon.js +1 -24
  23. package/lib/commonjs/icons/storage-icon.js +1 -24
  24. package/lib/commonjs/icons/wifi-icon.js +1 -24
  25. package/lib/commonjs/index.js +1 -723
  26. package/lib/commonjs/settings.js +1 -599
  27. package/lib/commonjs/utils.js +1 -72
  28. package/lib/module/FloatingToolsStore.js +1 -496
  29. package/lib/module/colors.js +1 -49
  30. package/lib/module/constants.js +1 -27
  31. package/lib/module/devToolsState.js +1 -318
  32. package/lib/module/dial.js +1 -603
  33. package/lib/module/easing.js +1 -62
  34. package/lib/module/icons/benchmark-icon.js +1 -15
  35. package/lib/module/icons/env-icon.js +1 -15
  36. package/lib/module/icons/events-icon.js +1 -15
  37. package/lib/module/icons/highlight-icon.js +1 -15
  38. package/lib/module/icons/icon-data.js +1 -2264
  39. package/lib/module/icons/icon-factories.js +1 -163
  40. package/lib/module/icons/icon-primitives.js +1 -547
  41. package/lib/module/icons/icon-primitives.native.js +1 -767
  42. package/lib/module/icons/icon-renderer.js +1 -255
  43. package/lib/module/icons/network-icon.js +1 -15
  44. package/lib/module/icons/query-icon.js +1 -15
  45. package/lib/module/icons/redux-icon.js +1 -81
  46. package/lib/module/icons/renders-icon.js +1 -17
  47. package/lib/module/icons/routes-icon.js +1 -41
  48. package/lib/module/icons/sentry-icon.js +1 -15
  49. package/lib/module/icons/storage-icon.js +1 -15
  50. package/lib/module/icons/wifi-icon.js +1 -15
  51. package/lib/module/index.js +1 -103
  52. package/lib/module/settings.js +1 -587
  53. package/lib/module/utils.js +1 -66
  54. package/package.json +8 -8
  55. package/lib/typescript/commonjs/FloatingToolsStore.d.ts.map +0 -1
  56. package/lib/typescript/commonjs/colors.d.ts.map +0 -1
  57. package/lib/typescript/commonjs/constants.d.ts.map +0 -1
  58. package/lib/typescript/commonjs/devToolsState.d.ts.map +0 -1
  59. package/lib/typescript/commonjs/dial.d.ts.map +0 -1
  60. package/lib/typescript/commonjs/easing.d.ts.map +0 -1
  61. package/lib/typescript/commonjs/icons/benchmark-icon.d.ts.map +0 -1
  62. package/lib/typescript/commonjs/icons/env-icon.d.ts.map +0 -1
  63. package/lib/typescript/commonjs/icons/events-icon.d.ts.map +0 -1
  64. package/lib/typescript/commonjs/icons/highlight-icon.d.ts.map +0 -1
  65. package/lib/typescript/commonjs/icons/icon-data.d.ts.map +0 -1
  66. package/lib/typescript/commonjs/icons/icon-factories.d.ts.map +0 -1
  67. package/lib/typescript/commonjs/icons/icon-primitives.d.ts.map +0 -1
  68. package/lib/typescript/commonjs/icons/icon-primitives.native.d.ts.map +0 -1
  69. package/lib/typescript/commonjs/icons/icon-renderer.d.ts.map +0 -1
  70. package/lib/typescript/commonjs/icons/network-icon.d.ts.map +0 -1
  71. package/lib/typescript/commonjs/icons/query-icon.d.ts.map +0 -1
  72. package/lib/typescript/commonjs/icons/redux-icon.d.ts.map +0 -1
  73. package/lib/typescript/commonjs/icons/renders-icon.d.ts.map +0 -1
  74. package/lib/typescript/commonjs/icons/routes-icon.d.ts.map +0 -1
  75. package/lib/typescript/commonjs/icons/sentry-icon.d.ts.map +0 -1
  76. package/lib/typescript/commonjs/icons/storage-icon.d.ts.map +0 -1
  77. package/lib/typescript/commonjs/icons/wifi-icon.d.ts.map +0 -1
  78. package/lib/typescript/commonjs/index.d.ts.map +0 -1
  79. package/lib/typescript/commonjs/settings.d.ts.map +0 -1
  80. package/lib/typescript/commonjs/types.d.ts.map +0 -1
  81. package/lib/typescript/commonjs/utils.d.ts.map +0 -1
  82. package/lib/typescript/module/FloatingToolsStore.d.ts.map +0 -1
  83. package/lib/typescript/module/colors.d.ts.map +0 -1
  84. package/lib/typescript/module/constants.d.ts.map +0 -1
  85. package/lib/typescript/module/devToolsState.d.ts.map +0 -1
  86. package/lib/typescript/module/dial.d.ts.map +0 -1
  87. package/lib/typescript/module/easing.d.ts.map +0 -1
  88. package/lib/typescript/module/icons/benchmark-icon.d.ts.map +0 -1
  89. package/lib/typescript/module/icons/env-icon.d.ts.map +0 -1
  90. package/lib/typescript/module/icons/events-icon.d.ts.map +0 -1
  91. package/lib/typescript/module/icons/highlight-icon.d.ts.map +0 -1
  92. package/lib/typescript/module/icons/icon-data.d.ts.map +0 -1
  93. package/lib/typescript/module/icons/icon-factories.d.ts.map +0 -1
  94. package/lib/typescript/module/icons/icon-primitives.d.ts.map +0 -1
  95. package/lib/typescript/module/icons/icon-primitives.native.d.ts.map +0 -1
  96. package/lib/typescript/module/icons/icon-renderer.d.ts.map +0 -1
  97. package/lib/typescript/module/icons/network-icon.d.ts.map +0 -1
  98. package/lib/typescript/module/icons/query-icon.d.ts.map +0 -1
  99. package/lib/typescript/module/icons/redux-icon.d.ts.map +0 -1
  100. package/lib/typescript/module/icons/renders-icon.d.ts.map +0 -1
  101. package/lib/typescript/module/icons/routes-icon.d.ts.map +0 -1
  102. package/lib/typescript/module/icons/sentry-icon.d.ts.map +0 -1
  103. package/lib/typescript/module/icons/storage-icon.d.ts.map +0 -1
  104. package/lib/typescript/module/icons/wifi-icon.d.ts.map +0 -1
  105. package/lib/typescript/module/index.d.ts.map +0 -1
  106. package/lib/typescript/module/settings.d.ts.map +0 -1
  107. package/lib/typescript/module/types.d.ts.map +0 -1
  108. package/lib/typescript/module/utils.d.ts.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,58 @@
1
+ PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2024-present Buoy. All rights reserved.
4
+
5
+ This software and its source code are proprietary and confidential.
6
+
7
+ NOTICE: This is NOT open source software. This software is licensed,
8
+ not sold, and is protected by copyright laws and international treaties.
9
+
10
+ TERMS AND CONDITIONS:
11
+
12
+ 1. LICENSE GRANT
13
+ Subject to the terms of this Agreement and payment of applicable fees,
14
+ Buoy grants you a limited, non-exclusive, non-transferable license
15
+ to use the compiled software packages in your applications.
16
+
17
+ 2. RESTRICTIONS
18
+ You may NOT:
19
+ - Copy, modify, or distribute the source code
20
+ - Reverse engineer, decompile, or disassemble the software
21
+ - Remove or alter any proprietary notices or labels
22
+ - Sublicense, rent, lease, or lend the software
23
+ - Use the software to create competing products
24
+ - Share access credentials with unauthorized parties
25
+
26
+ 3. OWNERSHIP
27
+ React Buoy retains all right, title, and interest in the software,
28
+ including all intellectual property rights. This license does not
29
+ grant you any rights to trademarks or service marks.
30
+
31
+ 4. TERMINATION
32
+ This license is effective until terminated. Your rights under this
33
+ license will terminate automatically without notice if you fail to
34
+ comply with any of its terms. Upon termination, you must cease all
35
+ use and destroy all copies of the software.
36
+
37
+ 5. DISCLAIMER OF WARRANTIES
38
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
39
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
41
+
42
+ 6. LIMITATION OF LIABILITY
43
+ IN NO EVENT SHALL BUOY BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
44
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
45
+ CONNECTION WITH THIS LICENSE OR THE USE OF THE SOFTWARE.
46
+
47
+ 7. GOVERNING LAW
48
+ This Agreement shall be governed by and construed in accordance with
49
+ the laws of the United States, without regard to its conflict of
50
+ law provisions.
51
+
52
+ For licensing inquiries and subscription information:
53
+ - Website: https://buoy.gg
54
+ - Email: AustinLovesWorking@gmail.com
55
+
56
+ Unauthorized reproduction or distribution of this software, or any
57
+ portion of it, may result in severe civil and criminal penalties,
58
+ and will be prosecuted to the maximum extent possible under the law.
@@ -1,501 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.FloatingToolsStore = void 0;
7
- var _constants = require("./constants.js");
8
- /**
9
- * FloatingToolsStore - Headless state management for floating tools.
10
- *
11
- * This class manages all the business logic for the floating tools bubble:
12
- * - Position state and validation
13
- * - Drag detection (tap vs drag)
14
- * - Hide/show toggle
15
- * - Auto-hide when dragged past edge
16
- * - Position persistence
17
- *
18
- * Platform-specific code (animation, event handling) is NOT included here.
19
- * Use this with platform-specific hooks/bindings.
20
- */
21
-
22
- class FloatingToolsStore {
23
- // State
24
-
25
- isDragging = false;
26
- isHidden = false;
27
-
28
- // Configuration
29
-
30
- // Callbacks
31
-
32
- // Drag tracking
33
- dragStartPos = {
34
- x: 0,
35
- y: 0
36
- };
37
- dragStartMouse = {
38
- x: 0,
39
- y: 0
40
- };
41
- hasMoved = false;
42
- savedPosition = null;
43
-
44
- // Persistence
45
- saveTimeout = null;
46
- isInitialized = false;
47
-
48
- // Subscribers (for useSyncExternalStore)
49
- listeners = new Set();
50
- constructor(options) {
51
- this.screenWidth = options.screenWidth;
52
- this.screenHeight = options.screenHeight;
53
- this.bubbleSize = options.initialBubbleSize ?? {
54
- width: 100,
55
- height: 32
56
- };
57
- this.minPosition = options.minPosition ?? {
58
- x: _constants.EDGE_PADDING,
59
- y: _constants.EDGE_PADDING
60
- };
61
- this.visibleHandleWidth = options.visibleHandleWidth ?? _constants.VISIBLE_HANDLE_WIDTH;
62
- this.dragThreshold = options.dragThreshold ?? _constants.DRAG_THRESHOLD;
63
- this.edgePadding = options.edgePadding ?? _constants.EDGE_PADDING;
64
- this.enablePositionPersistence = options.enablePositionPersistence ?? true;
65
- this.storage = options.storage;
66
- this.onPositionChange = options.onPositionChange;
67
- this.onHiddenChange = options.onHiddenChange;
68
- this.onDraggingChange = options.onDraggingChange;
69
-
70
- // Default position
71
- this.position = options.initialPosition ?? {
72
- x: this.screenWidth - this.bubbleSize.width - 20,
73
- y: Math.max(this.minPosition.y, Math.min(100, this.screenHeight - this.bubbleSize.height - this.edgePadding))
74
- };
75
-
76
- // Initialize snapshot
77
- this.stateSnapshot = this.createSnapshot();
78
- }
79
-
80
- // =============================
81
- // Subscription (for React hooks)
82
- // =============================
83
-
84
- subscribe = listener => {
85
- this.listeners.add(listener);
86
- return () => this.listeners.delete(listener);
87
- };
88
- getSnapshot = () => {
89
- return this.stateSnapshot;
90
- };
91
- createSnapshot() {
92
- return {
93
- position: {
94
- ...this.position
95
- },
96
- isDragging: this.isDragging,
97
- isHidden: this.isHidden,
98
- bubbleSize: {
99
- ...this.bubbleSize
100
- }
101
- };
102
- }
103
- notify() {
104
- this.stateSnapshot = this.createSnapshot();
105
- this.listeners.forEach(listener => listener());
106
- }
107
-
108
- // =============================
109
- // Initialization
110
- // =============================
111
-
112
- /**
113
- * Initialize the store by loading persisted position.
114
- * Call this after setting up storage adapter.
115
- */
116
- async initialize() {
117
- if (this.isInitialized || !this.enablePositionPersistence || !this.storage) {
118
- this.isInitialized = true;
119
- return;
120
- }
121
- try {
122
- const [xStr, yStr] = await Promise.all([this.storage.getItem(_constants.STORAGE_KEYS.POSITION_X), this.storage.getItem(_constants.STORAGE_KEYS.POSITION_Y)]);
123
- if (xStr !== null && yStr !== null) {
124
- const x = parseFloat(xStr);
125
- const y = parseFloat(yStr);
126
- if (!Number.isNaN(x) && !Number.isNaN(y)) {
127
- const saved = {
128
- x,
129
- y
130
- };
131
- const validated = this.validatePosition(saved);
132
-
133
- // Save corrected position if out of bounds
134
- if (Math.abs(saved.x - validated.x) > 5 || Math.abs(saved.y - validated.y) > 5) {
135
- this.savePosition(validated.x, validated.y);
136
- }
137
- this.position = validated;
138
-
139
- // Check if loaded in hidden state
140
- if (validated.x >= this.screenWidth - this.visibleHandleWidth - 5) {
141
- this.isHidden = true;
142
- }
143
- this.notify();
144
- }
145
- }
146
- } catch {
147
- // Failed to load - use default position
148
- }
149
- this.isInitialized = true;
150
- }
151
-
152
- // =============================
153
- // Position Management
154
- // =============================
155
-
156
- /**
157
- * Get current bounds for position validation.
158
- */
159
- getBounds() {
160
- return {
161
- minX: this.minPosition.x,
162
- maxX: this.screenWidth - this.visibleHandleWidth,
163
- minY: this.minPosition.y,
164
- maxY: this.screenHeight - this.bubbleSize.height - this.edgePadding
165
- };
166
- }
167
-
168
- /**
169
- * Validate and clamp a position to screen boundaries.
170
- */
171
- validatePosition(pos) {
172
- const bounds = this.getBounds();
173
- return {
174
- x: Math.max(bounds.minX, Math.min(pos.x, bounds.maxX)),
175
- y: Math.max(bounds.minY, Math.min(pos.y, bounds.maxY))
176
- };
177
- }
178
-
179
- /**
180
- * Set position directly (for animation callbacks).
181
- */
182
- setPosition(pos) {
183
- this.position = pos;
184
- this.onPositionChange?.(pos);
185
- this.notify();
186
- }
187
-
188
- /**
189
- * Update bubble size (call on layout).
190
- * Only notifies if size actually changed.
191
- */
192
- setBubbleSize(size) {
193
- if (this.bubbleSize.width === size.width && this.bubbleSize.height === size.height) {
194
- return;
195
- }
196
- this.bubbleSize = size;
197
- this.notify();
198
- }
199
-
200
- /**
201
- * Update screen dimensions (call on resize).
202
- */
203
- setScreenSize(width, height) {
204
- this.screenWidth = width;
205
- this.screenHeight = height;
206
- // Re-validate position
207
- const validated = this.validatePosition(this.position);
208
- if (validated.x !== this.position.x || validated.y !== this.position.y) {
209
- this.position = validated;
210
- this.notify();
211
- }
212
- }
213
-
214
- /**
215
- * Update min position (e.g., for safe area insets).
216
- */
217
- setMinPosition(minPos) {
218
- this.minPosition = minPos;
219
- }
220
-
221
- // =============================
222
- // Persistence
223
- // =============================
224
-
225
- async savePosition(x, y) {
226
- if (!this.enablePositionPersistence || !this.storage) return;
227
- try {
228
- await Promise.all([this.storage.setItem(_constants.STORAGE_KEYS.POSITION_X, x.toString()), this.storage.setItem(_constants.STORAGE_KEYS.POSITION_Y, y.toString())]);
229
- } catch {
230
- // Failed to save - continue without persistence
231
- }
232
- }
233
- debouncedSavePosition(x, y) {
234
- if (this.saveTimeout) clearTimeout(this.saveTimeout);
235
- this.saveTimeout = setTimeout(() => this.savePosition(x, y), _constants.SAVE_DEBOUNCE_MS);
236
- }
237
-
238
- // =============================
239
- // Hide/Show Toggle
240
- // =============================
241
-
242
- /**
243
- * Toggle between hidden and visible states.
244
- * Returns the target position for animation.
245
- */
246
- toggleHideShow() {
247
- const isVisuallyOffScreen = this.position.x > this.screenWidth - this.bubbleSize.width / 2;
248
- if (this.isHidden || isVisuallyOffScreen) {
249
- // Show the bubble
250
- let targetX;
251
- let targetY;
252
- if (this.savedPosition && this.savedPosition.x < this.screenWidth - this.bubbleSize.width / 2) {
253
- targetX = this.savedPosition.x;
254
- targetY = this.savedPosition.y;
255
- } else {
256
- targetX = this.screenWidth - this.bubbleSize.width - 20;
257
- targetY = this.position.y;
258
- }
259
- this.isHidden = false;
260
- this.onHiddenChange?.(false);
261
- this.notify();
262
- return {
263
- targetPosition: {
264
- x: targetX,
265
- y: targetY
266
- },
267
- isHiding: false
268
- };
269
- } else {
270
- // Hide the bubble
271
- this.savedPosition = {
272
- ...this.position
273
- };
274
- const hiddenX = this.screenWidth - this.visibleHandleWidth;
275
- this.isHidden = true;
276
- this.onHiddenChange?.(true);
277
- this.notify();
278
- return {
279
- targetPosition: {
280
- x: hiddenX,
281
- y: this.position.y
282
- },
283
- isHiding: true
284
- };
285
- }
286
- }
287
-
288
- /**
289
- * Force hide (for pushToSide behavior).
290
- */
291
- forceHide() {
292
- if (this.isHidden) {
293
- return {
294
- targetPosition: this.position
295
- };
296
- }
297
- this.savedPosition = {
298
- ...this.position
299
- };
300
- const hiddenX = this.screenWidth - this.visibleHandleWidth;
301
- this.isHidden = true;
302
- this.onHiddenChange?.(true);
303
- this.notify();
304
- return {
305
- targetPosition: {
306
- x: hiddenX,
307
- y: this.position.y
308
- }
309
- };
310
- }
311
-
312
- /**
313
- * Force show (restore from pushToSide).
314
- */
315
- forceShow() {
316
- if (!this.isHidden) {
317
- return {
318
- targetPosition: this.position
319
- };
320
- }
321
- let targetX;
322
- let targetY;
323
- if (this.savedPosition) {
324
- targetX = this.savedPosition.x;
325
- targetY = this.savedPosition.y;
326
- } else {
327
- targetX = this.screenWidth - this.bubbleSize.width - 20;
328
- targetY = this.position.y;
329
- }
330
- this.isHidden = false;
331
- this.onHiddenChange?.(false);
332
- this.notify();
333
- return {
334
- targetPosition: {
335
- x: targetX,
336
- y: targetY
337
- }
338
- };
339
- }
340
-
341
- // =============================
342
- // Drag Handling
343
- // =============================
344
-
345
- /**
346
- * Start a drag operation.
347
- */
348
- handleDragStart(event) {
349
- this.hasMoved = false;
350
- this.dragStartPos = {
351
- ...this.position
352
- };
353
- this.dragStartMouse = {
354
- x: event.clientX,
355
- y: event.clientY
356
- };
357
- }
358
-
359
- /**
360
- * Process drag movement.
361
- * Returns the new position (for animation) and whether drag threshold was exceeded.
362
- */
363
- handleDragMove(event) {
364
- const dx = event.clientX - this.dragStartMouse.x;
365
- const dy = event.clientY - this.dragStartMouse.y;
366
- const totalDistance = Math.abs(dx) + Math.abs(dy);
367
-
368
- // Check if moved enough to be considered a drag
369
- if (!this.hasMoved && totalDistance > this.dragThreshold) {
370
- this.hasMoved = true;
371
- this.isDragging = true;
372
- this.onDraggingChange?.(true);
373
- this.notify();
374
- }
375
- if (this.hasMoved) {
376
- const newX = this.dragStartPos.x + dx;
377
- const newY = this.dragStartPos.y + dy;
378
-
379
- // Allow overflow to right for hide detection, but clamp Y
380
- const bounds = this.getBounds();
381
- const clampedX = Math.max(bounds.minX, Math.min(newX, this.screenWidth - this.visibleHandleWidth + this.bubbleSize.width));
382
- const clampedY = Math.max(bounds.minY, Math.min(newY, bounds.maxY));
383
- this.position = {
384
- x: clampedX,
385
- y: clampedY
386
- };
387
- this.onPositionChange?.(this.position);
388
- this.notify();
389
- return {
390
- position: this.position,
391
- isDragging: true
392
- };
393
- }
394
- return {
395
- position: this.position,
396
- isDragging: false
397
- };
398
- }
399
-
400
- /**
401
- * End a drag operation.
402
- * Returns the result including whether to animate to hidden state.
403
- */
404
- handleDragEnd(event) {
405
- const wasTap = !this.hasMoved;
406
- if (wasTap) {
407
- this.isDragging = false;
408
- this.onDraggingChange?.(false);
409
- this.notify();
410
- return {
411
- position: this.position,
412
- shouldHide: false,
413
- wasTap: true
414
- };
415
- }
416
-
417
- // Calculate final position
418
- const dx = event.clientX - this.dragStartMouse.x;
419
- const dy = event.clientY - this.dragStartMouse.y;
420
- const currentX = this.dragStartPos.x + dx;
421
- const currentY = this.dragStartPos.y + dy;
422
-
423
- // Check if should auto-hide (bubble midpoint past right edge)
424
- const bubbleMidpoint = currentX + this.bubbleSize.width / 2;
425
- const shouldHide = bubbleMidpoint > this.screenWidth;
426
- const bounds = this.getBounds();
427
- if (shouldHide) {
428
- const hiddenX = this.screenWidth - this.visibleHandleWidth;
429
- const clampedY = Math.max(bounds.minY, Math.min(currentY, bounds.maxY));
430
- this.isHidden = true;
431
- this.onHiddenChange?.(true);
432
- this.isDragging = false;
433
- this.onDraggingChange?.(false);
434
- this.notify();
435
- return {
436
- position: {
437
- x: hiddenX,
438
- y: clampedY
439
- },
440
- shouldHide: true,
441
- wasTap: false
442
- };
443
- } else {
444
- // Check if pulling back from hidden
445
- if (this.isHidden && currentX < this.screenWidth - this.visibleHandleWidth - 10) {
446
- this.isHidden = false;
447
- this.onHiddenChange?.(false);
448
- }
449
-
450
- // Clamp to visible area
451
- const clampedX = Math.max(bounds.minX, Math.min(currentX, this.screenWidth - this.bubbleSize.width - this.edgePadding));
452
- const clampedY = Math.max(bounds.minY, Math.min(currentY, bounds.maxY));
453
-
454
- // Save position if visible
455
- if (clampedX < this.screenWidth - this.bubbleSize.width / 2) {
456
- this.savedPosition = {
457
- x: clampedX,
458
- y: clampedY
459
- };
460
- }
461
- this.position = {
462
- x: clampedX,
463
- y: clampedY
464
- };
465
- this.isDragging = false;
466
- this.onDraggingChange?.(false);
467
- this.debouncedSavePosition(clampedX, clampedY);
468
- this.notify();
469
- return {
470
- position: {
471
- x: clampedX,
472
- y: clampedY
473
- },
474
- shouldHide: false,
475
- wasTap: false
476
- };
477
- }
478
- }
479
-
480
- /**
481
- * Commit position after animation completes.
482
- */
483
- commitPosition(pos) {
484
- this.position = pos;
485
- this.savePosition(pos.x, pos.y);
486
- this.notify();
487
- }
488
-
489
- // =============================
490
- // Cleanup
491
- // =============================
492
-
493
- destroy() {
494
- if (this.saveTimeout) {
495
- clearTimeout(this.saveTimeout);
496
- this.saveTimeout = null;
497
- }
498
- this.listeners.clear();
499
- }
500
- }
501
- exports.FloatingToolsStore = FloatingToolsStore;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.FloatingToolsStore=void 0;var _constants=require("./constants.js");class FloatingToolsStore{isDragging=!1;isHidden=!1;dragStartPos={x:0,y:0};dragStartMouse={x:0,y:0};hasMoved=!1;savedPosition=null;saveTimeout=null;isInitialized=!1;listeners=new Set;constructor(i){this.screenWidth=i.screenWidth,this.screenHeight=i.screenHeight,this.bubbleSize=i.initialBubbleSize??{width:100,height:32},this.minPosition=i.minPosition??{x:_constants.EDGE_PADDING,y:_constants.EDGE_PADDING},this.visibleHandleWidth=i.visibleHandleWidth??_constants.VISIBLE_HANDLE_WIDTH,this.dragThreshold=i.dragThreshold??_constants.DRAG_THRESHOLD,this.edgePadding=i.edgePadding??_constants.EDGE_PADDING,this.enablePositionPersistence=i.enablePositionPersistence??!0,this.storage=i.storage,this.onPositionChange=i.onPositionChange,this.onHiddenChange=i.onHiddenChange,this.onDraggingChange=i.onDraggingChange,this.position=i.initialPosition??{x:this.screenWidth-this.bubbleSize.width-20,y:Math.max(this.minPosition.y,Math.min(100,this.screenHeight-this.bubbleSize.height-this.edgePadding))},this.stateSnapshot=this.createSnapshot()}subscribe=i=>(this.listeners.add(i),()=>this.listeners.delete(i));getSnapshot=()=>this.stateSnapshot;createSnapshot(){return{position:{...this.position},isDragging:this.isDragging,isHidden:this.isHidden,bubbleSize:{...this.bubbleSize}}}notify(){this.stateSnapshot=this.createSnapshot(),this.listeners.forEach(i=>i())}async initialize(){if(!this.isInitialized&&this.enablePositionPersistence&&this.storage){try{const[i,t]=await Promise.all([this.storage.getItem(_constants.STORAGE_KEYS.POSITION_X),this.storage.getItem(_constants.STORAGE_KEYS.POSITION_Y)]);if(null!==i&&null!==t){const s=parseFloat(i),e=parseFloat(t);if(!Number.isNaN(s)&&!Number.isNaN(e)){const i={x:s,y:e},t=this.validatePosition(i);(Math.abs(i.x-t.x)>5||Math.abs(i.y-t.y)>5)&&this.savePosition(t.x,t.y),this.position=t,t.x>=this.screenWidth-this.visibleHandleWidth-5&&(this.isHidden=!0),this.notify()}}}catch{}this.isInitialized=!0}else this.isInitialized=!0}getBounds(){return{minX:this.minPosition.x,maxX:this.screenWidth-this.visibleHandleWidth,minY:this.minPosition.y,maxY:this.screenHeight-this.bubbleSize.height-this.edgePadding}}validatePosition(i){const t=this.getBounds();return{x:Math.max(t.minX,Math.min(i.x,t.maxX)),y:Math.max(t.minY,Math.min(i.y,t.maxY))}}setPosition(i){this.position=i,this.onPositionChange?.(i),this.notify()}setBubbleSize(i){this.bubbleSize.width===i.width&&this.bubbleSize.height===i.height||(this.bubbleSize=i,this.notify())}setScreenSize(i,t){this.screenWidth=i,this.screenHeight=t;const s=this.validatePosition(this.position);s.x===this.position.x&&s.y===this.position.y||(this.position=s,this.notify())}setMinPosition(i){this.minPosition=i}async savePosition(i,t){if(this.enablePositionPersistence&&this.storage)try{await Promise.all([this.storage.setItem(_constants.STORAGE_KEYS.POSITION_X,i.toString()),this.storage.setItem(_constants.STORAGE_KEYS.POSITION_Y,t.toString())])}catch{}}debouncedSavePosition(i,t){this.saveTimeout&&clearTimeout(this.saveTimeout),this.saveTimeout=setTimeout(()=>this.savePosition(i,t),_constants.SAVE_DEBOUNCE_MS)}toggleHideShow(){const i=this.position.x>this.screenWidth-this.bubbleSize.width/2;if(this.isHidden||i){let i,t;return this.savedPosition&&this.savedPosition.x<this.screenWidth-this.bubbleSize.width/2?(i=this.savedPosition.x,t=this.savedPosition.y):(i=this.screenWidth-this.bubbleSize.width-20,t=this.position.y),this.isHidden=!1,this.onHiddenChange?.(!1),this.notify(),{targetPosition:{x:i,y:t},isHiding:!1}}{this.savedPosition={...this.position};const i=this.screenWidth-this.visibleHandleWidth;return this.isHidden=!0,this.onHiddenChange?.(!0),this.notify(),{targetPosition:{x:i,y:this.position.y},isHiding:!0}}}forceHide(){if(this.isHidden)return{targetPosition:this.position};this.savedPosition={...this.position};const i=this.screenWidth-this.visibleHandleWidth;return this.isHidden=!0,this.onHiddenChange?.(!0),this.notify(),{targetPosition:{x:i,y:this.position.y}}}forceShow(){if(!this.isHidden)return{targetPosition:this.position};let i,t;return this.savedPosition?(i=this.savedPosition.x,t=this.savedPosition.y):(i=this.screenWidth-this.bubbleSize.width-20,t=this.position.y),this.isHidden=!1,this.onHiddenChange?.(!1),this.notify(),{targetPosition:{x:i,y:t}}}handleDragStart(i){this.hasMoved=!1,this.dragStartPos={...this.position},this.dragStartMouse={x:i.clientX,y:i.clientY}}handleDragMove(i){const t=i.clientX-this.dragStartMouse.x,s=i.clientY-this.dragStartMouse.y,e=Math.abs(t)+Math.abs(s);if(!this.hasMoved&&e>this.dragThreshold&&(this.hasMoved=!0,this.isDragging=!0,this.onDraggingChange?.(!0),this.notify()),this.hasMoved){const i=this.dragStartPos.x+t,e=this.dragStartPos.y+s,n=this.getBounds(),h=Math.max(n.minX,Math.min(i,this.screenWidth-this.visibleHandleWidth+this.bubbleSize.width)),o=Math.max(n.minY,Math.min(e,n.maxY));return this.position={x:h,y:o},this.onPositionChange?.(this.position),this.notify(),{position:this.position,isDragging:!0}}return{position:this.position,isDragging:!1}}handleDragEnd(i){if(!this.hasMoved)return this.isDragging=!1,this.onDraggingChange?.(!1),this.notify(),{position:this.position,shouldHide:!1,wasTap:!0};const t=i.clientX-this.dragStartMouse.x,s=i.clientY-this.dragStartMouse.y,e=this.dragStartPos.x+t,n=this.dragStartPos.y+s,h=e+this.bubbleSize.width/2>this.screenWidth,o=this.getBounds();if(h){const i=this.screenWidth-this.visibleHandleWidth,t=Math.max(o.minY,Math.min(n,o.maxY));return this.isHidden=!0,this.onHiddenChange?.(!0),this.isDragging=!1,this.onDraggingChange?.(!1),this.notify(),{position:{x:i,y:t},shouldHide:!0,wasTap:!1}}{this.isHidden&&e<this.screenWidth-this.visibleHandleWidth-10&&(this.isHidden=!1,this.onHiddenChange?.(!1));const i=Math.max(o.minX,Math.min(e,this.screenWidth-this.bubbleSize.width-this.edgePadding)),t=Math.max(o.minY,Math.min(n,o.maxY));return i<this.screenWidth-this.bubbleSize.width/2&&(this.savedPosition={x:i,y:t}),this.position={x:i,y:t},this.isDragging=!1,this.onDraggingChange?.(!1),this.debouncedSavePosition(i,t),this.notify(),{position:{x:i,y:t},shouldHide:!1,wasTap:!1}}}commitPosition(i){this.position=i,this.savePosition(i.x,i.y),this.notify()}destroy(){this.saveTimeout&&(clearTimeout(this.saveTimeout),this.saveTimeout=null),this.listeners.clear()}}exports.FloatingToolsStore=FloatingToolsStore;
@@ -1,54 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.floatingToolsColors = void 0;
7
- exports.withAlpha = withAlpha;
8
- /**
9
- * Shared color palette for floating tools.
10
- * Matches the gameUIColors from @buoy-gg/shared-ui.
11
- *
12
- * These are duplicated here to avoid requiring @buoy-gg/shared-ui
13
- * as a dependency (which has React Native dependencies).
14
- *
15
- * TODO: Consider extracting colors to a truly platform-agnostic package
16
- * that both shared-ui and floating-tools-core can depend on.
17
- */
18
-
19
- /**
20
- * Buoy brand colors - EXACT values from web docs site dark theme
21
- */
22
- const floatingToolsColors = exports.floatingToolsColors = {
23
- /** Dark panel background */
24
- panel: '#1A1A1A',
25
- /** Muted gray for secondary elements */
26
- muted: '#888888',
27
- /** Primary text color */
28
- secondary: '#E0E0E0',
29
- /** Info/active state color (Buoy teal) */
30
- info: '#20C997',
31
- /** Success/admin color (Buoy teal) */
32
- success: '#20C997',
33
- /** Warning/optional color (Buoy orange) */
34
- optional: '#FFA94D',
35
- /** Error color (Buoy red) */
36
- error: '#EF4444',
37
- /** Primary accent color (Buoy teal) */
38
- primary: '#20C997',
39
- /** Color used when dragging the floating tools (Buoy teal) */
40
- dragActive: '#20C997'
41
- };
42
- /**
43
- * Get a color with optional alpha.
44
- * @param color - The base color (hex)
45
- * @param alpha - Alpha value as hex string (00-FF) or number (0-1)
46
- */
47
- function withAlpha(color, alpha) {
48
- if (typeof alpha === 'number') {
49
- // Convert 0-1 to hex
50
- const hex = Math.round(alpha * 255).toString(16).padStart(2, '0');
51
- return `${color}${hex}`;
52
- }
53
- return `${color}${alpha}`;
54
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.floatingToolsColors=void 0,exports.withAlpha=withAlpha;const floatingToolsColors=exports.floatingToolsColors={panel:"#1A1A1A",muted:"#888888",secondary:"#E0E0E0",info:"#20C997",success:"#20C997",optional:"#FFA94D",error:"#EF4444",primary:"#20C997",dragActive:"#20C997"};function withAlpha(o,t){return"number"==typeof t?`${o}${Math.round(255*t).toString(16).padStart(2,"0")}`:`${o}${t}`}
@@ -1,31 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.VISIBLE_HANDLE_WIDTH = exports.STORAGE_KEYS = exports.SAVE_DEBOUNCE_MS = exports.EDGE_PADDING = exports.DRAG_THRESHOLD = exports.ANIMATION_DURATION = void 0;
7
- /**
8
- * Shared constants for floating tools behavior.
9
- * These values ensure consistent behavior across platforms.
10
- */
11
-
12
- /** Width of the visible grip handle when bubble is hidden (pixels) */
13
- const VISIBLE_HANDLE_WIDTH = exports.VISIBLE_HANDLE_WIDTH = 32;
14
-
15
- /** Minimum movement to distinguish drag from tap (pixels) */
16
- const DRAG_THRESHOLD = exports.DRAG_THRESHOLD = 5;
17
-
18
- /** Animation duration for hide/show transitions (milliseconds) */
19
- const ANIMATION_DURATION = exports.ANIMATION_DURATION = 200;
20
-
21
- /** Padding from screen edges (pixels) */
22
- const EDGE_PADDING = exports.EDGE_PADDING = 10;
23
-
24
- /** Debounce delay for position persistence (milliseconds) */
25
- const SAVE_DEBOUNCE_MS = exports.SAVE_DEBOUNCE_MS = 500;
26
-
27
- /** Storage keys for position persistence */
28
- const STORAGE_KEYS = exports.STORAGE_KEYS = {
29
- POSITION_X: '@react_buoy_bubble_position_x',
30
- POSITION_Y: '@react_buoy_bubble_position_y'
31
- };
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.VISIBLE_HANDLE_WIDTH=exports.STORAGE_KEYS=exports.SAVE_DEBOUNCE_MS=exports.EDGE_PADDING=exports.DRAG_THRESHOLD=exports.ANIMATION_DURATION=void 0;const VISIBLE_HANDLE_WIDTH=exports.VISIBLE_HANDLE_WIDTH=32,DRAG_THRESHOLD=exports.DRAG_THRESHOLD=5,ANIMATION_DURATION=exports.ANIMATION_DURATION=200,EDGE_PADDING=exports.EDGE_PADDING=10,SAVE_DEBOUNCE_MS=exports.SAVE_DEBOUNCE_MS=500,STORAGE_KEYS=exports.STORAGE_KEYS={POSITION_X:"@react_buoy_bubble_position_x",POSITION_Y:"@react_buoy_bubble_position_y"};