@buoy-gg/debug-borders 7.0.40 → 7.0.42

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 (39) hide show
  1. package/README.md +9 -63
  2. package/lib/commonjs/debug-borders/components/DebugBordersModal.js +1 -236
  3. package/lib/commonjs/debug-borders/components/DebugBordersStandaloneOverlay.js +1 -469
  4. package/lib/commonjs/debug-borders/index.js +1 -51
  5. package/lib/commonjs/debug-borders/types.js +1 -1
  6. package/lib/commonjs/debug-borders/utils/DebugBordersManager.js +1 -119
  7. package/lib/commonjs/debug-borders/utils/ViewTypeMapper.js +1 -264
  8. package/lib/commonjs/debug-borders/utils/colorGeneration.js +1 -76
  9. package/lib/commonjs/debug-borders/utils/componentInfo.js +1 -183
  10. package/lib/commonjs/debug-borders/utils/componentMeasurement.js +1 -111
  11. package/lib/commonjs/debug-borders/utils/fiberTreeTraversal.js +1 -309
  12. package/lib/commonjs/debug-borders/utils/labelPositioning.js +1 -202
  13. package/lib/commonjs/index.js +1 -42
  14. package/lib/commonjs/preset.js +1 -178
  15. package/lib/commonjs/sync/debugBordersSyncAdapter.js +1 -34
  16. package/lib/module/debug-borders/components/DebugBordersModal.js +1 -231
  17. package/lib/module/debug-borders/components/DebugBordersStandaloneOverlay.js +1 -464
  18. package/lib/module/debug-borders/index.js +1 -15
  19. package/lib/module/debug-borders/types.js +1 -1
  20. package/lib/module/debug-borders/utils/DebugBordersManager.js +1 -119
  21. package/lib/module/debug-borders/utils/ViewTypeMapper.js +1 -255
  22. package/lib/module/debug-borders/utils/colorGeneration.js +1 -76
  23. package/lib/module/debug-borders/utils/componentInfo.js +1 -183
  24. package/lib/module/debug-borders/utils/componentMeasurement.js +1 -111
  25. package/lib/module/debug-borders/utils/fiberTreeTraversal.js +1 -309
  26. package/lib/module/debug-borders/utils/labelPositioning.js +1 -202
  27. package/lib/module/index.js +1 -10
  28. package/lib/module/preset.js +1 -166
  29. package/lib/module/sync/debugBordersSyncAdapter.js +1 -30
  30. package/lib/web/index.mjs +1 -0
  31. package/package.json +34 -12
  32. package/lib/typescript/debug-borders/components/DebugBordersModal.d.ts.map +0 -1
  33. package/lib/typescript/debug-borders/components/DebugBordersStandaloneOverlay.d.ts.map +0 -1
  34. package/lib/typescript/debug-borders/index.d.ts.map +0 -1
  35. package/lib/typescript/debug-borders/types.d.ts.map +0 -1
  36. package/lib/typescript/debug-borders/utils/ViewTypeMapper.d.ts.map +0 -1
  37. package/lib/typescript/index.d.ts.map +0 -1
  38. package/lib/typescript/preset.d.ts.map +0 -1
  39. package/lib/typescript/sync/debugBordersSyncAdapter.d.ts.map +0 -1
