@buoy-gg/core 1.7.7 → 2.1.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 (77) hide show
  1. package/lib/commonjs/floatingMenu/AppHost.js +3 -3
  2. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +25 -13
  3. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +746 -0
  4. package/lib/commonjs/floatingMenu/FloatingDevTools.js +16 -4
  5. package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +153 -0
  6. package/lib/commonjs/floatingMenu/FloatingMenu.js +8 -8
  7. package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +2 -2
  8. package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +30 -0
  9. package/lib/commonjs/floatingMenu/defaultConfig.js +14 -7
  10. package/lib/commonjs/floatingMenu/dial/DialDevTools.js +12 -6
  11. package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +593 -0
  12. package/lib/commonjs/floatingMenu/floatingTools.js +218 -38
  13. package/lib/commonjs/floatingMenu/floatingTools.web.js +357 -0
  14. package/lib/commonjs/index.js +2 -2
  15. package/lib/commonjs/index.web.js +131 -0
  16. package/lib/commonjs/utils/autoDiscoverPresets.web.js +181 -0
  17. package/lib/module/floatingMenu/AppHost.js +4 -4
  18. package/lib/module/floatingMenu/DevToolsSettingsModal.js +28 -16
  19. package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +756 -0
  20. package/lib/module/floatingMenu/FloatingDevTools.js +17 -5
  21. package/lib/module/floatingMenu/FloatingDevTools.web.js +149 -0
  22. package/lib/module/floatingMenu/FloatingMenu.js +9 -9
  23. package/lib/module/floatingMenu/MinimizedToolsContext.js +3 -3
  24. package/lib/module/floatingMenu/autoDiscoverPresets.js +30 -0
  25. package/lib/module/floatingMenu/defaultConfig.js +14 -7
  26. package/lib/module/floatingMenu/dial/DialDevTools.js +13 -7
  27. package/lib/module/floatingMenu/dial/DialDevTools.web.js +590 -0
  28. package/lib/module/floatingMenu/floatingTools.js +219 -39
  29. package/lib/module/floatingMenu/floatingTools.web.js +357 -0
  30. package/lib/module/index.js +2 -2
  31. package/lib/module/index.web.js +24 -0
  32. package/lib/module/utils/autoDiscoverPresets.web.js +174 -0
  33. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +23 -0
  35. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -0
  36. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts +1 -1
  37. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +48 -0
  39. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -0
  40. package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -1
  41. package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +8 -7
  43. package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts.map +1 -1
  44. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  45. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts +26 -0
  46. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -0
  47. package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts +1 -1
  48. package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts.map +1 -1
  49. package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts +27 -0
  50. package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +1 -0
  51. package/lib/typescript/commonjs/index.web.d.ts +20 -0
  52. package/lib/typescript/commonjs/index.web.d.ts.map +1 -0
  53. package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts +58 -0
  54. package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts.map +1 -0
  55. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
  56. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +23 -0
  57. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -0
  58. package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts +1 -1
  59. package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -1
  60. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +48 -0
  61. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -0
  62. package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -1
  63. package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
  64. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +8 -7
  65. package/lib/typescript/module/floatingMenu/defaultConfig.d.ts.map +1 -1
  66. package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  67. package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts +26 -0
  68. package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -0
  69. package/lib/typescript/module/floatingMenu/floatingTools.d.ts +1 -1
  70. package/lib/typescript/module/floatingMenu/floatingTools.d.ts.map +1 -1
  71. package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts +27 -0
  72. package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +1 -0
  73. package/lib/typescript/module/index.web.d.ts +20 -0
  74. package/lib/typescript/module/index.web.d.ts.map +1 -0
  75. package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts +58 -0
  76. package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts.map +1 -0
  77. package/package.json +5 -4
