@buoy-gg/floating-tools-core 2.1.4-beta.1 → 2.1.4

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 (107) hide show
  1. package/lib/commonjs/FloatingToolsStore.js +1 -501
  2. package/lib/commonjs/colors.js +1 -54
  3. package/lib/commonjs/constants.js +1 -31
  4. package/lib/commonjs/devToolsState.js +1 -325
  5. package/lib/commonjs/dial.js +1 -617
  6. package/lib/commonjs/easing.js +1 -69
  7. package/lib/commonjs/icons/benchmark-icon.js +1 -24
  8. package/lib/commonjs/icons/env-icon.js +1 -24
  9. package/lib/commonjs/icons/events-icon.js +1 -24
  10. package/lib/commonjs/icons/highlight-icon.js +1 -24
  11. package/lib/commonjs/icons/icon-data.js +1 -2268
  12. package/lib/commonjs/icons/icon-factories.js +1 -173
  13. package/lib/commonjs/icons/icon-primitives.js +1 -559
  14. package/lib/commonjs/icons/icon-primitives.native.js +1 -779
  15. package/lib/commonjs/icons/icon-renderer.js +1 -260
  16. package/lib/commonjs/icons/network-icon.js +1 -24
  17. package/lib/commonjs/icons/query-icon.js +1 -24
  18. package/lib/commonjs/icons/redux-icon.js +1 -85
  19. package/lib/commonjs/icons/renders-icon.js +1 -33
  20. package/lib/commonjs/icons/routes-icon.js +1 -49
  21. package/lib/commonjs/icons/sentry-icon.js +1 -24
  22. package/lib/commonjs/icons/storage-icon.js +1 -24
  23. package/lib/commonjs/icons/wifi-icon.js +1 -24
  24. package/lib/commonjs/index.js +1 -723
  25. package/lib/commonjs/settings.js +1 -588
  26. package/lib/commonjs/utils.js +1 -72
  27. package/lib/module/FloatingToolsStore.js +1 -496
  28. package/lib/module/colors.js +1 -49
  29. package/lib/module/constants.js +1 -27
  30. package/lib/module/devToolsState.js +1 -318
  31. package/lib/module/dial.js +1 -603
  32. package/lib/module/easing.js +1 -62
  33. package/lib/module/icons/benchmark-icon.js +1 -15
  34. package/lib/module/icons/env-icon.js +1 -15
  35. package/lib/module/icons/events-icon.js +1 -15
  36. package/lib/module/icons/highlight-icon.js +1 -15
  37. package/lib/module/icons/icon-data.js +1 -2264
  38. package/lib/module/icons/icon-factories.js +1 -163
  39. package/lib/module/icons/icon-primitives.js +1 -547
  40. package/lib/module/icons/icon-primitives.native.js +1 -767
  41. package/lib/module/icons/icon-renderer.js +1 -255
  42. package/lib/module/icons/network-icon.js +1 -15
  43. package/lib/module/icons/query-icon.js +1 -15
  44. package/lib/module/icons/redux-icon.js +1 -81
  45. package/lib/module/icons/renders-icon.js +1 -17
  46. package/lib/module/icons/routes-icon.js +1 -41
  47. package/lib/module/icons/sentry-icon.js +1 -15
  48. package/lib/module/icons/storage-icon.js +1 -15
  49. package/lib/module/icons/wifi-icon.js +1 -15
  50. package/lib/module/index.js +1 -103
  51. package/lib/module/settings.js +1 -576
  52. package/lib/module/utils.js +1 -66
  53. package/package.json +1 -1
  54. package/lib/typescript/commonjs/FloatingToolsStore.d.ts.map +0 -1
  55. package/lib/typescript/commonjs/colors.d.ts.map +0 -1
  56. package/lib/typescript/commonjs/constants.d.ts.map +0 -1
  57. package/lib/typescript/commonjs/devToolsState.d.ts.map +0 -1
  58. package/lib/typescript/commonjs/dial.d.ts.map +0 -1
  59. package/lib/typescript/commonjs/easing.d.ts.map +0 -1
  60. package/lib/typescript/commonjs/icons/benchmark-icon.d.ts.map +0 -1
  61. package/lib/typescript/commonjs/icons/env-icon.d.ts.map +0 -1
  62. package/lib/typescript/commonjs/icons/events-icon.d.ts.map +0 -1
  63. package/lib/typescript/commonjs/icons/highlight-icon.d.ts.map +0 -1
  64. package/lib/typescript/commonjs/icons/icon-data.d.ts.map +0 -1
  65. package/lib/typescript/commonjs/icons/icon-factories.d.ts.map +0 -1
  66. package/lib/typescript/commonjs/icons/icon-primitives.d.ts.map +0 -1
  67. package/lib/typescript/commonjs/icons/icon-primitives.native.d.ts.map +0 -1
  68. package/lib/typescript/commonjs/icons/icon-renderer.d.ts.map +0 -1
  69. package/lib/typescript/commonjs/icons/network-icon.d.ts.map +0 -1
  70. package/lib/typescript/commonjs/icons/query-icon.d.ts.map +0 -1
  71. package/lib/typescript/commonjs/icons/redux-icon.d.ts.map +0 -1
  72. package/lib/typescript/commonjs/icons/renders-icon.d.ts.map +0 -1
  73. package/lib/typescript/commonjs/icons/routes-icon.d.ts.map +0 -1
  74. package/lib/typescript/commonjs/icons/sentry-icon.d.ts.map +0 -1
  75. package/lib/typescript/commonjs/icons/storage-icon.d.ts.map +0 -1
  76. package/lib/typescript/commonjs/icons/wifi-icon.d.ts.map +0 -1
  77. package/lib/typescript/commonjs/index.d.ts.map +0 -1
  78. package/lib/typescript/commonjs/settings.d.ts.map +0 -1
  79. package/lib/typescript/commonjs/types.d.ts.map +0 -1
  80. package/lib/typescript/commonjs/utils.d.ts.map +0 -1
  81. package/lib/typescript/module/FloatingToolsStore.d.ts.map +0 -1
  82. package/lib/typescript/module/colors.d.ts.map +0 -1
  83. package/lib/typescript/module/constants.d.ts.map +0 -1
  84. package/lib/typescript/module/devToolsState.d.ts.map +0 -1
  85. package/lib/typescript/module/dial.d.ts.map +0 -1
  86. package/lib/typescript/module/easing.d.ts.map +0 -1
  87. package/lib/typescript/module/icons/benchmark-icon.d.ts.map +0 -1
  88. package/lib/typescript/module/icons/env-icon.d.ts.map +0 -1
  89. package/lib/typescript/module/icons/events-icon.d.ts.map +0 -1
  90. package/lib/typescript/module/icons/highlight-icon.d.ts.map +0 -1
  91. package/lib/typescript/module/icons/icon-data.d.ts.map +0 -1
  92. package/lib/typescript/module/icons/icon-factories.d.ts.map +0 -1
  93. package/lib/typescript/module/icons/icon-primitives.d.ts.map +0 -1
  94. package/lib/typescript/module/icons/icon-primitives.native.d.ts.map +0 -1
  95. package/lib/typescript/module/icons/icon-renderer.d.ts.map +0 -1
  96. package/lib/typescript/module/icons/network-icon.d.ts.map +0 -1
  97. package/lib/typescript/module/icons/query-icon.d.ts.map +0 -1
  98. package/lib/typescript/module/icons/redux-icon.d.ts.map +0 -1
  99. package/lib/typescript/module/icons/renders-icon.d.ts.map +0 -1
  100. package/lib/typescript/module/icons/routes-icon.d.ts.map +0 -1
  101. package/lib/typescript/module/icons/sentry-icon.d.ts.map +0 -1
  102. package/lib/typescript/module/icons/storage-icon.d.ts.map +0 -1
  103. package/lib/typescript/module/icons/wifi-icon.d.ts.map +0 -1
  104. package/lib/typescript/module/index.d.ts.map +0 -1
  105. package/lib/typescript/module/settings.d.ts.map +0 -1
  106. package/lib/typescript/module/types.d.ts.map +0 -1
  107. package/lib/typescript/module/utils.d.ts.map +0 -1
@@ -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"};