@buoy-gg/floating-tools-react 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +529 -0
- package/dist/index.d.ts +529 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/package.json +39 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import { FloatingToolsOptions, FloatingToolsState, FloatingToolsStore, DragEventData, Position, DragEndResult, AvailableToolConfig, StorageAdapter, DevToolsSettings, DevToolsStateManager, DevToolsState, SettingsTabKey, WebToolConfig, Environment, UserRole } from '@buoy-gg/floating-tools-core';
|
|
2
|
+
export { ANIMATION_DURATION, AvailableToolConfig, BaseToolConfig, DIAL_BUTTON_SIZE, DIAL_GRID_LINE_COUNT, DIAL_ICON_PADDING, DIAL_ICON_SIZE, DIAL_START_ANGLE, DRAG_THRESHOLD, DevToolsAction, DevToolsSettings, DevToolsState, DevToolsStateManager, DialAnimationConfigType, DialCSSBezierKey, DialColorKey, DialEasingName, DialLayout, DialLayoutConfig, DragEndResult, DragEventData, EDGE_PADDING, EasingFunction, Environment, FloatingToolsState, FloatingToolsStore, GlobalDevToolsSettings, GlobalSettingConfig, GripIconLayout, IconPosition, MAX_DIAL_SLOTS, MAX_SETTINGS_DIAL_SLOTS, MergeSettingsOptions, Position, SETTINGS_STORAGE_KEY, SettingsColorKey, SettingsEventBus, SettingsTab, SettingsTabKey, Size, SpiralPosition, SpringConfig, StorageAdapter, ToolMetadata, ToolSlot, UserRole, UserStatusConfig, VISIBLE_HANDLE_WIDTH, WebToolConfig, canEnableDialTool, countEnabledTools, devToolsReducer, devToolsStateManager, dialAnimationConfig, dialCSSBeziers, dialColors, dialStyles, easing, enforceDialLimit, floatingToolsColors, generateDefaultSettings, generateDialCSSKeyframes, getAllIconPositions, getDialCSSAnimationStyles, getDialCSSKeyframesString, getDialLayout, getEnabledToolIds, getGridLineRotations, getGripIconLayout, getIconAngle, getIconPosition, getIconStaggerInputRange, getSpiralAnimationPosition, getStaggeredIconProgress, getToolColor, getToolDescription, getToolLabel, getUserStatusConfig, globalSettingsConfig, interpolate, interpolatePosition, mergeSettingsWithDefaults, sanitizeFloatingSettings, settingsColors, settingsEventBus, settingsStyles, settingsTabs, toolColors, toolDescriptions, toolLabels, withAlpha } from '@buoy-gg/floating-tools-core';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
import { ReactNode, ReactElement } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* useFloatingTools - React hook for floating tools state management.
|
|
9
|
+
* Works with both web and React Native.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface UseFloatingToolsOptions extends Omit<FloatingToolsOptions, 'screenWidth' | 'screenHeight'> {
|
|
13
|
+
/**
|
|
14
|
+
* Screen dimensions. Required for boundary calculations.
|
|
15
|
+
* On web: { width: window.innerWidth, height: window.innerHeight }
|
|
16
|
+
* On RN: Dimensions.get('window')
|
|
17
|
+
*/
|
|
18
|
+
screenSize: {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
interface UseFloatingToolsReturn {
|
|
24
|
+
/** Current state (position, isDragging, isHidden, bubbleSize) */
|
|
25
|
+
state: FloatingToolsState;
|
|
26
|
+
/** The underlying store instance */
|
|
27
|
+
store: FloatingToolsStore;
|
|
28
|
+
/** Whether the store has been initialized (position loaded from storage) */
|
|
29
|
+
isInitialized: boolean;
|
|
30
|
+
/** Actions */
|
|
31
|
+
actions: {
|
|
32
|
+
/** Start a drag operation */
|
|
33
|
+
handleDragStart: (event: DragEventData) => void;
|
|
34
|
+
/** Process drag movement */
|
|
35
|
+
handleDragMove: (event: DragEventData) => {
|
|
36
|
+
position: Position;
|
|
37
|
+
isDragging: boolean;
|
|
38
|
+
};
|
|
39
|
+
/** End a drag operation */
|
|
40
|
+
handleDragEnd: (event: DragEventData) => DragEndResult;
|
|
41
|
+
/** Toggle between hidden and visible states */
|
|
42
|
+
toggleHideShow: () => {
|
|
43
|
+
targetPosition: Position;
|
|
44
|
+
isHiding: boolean;
|
|
45
|
+
};
|
|
46
|
+
/** Commit position after animation completes */
|
|
47
|
+
commitPosition: (position: Position) => void;
|
|
48
|
+
/** Update bubble size (call on layout) */
|
|
49
|
+
setBubbleSize: (size: {
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
}) => void;
|
|
53
|
+
/** Update screen size (call on resize/orientation change) */
|
|
54
|
+
setScreenSize: (width: number, height: number) => void;
|
|
55
|
+
/** Update min position (for safe area insets) */
|
|
56
|
+
setMinPosition: (minPos: Position) => void;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* React hook for managing floating tools state.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* // Web
|
|
65
|
+
* const { state, actions } = useFloatingTools({
|
|
66
|
+
* screenSize: { width: window.innerWidth, height: window.innerHeight },
|
|
67
|
+
* storage: webStorageAdapter,
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* // React Native
|
|
71
|
+
* const { state, actions } = useFloatingTools({
|
|
72
|
+
* screenSize: Dimensions.get('window'),
|
|
73
|
+
* storage: asyncStorageAdapter,
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function useFloatingTools(options: UseFloatingToolsOptions): UseFloatingToolsReturn;
|
|
78
|
+
|
|
79
|
+
interface FloatingToolsContextValue {
|
|
80
|
+
/** Whether the user is currently dragging */
|
|
81
|
+
isDragging: boolean;
|
|
82
|
+
/** Whether the floating tools are hidden */
|
|
83
|
+
isHidden: boolean;
|
|
84
|
+
}
|
|
85
|
+
declare const FloatingToolsContext: react.Context<FloatingToolsContextValue>;
|
|
86
|
+
/**
|
|
87
|
+
* Hook to access floating tools context.
|
|
88
|
+
* Must be used within a FloatingToolsProvider.
|
|
89
|
+
*/
|
|
90
|
+
declare function useFloatingToolsContext(): FloatingToolsContextValue;
|
|
91
|
+
/**
|
|
92
|
+
* Provider component for floating tools context.
|
|
93
|
+
*/
|
|
94
|
+
interface FloatingToolsProviderProps {
|
|
95
|
+
value: FloatingToolsContextValue;
|
|
96
|
+
children: ReactNode;
|
|
97
|
+
}
|
|
98
|
+
declare function FloatingToolsProvider({ value, children, }: FloatingToolsProviderProps): react_jsx_runtime.JSX.Element;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* useSettings - React hook for managing dev tools settings.
|
|
102
|
+
*
|
|
103
|
+
* Provides a complete settings management solution with:
|
|
104
|
+
* - Loading/persisting settings from storage
|
|
105
|
+
* - Toggle functions for dial and floating tools
|
|
106
|
+
* - Automatic enforcement of dial slot limits
|
|
107
|
+
* - Event bus integration for cross-component sync
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
interface UseSettingsOptions {
|
|
111
|
+
/**
|
|
112
|
+
* Available tools/apps from auto-discovery or manual configuration.
|
|
113
|
+
*/
|
|
114
|
+
availableTools?: AvailableToolConfig[];
|
|
115
|
+
/**
|
|
116
|
+
* Default tool IDs to enable in the floating bubble.
|
|
117
|
+
*/
|
|
118
|
+
defaultFloatingTools?: string[];
|
|
119
|
+
/**
|
|
120
|
+
* Default tool IDs to enable in the dial menu.
|
|
121
|
+
*/
|
|
122
|
+
defaultDialTools?: string[];
|
|
123
|
+
/**
|
|
124
|
+
* Storage adapter for persisting settings.
|
|
125
|
+
* Must implement getItem and setItem (sync or async).
|
|
126
|
+
*/
|
|
127
|
+
storage?: StorageAdapter;
|
|
128
|
+
/**
|
|
129
|
+
* Initial settings to use before loading from storage.
|
|
130
|
+
*/
|
|
131
|
+
initialSettings?: DevToolsSettings;
|
|
132
|
+
/**
|
|
133
|
+
* Callback when settings change.
|
|
134
|
+
*/
|
|
135
|
+
onSettingsChange?: (settings: DevToolsSettings) => void;
|
|
136
|
+
/**
|
|
137
|
+
* Whether to subscribe to settings event bus for cross-component updates.
|
|
138
|
+
* @default true
|
|
139
|
+
*/
|
|
140
|
+
subscribeToEventBus?: boolean;
|
|
141
|
+
}
|
|
142
|
+
interface UseSettingsReturn {
|
|
143
|
+
/**
|
|
144
|
+
* Current settings state.
|
|
145
|
+
*/
|
|
146
|
+
settings: DevToolsSettings;
|
|
147
|
+
/**
|
|
148
|
+
* Whether settings are currently loading from storage.
|
|
149
|
+
*/
|
|
150
|
+
isLoading: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Whether initial load from storage is complete.
|
|
153
|
+
*/
|
|
154
|
+
isInitialized: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Error message if loading failed.
|
|
157
|
+
*/
|
|
158
|
+
error: string | null;
|
|
159
|
+
/**
|
|
160
|
+
* Actions for modifying settings.
|
|
161
|
+
*/
|
|
162
|
+
actions: {
|
|
163
|
+
/**
|
|
164
|
+
* Toggle a dial tool on/off.
|
|
165
|
+
* Respects MAX_SETTINGS_DIAL_SLOTS limit.
|
|
166
|
+
*/
|
|
167
|
+
toggleDialTool: (toolId: string) => void;
|
|
168
|
+
/**
|
|
169
|
+
* Toggle a floating tool on/off.
|
|
170
|
+
*/
|
|
171
|
+
toggleFloatingTool: (toolId: string) => void;
|
|
172
|
+
/**
|
|
173
|
+
* Toggle the environment indicator.
|
|
174
|
+
*/
|
|
175
|
+
toggleEnvironment: () => void;
|
|
176
|
+
/**
|
|
177
|
+
* Toggle a global setting.
|
|
178
|
+
*/
|
|
179
|
+
toggleGlobalSetting: (setting: keyof NonNullable<DevToolsSettings['globalSettings']>) => void;
|
|
180
|
+
/**
|
|
181
|
+
* Save arbitrary settings changes.
|
|
182
|
+
*/
|
|
183
|
+
saveSettings: (newSettings: DevToolsSettings) => Promise<void>;
|
|
184
|
+
/**
|
|
185
|
+
* Reset settings to defaults.
|
|
186
|
+
*/
|
|
187
|
+
resetToDefaults: () => Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Reload settings from storage.
|
|
190
|
+
*/
|
|
191
|
+
reloadSettings: () => Promise<void>;
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Derived state helpers.
|
|
195
|
+
*/
|
|
196
|
+
helpers: {
|
|
197
|
+
/**
|
|
198
|
+
* Number of enabled dial tools.
|
|
199
|
+
*/
|
|
200
|
+
dialToolCount: number;
|
|
201
|
+
/**
|
|
202
|
+
* Whether the dial is at max capacity.
|
|
203
|
+
*/
|
|
204
|
+
isDialFull: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Array of enabled dial tool IDs.
|
|
207
|
+
*/
|
|
208
|
+
enabledDialTools: string[];
|
|
209
|
+
/**
|
|
210
|
+
* Array of enabled floating tool IDs.
|
|
211
|
+
*/
|
|
212
|
+
enabledFloatingTools: string[];
|
|
213
|
+
/**
|
|
214
|
+
* Check if a specific dial tool can be enabled.
|
|
215
|
+
*/
|
|
216
|
+
canEnableDialTool: (toolId: string) => boolean;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
declare function useSettings(options?: UseSettingsOptions): UseSettingsReturn;
|
|
220
|
+
|
|
221
|
+
interface SettingsContextValue extends UseSettingsReturn {
|
|
222
|
+
/**
|
|
223
|
+
* Available tools for configuration.
|
|
224
|
+
*/
|
|
225
|
+
availableTools: AvailableToolConfig[];
|
|
226
|
+
}
|
|
227
|
+
interface SettingsProviderProps {
|
|
228
|
+
/**
|
|
229
|
+
* Child components that will have access to settings.
|
|
230
|
+
*/
|
|
231
|
+
children: ReactNode;
|
|
232
|
+
/**
|
|
233
|
+
* Available tools/apps from auto-discovery or manual configuration.
|
|
234
|
+
*/
|
|
235
|
+
availableTools?: AvailableToolConfig[];
|
|
236
|
+
/**
|
|
237
|
+
* Default tool IDs to enable in the floating bubble.
|
|
238
|
+
*/
|
|
239
|
+
defaultFloatingTools?: string[];
|
|
240
|
+
/**
|
|
241
|
+
* Default tool IDs to enable in the dial menu.
|
|
242
|
+
*/
|
|
243
|
+
defaultDialTools?: string[];
|
|
244
|
+
/**
|
|
245
|
+
* Storage adapter for persisting settings.
|
|
246
|
+
*/
|
|
247
|
+
storage?: StorageAdapter;
|
|
248
|
+
/**
|
|
249
|
+
* Initial settings to use before loading from storage.
|
|
250
|
+
*/
|
|
251
|
+
initialSettings?: DevToolsSettings;
|
|
252
|
+
/**
|
|
253
|
+
* Callback when settings change.
|
|
254
|
+
*/
|
|
255
|
+
onSettingsChange?: (settings: DevToolsSettings) => void;
|
|
256
|
+
}
|
|
257
|
+
declare const SettingsContext: react.Context<SettingsContextValue | null>;
|
|
258
|
+
declare function SettingsProvider({ children, availableTools, defaultFloatingTools, defaultDialTools, storage, initialSettings, onSettingsChange, }: SettingsProviderProps): react_jsx_runtime.JSX.Element;
|
|
259
|
+
/**
|
|
260
|
+
* Hook to access settings context.
|
|
261
|
+
* Must be used within a SettingsProvider.
|
|
262
|
+
*
|
|
263
|
+
* @throws Error if used outside of SettingsProvider
|
|
264
|
+
*/
|
|
265
|
+
declare function useSettingsContext(): SettingsContextValue;
|
|
266
|
+
/**
|
|
267
|
+
* Hook to optionally access settings context.
|
|
268
|
+
* Returns null if used outside of SettingsProvider.
|
|
269
|
+
*
|
|
270
|
+
* Useful for components that work both with and without a provider.
|
|
271
|
+
*/
|
|
272
|
+
declare function useOptionalSettingsContext(): SettingsContextValue | null;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* useDevToolsState - React hook for DevTools state management.
|
|
276
|
+
*
|
|
277
|
+
* Provides a React-friendly interface to the DevToolsStateManager.
|
|
278
|
+
* Uses useSyncExternalStore for efficient subscription management.
|
|
279
|
+
*/
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Actions available for controlling DevTools state.
|
|
283
|
+
*/
|
|
284
|
+
interface DevToolsActions {
|
|
285
|
+
/** Open the dial menu */
|
|
286
|
+
openDial: () => void;
|
|
287
|
+
/** Close the dial menu */
|
|
288
|
+
closeDial: () => void;
|
|
289
|
+
/** Toggle the dial menu open/closed */
|
|
290
|
+
toggleDial: () => void;
|
|
291
|
+
/** Open the settings modal */
|
|
292
|
+
openSettings: () => void;
|
|
293
|
+
/** Close the settings modal */
|
|
294
|
+
closeSettings: () => void;
|
|
295
|
+
/** Set the active settings tab */
|
|
296
|
+
setSettingsTab: (tab: SettingsTabKey) => void;
|
|
297
|
+
/** Mark state as initialized */
|
|
298
|
+
initialize: () => void;
|
|
299
|
+
/** Reset state to initial values */
|
|
300
|
+
reset: () => void;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Return type of the useDevToolsState hook.
|
|
304
|
+
*/
|
|
305
|
+
interface UseDevToolsStateReturn {
|
|
306
|
+
/** Current state snapshot */
|
|
307
|
+
state: DevToolsState;
|
|
308
|
+
/** Action dispatchers */
|
|
309
|
+
actions: DevToolsActions;
|
|
310
|
+
/** The underlying state manager (for advanced use cases) */
|
|
311
|
+
manager: DevToolsStateManager;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Options for the useDevToolsState hook.
|
|
315
|
+
*/
|
|
316
|
+
interface UseDevToolsStateOptions {
|
|
317
|
+
/**
|
|
318
|
+
* Custom state manager instance.
|
|
319
|
+
* If not provided, uses the global devToolsStateManager.
|
|
320
|
+
*/
|
|
321
|
+
manager?: DevToolsStateManager;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* React hook for managing DevTools state.
|
|
325
|
+
*
|
|
326
|
+
* Uses useSyncExternalStore for efficient re-renders only when state changes.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```tsx
|
|
330
|
+
* function MyComponent() {
|
|
331
|
+
* const { state, actions } = useDevToolsState();
|
|
332
|
+
*
|
|
333
|
+
* return (
|
|
334
|
+
* <>
|
|
335
|
+
* <button onClick={actions.toggleDial}>
|
|
336
|
+
* {state.isDialOpen ? 'Close' : 'Open'} Dial
|
|
337
|
+
* </button>
|
|
338
|
+
* {state.isDialOpen && <DialMenu />}
|
|
339
|
+
* </>
|
|
340
|
+
* );
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
declare function useDevToolsState(options?: UseDevToolsStateOptions): UseDevToolsStateReturn;
|
|
345
|
+
/**
|
|
346
|
+
* Hook that returns only the dial open state and toggle action.
|
|
347
|
+
* Use when you only need dial functionality.
|
|
348
|
+
*/
|
|
349
|
+
declare function useDialState(options?: UseDevToolsStateOptions): {
|
|
350
|
+
isOpen: boolean;
|
|
351
|
+
open: () => void;
|
|
352
|
+
close: () => void;
|
|
353
|
+
toggle: () => void;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Hook that returns only the settings modal state and actions.
|
|
357
|
+
* Use when you only need settings functionality.
|
|
358
|
+
*/
|
|
359
|
+
declare function useSettingsModalState(options?: UseDevToolsStateOptions): {
|
|
360
|
+
isOpen: boolean;
|
|
361
|
+
activeTab: SettingsTabKey;
|
|
362
|
+
open: () => void;
|
|
363
|
+
close: () => void;
|
|
364
|
+
setTab: (tab: SettingsTabKey) => void;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Combined context value for the DevTools system.
|
|
369
|
+
*/
|
|
370
|
+
interface DevToolsContextValue {
|
|
371
|
+
/** Current DevTools state (dial open, settings open, etc.) */
|
|
372
|
+
devToolsState: DevToolsState;
|
|
373
|
+
/** Actions for controlling DevTools state */
|
|
374
|
+
devToolsActions: DevToolsActions;
|
|
375
|
+
/** Current settings (tool configurations) */
|
|
376
|
+
settings: DevToolsSettings;
|
|
377
|
+
/** Loading state for settings */
|
|
378
|
+
isSettingsLoading: boolean;
|
|
379
|
+
/** Settings actions (toggle tools, etc.) */
|
|
380
|
+
settingsActions: UseSettingsReturn['actions'];
|
|
381
|
+
/** Settings helpers (dialToolCount, isDialFull, etc.) */
|
|
382
|
+
settingsHelpers: UseSettingsReturn['helpers'];
|
|
383
|
+
/** Available tools (from auto-discovery + custom) */
|
|
384
|
+
tools: WebToolConfig[];
|
|
385
|
+
/** Current environment (local, dev, qa, staging, prod) */
|
|
386
|
+
environment?: Environment;
|
|
387
|
+
/** Current user role */
|
|
388
|
+
userRole?: UserRole;
|
|
389
|
+
/** Available environments for switching */
|
|
390
|
+
availableEnvironments?: Environment[];
|
|
391
|
+
/** Callback when environment is switched */
|
|
392
|
+
onEnvironmentSwitch?: (env: Environment) => void;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Props for the DevToolsProvider component.
|
|
396
|
+
*/
|
|
397
|
+
interface DevToolsProviderProps {
|
|
398
|
+
children: ReactNode;
|
|
399
|
+
/** Available tools (from auto-discovery + custom) */
|
|
400
|
+
tools?: WebToolConfig[];
|
|
401
|
+
/** Default tools to enable in floating toolbar */
|
|
402
|
+
defaultFloatingTools?: string[];
|
|
403
|
+
/** Default tools to enable in dial menu */
|
|
404
|
+
defaultDialTools?: string[];
|
|
405
|
+
/** Current environment */
|
|
406
|
+
environment?: Environment;
|
|
407
|
+
/** Current user role */
|
|
408
|
+
userRole?: UserRole;
|
|
409
|
+
/** Available environments for switching */
|
|
410
|
+
availableEnvironments?: Environment[];
|
|
411
|
+
/** Callback when environment is switched */
|
|
412
|
+
onEnvironmentSwitch?: (env: Environment) => void;
|
|
413
|
+
/** Custom state manager instance */
|
|
414
|
+
stateManager?: DevToolsStateManager;
|
|
415
|
+
}
|
|
416
|
+
declare const DevToolsContext: react.Context<DevToolsContextValue | null>;
|
|
417
|
+
/**
|
|
418
|
+
* Provider component for the DevTools system.
|
|
419
|
+
*
|
|
420
|
+
* Combines DevTools state, settings, and tool registry into a single context.
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```tsx
|
|
424
|
+
* function App() {
|
|
425
|
+
* return (
|
|
426
|
+
* <DevToolsProvider
|
|
427
|
+
* tools={myTools}
|
|
428
|
+
* environment="dev"
|
|
429
|
+
* userRole="admin"
|
|
430
|
+
* defaultDialTools={['env', 'network', 'storage']}
|
|
431
|
+
* >
|
|
432
|
+
* <MyApp />
|
|
433
|
+
* </DevToolsProvider>
|
|
434
|
+
* );
|
|
435
|
+
* }
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
declare function DevToolsProvider({ children, tools, defaultFloatingTools, defaultDialTools, environment, userRole, availableEnvironments, onEnvironmentSwitch, stateManager, }: DevToolsProviderProps): react_jsx_runtime.JSX.Element;
|
|
439
|
+
/**
|
|
440
|
+
* Hook to access the DevTools context.
|
|
441
|
+
* Must be used within a DevToolsProvider.
|
|
442
|
+
*
|
|
443
|
+
* @throws Error if used outside of DevToolsProvider
|
|
444
|
+
*/
|
|
445
|
+
declare function useDevToolsContext(): DevToolsContextValue;
|
|
446
|
+
/**
|
|
447
|
+
* Hook to access the DevTools context without throwing.
|
|
448
|
+
* Returns null if not within a DevToolsProvider.
|
|
449
|
+
*
|
|
450
|
+
* Useful for components that may or may not be within the provider.
|
|
451
|
+
*/
|
|
452
|
+
declare function useOptionalDevToolsContext(): DevToolsContextValue | null;
|
|
453
|
+
/**
|
|
454
|
+
* Hook to get the current environment and role.
|
|
455
|
+
*/
|
|
456
|
+
declare function useDevToolsEnvironment(): {
|
|
457
|
+
environment: Environment | undefined;
|
|
458
|
+
userRole: UserRole | undefined;
|
|
459
|
+
availableEnvironments: Environment[] | undefined;
|
|
460
|
+
onEnvironmentSwitch: ((env: Environment) => void) | undefined;
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Hook to get the available tools.
|
|
464
|
+
*/
|
|
465
|
+
declare function useDevTools(): {
|
|
466
|
+
tools: WebToolConfig[];
|
|
467
|
+
settings: DevToolsSettings;
|
|
468
|
+
isLoading: boolean;
|
|
469
|
+
};
|
|
470
|
+
/**
|
|
471
|
+
* Hook to control the dial menu.
|
|
472
|
+
*/
|
|
473
|
+
declare function useDevToolsDial(): {
|
|
474
|
+
isOpen: boolean;
|
|
475
|
+
open: () => void;
|
|
476
|
+
close: () => void;
|
|
477
|
+
toggle: () => void;
|
|
478
|
+
};
|
|
479
|
+
/**
|
|
480
|
+
* Hook to control the settings modal.
|
|
481
|
+
*/
|
|
482
|
+
declare function useDevToolsSettings(): {
|
|
483
|
+
isOpen: boolean;
|
|
484
|
+
activeTab: SettingsTabKey;
|
|
485
|
+
open: () => void;
|
|
486
|
+
close: () => void;
|
|
487
|
+
setTab: (tab: SettingsTabKey) => void;
|
|
488
|
+
settings: DevToolsSettings;
|
|
489
|
+
actions: {
|
|
490
|
+
toggleDialTool: (toolId: string) => void;
|
|
491
|
+
toggleFloatingTool: (toolId: string) => void;
|
|
492
|
+
toggleEnvironment: () => void;
|
|
493
|
+
toggleGlobalSetting: (setting: keyof NonNullable<DevToolsSettings["globalSettings"]>) => void;
|
|
494
|
+
saveSettings: (newSettings: DevToolsSettings) => Promise<void>;
|
|
495
|
+
resetToDefaults: () => Promise<void>;
|
|
496
|
+
reloadSettings: () => Promise<void>;
|
|
497
|
+
};
|
|
498
|
+
helpers: {
|
|
499
|
+
dialToolCount: number;
|
|
500
|
+
isDialFull: boolean;
|
|
501
|
+
enabledDialTools: string[];
|
|
502
|
+
enabledFloatingTools: string[];
|
|
503
|
+
canEnableDialTool: (toolId: string) => boolean;
|
|
504
|
+
};
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* React-specific utility functions for floating tools.
|
|
509
|
+
*/
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Interleave children with divider elements.
|
|
513
|
+
* Used to add separators between tool items.
|
|
514
|
+
*
|
|
515
|
+
* @param children - Array of React children
|
|
516
|
+
* @param renderDivider - Function to render a divider element with a unique key
|
|
517
|
+
* @returns Array of children interleaved with dividers
|
|
518
|
+
*
|
|
519
|
+
* @example
|
|
520
|
+
* ```tsx
|
|
521
|
+
* const items = interleaveWithDividers(
|
|
522
|
+
* Children.toArray(children),
|
|
523
|
+
* (key) => <Divider key={key} />
|
|
524
|
+
* );
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
declare function interleaveWithDividers(children: ReactNode[], renderDivider: (key: string) => ReactElement): ReactNode[];
|
|
528
|
+
|
|
529
|
+
export { type DevToolsActions, DevToolsContext, type DevToolsContextValue, DevToolsProvider, type DevToolsProviderProps, FloatingToolsContext, type FloatingToolsContextValue, FloatingToolsProvider, type FloatingToolsProviderProps, SettingsContext, type SettingsContextValue, SettingsProvider, type SettingsProviderProps, type UseDevToolsStateOptions, type UseDevToolsStateReturn, type UseFloatingToolsOptions, type UseFloatingToolsReturn, type UseSettingsOptions, type UseSettingsReturn, interleaveWithDividers, useDevTools, useDevToolsContext, useDevToolsDial, useDevToolsEnvironment, useDevToolsSettings, useDevToolsState, useDialState, useFloatingTools, useFloatingToolsContext, useOptionalDevToolsContext, useOptionalSettingsContext, useSettings, useSettingsContext, useSettingsModalState };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
import { FloatingToolsOptions, FloatingToolsState, FloatingToolsStore, DragEventData, Position, DragEndResult, AvailableToolConfig, StorageAdapter, DevToolsSettings, DevToolsStateManager, DevToolsState, SettingsTabKey, WebToolConfig, Environment, UserRole } from '@buoy-gg/floating-tools-core';
|
|
2
|
+
export { ANIMATION_DURATION, AvailableToolConfig, BaseToolConfig, DIAL_BUTTON_SIZE, DIAL_GRID_LINE_COUNT, DIAL_ICON_PADDING, DIAL_ICON_SIZE, DIAL_START_ANGLE, DRAG_THRESHOLD, DevToolsAction, DevToolsSettings, DevToolsState, DevToolsStateManager, DialAnimationConfigType, DialCSSBezierKey, DialColorKey, DialEasingName, DialLayout, DialLayoutConfig, DragEndResult, DragEventData, EDGE_PADDING, EasingFunction, Environment, FloatingToolsState, FloatingToolsStore, GlobalDevToolsSettings, GlobalSettingConfig, GripIconLayout, IconPosition, MAX_DIAL_SLOTS, MAX_SETTINGS_DIAL_SLOTS, MergeSettingsOptions, Position, SETTINGS_STORAGE_KEY, SettingsColorKey, SettingsEventBus, SettingsTab, SettingsTabKey, Size, SpiralPosition, SpringConfig, StorageAdapter, ToolMetadata, ToolSlot, UserRole, UserStatusConfig, VISIBLE_HANDLE_WIDTH, WebToolConfig, canEnableDialTool, countEnabledTools, devToolsReducer, devToolsStateManager, dialAnimationConfig, dialCSSBeziers, dialColors, dialStyles, easing, enforceDialLimit, floatingToolsColors, generateDefaultSettings, generateDialCSSKeyframes, getAllIconPositions, getDialCSSAnimationStyles, getDialCSSKeyframesString, getDialLayout, getEnabledToolIds, getGridLineRotations, getGripIconLayout, getIconAngle, getIconPosition, getIconStaggerInputRange, getSpiralAnimationPosition, getStaggeredIconProgress, getToolColor, getToolDescription, getToolLabel, getUserStatusConfig, globalSettingsConfig, interpolate, interpolatePosition, mergeSettingsWithDefaults, sanitizeFloatingSettings, settingsColors, settingsEventBus, settingsStyles, settingsTabs, toolColors, toolDescriptions, toolLabels, withAlpha } from '@buoy-gg/floating-tools-core';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
import { ReactNode, ReactElement } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* useFloatingTools - React hook for floating tools state management.
|
|
9
|
+
* Works with both web and React Native.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface UseFloatingToolsOptions extends Omit<FloatingToolsOptions, 'screenWidth' | 'screenHeight'> {
|
|
13
|
+
/**
|
|
14
|
+
* Screen dimensions. Required for boundary calculations.
|
|
15
|
+
* On web: { width: window.innerWidth, height: window.innerHeight }
|
|
16
|
+
* On RN: Dimensions.get('window')
|
|
17
|
+
*/
|
|
18
|
+
screenSize: {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
interface UseFloatingToolsReturn {
|
|
24
|
+
/** Current state (position, isDragging, isHidden, bubbleSize) */
|
|
25
|
+
state: FloatingToolsState;
|
|
26
|
+
/** The underlying store instance */
|
|
27
|
+
store: FloatingToolsStore;
|
|
28
|
+
/** Whether the store has been initialized (position loaded from storage) */
|
|
29
|
+
isInitialized: boolean;
|
|
30
|
+
/** Actions */
|
|
31
|
+
actions: {
|
|
32
|
+
/** Start a drag operation */
|
|
33
|
+
handleDragStart: (event: DragEventData) => void;
|
|
34
|
+
/** Process drag movement */
|
|
35
|
+
handleDragMove: (event: DragEventData) => {
|
|
36
|
+
position: Position;
|
|
37
|
+
isDragging: boolean;
|
|
38
|
+
};
|
|
39
|
+
/** End a drag operation */
|
|
40
|
+
handleDragEnd: (event: DragEventData) => DragEndResult;
|
|
41
|
+
/** Toggle between hidden and visible states */
|
|
42
|
+
toggleHideShow: () => {
|
|
43
|
+
targetPosition: Position;
|
|
44
|
+
isHiding: boolean;
|
|
45
|
+
};
|
|
46
|
+
/** Commit position after animation completes */
|
|
47
|
+
commitPosition: (position: Position) => void;
|
|
48
|
+
/** Update bubble size (call on layout) */
|
|
49
|
+
setBubbleSize: (size: {
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
}) => void;
|
|
53
|
+
/** Update screen size (call on resize/orientation change) */
|
|
54
|
+
setScreenSize: (width: number, height: number) => void;
|
|
55
|
+
/** Update min position (for safe area insets) */
|
|
56
|
+
setMinPosition: (minPos: Position) => void;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* React hook for managing floating tools state.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* // Web
|
|
65
|
+
* const { state, actions } = useFloatingTools({
|
|
66
|
+
* screenSize: { width: window.innerWidth, height: window.innerHeight },
|
|
67
|
+
* storage: webStorageAdapter,
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* // React Native
|
|
71
|
+
* const { state, actions } = useFloatingTools({
|
|
72
|
+
* screenSize: Dimensions.get('window'),
|
|
73
|
+
* storage: asyncStorageAdapter,
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function useFloatingTools(options: UseFloatingToolsOptions): UseFloatingToolsReturn;
|
|
78
|
+
|
|
79
|
+
interface FloatingToolsContextValue {
|
|
80
|
+
/** Whether the user is currently dragging */
|
|
81
|
+
isDragging: boolean;
|
|
82
|
+
/** Whether the floating tools are hidden */
|
|
83
|
+
isHidden: boolean;
|
|
84
|
+
}
|
|
85
|
+
declare const FloatingToolsContext: react.Context<FloatingToolsContextValue>;
|
|
86
|
+
/**
|
|
87
|
+
* Hook to access floating tools context.
|
|
88
|
+
* Must be used within a FloatingToolsProvider.
|
|
89
|
+
*/
|
|
90
|
+
declare function useFloatingToolsContext(): FloatingToolsContextValue;
|
|
91
|
+
/**
|
|
92
|
+
* Provider component for floating tools context.
|
|
93
|
+
*/
|
|
94
|
+
interface FloatingToolsProviderProps {
|
|
95
|
+
value: FloatingToolsContextValue;
|
|
96
|
+
children: ReactNode;
|
|
97
|
+
}
|
|
98
|
+
declare function FloatingToolsProvider({ value, children, }: FloatingToolsProviderProps): react_jsx_runtime.JSX.Element;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* useSettings - React hook for managing dev tools settings.
|
|
102
|
+
*
|
|
103
|
+
* Provides a complete settings management solution with:
|
|
104
|
+
* - Loading/persisting settings from storage
|
|
105
|
+
* - Toggle functions for dial and floating tools
|
|
106
|
+
* - Automatic enforcement of dial slot limits
|
|
107
|
+
* - Event bus integration for cross-component sync
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
interface UseSettingsOptions {
|
|
111
|
+
/**
|
|
112
|
+
* Available tools/apps from auto-discovery or manual configuration.
|
|
113
|
+
*/
|
|
114
|
+
availableTools?: AvailableToolConfig[];
|
|
115
|
+
/**
|
|
116
|
+
* Default tool IDs to enable in the floating bubble.
|
|
117
|
+
*/
|
|
118
|
+
defaultFloatingTools?: string[];
|
|
119
|
+
/**
|
|
120
|
+
* Default tool IDs to enable in the dial menu.
|
|
121
|
+
*/
|
|
122
|
+
defaultDialTools?: string[];
|
|
123
|
+
/**
|
|
124
|
+
* Storage adapter for persisting settings.
|
|
125
|
+
* Must implement getItem and setItem (sync or async).
|
|
126
|
+
*/
|
|
127
|
+
storage?: StorageAdapter;
|
|
128
|
+
/**
|
|
129
|
+
* Initial settings to use before loading from storage.
|
|
130
|
+
*/
|
|
131
|
+
initialSettings?: DevToolsSettings;
|
|
132
|
+
/**
|
|
133
|
+
* Callback when settings change.
|
|
134
|
+
*/
|
|
135
|
+
onSettingsChange?: (settings: DevToolsSettings) => void;
|
|
136
|
+
/**
|
|
137
|
+
* Whether to subscribe to settings event bus for cross-component updates.
|
|
138
|
+
* @default true
|
|
139
|
+
*/
|
|
140
|
+
subscribeToEventBus?: boolean;
|
|
141
|
+
}
|
|
142
|
+
interface UseSettingsReturn {
|
|
143
|
+
/**
|
|
144
|
+
* Current settings state.
|
|
145
|
+
*/
|
|
146
|
+
settings: DevToolsSettings;
|
|
147
|
+
/**
|
|
148
|
+
* Whether settings are currently loading from storage.
|
|
149
|
+
*/
|
|
150
|
+
isLoading: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Whether initial load from storage is complete.
|
|
153
|
+
*/
|
|
154
|
+
isInitialized: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Error message if loading failed.
|
|
157
|
+
*/
|
|
158
|
+
error: string | null;
|
|
159
|
+
/**
|
|
160
|
+
* Actions for modifying settings.
|
|
161
|
+
*/
|
|
162
|
+
actions: {
|
|
163
|
+
/**
|
|
164
|
+
* Toggle a dial tool on/off.
|
|
165
|
+
* Respects MAX_SETTINGS_DIAL_SLOTS limit.
|
|
166
|
+
*/
|
|
167
|
+
toggleDialTool: (toolId: string) => void;
|
|
168
|
+
/**
|
|
169
|
+
* Toggle a floating tool on/off.
|
|
170
|
+
*/
|
|
171
|
+
toggleFloatingTool: (toolId: string) => void;
|
|
172
|
+
/**
|
|
173
|
+
* Toggle the environment indicator.
|
|
174
|
+
*/
|
|
175
|
+
toggleEnvironment: () => void;
|
|
176
|
+
/**
|
|
177
|
+
* Toggle a global setting.
|
|
178
|
+
*/
|
|
179
|
+
toggleGlobalSetting: (setting: keyof NonNullable<DevToolsSettings['globalSettings']>) => void;
|
|
180
|
+
/**
|
|
181
|
+
* Save arbitrary settings changes.
|
|
182
|
+
*/
|
|
183
|
+
saveSettings: (newSettings: DevToolsSettings) => Promise<void>;
|
|
184
|
+
/**
|
|
185
|
+
* Reset settings to defaults.
|
|
186
|
+
*/
|
|
187
|
+
resetToDefaults: () => Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Reload settings from storage.
|
|
190
|
+
*/
|
|
191
|
+
reloadSettings: () => Promise<void>;
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Derived state helpers.
|
|
195
|
+
*/
|
|
196
|
+
helpers: {
|
|
197
|
+
/**
|
|
198
|
+
* Number of enabled dial tools.
|
|
199
|
+
*/
|
|
200
|
+
dialToolCount: number;
|
|
201
|
+
/**
|
|
202
|
+
* Whether the dial is at max capacity.
|
|
203
|
+
*/
|
|
204
|
+
isDialFull: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Array of enabled dial tool IDs.
|
|
207
|
+
*/
|
|
208
|
+
enabledDialTools: string[];
|
|
209
|
+
/**
|
|
210
|
+
* Array of enabled floating tool IDs.
|
|
211
|
+
*/
|
|
212
|
+
enabledFloatingTools: string[];
|
|
213
|
+
/**
|
|
214
|
+
* Check if a specific dial tool can be enabled.
|
|
215
|
+
*/
|
|
216
|
+
canEnableDialTool: (toolId: string) => boolean;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
declare function useSettings(options?: UseSettingsOptions): UseSettingsReturn;
|
|
220
|
+
|
|
221
|
+
interface SettingsContextValue extends UseSettingsReturn {
|
|
222
|
+
/**
|
|
223
|
+
* Available tools for configuration.
|
|
224
|
+
*/
|
|
225
|
+
availableTools: AvailableToolConfig[];
|
|
226
|
+
}
|
|
227
|
+
interface SettingsProviderProps {
|
|
228
|
+
/**
|
|
229
|
+
* Child components that will have access to settings.
|
|
230
|
+
*/
|
|
231
|
+
children: ReactNode;
|
|
232
|
+
/**
|
|
233
|
+
* Available tools/apps from auto-discovery or manual configuration.
|
|
234
|
+
*/
|
|
235
|
+
availableTools?: AvailableToolConfig[];
|
|
236
|
+
/**
|
|
237
|
+
* Default tool IDs to enable in the floating bubble.
|
|
238
|
+
*/
|
|
239
|
+
defaultFloatingTools?: string[];
|
|
240
|
+
/**
|
|
241
|
+
* Default tool IDs to enable in the dial menu.
|
|
242
|
+
*/
|
|
243
|
+
defaultDialTools?: string[];
|
|
244
|
+
/**
|
|
245
|
+
* Storage adapter for persisting settings.
|
|
246
|
+
*/
|
|
247
|
+
storage?: StorageAdapter;
|
|
248
|
+
/**
|
|
249
|
+
* Initial settings to use before loading from storage.
|
|
250
|
+
*/
|
|
251
|
+
initialSettings?: DevToolsSettings;
|
|
252
|
+
/**
|
|
253
|
+
* Callback when settings change.
|
|
254
|
+
*/
|
|
255
|
+
onSettingsChange?: (settings: DevToolsSettings) => void;
|
|
256
|
+
}
|
|
257
|
+
declare const SettingsContext: react.Context<SettingsContextValue | null>;
|
|
258
|
+
declare function SettingsProvider({ children, availableTools, defaultFloatingTools, defaultDialTools, storage, initialSettings, onSettingsChange, }: SettingsProviderProps): react_jsx_runtime.JSX.Element;
|
|
259
|
+
/**
|
|
260
|
+
* Hook to access settings context.
|
|
261
|
+
* Must be used within a SettingsProvider.
|
|
262
|
+
*
|
|
263
|
+
* @throws Error if used outside of SettingsProvider
|
|
264
|
+
*/
|
|
265
|
+
declare function useSettingsContext(): SettingsContextValue;
|
|
266
|
+
/**
|
|
267
|
+
* Hook to optionally access settings context.
|
|
268
|
+
* Returns null if used outside of SettingsProvider.
|
|
269
|
+
*
|
|
270
|
+
* Useful for components that work both with and without a provider.
|
|
271
|
+
*/
|
|
272
|
+
declare function useOptionalSettingsContext(): SettingsContextValue | null;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* useDevToolsState - React hook for DevTools state management.
|
|
276
|
+
*
|
|
277
|
+
* Provides a React-friendly interface to the DevToolsStateManager.
|
|
278
|
+
* Uses useSyncExternalStore for efficient subscription management.
|
|
279
|
+
*/
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Actions available for controlling DevTools state.
|
|
283
|
+
*/
|
|
284
|
+
interface DevToolsActions {
|
|
285
|
+
/** Open the dial menu */
|
|
286
|
+
openDial: () => void;
|
|
287
|
+
/** Close the dial menu */
|
|
288
|
+
closeDial: () => void;
|
|
289
|
+
/** Toggle the dial menu open/closed */
|
|
290
|
+
toggleDial: () => void;
|
|
291
|
+
/** Open the settings modal */
|
|
292
|
+
openSettings: () => void;
|
|
293
|
+
/** Close the settings modal */
|
|
294
|
+
closeSettings: () => void;
|
|
295
|
+
/** Set the active settings tab */
|
|
296
|
+
setSettingsTab: (tab: SettingsTabKey) => void;
|
|
297
|
+
/** Mark state as initialized */
|
|
298
|
+
initialize: () => void;
|
|
299
|
+
/** Reset state to initial values */
|
|
300
|
+
reset: () => void;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Return type of the useDevToolsState hook.
|
|
304
|
+
*/
|
|
305
|
+
interface UseDevToolsStateReturn {
|
|
306
|
+
/** Current state snapshot */
|
|
307
|
+
state: DevToolsState;
|
|
308
|
+
/** Action dispatchers */
|
|
309
|
+
actions: DevToolsActions;
|
|
310
|
+
/** The underlying state manager (for advanced use cases) */
|
|
311
|
+
manager: DevToolsStateManager;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Options for the useDevToolsState hook.
|
|
315
|
+
*/
|
|
316
|
+
interface UseDevToolsStateOptions {
|
|
317
|
+
/**
|
|
318
|
+
* Custom state manager instance.
|
|
319
|
+
* If not provided, uses the global devToolsStateManager.
|
|
320
|
+
*/
|
|
321
|
+
manager?: DevToolsStateManager;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* React hook for managing DevTools state.
|
|
325
|
+
*
|
|
326
|
+
* Uses useSyncExternalStore for efficient re-renders only when state changes.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```tsx
|
|
330
|
+
* function MyComponent() {
|
|
331
|
+
* const { state, actions } = useDevToolsState();
|
|
332
|
+
*
|
|
333
|
+
* return (
|
|
334
|
+
* <>
|
|
335
|
+
* <button onClick={actions.toggleDial}>
|
|
336
|
+
* {state.isDialOpen ? 'Close' : 'Open'} Dial
|
|
337
|
+
* </button>
|
|
338
|
+
* {state.isDialOpen && <DialMenu />}
|
|
339
|
+
* </>
|
|
340
|
+
* );
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
declare function useDevToolsState(options?: UseDevToolsStateOptions): UseDevToolsStateReturn;
|
|
345
|
+
/**
|
|
346
|
+
* Hook that returns only the dial open state and toggle action.
|
|
347
|
+
* Use when you only need dial functionality.
|
|
348
|
+
*/
|
|
349
|
+
declare function useDialState(options?: UseDevToolsStateOptions): {
|
|
350
|
+
isOpen: boolean;
|
|
351
|
+
open: () => void;
|
|
352
|
+
close: () => void;
|
|
353
|
+
toggle: () => void;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Hook that returns only the settings modal state and actions.
|
|
357
|
+
* Use when you only need settings functionality.
|
|
358
|
+
*/
|
|
359
|
+
declare function useSettingsModalState(options?: UseDevToolsStateOptions): {
|
|
360
|
+
isOpen: boolean;
|
|
361
|
+
activeTab: SettingsTabKey;
|
|
362
|
+
open: () => void;
|
|
363
|
+
close: () => void;
|
|
364
|
+
setTab: (tab: SettingsTabKey) => void;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Combined context value for the DevTools system.
|
|
369
|
+
*/
|
|
370
|
+
interface DevToolsContextValue {
|
|
371
|
+
/** Current DevTools state (dial open, settings open, etc.) */
|
|
372
|
+
devToolsState: DevToolsState;
|
|
373
|
+
/** Actions for controlling DevTools state */
|
|
374
|
+
devToolsActions: DevToolsActions;
|
|
375
|
+
/** Current settings (tool configurations) */
|
|
376
|
+
settings: DevToolsSettings;
|
|
377
|
+
/** Loading state for settings */
|
|
378
|
+
isSettingsLoading: boolean;
|
|
379
|
+
/** Settings actions (toggle tools, etc.) */
|
|
380
|
+
settingsActions: UseSettingsReturn['actions'];
|
|
381
|
+
/** Settings helpers (dialToolCount, isDialFull, etc.) */
|
|
382
|
+
settingsHelpers: UseSettingsReturn['helpers'];
|
|
383
|
+
/** Available tools (from auto-discovery + custom) */
|
|
384
|
+
tools: WebToolConfig[];
|
|
385
|
+
/** Current environment (local, dev, qa, staging, prod) */
|
|
386
|
+
environment?: Environment;
|
|
387
|
+
/** Current user role */
|
|
388
|
+
userRole?: UserRole;
|
|
389
|
+
/** Available environments for switching */
|
|
390
|
+
availableEnvironments?: Environment[];
|
|
391
|
+
/** Callback when environment is switched */
|
|
392
|
+
onEnvironmentSwitch?: (env: Environment) => void;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Props for the DevToolsProvider component.
|
|
396
|
+
*/
|
|
397
|
+
interface DevToolsProviderProps {
|
|
398
|
+
children: ReactNode;
|
|
399
|
+
/** Available tools (from auto-discovery + custom) */
|
|
400
|
+
tools?: WebToolConfig[];
|
|
401
|
+
/** Default tools to enable in floating toolbar */
|
|
402
|
+
defaultFloatingTools?: string[];
|
|
403
|
+
/** Default tools to enable in dial menu */
|
|
404
|
+
defaultDialTools?: string[];
|
|
405
|
+
/** Current environment */
|
|
406
|
+
environment?: Environment;
|
|
407
|
+
/** Current user role */
|
|
408
|
+
userRole?: UserRole;
|
|
409
|
+
/** Available environments for switching */
|
|
410
|
+
availableEnvironments?: Environment[];
|
|
411
|
+
/** Callback when environment is switched */
|
|
412
|
+
onEnvironmentSwitch?: (env: Environment) => void;
|
|
413
|
+
/** Custom state manager instance */
|
|
414
|
+
stateManager?: DevToolsStateManager;
|
|
415
|
+
}
|
|
416
|
+
declare const DevToolsContext: react.Context<DevToolsContextValue | null>;
|
|
417
|
+
/**
|
|
418
|
+
* Provider component for the DevTools system.
|
|
419
|
+
*
|
|
420
|
+
* Combines DevTools state, settings, and tool registry into a single context.
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```tsx
|
|
424
|
+
* function App() {
|
|
425
|
+
* return (
|
|
426
|
+
* <DevToolsProvider
|
|
427
|
+
* tools={myTools}
|
|
428
|
+
* environment="dev"
|
|
429
|
+
* userRole="admin"
|
|
430
|
+
* defaultDialTools={['env', 'network', 'storage']}
|
|
431
|
+
* >
|
|
432
|
+
* <MyApp />
|
|
433
|
+
* </DevToolsProvider>
|
|
434
|
+
* );
|
|
435
|
+
* }
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
declare function DevToolsProvider({ children, tools, defaultFloatingTools, defaultDialTools, environment, userRole, availableEnvironments, onEnvironmentSwitch, stateManager, }: DevToolsProviderProps): react_jsx_runtime.JSX.Element;
|
|
439
|
+
/**
|
|
440
|
+
* Hook to access the DevTools context.
|
|
441
|
+
* Must be used within a DevToolsProvider.
|
|
442
|
+
*
|
|
443
|
+
* @throws Error if used outside of DevToolsProvider
|
|
444
|
+
*/
|
|
445
|
+
declare function useDevToolsContext(): DevToolsContextValue;
|
|
446
|
+
/**
|
|
447
|
+
* Hook to access the DevTools context without throwing.
|
|
448
|
+
* Returns null if not within a DevToolsProvider.
|
|
449
|
+
*
|
|
450
|
+
* Useful for components that may or may not be within the provider.
|
|
451
|
+
*/
|
|
452
|
+
declare function useOptionalDevToolsContext(): DevToolsContextValue | null;
|
|
453
|
+
/**
|
|
454
|
+
* Hook to get the current environment and role.
|
|
455
|
+
*/
|
|
456
|
+
declare function useDevToolsEnvironment(): {
|
|
457
|
+
environment: Environment | undefined;
|
|
458
|
+
userRole: UserRole | undefined;
|
|
459
|
+
availableEnvironments: Environment[] | undefined;
|
|
460
|
+
onEnvironmentSwitch: ((env: Environment) => void) | undefined;
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Hook to get the available tools.
|
|
464
|
+
*/
|
|
465
|
+
declare function useDevTools(): {
|
|
466
|
+
tools: WebToolConfig[];
|
|
467
|
+
settings: DevToolsSettings;
|
|
468
|
+
isLoading: boolean;
|
|
469
|
+
};
|
|
470
|
+
/**
|
|
471
|
+
* Hook to control the dial menu.
|
|
472
|
+
*/
|
|
473
|
+
declare function useDevToolsDial(): {
|
|
474
|
+
isOpen: boolean;
|
|
475
|
+
open: () => void;
|
|
476
|
+
close: () => void;
|
|
477
|
+
toggle: () => void;
|
|
478
|
+
};
|
|
479
|
+
/**
|
|
480
|
+
* Hook to control the settings modal.
|
|
481
|
+
*/
|
|
482
|
+
declare function useDevToolsSettings(): {
|
|
483
|
+
isOpen: boolean;
|
|
484
|
+
activeTab: SettingsTabKey;
|
|
485
|
+
open: () => void;
|
|
486
|
+
close: () => void;
|
|
487
|
+
setTab: (tab: SettingsTabKey) => void;
|
|
488
|
+
settings: DevToolsSettings;
|
|
489
|
+
actions: {
|
|
490
|
+
toggleDialTool: (toolId: string) => void;
|
|
491
|
+
toggleFloatingTool: (toolId: string) => void;
|
|
492
|
+
toggleEnvironment: () => void;
|
|
493
|
+
toggleGlobalSetting: (setting: keyof NonNullable<DevToolsSettings["globalSettings"]>) => void;
|
|
494
|
+
saveSettings: (newSettings: DevToolsSettings) => Promise<void>;
|
|
495
|
+
resetToDefaults: () => Promise<void>;
|
|
496
|
+
reloadSettings: () => Promise<void>;
|
|
497
|
+
};
|
|
498
|
+
helpers: {
|
|
499
|
+
dialToolCount: number;
|
|
500
|
+
isDialFull: boolean;
|
|
501
|
+
enabledDialTools: string[];
|
|
502
|
+
enabledFloatingTools: string[];
|
|
503
|
+
canEnableDialTool: (toolId: string) => boolean;
|
|
504
|
+
};
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* React-specific utility functions for floating tools.
|
|
509
|
+
*/
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Interleave children with divider elements.
|
|
513
|
+
* Used to add separators between tool items.
|
|
514
|
+
*
|
|
515
|
+
* @param children - Array of React children
|
|
516
|
+
* @param renderDivider - Function to render a divider element with a unique key
|
|
517
|
+
* @returns Array of children interleaved with dividers
|
|
518
|
+
*
|
|
519
|
+
* @example
|
|
520
|
+
* ```tsx
|
|
521
|
+
* const items = interleaveWithDividers(
|
|
522
|
+
* Children.toArray(children),
|
|
523
|
+
* (key) => <Divider key={key} />
|
|
524
|
+
* );
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
declare function interleaveWithDividers(children: ReactNode[], renderDivider: (key: string) => ReactElement): ReactNode[];
|
|
528
|
+
|
|
529
|
+
export { type DevToolsActions, DevToolsContext, type DevToolsContextValue, DevToolsProvider, type DevToolsProviderProps, FloatingToolsContext, type FloatingToolsContextValue, FloatingToolsProvider, type FloatingToolsProviderProps, SettingsContext, type SettingsContextValue, SettingsProvider, type SettingsProviderProps, type UseDevToolsStateOptions, type UseDevToolsStateReturn, type UseFloatingToolsOptions, type UseFloatingToolsReturn, type UseSettingsOptions, type UseSettingsReturn, interleaveWithDividers, useDevTools, useDevToolsContext, useDevToolsDial, useDevToolsEnvironment, useDevToolsSettings, useDevToolsState, useDialState, useFloatingTools, useFloatingToolsContext, useOptionalDevToolsContext, useOptionalSettingsContext, useSettings, useSettingsContext, useSettingsModalState };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var k=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var he=Object.prototype.hasOwnProperty;var Pe=(t,o)=>{for(var s in o)k(t,s,{get:o[s],enumerable:!0})},Ae=(t,o,s,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let a of Ee(o))!he.call(t,a)&&a!==s&&k(t,a,{get:()=>o[a],enumerable:!(n=ye(o,a))||n.enumerable});return t};var Fe=t=>Ae(k({},"__esModule",{value:!0}),t);var Re={};Pe(Re,{ANIMATION_DURATION:()=>e.ANIMATION_DURATION,DIAL_BUTTON_SIZE:()=>e.DIAL_BUTTON_SIZE,DIAL_GRID_LINE_COUNT:()=>e.DIAL_GRID_LINE_COUNT,DIAL_ICON_PADDING:()=>e.DIAL_ICON_PADDING,DIAL_ICON_SIZE:()=>e.DIAL_ICON_SIZE,DIAL_START_ANGLE:()=>e.DIAL_START_ANGLE,DRAG_THRESHOLD:()=>e.DRAG_THRESHOLD,DevToolsContext:()=>R,DevToolsProvider:()=>le,DevToolsStateManager:()=>L.DevToolsStateManager,EDGE_PADDING:()=>e.EDGE_PADDING,FloatingToolsContext:()=>z,FloatingToolsProvider:()=>$,FloatingToolsStore:()=>e.FloatingToolsStore,MAX_DIAL_SLOTS:()=>e.MAX_DIAL_SLOTS,MAX_SETTINGS_DIAL_SLOTS:()=>G.MAX_SETTINGS_DIAL_SLOTS,SETTINGS_STORAGE_KEY:()=>G.SETTINGS_STORAGE_KEY,SettingsContext:()=>U,SettingsEventBus:()=>H.SettingsEventBus,SettingsProvider:()=>Q,VISIBLE_HANDLE_WIDTH:()=>e.VISIBLE_HANDLE_WIDTH,canEnableDialTool:()=>c.canEnableDialTool,countEnabledTools:()=>c.countEnabledTools,devToolsReducer:()=>L.devToolsReducer,devToolsStateManager:()=>L.devToolsStateManager,dialAnimationConfig:()=>e.dialAnimationConfig,dialCSSBeziers:()=>e.dialCSSBeziers,dialColors:()=>e.dialColors,dialStyles:()=>e.dialStyles,easing:()=>e.easing,enforceDialLimit:()=>c.enforceDialLimit,floatingToolsColors:()=>e.floatingToolsColors,generateDefaultSettings:()=>c.generateDefaultSettings,generateDialCSSKeyframes:()=>e.generateDialCSSKeyframes,getAllIconPositions:()=>e.getAllIconPositions,getDialCSSAnimationStyles:()=>e.getDialCSSAnimationStyles,getDialCSSKeyframesString:()=>e.getDialCSSKeyframesString,getDialLayout:()=>e.getDialLayout,getEnabledToolIds:()=>c.getEnabledToolIds,getGridLineRotations:()=>e.getGridLineRotations,getGripIconLayout:()=>e.getGripIconLayout,getIconAngle:()=>e.getIconAngle,getIconPosition:()=>e.getIconPosition,getIconStaggerInputRange:()=>e.getIconStaggerInputRange,getSpiralAnimationPosition:()=>e.getSpiralAnimationPosition,getStaggeredIconProgress:()=>e.getStaggeredIconProgress,getToolColor:()=>C.getToolColor,getToolDescription:()=>y.getToolDescription,getToolLabel:()=>y.getToolLabel,getUserStatusConfig:()=>e.getUserStatusConfig,globalSettingsConfig:()=>pe.globalSettingsConfig,interleaveWithDividers:()=>ve,interpolate:()=>e.interpolate,interpolatePosition:()=>e.interpolatePosition,mergeSettingsWithDefaults:()=>c.mergeSettingsWithDefaults,sanitizeFloatingSettings:()=>c.sanitizeFloatingSettings,settingsColors:()=>C.settingsColors,settingsEventBus:()=>H.settingsEventBus,settingsStyles:()=>C.settingsStyles,settingsTabs:()=>de.settingsTabs,toolColors:()=>C.toolColors,toolDescriptions:()=>y.toolDescriptions,toolLabels:()=>y.toolLabels,useDevTools:()=>ge,useDevToolsContext:()=>O,useDevToolsDial:()=>Se,useDevToolsEnvironment:()=>re,useDevToolsSettings:()=>Te,useDevToolsState:()=>I,useDialState:()=>ne,useFloatingTools:()=>J,useFloatingToolsContext:()=>Z,useOptionalDevToolsContext:()=>ae,useOptionalSettingsContext:()=>ee,useSettings:()=>F,useSettingsContext:()=>j,useSettingsModalState:()=>se,withAlpha:()=>e.withAlpha});module.exports=Fe(Re);var D=require("react"),X=require("@buoy-gg/floating-tools-core"),Y=require("react");function J(t){let{screenSize:o,...s}=t,n=(0,D.useMemo)(()=>new X.FloatingToolsStore({...s,screenWidth:o.width,screenHeight:o.height}),[s.enablePositionPersistence,s.storage,s.visibleHandleWidth,s.dragThreshold,s.edgePadding]),a=(0,D.useRef)(!1),[v,f]=(0,Y.useState)(!1);(0,D.useEffect)(()=>(a.current||(a.current=!0,n.initialize().then(()=>{f(!0)})),()=>{n.destroy()}),[n]),(0,D.useEffect)(()=>{n.setScreenSize(o.width,o.height)},[n,o.width,o.height]);let p=(0,D.useSyncExternalStore)(n.subscribe,n.getSnapshot),T=(0,D.useMemo)(()=>({handleDragStart:S=>n.handleDragStart(S),handleDragMove:S=>n.handleDragMove(S),handleDragEnd:S=>n.handleDragEnd(S),toggleHideShow:()=>n.toggleHideShow(),commitPosition:S=>n.commitPosition(S),setBubbleSize:S=>n.setBubbleSize(S),setScreenSize:(S,E)=>n.setScreenSize(S,E),setMinPosition:S=>n.setMinPosition(S)}),[n]);return{state:p,store:n,isInitialized:v,actions:T}}var _=require("react"),q=require("react/jsx-runtime"),Ie={isDragging:!1,isHidden:!1},z=(0,_.createContext)(Ie);function Z(){return(0,_.useContext)(z)}function $({value:t,children:o}){return(0,q.jsx)(z.Provider,{value:t,children:o})}var r=require("react"),g=require("@buoy-gg/floating-tools-core");function F(t={}){let{availableTools:o=[],defaultFloatingTools:s,defaultDialTools:n,storage:a,initialSettings:v,onSettingsChange:f,subscribeToEventBus:p=!0}=t,T=(0,r.useMemo)(()=>(0,g.generateDefaultSettings)(o,s,n),[o,s,n]),S=(0,r.useMemo)(()=>Object.keys(T.dialTools),[T]),E=(0,r.useMemo)(()=>Object.keys(T.floatingTools).filter(i=>i!=="environment"),[T]),[l,b]=(0,r.useState)(v??T),[N,P]=(0,r.useState)(!0),[w,M]=(0,r.useState)(!1),[A,K]=(0,r.useState)(null),W=(0,r.useCallback)(async()=>{if(!a){P(!1),M(!0);return}try{P(!0),K(null);let i=await a.getItem(g.SETTINGS_STORAGE_KEY);if(i){let u=JSON.parse(i),m=(0,g.mergeSettingsWithDefaults)(T,u,{allowedDialKeys:S,allowedFloatingKeys:E});b(m)}else b(T)}catch(i){console.error("Failed to load dev tools settings:",i),K(i instanceof Error?i.message:"Failed to load settings"),b(T)}finally{P(!1),M(!0)}},[a,T,S,E]),d=(0,r.useCallback)(async i=>{let u={...i,dialTools:(0,g.enforceDialLimit)(i.dialTools)};try{a&&await a.setItem(g.SETTINGS_STORAGE_KEY,JSON.stringify(u)),b(u),f?.(u),g.settingsEventBus.emit(u)}catch(m){throw console.error("Failed to save dev tools settings:",m),K(m instanceof Error?m.message:"Failed to save settings"),m}},[a,f]),De=(0,r.useCallback)(i=>{let u=(0,g.countEnabledTools)(l.dialTools);if(!l.dialTools[i]&&u>=g.MAX_SETTINGS_DIAL_SLOTS)return;let B={...l,dialTools:{...l.dialTools,[i]:!l.dialTools[i]}};d(B)},[l,d]),fe=(0,r.useCallback)(i=>{let u={...l,floatingTools:{...l.floatingTools,[i]:!l.floatingTools[i]}};d(u)},[l,d]),me=(0,r.useCallback)(()=>{let i={...l,floatingTools:{...l.floatingTools,environment:!l.floatingTools.environment}};d(i)},[l,d]),be=(0,r.useCallback)(i=>{let u={...l,globalSettings:{...l.globalSettings,[i]:!l.globalSettings?.[i]}};d(u)},[l,d]),xe=(0,r.useCallback)(async()=>{await d(T)},[T,d]);(0,r.useEffect)(()=>{W()},[W]),(0,r.useEffect)(()=>p?g.settingsEventBus.addListener(u=>{b(u)}):void 0,[p]);let Ce=(0,r.useMemo)(()=>{let i=(0,g.countEnabledTools)(l.dialTools),{dial:u,floating:m}=(0,g.getEnabledToolIds)(l);return{dialToolCount:i,isDialFull:i>=g.MAX_SETTINGS_DIAL_SLOTS,enabledDialTools:u,enabledFloatingTools:m,canEnableDialTool:B=>l.dialTools[B]?!0:i<g.MAX_SETTINGS_DIAL_SLOTS}},[l]);return{settings:l,isLoading:N,isInitialized:w,error:A,actions:{toggleDialTool:De,toggleFloatingTool:fe,toggleEnvironment:me,toggleGlobalSetting:be,saveSettings:d,resetToDefaults:xe,reloadSettings:W},helpers:Ce}}var h=require("react");var te=require("react/jsx-runtime"),U=(0,h.createContext)(null);function Q({children:t,availableTools:o=[],defaultFloatingTools:s,defaultDialTools:n,storage:a,initialSettings:v,onSettingsChange:f}){let p=F({availableTools:o,defaultFloatingTools:s,defaultDialTools:n,storage:a,initialSettings:v,onSettingsChange:f}),T=(0,h.useMemo)(()=>({...p,availableTools:o}),[p,o]);return(0,te.jsx)(U.Provider,{value:T,children:t})}function j(){let t=(0,h.useContext)(U);if(!t)throw new Error("useSettingsContext must be used within a SettingsProvider");return t}function ee(){return(0,h.useContext)(U)}var V=require("react"),oe=require("@buoy-gg/floating-tools-core");function I(t={}){let{manager:o=oe.devToolsStateManager}=t,s=(0,V.useSyncExternalStore)(o.subscribe,o.getState,o.getServerState),n=(0,V.useMemo)(()=>({openDial:()=>o.openDial(),closeDial:()=>o.closeDial(),toggleDial:()=>o.toggleDial(),openSettings:()=>o.openSettings(),closeSettings:()=>o.closeSettings(),setSettingsTab:a=>o.setSettingsTab(a),initialize:()=>o.initialize(),reset:()=>o.reset()}),[o]);return{state:s,actions:n,manager:o}}function ne(t={}){let{state:o,actions:s}=I(t);return{isOpen:o.isDialOpen,open:s.openDial,close:s.closeDial,toggle:s.toggleDial}}function se(t={}){let{state:o,actions:s}=I(t);return{isOpen:o.isSettingsOpen,activeTab:o.activeSettingsTab,open:s.openSettings,close:s.closeSettings,setTab:s.setSettingsTab}}var x=require("react"),ie=require("@buoy-gg/floating-tools-core");var ue=require("react/jsx-runtime"),R=(0,x.createContext)(null);R.displayName="DevToolsContext";function le({children:t,tools:o=[],defaultFloatingTools:s,defaultDialTools:n,environment:a,userRole:v,availableEnvironments:f,onEnvironmentSwitch:p,stateManager:T=ie.devToolsStateManager}){let{state:S,actions:E}=I({manager:T}),l=(0,x.useMemo)(()=>o.map(A=>({id:A.id,name:A.name,description:A.description,slot:A.slot})),[o]),{settings:b,isLoading:N,actions:P,helpers:w}=F({availableTools:l,defaultFloatingTools:s,defaultDialTools:n}),M=(0,x.useMemo)(()=>({devToolsState:S,devToolsActions:E,settings:b,isSettingsLoading:N,settingsActions:P,settingsHelpers:w,tools:o,environment:a,userRole:v,availableEnvironments:f,onEnvironmentSwitch:p}),[S,E,b,N,P,w,o,a,v,f,p]);return(0,ue.jsx)(R.Provider,{value:M,children:t})}function O(){let t=(0,x.useContext)(R);if(!t)throw new Error("useDevToolsContext must be used within a DevToolsProvider. Wrap your app with <DevToolsProvider> or <FloatingDevTools>.");return t}function ae(){return(0,x.useContext)(R)}function re(){let t=O();return{environment:t.environment,userRole:t.userRole,availableEnvironments:t.availableEnvironments,onEnvironmentSwitch:t.onEnvironmentSwitch}}function ge(){let t=O();return{tools:t.tools,settings:t.settings,isLoading:t.isSettingsLoading}}function Se(){let t=O();return{isOpen:t.devToolsState.isDialOpen,open:t.devToolsActions.openDial,close:t.devToolsActions.closeDial,toggle:t.devToolsActions.toggleDial}}function Te(){let t=O();return{isOpen:t.devToolsState.isSettingsOpen,activeTab:t.devToolsState.activeSettingsTab,open:t.devToolsActions.openSettings,close:t.devToolsActions.closeSettings,setTab:t.devToolsActions.setSettingsTab,settings:t.settings,actions:t.settingsActions,helpers:t.settingsHelpers}}var ce=require("@buoy-gg/floating-tools-core");function ve(t,o){let s=(0,ce.filterValidChildren)(t),n=[];return s.forEach((a,v)=>{n.push(a),v<s.length-1&&n.push(o(`divider-${v}`))}),n}var L=require("@buoy-gg/floating-tools-core"),e=require("@buoy-gg/floating-tools-core"),G=require("@buoy-gg/floating-tools-core"),de=require("@buoy-gg/floating-tools-core"),C=require("@buoy-gg/floating-tools-core"),y=require("@buoy-gg/floating-tools-core"),pe=require("@buoy-gg/floating-tools-core"),c=require("@buoy-gg/floating-tools-core"),H=require("@buoy-gg/floating-tools-core");0&&(module.exports={ANIMATION_DURATION,DIAL_BUTTON_SIZE,DIAL_GRID_LINE_COUNT,DIAL_ICON_PADDING,DIAL_ICON_SIZE,DIAL_START_ANGLE,DRAG_THRESHOLD,DevToolsContext,DevToolsProvider,DevToolsStateManager,EDGE_PADDING,FloatingToolsContext,FloatingToolsProvider,FloatingToolsStore,MAX_DIAL_SLOTS,MAX_SETTINGS_DIAL_SLOTS,SETTINGS_STORAGE_KEY,SettingsContext,SettingsEventBus,SettingsProvider,VISIBLE_HANDLE_WIDTH,canEnableDialTool,countEnabledTools,devToolsReducer,devToolsStateManager,dialAnimationConfig,dialCSSBeziers,dialColors,dialStyles,easing,enforceDialLimit,floatingToolsColors,generateDefaultSettings,generateDialCSSKeyframes,getAllIconPositions,getDialCSSAnimationStyles,getDialCSSKeyframesString,getDialLayout,getEnabledToolIds,getGridLineRotations,getGripIconLayout,getIconAngle,getIconPosition,getIconStaggerInputRange,getSpiralAnimationPosition,getStaggeredIconProgress,getToolColor,getToolDescription,getToolLabel,getUserStatusConfig,globalSettingsConfig,interleaveWithDividers,interpolate,interpolatePosition,mergeSettingsWithDefaults,sanitizeFloatingSettings,settingsColors,settingsEventBus,settingsStyles,settingsTabs,toolColors,toolDescriptions,toolLabels,useDevTools,useDevToolsContext,useDevToolsDial,useDevToolsEnvironment,useDevToolsSettings,useDevToolsState,useDialState,useFloatingTools,useFloatingToolsContext,useOptionalDevToolsContext,useOptionalSettingsContext,useSettings,useSettingsContext,useSettingsModalState,withAlpha});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useMemo as w,useSyncExternalStore as $,useEffect as M,useRef as q}from"react";import{FloatingToolsStore as Q}from"@buoy-gg/floating-tools-core";import{useState as ee}from"react";function j(e){let{screenSize:t,...s}=e,o=w(()=>new Q({...s,screenWidth:t.width,screenHeight:t.height}),[s.enablePositionPersistence,s.storage,s.visibleHandleWidth,s.dragThreshold,s.edgePadding]),a=q(!1),[S,c]=ee(!1);M(()=>(a.current||(a.current=!0,o.initialize().then(()=>{c(!0)})),()=>{o.destroy()}),[o]),M(()=>{o.setScreenSize(t.width,t.height)},[o,t.width,t.height]);let u=$(o.subscribe,o.getSnapshot),r=w(()=>({handleDragStart:l=>o.handleDragStart(l),handleDragMove:l=>o.handleDragMove(l),handleDragEnd:l=>o.handleDragEnd(l),toggleHideShow:()=>o.toggleHideShow(),commitPosition:l=>o.commitPosition(l),setBubbleSize:l=>o.setBubbleSize(l),setScreenSize:(l,p)=>o.setScreenSize(l,p),setMinPosition:l=>o.setMinPosition(l)}),[o]);return{state:u,store:o,isInitialized:S,actions:r}}import{createContext as te,useContext as oe}from"react";import{jsx as le}from"react/jsx-runtime";var ne={isDragging:!1,isHidden:!1},U=te(ne);function se(){return oe(U)}function ie({value:e,children:t}){return le(U.Provider,{value:e,children:t})}import{useState as A,useEffect as _,useCallback as D,useMemo as F}from"react";import{settingsEventBus as z,SETTINGS_STORAGE_KEY as V,MAX_SETTINGS_DIAL_SLOTS as N,enforceDialLimit as ae,mergeSettingsWithDefaults as re,generateDefaultSettings as ge,countEnabledTools as G,getEnabledToolIds as Se}from"@buoy-gg/floating-tools-core";function b(e={}){let{availableTools:t=[],defaultFloatingTools:s,defaultDialTools:o,storage:a,initialSettings:S,onSettingsChange:c,subscribeToEventBus:u=!0}=e,r=F(()=>ge(t,s,o),[t,s,o]),l=F(()=>Object.keys(r.dialTools),[r]),p=F(()=>Object.keys(r.floatingTools).filter(n=>n!=="environment"),[r]),[i,d]=A(S??r),[E,f]=A(!0),[h,P]=A(!1),[m,R]=A(null),O=D(async()=>{if(!a){f(!1),P(!0);return}try{f(!0),R(null);let n=await a.getItem(V);if(n){let g=JSON.parse(n),v=re(r,g,{allowedDialKeys:l,allowedFloatingKeys:p});d(v)}else d(r)}catch(n){console.error("Failed to load dev tools settings:",n),R(n instanceof Error?n.message:"Failed to load settings"),d(r)}finally{f(!1),P(!0)}},[a,r,l,p]),T=D(async n=>{let g={...n,dialTools:ae(n.dialTools)};try{a&&await a.setItem(V,JSON.stringify(g)),d(g),c?.(g),z.emit(g)}catch(v){throw console.error("Failed to save dev tools settings:",v),R(v instanceof Error?v.message:"Failed to save settings"),v}},[a,c]),B=D(n=>{let g=G(i.dialTools);if(!i.dialTools[n]&&g>=N)return;let L={...i,dialTools:{...i.dialTools,[n]:!i.dialTools[n]}};T(L)},[i,T]),k=D(n=>{let g={...i,floatingTools:{...i.floatingTools,[n]:!i.floatingTools[n]}};T(g)},[i,T]),X=D(()=>{let n={...i,floatingTools:{...i.floatingTools,environment:!i.floatingTools.environment}};T(n)},[i,T]),J=D(n=>{let g={...i,globalSettings:{...i.globalSettings,[n]:!i.globalSettings?.[n]}};T(g)},[i,T]),Y=D(async()=>{await T(r)},[r,T]);_(()=>{O()},[O]),_(()=>u?z.addListener(g=>{d(g)}):void 0,[u]);let Z=F(()=>{let n=G(i.dialTools),{dial:g,floating:v}=Se(i);return{dialToolCount:n,isDialFull:n>=N,enabledDialTools:g,enabledFloatingTools:v,canEnableDialTool:L=>i.dialTools[L]?!0:n<N}},[i]);return{settings:i,isLoading:E,isInitialized:h,error:m,actions:{toggleDialTool:B,toggleFloatingTool:k,toggleEnvironment:X,toggleGlobalSetting:J,saveSettings:T,resetToDefaults:Y,reloadSettings:O},helpers:Z}}import{createContext as Te,useContext as H,useMemo as ue}from"react";import{jsx as pe}from"react/jsx-runtime";var I=Te(null);function ce({children:e,availableTools:t=[],defaultFloatingTools:s,defaultDialTools:o,storage:a,initialSettings:S,onSettingsChange:c}){let u=b({availableTools:t,defaultFloatingTools:s,defaultDialTools:o,storage:a,initialSettings:S,onSettingsChange:c}),r=ue(()=>({...u,availableTools:t}),[u,t]);return pe(I.Provider,{value:r,children:e})}function ve(){let e=H(I);if(!e)throw new Error("useSettingsContext must be used within a SettingsProvider");return e}function de(){return H(I)}import{useSyncExternalStore as De,useMemo as fe}from"react";import{devToolsStateManager as me}from"@buoy-gg/floating-tools-core";function x(e={}){let{manager:t=me}=e,s=De(t.subscribe,t.getState,t.getServerState),o=fe(()=>({openDial:()=>t.openDial(),closeDial:()=>t.closeDial(),toggleDial:()=>t.toggleDial(),openSettings:()=>t.openSettings(),closeSettings:()=>t.closeSettings(),setSettingsTab:a=>t.setSettingsTab(a),initialize:()=>t.initialize(),reset:()=>t.reset()}),[t]);return{state:s,actions:o,manager:t}}function be(e={}){let{state:t,actions:s}=x(e);return{isOpen:t.isDialOpen,open:s.openDial,close:s.closeDial,toggle:s.toggleDial}}function xe(e={}){let{state:t,actions:s}=x(e);return{isOpen:t.isSettingsOpen,activeTab:t.activeSettingsTab,open:s.openSettings,close:s.closeSettings,setTab:s.setSettingsTab}}import{createContext as Ce,useContext as W,useMemo as K}from"react";import{devToolsStateManager as ye}from"@buoy-gg/floating-tools-core";import{jsx as Re}from"react/jsx-runtime";var C=Ce(null);C.displayName="DevToolsContext";function Ee({children:e,tools:t=[],defaultFloatingTools:s,defaultDialTools:o,environment:a,userRole:S,availableEnvironments:c,onEnvironmentSwitch:u,stateManager:r=ye}){let{state:l,actions:p}=x({manager:r}),i=K(()=>t.map(m=>({id:m.id,name:m.name,description:m.description,slot:m.slot})),[t]),{settings:d,isLoading:E,actions:f,helpers:h}=b({availableTools:i,defaultFloatingTools:s,defaultDialTools:o}),P=K(()=>({devToolsState:l,devToolsActions:p,settings:d,isSettingsLoading:E,settingsActions:f,settingsHelpers:h,tools:t,environment:a,userRole:S,availableEnvironments:c,onEnvironmentSwitch:u}),[l,p,d,E,f,h,t,a,S,c,u]);return Re(C.Provider,{value:P,children:e})}function y(){let e=W(C);if(!e)throw new Error("useDevToolsContext must be used within a DevToolsProvider. Wrap your app with <DevToolsProvider> or <FloatingDevTools>.");return e}function he(){return W(C)}function Pe(){let e=y();return{environment:e.environment,userRole:e.userRole,availableEnvironments:e.availableEnvironments,onEnvironmentSwitch:e.onEnvironmentSwitch}}function Ae(){let e=y();return{tools:e.tools,settings:e.settings,isLoading:e.isSettingsLoading}}function Fe(){let e=y();return{isOpen:e.devToolsState.isDialOpen,open:e.devToolsActions.openDial,close:e.devToolsActions.closeDial,toggle:e.devToolsActions.toggleDial}}function Ie(){let e=y();return{isOpen:e.devToolsState.isSettingsOpen,activeTab:e.devToolsState.activeSettingsTab,open:e.devToolsActions.openSettings,close:e.devToolsActions.closeSettings,setTab:e.devToolsActions.setSettingsTab,settings:e.settings,actions:e.settingsActions,helpers:e.settingsHelpers}}import{filterValidChildren as Oe}from"@buoy-gg/floating-tools-core";function Le(e,t){let s=Oe(e),o=[];return s.forEach((a,S)=>{o.push(a),S<s.length-1&&o.push(t(`divider-${S}`))}),o}import{DevToolsStateManager as bt,devToolsStateManager as xt,devToolsReducer as Ct}from"@buoy-gg/floating-tools-core";import{FloatingToolsStore as Et,floatingToolsColors as ht,withAlpha as Pt,getUserStatusConfig as At,getGripIconLayout as Ft,easing as It,interpolate as Rt,interpolatePosition as Ot,VISIBLE_HANDLE_WIDTH as Lt,ANIMATION_DURATION as Ut,DRAG_THRESHOLD as Nt,EDGE_PADDING as wt,MAX_DIAL_SLOTS as Mt,DIAL_START_ANGLE as _t,DIAL_BUTTON_SIZE as zt,DIAL_ICON_SIZE as Vt,DIAL_ICON_PADDING as Gt,DIAL_GRID_LINE_COUNT as Ht,dialColors as Kt,dialStyles as Wt,getGridLineRotations as Bt,getDialLayout as kt,getIconAngle as Xt,getIconPosition as Jt,getAllIconPositions as Yt,dialAnimationConfig as Zt,getIconStaggerInputRange as $t,dialCSSBeziers as qt,generateDialCSSKeyframes as Qt,getDialCSSAnimationStyles as jt,getDialCSSKeyframesString as eo,getSpiralAnimationPosition as to,getStaggeredIconProgress as oo}from"@buoy-gg/floating-tools-core";import{SETTINGS_STORAGE_KEY as so,MAX_SETTINGS_DIAL_SLOTS as io}from"@buoy-gg/floating-tools-core";import{settingsTabs as ao}from"@buoy-gg/floating-tools-core";import{settingsColors as go,toolColors as So,getToolColor as To,settingsStyles as uo}from"@buoy-gg/floating-tools-core";import{toolLabels as vo,getToolLabel as po,toolDescriptions as Do,getToolDescription as fo}from"@buoy-gg/floating-tools-core";import{globalSettingsConfig as bo}from"@buoy-gg/floating-tools-core";import{enforceDialLimit as Co,sanitizeFloatingSettings as yo,mergeSettingsWithDefaults as Eo,generateDefaultSettings as ho,countEnabledTools as Po,canEnableDialTool as Ao,getEnabledToolIds as Fo}from"@buoy-gg/floating-tools-core";import{SettingsEventBus as Ro,settingsEventBus as Oo}from"@buoy-gg/floating-tools-core";export{Ut as ANIMATION_DURATION,zt as DIAL_BUTTON_SIZE,Ht as DIAL_GRID_LINE_COUNT,Gt as DIAL_ICON_PADDING,Vt as DIAL_ICON_SIZE,_t as DIAL_START_ANGLE,Nt as DRAG_THRESHOLD,C as DevToolsContext,Ee as DevToolsProvider,bt as DevToolsStateManager,wt as EDGE_PADDING,U as FloatingToolsContext,ie as FloatingToolsProvider,Et as FloatingToolsStore,Mt as MAX_DIAL_SLOTS,io as MAX_SETTINGS_DIAL_SLOTS,so as SETTINGS_STORAGE_KEY,I as SettingsContext,Ro as SettingsEventBus,ce as SettingsProvider,Lt as VISIBLE_HANDLE_WIDTH,Ao as canEnableDialTool,Po as countEnabledTools,Ct as devToolsReducer,xt as devToolsStateManager,Zt as dialAnimationConfig,qt as dialCSSBeziers,Kt as dialColors,Wt as dialStyles,It as easing,Co as enforceDialLimit,ht as floatingToolsColors,ho as generateDefaultSettings,Qt as generateDialCSSKeyframes,Yt as getAllIconPositions,jt as getDialCSSAnimationStyles,eo as getDialCSSKeyframesString,kt as getDialLayout,Fo as getEnabledToolIds,Bt as getGridLineRotations,Ft as getGripIconLayout,Xt as getIconAngle,Jt as getIconPosition,$t as getIconStaggerInputRange,to as getSpiralAnimationPosition,oo as getStaggeredIconProgress,To as getToolColor,fo as getToolDescription,po as getToolLabel,At as getUserStatusConfig,bo as globalSettingsConfig,Le as interleaveWithDividers,Rt as interpolate,Ot as interpolatePosition,Eo as mergeSettingsWithDefaults,yo as sanitizeFloatingSettings,go as settingsColors,Oo as settingsEventBus,uo as settingsStyles,ao as settingsTabs,So as toolColors,Do as toolDescriptions,vo as toolLabels,Ae as useDevTools,y as useDevToolsContext,Fe as useDevToolsDial,Pe as useDevToolsEnvironment,Ie as useDevToolsSettings,x as useDevToolsState,be as useDialState,j as useFloatingTools,se as useFloatingToolsContext,he as useOptionalDevToolsContext,de as useOptionalSettingsContext,b as useSettings,ve as useSettingsContext,xe as useSettingsModalState,Pt as withAlpha};
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@buoy-gg/floating-tools-react",
|
|
3
|
+
"version": "1.7.2",
|
|
4
|
+
"description": "React bindings for floating tools - shared hooks and context for web and React Native",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean --no-sourcemap --minify",
|
|
17
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
18
|
+
"typecheck": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@buoy-gg/floating-tools-core": "workspace:*"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react": ">=17.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/react": "^18.0.0 || ^19.0.0",
|
|
31
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
32
|
+
"tsup": "^8.0.0",
|
|
33
|
+
"typescript": "~5.8.3"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"tag": "latest"
|
|
38
|
+
}
|
|
39
|
+
}
|