@@ -0,0 +1,357 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * FloatingTools - Web renderer using shared React bindings.
5
+ *
6
+ * This file contains ONLY web-specific code (React DOM):
7
+ * - Mouse event handling
8
+ * - requestAnimationFrame animation
9
+ * - Web JSX (div, span)
10
+ * - localStorage adapter
11
+ *
12
+ * All logic is shared via @buoy-gg/floating-tools-react
13
+ *
14
+ * @platform React DOM Web (Vite, CRA, Next.js, Electron)
15
+ */
16
+
17
+ import { useState, useRef, useCallback, useEffect, useMemo, Children } from 'react';
18
+ import {
19
+ // Hook and context
20
+ useFloatingTools, FloatingToolsProvider, useFloatingToolsContext, interleaveWithDividers,
21
+ // Utils from core (re-exported)
22
+ floatingToolsColors, withAlpha, getUserStatusConfig, getGripIconLayout, interpolatePosition, easing, VISIBLE_HANDLE_WIDTH, ANIMATION_DURATION
23
+ // Types
24
+ } from '@buoy-gg/floating-tools-react';
25
+
26
+ // Re-export for consumers
27
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
28
+ // =============================
29
+ // Web Storage Adapter
30
+ // =============================
31
+ const webStorageAdapter = {
32
+ getItem: key => localStorage.getItem(key),
33
+ setItem: (key, value) => localStorage.setItem(key, value)
34
+ };
35
+
36
+ // =============================
37
+ // GripVerticalIcon (web JSX)
38
+ // =============================
39
+ function GripVerticalIcon({
40
+ size = 24,
41
+ color = withAlpha(floatingToolsColors.secondary, 'CC')
42
+ }) {
43
+ const layout = getGripIconLayout(size);
44
+ return /*#__PURE__*/_jsx("div", {
45
+ style: {
46
+ width: size,
47
+ height: size,
48
+ display: 'flex',
49
+ flexDirection: 'row',
50
+ alignItems: 'center',
51
+ justifyContent: 'center'
52
+ },
53
+ children: [0, 1].map(col => /*#__PURE__*/_jsx("div", {
54
+ style: {
55
+ display: 'flex',
56
+ flexDirection: 'column',
57
+ alignItems: 'center',
58
+ justifyContent: 'center',
59
+ marginLeft: col === 0 ? 0 : layout.columnGap
60
+ },
61
+ children: [0, 1, 2].map(row => /*#__PURE__*/_jsx("div", {
62
+ style: {
63
+ width: layout.dotSize,
64
+ height: layout.dotSize,
65
+ borderRadius: layout.dotSize / 2,
66
+ backgroundColor: color,
67
+ marginTop: row === 0 ? 0 : layout.rowGap
68
+ }
69
+ }, row))
70
+ }, col))
71
+ });
72
+ }
73
+
74
+ // =============================
75
+ // Divider (web JSX)
76
+ // =============================
77
+ export function Divider() {
78
+ return /*#__PURE__*/_jsx("div", {
79
+ style: {
80
+ width: 1,
81
+ height: 12,
82
+ backgroundColor: withAlpha(floatingToolsColors.muted, '66'),
83
+ flexShrink: 0
84
+ }
85
+ });
86
+ }
87
+
88
+ // =============================
89
+ // UserStatus (web JSX)
90
+ // =============================
91
+ export function UserStatus({
92
+ userRole,
93
+ onPress
94
+ }) {
95
+ const {
96
+ isDragging
97
+ } = useFloatingToolsContext();
98
+ const config = getUserStatusConfig(userRole, floatingToolsColors);
99
+ const handleClick = e => {
100
+ if (!isDragging && onPress) {
101
+ e.stopPropagation();
102
+ onPress();
103
+ }
104
+ };
105
+ return /*#__PURE__*/_jsxs("button", {
106
+ role: "button",
107
+ "aria-label": `User status: ${config.label}`,
108
+ onClick: handleClick,
109
+ style: {
110
+ display: 'flex',
111
+ flexDirection: 'row',
112
+ alignItems: 'center',
113
+ paddingTop: 6,
114
+ paddingBottom: 6,
115
+ paddingLeft: 8,
116
+ paddingRight: 8,
117
+ flexShrink: 0,
118
+ cursor: onPress && !isDragging ? 'pointer' : 'default',
119
+ background: 'none',
120
+ border: 'none'
121
+ },
122
+ children: [/*#__PURE__*/_jsx("div", {
123
+ style: {
124
+ width: 6,
125
+ height: 6,
126
+ borderRadius: 3,
127
+ backgroundColor: config.dotColor,
128
+ marginRight: 4
129
+ }
130
+ }), /*#__PURE__*/_jsx("span", {
131
+ style: {
132
+ fontSize: 10,
133
+ fontWeight: 500,
134
+ color: config.textColor,
135
+ letterSpacing: 0.3
136
+ },
137
+ children: config.label
138
+ })]
139
+ });
140
+ }
141
+
142
+ // =============================
143
+ // Web Animation Hook
144
+ // =============================
145
+ function useWebAnimation() {
146
+ const animationRef = useRef(null);
147
+ const [position, setPosition] = useState({
148
+ x: 0,
149
+ y: 0
150
+ });
151
+ const animateTo = useCallback((from, to, onComplete) => {
152
+ if (animationRef.current) {
153
+ cancelAnimationFrame(animationRef.current);
154
+ }
155
+ const startTime = performance.now();
156
+ const animate = currentTime => {
157
+ const elapsed = currentTime - startTime;
158
+ const progress = Math.min(elapsed / ANIMATION_DURATION, 1);
159
+ const newPosition = interpolatePosition(from, to, progress, easing.easeOutCubic);
160
+ setPosition(newPosition);
161
+ if (progress < 1) {
162
+ animationRef.current = requestAnimationFrame(animate);
163
+ } else {
164
+ setPosition(to);
165
+ onComplete?.();
166
+ }
167
+ };
168
+ animationRef.current = requestAnimationFrame(animate);
169
+ }, []);
170
+ useEffect(() => {
171
+ return () => {
172
+ if (animationRef.current) {
173
+ cancelAnimationFrame(animationRef.current);
174
+ }
175
+ };
176
+ }, []);
177
+ return {
178
+ position,
179
+ setPosition,
180
+ animateTo
181
+ };
182
+ }
183
+
184
+ // =============================
185
+ // Main FloatingTools Component
186
+ // =============================
187
+
188
+ export function FloatingTools({
189
+ enablePositionPersistence = true,
190
+ children
191
+ }) {
192
+ const bubbleRef = useRef(null);
193
+
194
+ // Use shared hook
195
+ const {
196
+ state,
197
+ actions,
198
+ isInitialized
199
+ } = useFloatingTools({
200
+ screenSize: {
201
+ width: window.innerWidth,
202
+ height: window.innerHeight
203
+ },
204
+ enablePositionPersistence,
205
+ storage: webStorageAdapter
206
+ });
207
+
208
+ // Web-specific animation
209
+ const {
210
+ position: animatedPosition,
211
+ setPosition: setAnimatedPosition,
212
+ animateTo
213
+ } = useWebAnimation();
214
+
215
+ // Sync position when initialized
216
+ useEffect(() => {
217
+ if (isInitialized) {
218
+ setAnimatedPosition(state.position);
219
+ }
220
+ }, [isInitialized, state.position, setAnimatedPosition]);
221
+
222
+ // Handle window resize
223
+ useEffect(() => {
224
+ const handleResize = () => {
225
+ actions.setScreenSize(window.innerWidth, window.innerHeight);
226
+ };
227
+ window.addEventListener('resize', handleResize);
228
+ return () => window.removeEventListener('resize', handleResize);
229
+ }, [actions]);
230
+
231
+ // Update bubble size on layout
232
+ const [bubbleMeasured, setBubbleMeasured] = useState(false);
233
+ useEffect(() => {
234
+ if (!bubbleMeasured && bubbleRef.current) {
235
+ const rect = bubbleRef.current.getBoundingClientRect();
236
+ if (rect.width > 0 && rect.height > 0) {
237
+ actions.setBubbleSize({
238
+ width: rect.width,
239
+ height: rect.height
240
+ });
241
+ setBubbleMeasured(true);
242
+ }
243
+ }
244
+ }, [bubbleMeasured, actions]);
245
+
246
+ // Web-specific: mouse event handling
247
+ const [isMouseDown, setIsMouseDown] = useState(false);
248
+ const handleMouseDown = useCallback(e => {
249
+ e.preventDefault();
250
+ setIsMouseDown(true);
251
+ actions.handleDragStart({
252
+ clientX: e.clientX,
253
+ clientY: e.clientY
254
+ });
255
+ }, [actions]);
256
+ const handleMouseMove = useCallback(e => {
257
+ const result = actions.handleDragMove({
258
+ clientX: e.clientX,
259
+ clientY: e.clientY
260
+ });
261
+ if (result.isDragging) {
262
+ setAnimatedPosition(result.position);
263
+ }
264
+ }, [actions, setAnimatedPosition]);
265
+ const handleMouseUp = useCallback(e => {
266
+ setIsMouseDown(false);
267
+ const result = actions.handleDragEnd({
268
+ clientX: e.clientX,
269
+ clientY: e.clientY
270
+ });
271
+ if (result.wasTap) {
272
+ const toggleResult = actions.toggleHideShow();
273
+ animateTo(state.position, toggleResult.targetPosition, () => {
274
+ actions.commitPosition(toggleResult.targetPosition);
275
+ });
276
+ } else if (result.shouldHide) {
277
+ animateTo(state.position, result.position, () => {
278
+ actions.commitPosition(result.position);
279
+ });
280
+ }
281
+ }, [actions, animateTo, state.position]);
282
+ useEffect(() => {
283
+ if (isMouseDown) {
284
+ window.addEventListener('mousemove', handleMouseMove);
285
+ window.addEventListener('mouseup', handleMouseUp);
286
+ return () => {
287
+ window.removeEventListener('mousemove', handleMouseMove);
288
+ window.removeEventListener('mouseup', handleMouseUp);
289
+ };
290
+ }
291
+ }, [isMouseDown, handleMouseMove, handleMouseUp]);
292
+
293
+ // Interleave children with dividers
294
+ const actionsContent = useMemo(() => interleaveWithDividers(Children.toArray(children), key => /*#__PURE__*/_jsx(Divider, {}, key)), [children]);
295
+ return /*#__PURE__*/_jsxs("div", {
296
+ ref: bubbleRef,
297
+ role: "toolbar",
298
+ "aria-label": "Floating Tools",
299
+ style: {
300
+ position: 'fixed',
301
+ left: animatedPosition.x,
302
+ top: animatedPosition.y,
303
+ zIndex: 9999,
304
+ display: 'flex',
305
+ flexDirection: 'row',
306
+ alignItems: 'center',
307
+ backgroundColor: floatingToolsColors.panel,
308
+ borderRadius: 6,
309
+ borderWidth: state.isDragging ? 2 : 1,
310
+ borderStyle: 'solid',
311
+ borderColor: state.isDragging ? floatingToolsColors.dragActive : withAlpha(floatingToolsColors.muted, '66'),
312
+ boxShadow: state.isDragging ? `0 6px 12px ${withAlpha(floatingToolsColors.dragActive, '99')}` : '0 4px 8px rgba(0, 0, 0, 0.3)',
313
+ userSelect: 'none',
314
+ touchAction: 'none'
315
+ },
316
+ children: [/*#__PURE__*/_jsx("div", {
317
+ role: "slider",
318
+ "aria-label": "Drag handle",
319
+ "aria-valuetext": `Position: ${Math.round(animatedPosition.x)}, ${Math.round(animatedPosition.y)}`,
320
+ tabIndex: 0,
321
+ onMouseDown: handleMouseDown,
322
+ style: {
323
+ paddingLeft: 6,
324
+ paddingRight: 6,
325
+ paddingTop: 6,
326
+ paddingBottom: 6,
327
+ backgroundColor: withAlpha(floatingToolsColors.muted, '1A'),
328
+ display: 'flex',
329
+ alignItems: 'center',
330
+ justifyContent: 'center',
331
+ width: VISIBLE_HANDLE_WIDTH,
332
+ borderRight: `1px solid ${withAlpha(floatingToolsColors.muted, '66')}`,
333
+ borderTopLeftRadius: 5,
334
+ borderBottomLeftRadius: 5,
335
+ cursor: state.isDragging ? 'grabbing' : 'grab'
336
+ },
337
+ children: /*#__PURE__*/_jsx(GripVerticalIcon, {
338
+ size: 12
339
+ })
340
+ }), /*#__PURE__*/_jsx(FloatingToolsProvider, {
341
+ value: {
342
+ isDragging: state.isDragging,
343
+ isHidden: state.isHidden
344
+ },
345
+ children: /*#__PURE__*/_jsx("div", {
346
+ style: {
347
+ display: 'flex',
348
+ flexDirection: 'row',
349
+ alignItems: 'center',
350
+ gap: 6,
351
+ paddingRight: 8
352
+ },
353
+ children: actionsContent
354
+ })
355
+ })]
356
+ });
357
+ }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  // Export unified component - primary interface
4
- export { FloatingDevTools } from "./floatingMenu/FloatingDevTools.js";
4
+ export { FloatingDevTools } from "./floatingMenu/FloatingDevTools";
5
5
  // Export auto-discovery utilities
