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