@buoy-gg/debug-borders 2.0.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.
Files changed (43) hide show
  1. package/README.md +334 -0
  2. package/lib/commonjs/debug-borders/components/DebugBordersModal.js +234 -0
  3. package/lib/commonjs/debug-borders/components/DebugBordersStandaloneOverlay.js +436 -0
  4. package/lib/commonjs/debug-borders/index.js +51 -0
  5. package/lib/commonjs/debug-borders/types.js +1 -0
  6. package/lib/commonjs/debug-borders/utils/DebugBordersManager.js +119 -0
  7. package/lib/commonjs/debug-borders/utils/ViewTypeMapper.js +264 -0
  8. package/lib/commonjs/debug-borders/utils/colorGeneration.js +76 -0
  9. package/lib/commonjs/debug-borders/utils/componentInfo.js +183 -0
  10. package/lib/commonjs/debug-borders/utils/componentMeasurement.js +111 -0
  11. package/lib/commonjs/debug-borders/utils/fiberTreeTraversal.js +309 -0
  12. package/lib/commonjs/debug-borders/utils/labelPositioning.js +202 -0
  13. package/lib/commonjs/index.js +34 -0
  14. package/lib/commonjs/package.json +1 -0
  15. package/lib/commonjs/preset.js +178 -0
  16. package/lib/module/debug-borders/components/DebugBordersModal.js +229 -0
  17. package/lib/module/debug-borders/components/DebugBordersStandaloneOverlay.js +432 -0
  18. package/lib/module/debug-borders/index.js +15 -0
  19. package/lib/module/debug-borders/types.js +1 -0
  20. package/lib/module/debug-borders/utils/DebugBordersManager.js +119 -0
  21. package/lib/module/debug-borders/utils/ViewTypeMapper.js +255 -0
  22. package/lib/module/debug-borders/utils/colorGeneration.js +76 -0
  23. package/lib/module/debug-borders/utils/componentInfo.js +183 -0
  24. package/lib/module/debug-borders/utils/componentMeasurement.js +111 -0
  25. package/lib/module/debug-borders/utils/fiberTreeTraversal.js +309 -0
  26. package/lib/module/debug-borders/utils/labelPositioning.js +202 -0
  27. package/lib/module/index.js +7 -0
  28. package/lib/module/preset.js +166 -0
  29. package/lib/typescript/debug-borders/components/DebugBordersModal.d.ts +11 -0
  30. package/lib/typescript/debug-borders/components/DebugBordersModal.d.ts.map +1 -0
  31. package/lib/typescript/debug-borders/components/DebugBordersStandaloneOverlay.d.ts +15 -0
  32. package/lib/typescript/debug-borders/components/DebugBordersStandaloneOverlay.d.ts.map +1 -0
  33. package/lib/typescript/debug-borders/index.d.ts +8 -0
  34. package/lib/typescript/debug-borders/index.d.ts.map +1 -0
  35. package/lib/typescript/debug-borders/types.d.ts +45 -0
  36. package/lib/typescript/debug-borders/types.d.ts.map +1 -0
  37. package/lib/typescript/debug-borders/utils/ViewTypeMapper.d.ts +66 -0
  38. package/lib/typescript/debug-borders/utils/ViewTypeMapper.d.ts.map +1 -0
  39. package/lib/typescript/index.d.ts +3 -0
  40. package/lib/typescript/index.d.ts.map +1 -0
  41. package/lib/typescript/preset.d.ts +108 -0
  42. package/lib/typescript/preset.d.ts.map +1 -0
  43. package/package.json +72 -0
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "DebugBordersStandaloneOverlay", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _DebugBordersStandaloneOverlay.DebugBordersStandaloneOverlay;
10
+ }
11
+ });
12
+ exports.createDebugBordersTool = createDebugBordersTool;
13
+ exports.debugBordersToolPreset = void 0;
14
+ var _react = _interopRequireWildcard(require("react"));
15
+ var _sharedUi = require("@buoy-gg/shared-ui");
16
+ var _jsxRuntime = require("react/jsx-runtime");
17
+ var _DebugBordersStandaloneOverlay = require("./debug-borders/components/DebugBordersStandaloneOverlay");
18
+ 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); }
19
+ /**
20
+ * Pre-configured debug borders tool for FloatingDevTools
21
+ *
22
+ * This preset provides a zero-config way to add visual layout debugging to your dev tools.
23
+ * Just import and add it to your apps array! Tap the icon to cycle through modes:
24
+ * - Off (gray icon)
25
+ * - Borders only (green icon)
26
+ * - Borders + Labels (cyan icon)
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * import { debugBordersToolPreset } from '@buoy-gg/debug-borders';
31
+ *
32
+ * const installedApps = [
33
+ * debugBordersToolPreset, // That's it!
34
+ * // ...other tools
35
+ * ];
36
+ * ```
37
+ */
38
+
39
+ const DebugBordersManager = require("./debug-borders/utils/DebugBordersManager");
40
+ /**
41
+ * Mode colors for the icon
42
+ * - off: gray (disabled)
43
+ * - borders: green (enabled, borders only)
44
+ * - labels: cyan (enabled, with labels)
45
+ */
46
+ const MODE_COLORS = {
47
+ off: "#6b7280",
48
+ // Gray
49
+ borders: "#10b981",
50
+ // Green
51
+ labels: "#06b6d4" // Cyan
52
+ };
53
+
54
+ /**
55
+ * Icon component that changes color based on display mode.
56
+ *
57
+ * ⚠️ IMPORTANT - DO NOT MODIFY THIS COMPONENT ⚠️
58
+ * This component MUST use useState and useEffect hooks to subscribe to the manager.
59
+ * It is rendered as a JSX component (<IconComponent />) in FloatingMenu and DialIcon,
60
+ * which allows hooks to work properly.
61
+ *
62
+ * If you remove the hooks or change this to read getMode() directly,
63
+ * the icon color will NOT update when the toggle is pressed.
64
+ */
65
+ function BordersIcon({
66
+ size
67
+ }) {
68
+ const [mode, setMode] = (0, _react.useState)(() => DebugBordersManager.getMode());
69
+ (0, _react.useEffect)(() => {
70
+ const unsubscribe = DebugBordersManager.subscribe(newMode => {
71
+ setMode(newMode);
72
+ });
73
+ return unsubscribe;
74
+ }, []);
75
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Layers, {
76
+ size: size,
77
+ color: MODE_COLORS[mode]
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Empty component for toggle-only tools (no modal needed)
83
+ */
84
+ function EmptyComponent() {
85
+ return null;
86
+ }
87
+
88
+ /**
89
+ * Pre-configured debug borders tool for FloatingDevTools.
90
+ * Tap the icon to cycle through modes: Off → Borders → Labels → Off
91
+ *
92
+ * Features:
93
+ * - Visual layout debugging with colored borders
94
+ * - Optional component labels showing testID, nativeID, component name, etc.
95
+ * - Automatic component tracking
96
+ * - Real-time updates every 2 seconds
97
+ * - Icon changes color: gray (off), green (borders), cyan (labels)
98
+ */
99
+ const debugBordersToolPreset = exports.debugBordersToolPreset = {
100
+ id: "debug-borders",
101
+ name: "BORDERS",
102
+ description: "Visual layout debugger - tap to cycle modes",
103
+ slot: "menu",
104
+ icon: BordersIcon,
105
+ component: EmptyComponent,
106
+ props: {},
107
+ launchMode: "toggle-only",
108
+ onPress: () => {
109
+ DebugBordersManager.cycle();
110
+ // Icon updates automatically via subscription in BordersIcon component
111
+ }
112
+ };
113
+
114
+ /**
115
+ * Create a custom debug borders tool configuration.
116
+ * Use this if you want to override default settings.
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * import { createDebugBordersTool } from '@buoy-gg/debug-borders';
121
+ *
122
+ * const myBordersTool = createDebugBordersTool({
123
+ * name: "LAYOUT",
124
+ * offColor: "#9ca3af",
125
+ * bordersColor: "#ec4899",
126
+ * labelsColor: "#8b5cf6",
127
+ * });
128
+ * ```
129
+ */
130
+ function createDebugBordersTool(options) {
131
+ const colors = {
132
+ off: options?.offColor || "#6b7280",
133
+ borders: options?.bordersColor || "#10b981",
134
+ labels: options?.labelsColor || "#06b6d4"
135
+ };
136
+
137
+ /**
138
+ * Custom icon component with hooks - rendered as JSX component.
139
+ *
140
+ * ⚠️ IMPORTANT - DO NOT MODIFY THIS COMPONENT ⚠️
141
+ * This component MUST use useState and useEffect hooks to subscribe to the manager.
142
+ * See the comment on BordersIcon above for full explanation.
143
+ */
144
+ const CustomBordersIcon = ({
145
+ size
146
+ }) => {
147
+ const [mode, setMode] = (0, _react.useState)(() => DebugBordersManager.getMode());
148
+ (0, _react.useEffect)(() => {
149
+ const unsubscribe = DebugBordersManager.subscribe(newMode => {
150
+ setMode(newMode);
151
+ });
152
+ return unsubscribe;
153
+ }, []);
154
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Layers, {
155
+ size: size,
156
+ color: colors[mode]
157
+ });
158
+ };
159
+ return {
160
+ id: options?.id || "debug-borders",
161
+ name: options?.name || "BORDERS",
162
+ description: options?.description || "Visual layout debugger - tap to cycle modes",
163
+ slot: "menu",
164
+ icon: CustomBordersIcon,
165
+ component: EmptyComponent,
166
+ props: {},
167
+ launchMode: "toggle-only",
168
+ onPress: () => {
169
+ DebugBordersManager.cycle();
170
+ // Icon updates automatically via subscription
171
+ }
172
+ };
173
+ }
174
+
175
+ /**
176
+ * Export the standalone overlay for manual integration
177
+ * Use this if you want to control debug borders outside of FloatingDevTools
178
+ */
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+
3
+ import React, { useEffect, useState } from "react";
4
+ import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
5
+ import { macOSColors, Layers, StatusBadge, StatusIndicator } from "@buoy-gg/shared-ui";
6
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
+ const DebugBordersManager = require("../utils/DebugBordersManager");
8
+
9
+ /**
10
+ * Modal component for controlling debug borders.
11
+ * This allows developers to toggle visual layout debugging borders on/off.
12
+ */
13
+ export function DebugBordersModal({
14
+ visible,
15
+ onClose
16
+ }) {
17
+ const [enabled, setEnabled] = useState(false);
18
+ const [componentCount, setComponentCount] = useState(0);
19
+
20
+ // Subscribe to manager state
21
+ useEffect(() => {
22
+ const unsubscribe = DebugBordersManager.subscribe(setEnabled);
23
+ setEnabled(DebugBordersManager.isEnabled());
24
+ return unsubscribe;
25
+ }, []);
26
+
27
+ // Track component count when enabled
28
+ useEffect(() => {
29
+ if (!enabled) {
30
+ setComponentCount(0);
31
+ return;
32
+ }
33
+
34
+ // Update component count periodically
35
+ const updateCount = () => {
36
+ try {
37
+ const {
38
+ getAllHostComponentInstances
39
+ } = require("../utils/fiberTreeTraversal");
40
+ const instances = getAllHostComponentInstances();
41
+ setComponentCount(instances.length);
42
+ } catch (error) {
43
+ console.error("[DebugBorders] Error getting component count:", error);
44
+ }
45
+ };
46
+
47
+ // Initial count
48
+ setTimeout(updateCount, 600);
49
+
50
+ // Update every 2 seconds
51
+ const interval = setInterval(updateCount, 2000);
52
+ return () => clearInterval(interval);
53
+ }, [enabled]);
54
+ const handleToggle = () => {
55
+ DebugBordersManager.toggle();
56
+ };
57
+ if (!visible) return null;
58
+ return /*#__PURE__*/_jsx(View, {
59
+ style: styles.container,
60
+ children: /*#__PURE__*/_jsxs(View, {
61
+ style: styles.content,
62
+ children: [/*#__PURE__*/_jsx(Text, {
63
+ style: styles.title,
64
+ children: "Debug Borders"
65
+ }), /*#__PURE__*/_jsx(Text, {
66
+ style: styles.description,
67
+ children: "Visualize component layout structure with colored borders"
68
+ }), /*#__PURE__*/_jsxs(View, {
69
+ style: styles.statusRow,
70
+ children: [/*#__PURE__*/_jsx(Text, {
71
+ style: styles.statusLabel,
72
+ children: "Status:"
73
+ }), /*#__PURE__*/_jsx(StatusBadge, {
74
+ status: enabled ? "active" : "inactive"
75
+ })]
76
+ }), enabled && componentCount > 0 && /*#__PURE__*/_jsxs(View, {
77
+ style: styles.statsRow,
78
+ children: [/*#__PURE__*/_jsx(Text, {
79
+ style: styles.statsLabel,
80
+ children: "Components Tracked:"
81
+ }), /*#__PURE__*/_jsx(Text, {
82
+ style: styles.statsValue,
83
+ children: componentCount
84
+ })]
85
+ }), /*#__PURE__*/_jsx(View, {
86
+ style: styles.toggleContainer,
87
+ children: /*#__PURE__*/_jsxs(TouchableOpacity, {
88
+ style: [styles.button, enabled && styles.buttonActive],
89
+ onPress: handleToggle,
90
+ accessibilityRole: "button",
91
+ accessibilityLabel: `Debug borders ${enabled ? "enabled" : "disabled"}`,
92
+ accessibilityHint: "Tap to toggle debug borders",
93
+ children: [/*#__PURE__*/_jsx(Layers, {
94
+ size: 40,
95
+ color: enabled ? macOSColors.semantic.success : macOSColors.text.secondary
96
+ }), /*#__PURE__*/_jsx(Text, {
97
+ style: [styles.buttonText, enabled && styles.buttonTextActive],
98
+ children: enabled ? "Disable Borders" : "Enable Borders"
99
+ })]
100
+ })
101
+ }), /*#__PURE__*/_jsxs(View, {
102
+ style: styles.infoBox,
103
+ children: [/*#__PURE__*/_jsx(StatusIndicator, {
104
+ status: enabled ? "success" : "info",
105
+ size: "small"
106
+ }), /*#__PURE__*/_jsx(Text, {
107
+ style: styles.infoText,
108
+ children: enabled ? "Borders update every 2 seconds. Tap button to disable." : "Tap button to show colored borders around all components."
109
+ })]
110
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
111
+ style: styles.closeButton,
112
+ onPress: onClose,
113
+ children: /*#__PURE__*/_jsx(Text, {
114
+ style: styles.closeButtonText,
115
+ children: "Close"
116
+ })
117
+ })]
118
+ })
119
+ });
120
+ }
121
+ const styles = StyleSheet.create({
122
+ container: {
123
+ flex: 1,
124
+ justifyContent: "center",
125
+ alignItems: "center",
126
+ backgroundColor: "rgba(0, 0, 0, 0.5)"
127
+ },
128
+ content: {
129
+ backgroundColor: macOSColors.background.card,
130
+ borderRadius: 16,
131
+ padding: 32,
132
+ width: "85%",
133
+ maxWidth: 420,
134
+ alignItems: "center"
135
+ },
136
+ title: {
137
+ fontSize: 24,
138
+ fontWeight: "700",
139
+ color: macOSColors.text.primary,
140
+ marginBottom: 8
141
+ },
142
+ description: {
143
+ fontSize: 14,
144
+ color: macOSColors.text.secondary,
145
+ textAlign: "center",
146
+ marginBottom: 24
147
+ },
148
+ statusRow: {
149
+ flexDirection: "row",
150
+ alignItems: "center",
151
+ marginBottom: 16,
152
+ gap: 8
153
+ },
154
+ statusLabel: {
155
+ fontSize: 14,
156
+ color: macOSColors.text.secondary,
157
+ fontWeight: "600"
158
+ },
159
+ statsRow: {
160
+ flexDirection: "row",
161
+ alignItems: "center",
162
+ marginBottom: 16,
163
+ gap: 8
164
+ },
165
+ statsLabel: {
166
+ fontSize: 14,
167
+ color: macOSColors.text.secondary,
168
+ fontWeight: "600"
169
+ },
170
+ statsValue: {
171
+ fontSize: 16,
172
+ color: macOSColors.text.primary,
173
+ fontWeight: "700"
174
+ },
175
+ toggleContainer: {
176
+ alignItems: "center",
177
+ justifyContent: "center",
178
+ marginBottom: 24
179
+ },
180
+ button: {
181
+ alignItems: "center",
182
+ justifyContent: "center",
183
+ padding: 24,
184
+ borderRadius: 16,
185
+ backgroundColor: macOSColors.background.hover,
186
+ borderWidth: 2,
187
+ borderColor: macOSColors.border.default,
188
+ minWidth: 200
189
+ },
190
+ buttonActive: {
191
+ borderColor: macOSColors.semantic.success,
192
+ backgroundColor: `${macOSColors.semantic.success}15`
193
+ },
194
+ buttonText: {
195
+ marginTop: 12,
196
+ fontSize: 16,
197
+ fontWeight: "600",
198
+ color: macOSColors.text.secondary
199
+ },
200
+ buttonTextActive: {
201
+ color: macOSColors.semantic.success
202
+ },
203
+ infoBox: {
204
+ flexDirection: "row",
205
+ alignItems: "flex-start",
206
+ backgroundColor: macOSColors.background.hover,
207
+ padding: 12,
208
+ borderRadius: 8,
209
+ marginBottom: 24,
210
+ gap: 8
211
+ },
212
+ infoText: {
213
+ flex: 1,
214
+ fontSize: 12,
215
+ color: macOSColors.text.secondary,
216
+ lineHeight: 16
217
+ },
218
+ closeButton: {
219
+ paddingVertical: 12,
220
+ paddingHorizontal: 32,
221
+ backgroundColor: macOSColors.semantic.info,
222
+ borderRadius: 8
223
+ },
224
+ closeButtonText: {
225
+ color: macOSColors.text.primary,
226
+ fontSize: 16,
227
+ fontWeight: "600"
228
+ }
229
+ });