@@ -1,469 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.DebugBordersStandaloneOverlay = DebugBordersStandaloneOverlay;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _jsxRuntime = require("react/jsx-runtime");
11
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
- /**
13
- * Standalone Debug Borders Overlay
14
- *
15
- * This component renders debug borders independently of the Provider.
16
- * It should be rendered at the root level of the app to ensure it appears on top.
17
- *
18
- * Supports two display modes:
19
- * - "borders" - Shows colored borders only
20
- * - "labels" - Shows colored borders with component labels
21
- *
22
- * Automatically hides borders when DevTools modals are open to avoid visual clutter.
23
- */
24
-
25
- // Import JsModal from shared
26
- let JsModal = null;
27
- let DataViewer = null;
28
- /**
29
- * Where this overlay's info window remembers its size.
30
- *
31
- * It used to be the bare string `"debug-borders-info-modal"`, which is the one
32
- * Buoy key in the app that `isDevToolsStorageKey` does not recognise — no
33
- * `@react_buoy`, no `buoy-`, no `@buoy`. The consequences were small but wrong
34
- * in both directions: it showed up in the Storage tool as if it were the app's
35
- * own data, and the Events timeline reported Buoy resizing its own window as an
36
- * application storage write.
37
- */
38
- let infoModalKey = "@react_buoy_debug_borders_info_modal";
39
- try {
40
- const sharedModule = require("@buoy-gg/shared-ui");
41
- JsModal = sharedModule.JsModal;
42
- const keys = sharedModule.devToolsStorageKeys;
43
- if (keys?.debugBorders?.infoModal) {
44
- infoModalKey = keys.debugBorders.infoModal();
45
- }
46
- } catch (e) {
47
- // JsModal not available
48
- }
49
- try {
50
- const dataViewerModule = require("@buoy-gg/shared-ui/dataViewer");
51
- DataViewer = dataViewerModule.DataViewer;
52
- } catch (e) {
53
- // DataViewer not available
54
- }
55
- const DebugBordersManager = require("../utils/DebugBordersManager");
56
- const {
57
- getAllHostComponentInstances
58
- } = require("../utils/fiberTreeTraversal");
59
- const {
60
- measureInstances
61
- } = require("../utils/componentMeasurement");
62
- const {
63
- getColorForDepth
64
- } = require("../utils/colorGeneration");
65
- const {
66
- getShortLabel
67
- } = require("../utils/componentInfo");
68
- const {
69
- resolveOverlappingLabels
70
- } = require("../utils/labelPositioning");
71
-
72
- // Import DevToolsVisibility context to detect when DevTools are open.
73
- //
74
- // Resolved lazily (on first render) instead of at module load to avoid a
75
- // require cycle: @buoy-gg/core -> FloatingDevTools -> autoExternalSync ->
76
- // @buoy-gg/debug-borders -> preset -> this file -> @buoy-gg/core.
77
- // Deferring the require breaks the cycle while keeping the optional dependency.
78
-
79
- let useDevToolsVisibility;
80
- function resolveUseDevToolsVisibility() {
81
- if (useDevToolsVisibility !== undefined) {
82
- return useDevToolsVisibility;
83
- }
84
- try {
85
- // Optional import - will gracefully fail if not available
86
- const coreModule = require("@buoy-gg/core");
87
- useDevToolsVisibility = coreModule.useDevToolsVisibility ?? null;
88
- } catch (e) {
89
- // DevToolsVisibility not available, that's ok - borders will always work
90
- useDevToolsVisibility = null;
91
- }
92
- return useDevToolsVisibility ?? null;
93
- }
94
- // Row component for displaying info
95
- function InfoRow({
96
- label,
97
- value,
98
- color
99
- }) {
100
- if (value === null || value === undefined) return null;
101
- let displayValue;
102
- if (typeof value === "object") {
103
- try {
104
- displayValue = JSON.stringify(value, null, 2);
105
- } catch {
106
- displayValue = String(value);
107
- }
108
- } else {
109
- displayValue = String(value);
110
- }
111
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
112
- style: modalStyles.row,
113
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
114
- style: modalStyles.label,
115
- children: label
116
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
117
- style: [modalStyles.value, color ? {
118
- color
119
- } : null],
120
- children: displayValue
121
- })]
122
- });
123
- }
124
-
125
- // Simple header with just title (no hints)
126
- function SimpleHeader({
127
- title
128
- }) {
129
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
130
- style: headerStyles.container,
131
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
132
- style: headerStyles.title,
133
- numberOfLines: 1,
134
- children: title
135
- })
136
- });
137
- }
138
-
139
- // Component Info Modal Content
140
- function ComponentInfoContent({
141
- info,
142
- rect
143
- }) {
144
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
145
- style: modalStyles.content,
146
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
147
- style: modalStyles.sectionTitle,
148
- children: "Identifiers"
149
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
150
- label: "testID",
151
- value: info.testID,
152
- color: "#10b981"
153
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
154
- label: "accessibilityLabel",
155
- value: info.accessibilityLabel,
156
- color: "#ec4899"
157
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
158
- label: "nativeID",
159
- value: info.nativeID,
160
- color: "#f59e0b"
161
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
162
- label: "key",
163
- value: info.fiberKey
164
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
165
- style: modalStyles.sectionTitle,
166
- children: "Component"
167
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
168
- label: "Component Name",
169
- value: info.componentName,
170
- color: "#a855f7"
171
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
172
- label: "Parent Component",
173
- value: info.parentComponentName
174
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
175
- label: "Display Name",
176
- value: info.displayName
177
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
178
- label: "Native View Type",
179
- value: info.viewType
180
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
181
- label: "Fiber Tag",
182
- value: info.fiberTag
183
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
184
- style: modalStyles.sectionTitle,
185
- children: "Position & Size"
186
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
187
- label: "X",
188
- value: Math.round(rect.x)
189
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
190
- label: "Y",
191
- value: Math.round(rect.y)
192
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
193
- label: "Width",
194
- value: Math.round(rect.width)
195
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
196
- label: "Height",
197
- value: Math.round(rect.height)
198
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
199
- label: "Depth",
200
- value: rect.depth
201
- }), (info.accessibilityRole || info.accessibilityHint || info.accessibilityState) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
202
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
203
- style: modalStyles.sectionTitle,
204
- children: "Accessibility"
205
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
206
- label: "Role",
207
- value: info.accessibilityRole
208
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
209
- label: "Hint",
210
- value: info.accessibilityHint
211
- }), info.accessibilityState && DataViewer ? /*#__PURE__*/(0, _jsxRuntime.jsx)(DataViewer, {
212
- title: "",
213
- data: info.accessibilityState,
214
- showTypeFilter: true,
215
- rawMode: true,
216
- initialExpanded: true
217
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
218
- label: "State",
219
- value: info.accessibilityState
220
- })]
221
- }), info.styleInfo && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
222
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
223
- style: modalStyles.sectionTitle,
224
- children: "Styles"
225
- }), DataViewer ? /*#__PURE__*/(0, _jsxRuntime.jsx)(DataViewer, {
226
- title: "",
227
- data: info.styleInfo,
228
- showTypeFilter: true,
229
- rawMode: true,
230
- initialExpanded: true
231
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
232
- style: modalStyles.codeBlock,
233
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
234
- style: modalStyles.codeText,
235
- children: JSON.stringify(info.styleInfo, null, 2)
236
- })
237
- })]
238
- })]
239
- });
240
- }
241
- function DebugBordersStandaloneOverlay() {
242
- const [mode, setMode] = (0, _react.useState)("off");
243
- const [rectangles, setRectangles] = (0, _react.useState)([]);
244
- const [selectedRect, setSelectedRect] = (0, _react.useState)(null);
245
- const [modalVisible, setModalVisible] = (0, _react.useState)(false);
246
- const measuringRef = _react.default.useRef(false); // Prevent overlapping measurements
247
-
248
- // Check if any DevTools are open (if context is available).
249
- // The hook reference is resolved lazily but is stable for the app's lifetime,
250
- // so calling it conditionally here is safe across renders.
251
- const isDevToolsActive = resolveUseDevToolsVisibility()?.()?.isDevToolsActive ?? false;
252
- const handleLabelPress = (0, _react.useCallback)(rect => {
253
- setSelectedRect(rect);
254
- setModalVisible(true);
255
- }, []);
256
- const handleCloseModal = (0, _react.useCallback)(() => {
257
- setModalVisible(false);
258
- setSelectedRect(null);
259
- }, []);
260
-
261
- // Effective enabled state: user enabled AND no DevTools active
262
- const isEnabled = mode !== "off" && !isDevToolsActive;
263
- const showLabels = mode === "labels" && !isDevToolsActive;
264
-
265
- // Subscribe to manager
266
- (0, _react.useEffect)(() => {
267
- const unsubscribe = DebugBordersManager.subscribe(newMode => {
268
- setMode(newMode);
269
- });
270
- return unsubscribe;
271
- }, []);
272
-
273
- // Update measurements when enabled
274
- (0, _react.useEffect)(() => {
275
- if (!isEnabled) {
276
- setRectangles([]);
277
- return;
278
- }
279
- let mounted = true;
280
- let timer;
281
- const updateMeasurements = async () => {
282
- if (!mounted || measuringRef.current) {
283
- return;
284
- }
285
- measuringRef.current = true;
286
- try {
287
- const instances = getAllHostComponentInstances();
288
- if (instances.length === 0) {
289
- measuringRef.current = false;
290
- return;
291
- }
292
- const measurements = await measureInstances(instances);
293
- if (mounted) {
294
- // Resolve overlapping labels when in labels mode
295
- const processedMeasurements = showLabels ? resolveOverlappingLabels(measurements) : measurements;
296
- setRectangles(processedMeasurements);
297
- }
298
- } catch (error) {
299
- console.error("[DebugBorders] Error updating measurements:", error);
300
- } finally {
301
- measuringRef.current = false;
302
- }
303
- };
304
-
305
- // Initial measurement with delay to let UI settle
306
- const initialTimer = setTimeout(() => {
307
- updateMeasurements();
308
- }, 500);
309
-
310
- // Periodic updates (less frequent to avoid performance issues)
311
- timer = setInterval(updateMeasurements, 2000);
312
- return () => {
313
- mounted = false;
314
- clearTimeout(initialTimer);
315
- clearInterval(timer);
316
- measuringRef.current = false;
317
- };
318
- }, [isEnabled, showLabels, rectangles.length]);
319
- if (!isEnabled) {
320
- return null;
321
- }
322
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
323
- style: styles.overlay,
324
- pointerEvents: "box-none"
325
- // @ts-ignore - custom prop to identify this as debug overlay
326
- ,
327
- dataSet: {
328
- debugOverlay: "true"
329
- },
330
- nativeID: "debug-borders-overlay",
331
- children: [rectangles.map((rect, index) => {
332
- const info = rect.componentInfo;
333
- const hasValidLabel = info && (info.testID || info.accessibilityLabel);
334
-
335
- // In labels mode, only show components with testID or accessibilityLabel
336
- if (showLabels && !hasValidLabel) {
337
- return null;
338
- }
339
-
340
- // Use label color for border when in labels mode, otherwise use depth-based color
341
- const borderColor = showLabels && info ? info.primaryColor : getColorForDepth(rect.depth);
342
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.default.Fragment, {
343
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
344
- pointerEvents: "none",
345
- style: [styles.border, {
346
- left: rect.x,
347
- top: rect.y,
348
- width: rect.width,
349
- height: rect.height,
350
- borderColor: borderColor
351
- }]
352
- }), showLabels && hasValidLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
353
- activeOpacity: 0.7,
354
- onPress: () => handleLabelPress(rect),
355
- style: [styles.labelContainer, {
356
- left: rect.x,
357
- top: rect.y - 10 - (rect.labelOffsetY || 0),
358
- backgroundColor: info.primaryColor
359
- }],
360
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
361
- style: styles.labelText,
362
- numberOfLines: 1,
363
- children: info.primaryLabel
364
- })
365
- })]
366
- }, `border-${index}`);
367
- }), JsModal && selectedRect?.componentInfo && /*#__PURE__*/(0, _jsxRuntime.jsx)(JsModal, {
368
- visible: modalVisible,
369
- onClose: handleCloseModal,
370
- initialMode: "bottomSheet",
371
- header: {
372
- customContent: /*#__PURE__*/(0, _jsxRuntime.jsx)(SimpleHeader, {
373
- title: selectedRect.componentInfo.primaryLabel
374
- })
375
- },
376
- persistenceKey: infoModalKey,
377
- enablePersistence: false,
378
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ComponentInfoContent, {
379
- info: selectedRect.componentInfo,
380
- rect: selectedRect
381
- })
382
- })]
383
- });
384
- }
385
- const styles = _reactNative.StyleSheet.create({
386
- overlay: {
387
- position: "absolute",
388
- top: 0,
389
- left: 0,
390
- right: 0,
391
- bottom: 0,
392
- // Use z-index below floating dev tools (9999-10001) but above normal app content
393
- zIndex: 9000,
394
- elevation: 9000
395
- },
396
- border: {
397
- position: "absolute",
398
- borderWidth: 1,
399
- borderStyle: "solid"
400
- },
401
- labelContainer: {
402
- position: "absolute",
403
- paddingHorizontal: 4,
404
- paddingVertical: 1,
405
- borderRadius: 2
406
- },
407
- labelText: {
408
- fontSize: 8,
409
- fontWeight: "700",
410
- fontFamily: _sharedUi.monoFont,
411
- color: "#ffffff"
412
- }
413
- });
414
- const headerStyles = _reactNative.StyleSheet.create({
415
- container: {
416
- paddingHorizontal: 16,
417
- paddingVertical: 8,
418
- alignItems: "center"
419
- },
420
- title: {
421
- fontSize: 16,
422
- fontWeight: "600",
423
- color: "#ffffff",
424
- fontFamily: _sharedUi.monoFont
425
- }
426
- });
427
- const modalStyles = _reactNative.StyleSheet.create({
428
- content: {
429
- padding: 16
430
- },
431
- sectionTitle: {
432
- fontSize: 12,
433
- fontWeight: "700",
434
- color: "#6b7280",
435
- marginTop: 16,
436
- marginBottom: 8,
437
- textTransform: "uppercase",
438
- letterSpacing: 1
439
- },
440
- row: {
441
- flexDirection: "row",
442
- paddingVertical: 8,
443
- borderBottomWidth: 1,
444
- borderBottomColor: "rgba(255, 255, 255, 0.1)"
445
- },
446
- label: {
447
- fontSize: 13,
448
- color: "#9ca3af",
449
- width: 140,
450
- fontFamily: _sharedUi.monoFont
451
- },
452
- value: {
453
- fontSize: 13,
454
- color: "#ffffff",
455
- flex: 1,
456
- fontFamily: _sharedUi.monoFont
457
- },
458
- codeBlock: {
459
- backgroundColor: "rgba(0, 0, 0, 0.3)",
460
- padding: 12,
461
- borderRadius: 8,
462
- marginTop: 4
463
- },
464
- codeText: {
465
- fontSize: 11,
466
- color: "#e5e7eb",
467
- fontFamily: _sharedUi.monoFont
468
- }
469
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.DebugBordersStandaloneOverlay=DebugBordersStandaloneOverlay;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _dataViewer=require("@buoy-gg/shared-ui/dataViewer");var _utils=require("@buoy-gg/shared-ui/utils");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(e,r){if("function"==typeof WeakMap)var c=new WeakMap,s=new WeakMap;return(_interopRequireWildcard=function(t,f){if(!f&&t&&t.__esModule)return t;var a,u,o={__proto__:null,default:t};if(null===t||"object"!=typeof t&&"function"!=typeof t)return o;if(a=f?s:c){if(a.has(t))return a.get(t);a.set(t,o)}for(const i in t)"default"!==i&&{}.hasOwnProperty.call(t,i)&&((u=(a=Object.defineProperty)&&Object.getOwnPropertyDescriptor(t,i))&&(u.get||u.set)?a(o,i,u):o[i]=t[i]);return o})(e,r)}const infoModalKey=_sharedUi.devToolsStorageKeys.debugBorders.infoModal();const DebugBordersManager=require("../utils/DebugBordersManager");const{getAllHostComponentInstances}=require("../utils/fiberTreeTraversal");const{measureInstances}=require("../utils/componentMeasurement");const{getColorForDepth}=require("../utils/colorGeneration");const{getShortLabel}=require("../utils/componentInfo");const{resolveOverlappingLabels}=require("../utils/labelPositioning");let useDevToolsVisibility;function resolveUseDevToolsVisibility(){if(useDevToolsVisibility!==void 0){return useDevToolsVisibility}try{const e=(0,_utils.loadToolModule)("@buoy-gg/core");useDevToolsVisibility=e.useDevToolsVisibility??null}catch(e){useDevToolsVisibility=null}return useDevToolsVisibility??null}function InfoRow({label:e,value:r,color:c}){if(r===null||r===void 0)return null;let s;if(typeof r==="object"){try{s=JSON.stringify(r,null,2)}catch{s=String(r)}}else{s=String(r)}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:modalStyles.row,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:modalStyles.label,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[modalStyles.value,c?{color:c}:null],children:s})]})}function SimpleHeader({title:e}){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:headerStyles.container,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:headerStyles.title,numberOfLines:1,children:e})})}function ComponentInfoContent({info:e,rect:r}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:modalStyles.content,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:modalStyles.sectionTitle,children:"Identifiers"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"testID",value:e.testID,color:"#10b981"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"accessibilityLabel",value:e.accessibilityLabel,color:"#ec4899"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"nativeID",value:e.nativeID,color:"#f59e0b"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"key",value:e.fiberKey}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:modalStyles.sectionTitle,children:"Component"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Component Name",value:e.componentName,color:"#a855f7"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Parent Component",value:e.parentComponentName}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Display Name",value:e.displayName}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Native View Type",value:e.viewType}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Fiber Tag",value:e.fiberTag}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:modalStyles.sectionTitle,children:"Position & Size"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"X",value:Math.round(r.x)}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Y",value:Math.round(r.y)}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Width",value:Math.round(r.width)}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Height",value:Math.round(r.height)}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Depth",value:r.depth}),(e.accessibilityRole||e.accessibilityHint||e.accessibilityState)&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:modalStyles.sectionTitle,children:"Accessibility"}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Role",value:e.accessibilityRole}),(0,_jsxRuntime.jsx)(InfoRow,{label:"Hint",value:e.accessibilityHint}),e.accessibilityState&&_dataViewer.DataViewer?(0,_jsxRuntime.jsx)(_dataViewer.DataViewer,{title:"",data:e.accessibilityState,showTypeFilter:true,rawMode:true,initialExpanded:true}):(0,_jsxRuntime.jsx)(InfoRow,{label:"State",value:e.accessibilityState})]}),e.styleInfo&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:modalStyles.sectionTitle,children:"Styles"}),_dataViewer.DataViewer?(0,_jsxRuntime.jsx)(_dataViewer.DataViewer,{title:"",data:e.styleInfo,showTypeFilter:true,rawMode:true,initialExpanded:true}):(0,_jsxRuntime.jsx)(_reactNative.View,{style:modalStyles.codeBlock,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:modalStyles.codeText,children:JSON.stringify(e.styleInfo,null,2)})})]})]})}function DebugBordersStandaloneOverlay(){const[e,r]=(0,_react.useState)("off");const[c,s]=(0,_react.useState)([]);const[t,f]=(0,_react.useState)(null);const[a,u]=(0,_react.useState)(false);const o=_react.default.useRef(false);const i=resolveUseDevToolsVisibility()?.()?.isDevToolsActive??false;const m=(0,_react.useCallback)(l=>{f(l);u(true)},[]);const g=(0,_react.useCallback)(()=>{u(false);f(null)},[]);const h=e!=="off"&&!i;const y=e==="labels"&&!i;(0,_react.useEffect)(()=>{const l=DebugBordersManager.subscribe(d=>{r(d)});return l},[]);(0,_react.useEffect)(()=>{if(!h){s([]);return}let l=true;let d;const n=async()=>{if(!l||o.current){return}o.current=true;try{const b=getAllHostComponentInstances();if(b.length===0){o.current=false;return}const x=await measureInstances(b);if(l){const v=y?resolveOverlappingLabels(x):x;s(v)}}catch(b){console.error("[DebugBorders] Error updating measurements:",b)}finally{o.current=false}};const p=setTimeout(()=>{n()},500);d=setInterval(n,2e3);return()=>{l=false;clearTimeout(p);clearInterval(d);o.current=false}},[h,y,c.length]);if(!h){return null}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",dataSet:{debugOverlay:"true"},nativeID:"debug-borders-overlay",children:[c.map((l,d)=>{const n=l.componentInfo;const p=n&&(n.testID||n.accessibilityLabel);if(y&&!p){return null}const b=y&&n?n.primaryColor:getColorForDepth(l.depth);return(0,_jsxRuntime.jsxs)(_react.default.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.border,{left:l.x,top:l.y,width:l.width,height:l.height,borderColor:b}]}),y&&p&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{activeOpacity:.7,onPress:()=>m(l),style:[styles.labelContainer,{left:l.x,top:l.y-10-(l.labelOffsetY||0),backgroundColor:n.primaryColor}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.labelText,numberOfLines:1,children:n.primaryLabel})})]},`border-${d}`)}),_sharedUi.JsModal&&t?.componentInfo&&(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:a,onClose:g,initialMode:"bottomSheet",header:{customContent:(0,_jsxRuntime.jsx)(SimpleHeader,{title:t.componentInfo.primaryLabel})},persistenceKey:infoModalKey,enablePersistence:false,children:(0,_jsxRuntime.jsx)(ComponentInfoContent,{info:t.componentInfo,rect:t})})]})}const styles=_reactNative.StyleSheet.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:9e3,elevation:9e3},border:{position:"absolute",borderWidth:1,borderStyle:"solid"},labelContainer:{position:"absolute",paddingHorizontal:4,paddingVertical:1,borderRadius:2},labelText:{fontSize:8,fontWeight:"700",fontFamily:_sharedUi.monoFont,color:"#ffffff"}});const headerStyles=_reactNative.StyleSheet.create({container:{paddingHorizontal:16,paddingVertical:8,alignItems:"center"},title:{fontSize:16,fontWeight:"600",color:"#ffffff",fontFamily:_sharedUi.monoFont}});const modalStyles=_reactNative.StyleSheet.create({content:{padding:16},sectionTitle:{fontSize:12,fontWeight:"700",color:"#6b7280",marginTop:16,marginBottom:8,textTransform:"uppercase",letterSpacing:1},row:{flexDirection:"row",paddingVertical:8,borderBottomWidth:1,borderBottomColor:"rgba(255, 255, 255, 0.1)"},label:{fontSize:13,color:"#9ca3af",width:140,fontFamily:_sharedUi.monoFont},value:{fontSize:13,color:"#ffffff",flex:1,fontFamily:_sharedUi.monoFont},codeBlock:{backgroundColor:"rgba(0, 0, 0, 0.3)",padding:12,borderRadius:8,marginTop:4},codeText:{fontSize:11,color:"#e5e7eb",fontFamily:_sharedUi.monoFont}});
@@ -1,51 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- var _exportNames = {
7
- DebugBordersManager: true,
8
- fiberTreeTraversal: true,
9
- componentMeasurement: true,
10
- colorGeneration: true,
11
- DebugBordersModal: true,
12
- DebugBordersStandaloneOverlay: true
13
- };
14
- exports.DebugBordersManager = void 0;
15
- Object.defineProperty(exports, "DebugBordersModal", {
16
- enumerable: true,
17
- get: function () {
18
- return _DebugBordersModal.DebugBordersModal;
19
- }
20
- });
21
- Object.defineProperty(exports, "DebugBordersStandaloneOverlay", {
22
- enumerable: true,
23
- get: function () {
24
- return _DebugBordersStandaloneOverlay.DebugBordersStandaloneOverlay;
25
- }
26
- });
27
- exports.fiberTreeTraversal = exports.componentMeasurement = exports.colorGeneration = void 0;
28
- var _types = require("./types");
29
- Object.keys(_types).forEach(function (key) {
30
- if (key === "default" || key === "__esModule") return;
31
- if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
32
- if (key in exports && exports[key] === _types[key]) return;
33
- Object.defineProperty(exports, key, {
34
- enumerable: true,
35
- get: function () {
36
- return _types[key];
37
- }
38
- });
39
- });
40
- var _DebugBordersModal = require("./components/DebugBordersModal");
41
- var _DebugBordersStandaloneOverlay = require("./components/DebugBordersStandaloneOverlay");
42
- // Export types
43
-
44
- // Export components
45
-
46
- // Export utilities (JS modules - will be typed when converted to TS)
47
- // Note: These are CommonJS modules, so we use require for now
48
- const DebugBordersManager = exports.DebugBordersManager = require("./utils/DebugBordersManager");
49
- const fiberTreeTraversal = exports.fiberTreeTraversal = require("./utils/fiberTreeTraversal");
50
- const componentMeasurement = exports.componentMeasurement = require("./utils/componentMeasurement");
51
- const colorGeneration = exports.colorGeneration = require("./utils/colorGeneration");
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});var _exportNames={DebugBordersManager:true,fiberTreeTraversal:true,componentMeasurement:true,colorGeneration:true,DebugBordersModal:true,DebugBordersStandaloneOverlay:true};exports.DebugBordersManager=void 0;Object.defineProperty(exports,"DebugBordersModal",{enumerable:true,get:function(){return _DebugBordersModal.DebugBordersModal}});Object.defineProperty(exports,"DebugBordersStandaloneOverlay",{enumerable:true,get:function(){return _DebugBordersStandaloneOverlay.DebugBordersStandaloneOverlay}});exports.fiberTreeTraversal=exports.componentMeasurement=exports.colorGeneration=void 0;var _types=require("./types");Object.keys(_types).forEach(function(e){if(e==="default"||e==="__esModule")return;if(Object.prototype.hasOwnProperty.call(_exportNames,e))return;if(e in exports&&exports[e]===_types[e])return;Object.defineProperty(exports,e,{enumerable:true,get:function(){return _types[e]}})});var _DebugBordersModal=require("./components/DebugBordersModal");var _DebugBordersStandaloneOverlay=require("./components/DebugBordersStandaloneOverlay");const DebugBordersManager=exports.DebugBordersManager=require("./utils/DebugBordersManager");const fiberTreeTraversal=exports.fiberTreeTraversal=require("./utils/fiberTreeTraversal");const componentMeasurement=exports.componentMeasurement=require("./utils/componentMeasurement");const colorGeneration=exports.colorGeneration=require("./utils/colorGeneration");
@@ -1 +1 @@
1
- "use strict";
1
+ "use strict";
@@ -1,119 +1 @@
1
- "use strict";
2
-
3
- let globalMode = "off";
4
- const listeners = new Set();
5
- const MODE_CYCLE_FULL = ["off", "borders", "labels"];
6
- const MODE_CYCLE_FREE = ["off", "borders"];
7
- let _isPro = null;
8
- let _licenseLoadAttempted = false;
9
- function loadLicenseModule() {
10
- if (_licenseLoadAttempted) return;
11
- _licenseLoadAttempted = true;
12
- try {
13
- const mod = require("@buoy-gg/license");
14
- if (mod && typeof mod.isPro === "function") {
15
- _isPro = mod.isPro;
16
- }
17
- } catch {
18
- _isPro = null;
19
- }
20
- }
21
- function checkIsPro() {
22
- loadLicenseModule();
23
- if (_isPro) {
24
- try {
25
- return _isPro();
26
- } catch {
27
- return false;
28
- }
29
- }
30
- return false;
31
- }
32
- function getModeCycle() {
33
- return checkIsPro() ? MODE_CYCLE_FULL : MODE_CYCLE_FREE;
34
- }
35
- const MODE_CYCLE = MODE_CYCLE_FULL;
36
- function subscribe(listener) {
37
- listeners.add(listener);
38
- listener(globalMode);
39
- return () => {
40
- listeners.delete(listener);
41
- };
42
- }
43
- function notifyListeners() {
44
- listeners.forEach(listener => {
45
- try {
46
- listener(globalMode);
47
- } catch (error) {
48
- console.error("[DebugBorders] Error in listener:", error);
49
- }
50
- });
51
- }
52
- function setMode(mode) {
53
- if (globalMode === mode) {
54
- return true;
55
- }
56
- if (mode === "labels" && !checkIsPro()) {
57
- console.warn("[DebugBorders] Labels mode requires React Buoy Pro. Upgrade at https://buoy.gg/pro");
58
- return false;
59
- }
60
- globalMode = mode;
61
- notifyListeners();
62
- return true;
63
- }
64
- function getMode() {
65
- return globalMode;
66
- }
67
- function cycle() {
68
- const availableModes = getModeCycle();
69
- const currentIndex = availableModes.indexOf(globalMode);
70
- if (currentIndex === -1) {
71
- setMode("off");
72
- return;
73
- }
74
- const nextIndex = (currentIndex + 1) % availableModes.length;
75
- setMode(availableModes[nextIndex]);
76
- }
77
- function enable() {
78
- setMode("borders");
79
- }
80
- function disable() {
81
- setMode("off");
82
- }
83
- function toggle() {
84
- cycle();
85
- }
86
- function isEnabled() {
87
- return globalMode !== "off";
88
- }
89
- function showLabels() {
90
- return globalMode === "labels" && checkIsPro();
91
- }
92
- function isProEnabled() {
93
- return checkIsPro();
94
- }
95
- function getAvailableModes() {
96
- return getModeCycle();
97
- }
98
- function setEnabled(enabled) {
99
- if (enabled) {
100
- enable();
101
- } else {
102
- disable();
103
- }
104
- }
105
- module.exports = {
106
- subscribe,
107
- enable,
108
- disable,
109
- toggle,
110
- cycle,
111
- isEnabled,
112
- showLabels,
113
- setEnabled,
114
- getMode,
115
- setMode,
116
- isProEnabled,
117
- getAvailableModes,
118
- MODE_CYCLE
119
- };
1
+ "use strict";var _utils=require("@buoy-gg/shared-ui/utils");"use strict";let globalMode="off";const listeners=new Set;const MODE_CYCLE_FULL=["off","borders","labels"];const MODE_CYCLE_FREE=["off","borders"];let _isPro=null;let _licenseLoadAttempted=false;function loadLicenseModule(){if(_licenseLoadAttempted)return;_licenseLoadAttempted=true;try{const e=(0,_utils.loadToolModule)("@buoy-gg/license");if(e&&typeof e.isPro==="function"){_isPro=e.isPro}}catch{_isPro=null}}function checkIsPro(){loadLicenseModule();if(_isPro){try{return _isPro()}catch{return false}}return false}function getModeCycle(){return checkIsPro()?MODE_CYCLE_FULL:MODE_CYCLE_FREE}const MODE_CYCLE=MODE_CYCLE_FULL;function subscribe(e){listeners.add(e);e(globalMode);return()=>{listeners.delete(e)}}function notifyListeners(){listeners.forEach(e=>{try{e(globalMode)}catch(t){console.error("[DebugBorders] Error in listener:",t)}})}function setMode(e){if(globalMode===e){return true}if(e==="labels"&&!checkIsPro()){console.warn("[DebugBorders] Labels mode requires React Buoy Pro. Upgrade at https://buoy.gg/pro");return false}globalMode=e;notifyListeners();return true}function getMode(){return globalMode}function cycle(){const e=getModeCycle();const t=e.indexOf(globalMode);if(t===-1){setMode("off");return}const n=(t+1)%e.length;setMode(e[n])}function enable(){setMode("borders")}function disable(){setMode("off")}function toggle(){cycle()}function isEnabled(){return globalMode!=="off"}function showLabels(){return globalMode==="labels"&&checkIsPro()}function isProEnabled(){return checkIsPro()}function getAvailableModes(){return getModeCycle()}function setEnabled(e){if(e){enable()}else{disable()}}module.exports={subscribe,enable,disable,toggle,cycle,isEnabled,showLabels,setEnabled,getMode,setMode,isProEnabled,getAvailableModes,MODE_CYCLE};