6
6
  export { autoDiscoverPresets, autoDiscoverPresetsWithCustom } from "./floatingMenu/autoDiscoverPresets.js";
7
7
 
@@ -10,7 +10,7 @@ export { createDefaultConfig, validateDialConfig, isFloatingToolId, isDialToolId
10
10
  // Export FloatingMenu and its types
11
11
  export { FloatingMenu } from "./floatingMenu/FloatingMenu.js";
12
12
  export * from "./floatingMenu/types.js";
13
- export { DevToolsSettingsModal, useDevToolsSettings } from "./floatingMenu/DevToolsSettingsModal.js";
13
+ export { DevToolsSettingsModal, useDevToolsSettings } from "./floatingMenu/DevToolsSettingsModal";
14
14
  // Export AppHost components for advanced use cases
15
15
  export { AppHostProvider, AppOverlay, useAppHost } from "./floatingMenu/AppHost.js";
16
16
 
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * @buoy-gg/core - Web Entry Point
5
+ *
6
+ * This is the entry point for React DOM Web apps (Vite, CRA, Next.js, Electron).
7
+ * Bundlers will automatically resolve this file over index.tsx for web builds.
8
+ *
9
+ * @platform React DOM Web
10
+ */
11
+
12
+ // Export unified component - primary interface (web version)
13
+ export { FloatingDevTools } from "./floatingMenu/FloatingDevTools.web.js";
14
+ // Export individual web components for advanced use cases
15
+ export { FloatingTools, UserStatus, Divider } from "./floatingMenu/floatingTools.web.js";
16
+ export { DialMenu } from "./floatingMenu/dial/DialDevTools.web.js";
17
+ export { SettingsModal } from "./floatingMenu/DevToolsSettingsModal.web.js";
18
+ // Export auto-discovery utilities (web version)
19
+ export { autoDiscoverWebPresets, autoDiscoverWithCustom, getToolsBySlot, getEnabledTools, defaultToolPresets } from "./utils/autoDiscoverPresets.web.js";
20
+
21
+ // Re-export types from floating-tools-react for convenience
22
+
23
+ // Re-export commonly used utilities from floating-tools-react
24
+ export { useSettings, useFloatingTools, getToolLabel, getToolDescription, getToolColor, settingsColors, settingsStyles, dialColors, dialStyles } from "@buoy-gg/floating-tools-react";
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Auto-discovery utility for React DOM Web.
5
+ *
6
+ * Uses Vite's import.meta.glob to discover installed @buoy-gg/* packages
7
+ * at build time. This provides Metro-like auto-discovery behavior for web.
8
+ *
9
+ * How it works:
10
+ * 1. import.meta.glob scans node_modules at build time
11
+ * 2. Only packages that are actually installed are included
12
+ * 3. Missing packages don't cause errors (like Metro's try-catch)
13
+ * 4. Custom tools can override discovered ones by ID
14
+ *
15
+ * @platform React DOM Web (Vite, CRA, Next.js, Electron)
16
+ */
17
+
18
+ import { NetworkIcon, EnvIcon } from '@buoy-gg/floating-tools-core';
19
+
20
+ // =============================
21
+ // Default Tool Presets (Fallback)
22
+ // =============================
23
+
24
+ /**
25
+ * Default tool presets for when packages don't export web presets yet.
26
+ * These will be used until each @buoy-gg/* package exports its own preset.
27
+ */
28
+ import { jsx as _jsx } from "react/jsx-runtime";
29
+ export const defaultToolPresets = [{
30
+ id: 'env',
31
+ name: 'ENV',
32
+ description: 'Environment variables debugger',
33
+ slot: 'both',
34
+ icon: size => /*#__PURE__*/_jsx(EnvIcon, {
35
+ size: size
36
+ }),
37
+ color: '#4AFF9F'
38
+ }, {
39
+ id: 'storage',
40
+ name: 'STORAGE',
41
+ description: 'AsyncStorage browser',
42
+ slot: 'both',
43
+ icon: '💾',
44
+ color: '#BA68C8'
45
+ }, {
46
+ id: 'network',
47
+ name: 'NET',
48
+ description: 'Network request logger',
49
+ slot: 'both',
50
+ icon: size => /*#__PURE__*/_jsx(NetworkIcon, {
51
+ size: size
52
+ }),
53
+ color: '#4AFF9F'
54
+ }, {
55
+ id: 'query',
56
+ name: 'QUERY',
57
+ description: 'React Query inspector',
58
+ slot: 'both',
59
+ icon: '🔍',
60
+ color: '#FF4154'
61
+ }, {
62
+ id: 'route-events',
63
+ name: 'ROUTES',
64
+ description: 'Route tracking & navigation inspector',
65
+ slot: 'both',
66
+ icon: '🗺️',
67
+ color: '#FF9F1C'
68
+ }, {
69
+ id: 'highlight-updates',
70
+ name: 'RENDERS',
71
+ description: 'View component render tracking',
72
+ slot: 'dial',
73
+ icon: '✨',
74
+ color: '#10b981'
75
+ }, {
76
+ id: 'debug-borders',
77
+ name: 'DEBUG BORDERS',
78
+ description: 'Component layout borders',
79
+ slot: 'dial',
80
+ icon: '📐',
81
+ color: '#10b981'
82
+ }, {
83
+ id: 'benchmark',
84
+ name: 'BENCHMARK',
85
+ description: 'Performance benchmarks',
86
+ slot: 'dial',
87
+ icon: '⚡',
88
+ color: '#F59E0B'
89
+ }];
90
+
91
+ // =============================
92
+ // Auto-Discovery Functions
93
+ // =============================
94
+
95
+ /**
96
+ * Auto-discover installed @buoy-gg/* tool packages.
97
+ *
98
+ * Uses Vite's import.meta.glob to find packages at build time.
99
+ * Only installed packages are included (no errors for missing ones).
100
+ *
101
+ * Note: Until packages export web presets, this returns default presets.
102
+ *
103
+ * @returns Array of discovered tool configurations
104
+ */
105
+ export function autoDiscoverWebPresets() {
106
+ // TODO: When @buoy-gg/* packages export web presets, use import.meta.glob:
107
+ //
108
+ // const modules = import.meta.glob(
109
+ // '/node_modules/@buoy-gg/*/dist/preset.{js,mjs}',
110
+ // { eager: true, import: 'default' }
111
+ // );
112
+ //
113
+ // const presets: WebToolConfig[] = [];
114
+ // for (const [path, preset] of Object.entries(modules)) {
115
+ // if (preset && typeof preset === 'object' && 'id' in preset) {
116
+ // presets.push(preset as WebToolConfig);
117
+ // }
118
+ // }
119
+ // return presets;
120
+
121
+ // For now, return default presets
122
+ return [...defaultToolPresets];
123
+ }
124
+
125
+ /**
126
+ * Merge custom tools with auto-discovered ones.
127
+ *
128
+ * Custom tools take precedence - if a custom tool has the same ID as
129
+ * a discovered tool, the custom one is used (same behavior as mobile).
130
+ *
131
+ * @param customTools - Custom tools to merge (optional)
132
+ * @returns Merged array with custom tools taking precedence
133
+ */
134
+ export function autoDiscoverWithCustom(customTools = []) {
135
+ const discovered = autoDiscoverWebPresets();
136
+ if (customTools.length === 0) {
137
+ return discovered;
138
+ }
139
+
140
+ // Create set of custom tool IDs for quick lookup
141
+ const customIds = new Set(customTools.map(t => t.id));
142
+
143
+ // Filter out discovered tools that have custom overrides
144
+ const filteredDiscovered = discovered.filter(t => !customIds.has(t.id));
145
+
146
+ // Custom tools first, then remaining discovered
147
+ return [...customTools, ...filteredDiscovered];
148
+ }
149
+
150
+ /**
151
+ * Get tools filtered by slot.
152
+ *
153
+ * @param tools - Array of tool configurations
154
+ * @param slot - Slot to filter by ('dial' or 'row')
155
+ * @returns Filtered array of tools that can appear in the specified slot
156
+ */
157
+ export function getToolsBySlot(tools, slot) {
158
+ return tools.filter(tool => {
159
+ const toolSlot = tool.slot || 'both';
160
+ return toolSlot === 'both' || toolSlot === slot;
161
+ });
162
+ }
163
+
164
+ /**
165
+ * Get enabled tools based on settings.
166
+ *
167
+ * @param tools - Array of all tool configurations
168
+ * @param enabledIds - Set or array of enabled tool IDs
169
+ * @returns Filtered array of enabled tools
170
+ */
171
+ export function getEnabledTools(tools, enabledIds) {
172
+ const idSet = enabledIds instanceof Set ? enabledIds : new Set(enabledIds);
173
+ return tools.filter(tool => idSet.has(tool.id));
174
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsSettingsModal.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/DevToolsSettingsModal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6C,EAAE,EAAE,MAAM,OAAO,CAAC;AA8MtE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QACvC,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,kDAAkD;IAClD,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAED,UAAU,0BAA0B;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,aAAa,CAAC,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;KAChC,EAAE,CAAC;CACL;AAsDD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CAgrChE,CAAC;AAiDF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;;;CAuD/B,CAAC"}
1
+ {"version":3,"file":"DevToolsSettingsModal.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/DevToolsSettingsModal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6C,EAAE,EAAE,MAAM,OAAO,CAAC;AA4MtE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QACvC,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,kDAAkD;IAClD,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAED,UAAU,0BAA0B;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,aAAa,CAAC,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;KAChC,EAAE,CAAC;CACL;AA0DD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CAkrChE,CAAC;AAwDF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;;;CAuD/B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * DevToolsSettingsModal - Web renderer for the dev tools settings modal.
3
+ *
4
+ * Uses shared configuration and logic from @buoy-gg/floating-tools-react.
5
+ * Platform-specific: CSS, mouse events, web JSX.
6
+ *
7
+ * This follows the same pattern as DialDevTools - all colors, labels, descriptions,
8
+ * and styling constants come from the shared core package.
9
+ *
10
+ * @platform React DOM Web (Vite, CRA, Next.js, Electron)
11
+ */
12
+ import { type AvailableToolConfig, type DevToolsSettings, type StorageAdapter } from '@buoy-gg/floating-tools-react';
13
+ export interface SettingsModalProps {
14
+ visible: boolean;
15
+ onClose: () => void;
16
+ availableTools?: AvailableToolConfig[];
17
+ defaultFloatingTools?: string[];
18
+ defaultDialTools?: string[];
19
+ storage?: StorageAdapter;
20
+ onSettingsChange?: (settings: DevToolsSettings) => void;
21
+ }
22
+ export declare function SettingsModal({ visible, onClose, availableTools, defaultFloatingTools, defaultDialTools, storage, onSettingsChange, }: SettingsModalProps): import("react").JSX.Element | null;
23
+ //# sourceMappingURL=DevToolsSettingsModal.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevToolsSettingsModal.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/DevToolsSettingsModal.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAiBL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEpB,MAAM,+BAA+B,CAAC;AAOvC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACzD;AAoQD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,OAAO,EACP,cAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,OAA2B,EAC3B,gBAAgB,GACjB,EAAE,kBAAkB,sCAiYpB"}
@@ -222,5 +222,5 @@ export interface FloatingDevToolsProps extends Omit<FloatingMenuProps, "apps"> {
222
222
  *
223
223
  * @param props - FloatingDevTools props
224
224
  */
225
- export declare const FloatingDevTools: ({ apps, requiredEnvVars, requiredStorageKeys, children, disableHints, defaultFloatingTools, defaultDialTools, ...props }: FloatingDevToolsProps) => React.JSX.Element;
225
+ export declare const FloatingDevTools: ({ apps, requiredEnvVars, requiredStorageKeys, children, disableHints, defaultFloatingTools, defaultDialTools, ...props }: FloatingDevToolsProps) => React.JSX.Element | null;
226
226
  //# sourceMappingURL=FloatingDevTools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingDevTools.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/FloatingDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAG1E,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAC;AAIzB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC1C;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAC5E;;;;;OAKG;IACH,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;IAEjC;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEzC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAE7C;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IAErC;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,OAAO,oBAAoB,EAAE,WAAW,EAAE,CAAC;IAEnE;;;;;;;;;;;;;OAaG;IACH,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,oBAAoB,EAAE,WAAW,KAAK,IAAI,CAAC;CAEvF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,gBAAgB,GAAI,0HAS9B,qBAAqB,sBAuIvB,CAAC"}
1
+ {"version":3,"file":"FloatingDevTools.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/FloatingDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAG1E,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAC;AAIzB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACD;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;IACV,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC1C;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAC5E;;;;;OAKG;IACH,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;IAEjC;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEzC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAE7C;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IAErC;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,OAAO,oBAAoB,EAAE,WAAW,EAAE,CAAC;IAEnE;;;;;;;;;;;;;OAaG;IACH,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,oBAAoB,EAAE,WAAW,KAAK,IAAI,CAAC;CAEvF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,gBAAgB,GAAI,0HAS9B,qBAAqB,6BAmJvB,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * FloatingDevTools - Unified dev tools component for React DOM Web.
3
+ *
4
+ * Matches the mobile FloatingDevTools API exactly:
5
+ * - Self-contained (doesn't wrap your app)
6
+ * - Auto-discovers installed tool packages
7
+ * - Manages dial menu and settings modal state internally
8
+ *
9
+ * Usage (same as mobile):
10
+ * ```tsx
11
+ * <>
12
+ * <YourApp />
13
+ * <FloatingDevTools environment="qa" userRole="admin" />
14
+ * </>
15
+ * ```
16
+ *
17
+ * @platform React DOM Web (Vite, CRA, Next.js, Electron)
18
+ */
19
+ import { type WebToolConfig, type Environment, type UserRole } from '@buoy-gg/floating-tools-react';
20
+ export interface FloatingDevToolsProps {
21
+ /** Current environment (local, dev, qa, staging, prod) */
22
+ environment?: Environment;
23
+ /** Current user role (admin, internal, user) */
24
+ userRole?: UserRole;
25
+ /** Available environments for switching */
26
+ availableEnvironments?: Environment[];
27
+ /** Callback when environment is switched */
28
+ onEnvironmentSwitch?: (env: Environment) => void;
29
+ /** Custom tools to add (will be merged with auto-discovered) */
30
+ apps?: WebToolConfig[];
31
+ /** Disable onboarding hints (not implemented yet) */
32
+ disableHints?: boolean;
33
+ }
34
+ /**
35
+ * Unified FloatingDevTools component - self-contained, no wrapping required.
36
+ *
37
+ * Matches mobile API exactly:
38
+ * ```tsx
39
+ * // Mobile
40
+ * <FloatingDevTools environment="qa" userRole={userRole} />
41
+ *
42
+ * // Web (this component)
43
+ * <FloatingDevTools environment="qa" userRole="admin" />
44
+ * ```
45
+ */
46
+ export declare function FloatingDevTools({ environment: _environment, userRole, availableEnvironments: _availableEnvironments, onEnvironmentSwitch: _onEnvironmentSwitch, apps, disableHints: _disableHints, }: FloatingDevToolsProps): import("react").JSX.Element;
47
+ export type { WebToolConfig, Environment, UserRole };
48
+ //# sourceMappingURL=FloatingDevTools.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingDevTools.web.d.ts","sourceRoot":"","sources":["../../../../src/floatingMenu/FloatingDevTools.web.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EAId,MAAM,+BAA+B,CAAC;AAUvC,MAAM,WAAW,qBAAqB;IAEpC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,2CAA2C;IAC3C,qBAAqB,CAAC,EAAE,WAAW,EAAE,CAAC;IACtC,4CAA4C;IAC5C,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;IAGjD,gEAAgE;IAChE,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC;IAGvB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,WAAW,EAAE,YAAY,EACzB,QAAQ,EACR,qBAAqB,EAAE,sBAAsB,EAC7C,mBAAmB,EAAE,oBAAoB,EACzC,IAAI,EACJ,YAAY,EAAE,aAAa,GAC5B,EAAE,qBAAqB,+BA8GvB;AAMD,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC"}