@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.
- package/README.md +334 -0
- package/lib/commonjs/debug-borders/components/DebugBordersModal.js +234 -0
- package/lib/commonjs/debug-borders/components/DebugBordersStandaloneOverlay.js +436 -0
- package/lib/commonjs/debug-borders/index.js +51 -0
- package/lib/commonjs/debug-borders/types.js +1 -0
- package/lib/commonjs/debug-borders/utils/DebugBordersManager.js +119 -0
- package/lib/commonjs/debug-borders/utils/ViewTypeMapper.js +264 -0
- package/lib/commonjs/debug-borders/utils/colorGeneration.js +76 -0
- package/lib/commonjs/debug-borders/utils/componentInfo.js +183 -0
- package/lib/commonjs/debug-borders/utils/componentMeasurement.js +111 -0
- package/lib/commonjs/debug-borders/utils/fiberTreeTraversal.js +309 -0
- package/lib/commonjs/debug-borders/utils/labelPositioning.js +202 -0
- package/lib/commonjs/index.js +34 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/preset.js +178 -0
- package/lib/module/debug-borders/components/DebugBordersModal.js +229 -0
- package/lib/module/debug-borders/components/DebugBordersStandaloneOverlay.js +432 -0
- package/lib/module/debug-borders/index.js +15 -0
- package/lib/module/debug-borders/types.js +1 -0
- package/lib/module/debug-borders/utils/DebugBordersManager.js +119 -0
- package/lib/module/debug-borders/utils/ViewTypeMapper.js +255 -0
- package/lib/module/debug-borders/utils/colorGeneration.js +76 -0
- package/lib/module/debug-borders/utils/componentInfo.js +183 -0
- package/lib/module/debug-borders/utils/componentMeasurement.js +111 -0
- package/lib/module/debug-borders/utils/fiberTreeTraversal.js +309 -0
- package/lib/module/debug-borders/utils/labelPositioning.js +202 -0
- package/lib/module/index.js +7 -0
- package/lib/module/preset.js +166 -0
- package/lib/typescript/debug-borders/components/DebugBordersModal.d.ts +11 -0
- package/lib/typescript/debug-borders/components/DebugBordersModal.d.ts.map +1 -0
- package/lib/typescript/debug-borders/components/DebugBordersStandaloneOverlay.d.ts +15 -0
- package/lib/typescript/debug-borders/components/DebugBordersStandaloneOverlay.d.ts.map +1 -0
- package/lib/typescript/debug-borders/index.d.ts +8 -0
- package/lib/typescript/debug-borders/index.d.ts.map +1 -0
- package/lib/typescript/debug-borders/types.d.ts +45 -0
- package/lib/typescript/debug-borders/types.d.ts.map +1 -0
- package/lib/typescript/debug-borders/utils/ViewTypeMapper.d.ts +66 -0
- package/lib/typescript/debug-borders/utils/ViewTypeMapper.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +3 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/preset.d.ts +108 -0
- package/lib/typescript/preset.d.ts.map +1 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# @buoy/debug-borders
|
|
2
|
+
|
|
3
|
+
A visual layout debugging tool for React Native that highlights components with colored borders and labels. Features three display modes, smart filtering to show only meaningful components, and tap-to-inspect functionality. Works with Expo, React Native CLI, and supports both the new architecture (Fabric) and legacy architecture.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Three Display Modes**: Cycle through Off → Borders → Labels with a single tap
|
|
8
|
+
- **Smart Filtering**: Only shows borders/labels for components with `testID` or `accessibilityLabel`
|
|
9
|
+
- **Tap-to-Inspect**: Tap any label to see detailed component information in a modal
|
|
10
|
+
- **Color-Coded Labels**: Labels match border colors based on identifier type (testID = green, accessibilityLabel = pink)
|
|
11
|
+
- **Label Stacking**: Overlapping labels automatically stack upward like a menu
|
|
12
|
+
- **Hidden Screen Detection**: Automatically hides borders on inactive screens in stack navigators
|
|
13
|
+
- **DevTools Aware**: Hides borders when DevTools modals are open
|
|
14
|
+
- **Real-Time Updates**: Automatically tracks layout changes (updates every 2 seconds)
|
|
15
|
+
- **Touch-Through**: Borders don't interfere with touch interactions
|
|
16
|
+
- **Performance Optimized**: Minimal impact (~30ms to measure 400+ components)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @buoy/debug-borders
|
|
22
|
+
# or
|
|
23
|
+
pnpm add @buoy/debug-borders
|
|
24
|
+
# or
|
|
25
|
+
yarn add @buoy/debug-borders
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { debugBordersToolPreset, DebugBordersStandaloneOverlay } from '@buoy/debug-borders';
|
|
32
|
+
import { FloatingDevTools } from '@buoy/core';
|
|
33
|
+
|
|
34
|
+
const installedApps = [
|
|
35
|
+
debugBordersToolPreset, // Add the tool to your menu
|
|
36
|
+
// ...your other tools
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
function App() {
|
|
40
|
+
return (
|
|
41
|
+
<>
|
|
42
|
+
<FloatingDevTools
|
|
43
|
+
apps={installedApps}
|
|
44
|
+
environment="local"
|
|
45
|
+
userRole="admin"
|
|
46
|
+
/>
|
|
47
|
+
|
|
48
|
+
{/* IMPORTANT: Render overlay at root level */}
|
|
49
|
+
<DebugBordersStandaloneOverlay />
|
|
50
|
+
|
|
51
|
+
{/* Your app content */}
|
|
52
|
+
<YourAppContent />
|
|
53
|
+
</>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Done!** Tap the BORDERS icon in the floating menu to cycle through modes.
|
|
59
|
+
|
|
60
|
+
## Display Modes
|
|
61
|
+
|
|
62
|
+
The tool cycles through three modes when you tap the icon:
|
|
63
|
+
|
|
64
|
+
| Mode | Icon Color | Description |
|
|
65
|
+
|------|------------|-------------|
|
|
66
|
+
| **Off** | Gray | No borders displayed |
|
|
67
|
+
| **Borders** | Green | Rainbow-colored borders for all components (depth-based colors) |
|
|
68
|
+
| **Labels** | Cyan | Borders + labels only for components with `testID` or `accessibilityLabel` |
|
|
69
|
+
|
|
70
|
+
### Labels Mode Features
|
|
71
|
+
|
|
72
|
+
In Labels mode, the tool provides focused debugging:
|
|
73
|
+
|
|
74
|
+
- **Only shows components with identifiers** - Components with `testID` or `accessibilityLabel` get borders and labels
|
|
75
|
+
- **Color-coded by identifier type**:
|
|
76
|
+
- 🟢 Green = `testID`
|
|
77
|
+
- 🩷 Pink = `accessibilityLabel`
|
|
78
|
+
- **Labels positioned above boxes** - Easy to read without obscuring content
|
|
79
|
+
- **Automatic stacking** - Overlapping labels stack upward like a menu
|
|
80
|
+
- **Tap to inspect** - Tap any label to see full component details
|
|
81
|
+
|
|
82
|
+
## Tap-to-Inspect Modal
|
|
83
|
+
|
|
84
|
+
Tap any label in Labels mode to open a detailed inspection modal showing:
|
|
85
|
+
|
|
86
|
+
### Identifiers
|
|
87
|
+
- `testID` (green)
|
|
88
|
+
- `accessibilityLabel` (pink)
|
|
89
|
+
- `nativeID` (amber)
|
|
90
|
+
- `key`
|
|
91
|
+
|
|
92
|
+
### Component Info
|
|
93
|
+
- Component Name (the React component that rendered this)
|
|
94
|
+
- Parent Component
|
|
95
|
+
- Display Name (friendly name like "View", "Text")
|
|
96
|
+
- Native View Type (e.g., "RCTView", "RCTText")
|
|
97
|
+
- Fiber Tag
|
|
98
|
+
|
|
99
|
+
### Position & Size
|
|
100
|
+
- X, Y coordinates
|
|
101
|
+
- Width, Height
|
|
102
|
+
- Depth in component tree
|
|
103
|
+
|
|
104
|
+
### Accessibility
|
|
105
|
+
- Role
|
|
106
|
+
- Hint
|
|
107
|
+
- State (displayed with interactive DataViewer)
|
|
108
|
+
|
|
109
|
+
### Styles
|
|
110
|
+
- Full computed styles (displayed with interactive DataViewer)
|
|
111
|
+
|
|
112
|
+
## Usage Examples
|
|
113
|
+
|
|
114
|
+
### Basic Usage with Preset
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import { debugBordersToolPreset, DebugBordersStandaloneOverlay } from '@buoy/debug-borders';
|
|
118
|
+
|
|
119
|
+
// Add to your FloatingDevTools apps array
|
|
120
|
+
const installedApps = [debugBordersToolPreset];
|
|
121
|
+
|
|
122
|
+
// Render overlay at root level
|
|
123
|
+
<DebugBordersStandaloneOverlay />
|
|
124
|
+
|
|
125
|
+
// Tap the BORDERS icon to cycle: Off → Borders → Labels → Off
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Custom Configuration
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
import { createDebugBordersTool, DebugBordersStandaloneOverlay } from '@buoy/debug-borders';
|
|
132
|
+
|
|
133
|
+
const customBordersTool = createDebugBordersTool({
|
|
134
|
+
name: "LAYOUT",
|
|
135
|
+
description: "Layout visualizer",
|
|
136
|
+
offColor: "#9ca3af", // Gray when off
|
|
137
|
+
bordersColor: "#ec4899", // Pink in borders mode
|
|
138
|
+
labelsColor: "#8b5cf6", // Purple in labels mode
|
|
139
|
+
id: "custom-borders",
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const installedApps = [customBordersTool];
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Programmatic Control
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { DebugBordersManager, DebugBordersStandaloneOverlay } from '@buoy/debug-borders';
|
|
149
|
+
|
|
150
|
+
// Get current mode
|
|
151
|
+
const mode = DebugBordersManager.getMode(); // "off" | "borders" | "labels"
|
|
152
|
+
|
|
153
|
+
// Set specific mode
|
|
154
|
+
DebugBordersManager.setMode("borders");
|
|
155
|
+
DebugBordersManager.setMode("labels");
|
|
156
|
+
DebugBordersManager.setMode("off");
|
|
157
|
+
|
|
158
|
+
// Cycle to next mode
|
|
159
|
+
DebugBordersManager.cycle(); // off → borders → labels → off
|
|
160
|
+
|
|
161
|
+
// Check if labels should be shown
|
|
162
|
+
const showLabels = DebugBordersManager.showLabels(); // true when mode is "labels"
|
|
163
|
+
|
|
164
|
+
// Subscribe to mode changes
|
|
165
|
+
const unsubscribe = DebugBordersManager.subscribe((mode) => {
|
|
166
|
+
console.log('Mode changed to:', mode);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Clean up
|
|
170
|
+
unsubscribe();
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## API Reference
|
|
174
|
+
|
|
175
|
+
### Preset
|
|
176
|
+
|
|
177
|
+
#### `debugBordersToolPreset`
|
|
178
|
+
|
|
179
|
+
Pre-configured tool for FloatingDevTools. Shows only in the floating menu (not the dial).
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
import { debugBordersToolPreset } from '@buoy/debug-borders';
|
|
183
|
+
|
|
184
|
+
const installedApps = [debugBordersToolPreset];
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Functions
|
|
188
|
+
|
|
189
|
+
#### `createDebugBordersTool(options?)`
|
|
190
|
+
|
|
191
|
+
Create a custom debug borders tool configuration.
|
|
192
|
+
|
|
193
|
+
**Options:**
|
|
194
|
+
- `name?: string` - Tool name (default: "BORDERS")
|
|
195
|
+
- `description?: string` - Tool description
|
|
196
|
+
- `offColor?: string` - Icon color when off (default: "#6b7280" gray)
|
|
197
|
+
- `bordersColor?: string` - Icon color in borders mode (default: "#10b981" green)
|
|
198
|
+
- `labelsColor?: string` - Icon color in labels mode (default: "#06b6d4" cyan)
|
|
199
|
+
- `id?: string` - Custom tool ID (default: "debug-borders")
|
|
200
|
+
|
|
201
|
+
### Components
|
|
202
|
+
|
|
203
|
+
#### `<DebugBordersStandaloneOverlay />`
|
|
204
|
+
|
|
205
|
+
The main overlay component that renders borders and labels. **Must be rendered at root level.**
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
import { DebugBordersStandaloneOverlay } from '@buoy/debug-borders';
|
|
209
|
+
|
|
210
|
+
<DebugBordersStandaloneOverlay />
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Note:** This component must be rendered at the root level of your app, outside all modals and navigation containers, for borders to appear on top of everything.
|
|
214
|
+
|
|
215
|
+
### Manager API
|
|
216
|
+
|
|
217
|
+
#### `DebugBordersManager`
|
|
218
|
+
|
|
219
|
+
Global state manager for controlling debug borders.
|
|
220
|
+
|
|
221
|
+
**Methods:**
|
|
222
|
+
- `getMode(): "off" | "borders" | "labels"` - Get current display mode
|
|
223
|
+
- `setMode(mode)` - Set display mode
|
|
224
|
+
- `cycle()` - Cycle to next mode (off → borders → labels → off)
|
|
225
|
+
- `showLabels(): boolean` - Check if labels should be shown (mode === "labels")
|
|
226
|
+
- `subscribe(callback: (mode) => void): () => void` - Subscribe to mode changes
|
|
227
|
+
|
|
228
|
+
## How It Works
|
|
229
|
+
|
|
230
|
+
### Smart Filtering
|
|
231
|
+
|
|
232
|
+
The tool intelligently filters what it displays:
|
|
233
|
+
|
|
234
|
+
1. **Hidden Screen Detection** - Skips components in inactive screens (React Navigation stack)
|
|
235
|
+
2. **SVG Filtering** - Excludes SVG elements (RNSVG* components)
|
|
236
|
+
3. **DevTools Filtering** - Excludes FloatingDevTools, modals, and other dev tool components
|
|
237
|
+
4. **Identifier Filtering** (Labels mode) - Only shows components with `testID` or `accessibilityLabel`
|
|
238
|
+
|
|
239
|
+
### Label Positioning
|
|
240
|
+
|
|
241
|
+
Labels are positioned above their component boxes and automatically stack when they would overlap:
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
┌─────────────────────────────────────┐
|
|
245
|
+
│ [submitButton] │ ← Labels stack upward
|
|
246
|
+
│ [formContainer] │
|
|
247
|
+
├─────────────────────────────────────┤
|
|
248
|
+
│ │
|
|
249
|
+
│ Component Content │
|
|
250
|
+
│ │
|
|
251
|
+
└─────────────────────────────────────┘
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Color Scheme
|
|
255
|
+
|
|
256
|
+
**Borders Mode** - Colors based on nesting depth using golden angle (137.5°):
|
|
257
|
+
| Depth | Color |
|
|
258
|
+
|-------|-------|
|
|
259
|
+
| 0 | Red-Orange |
|
|
260
|
+
| 1 | Green |
|
|
261
|
+
| 2 | Blue |
|
|
262
|
+
| 3+ | Continues with golden angle |
|
|
263
|
+
|
|
264
|
+
**Labels Mode** - Colors based on identifier type:
|
|
265
|
+
| Identifier | Color |
|
|
266
|
+
|------------|-------|
|
|
267
|
+
| testID | Green (#10b981) |
|
|
268
|
+
| accessibilityLabel | Pink (#ec4899) |
|
|
269
|
+
| componentName | Purple (#a855f7) |
|
|
270
|
+
| nativeID | Amber (#f59e0b) |
|
|
271
|
+
| viewType (fallback) | Gray (#6b7280) |
|
|
272
|
+
|
|
273
|
+
## Performance
|
|
274
|
+
|
|
275
|
+
- **Measurement Time:** ~30ms for 400+ components
|
|
276
|
+
- **Update Frequency:** Every 2 seconds when enabled
|
|
277
|
+
- **Memory Impact:** Minimal (only stores rectangle data)
|
|
278
|
+
- **Runtime Impact:** Zero when disabled
|
|
279
|
+
- **Label Positioning:** O(n²) worst case, optimized with early exits
|
|
280
|
+
|
|
281
|
+
## Compatibility
|
|
282
|
+
|
|
283
|
+
- React Native >= 0.70.0
|
|
284
|
+
- Fabric (New Architecture)
|
|
285
|
+
- Paper (Legacy Architecture)
|
|
286
|
+
- Expo
|
|
287
|
+
- React Native CLI
|
|
288
|
+
|
|
289
|
+
## Troubleshooting
|
|
290
|
+
|
|
291
|
+
### Borders not showing?
|
|
292
|
+
|
|
293
|
+
1. Make sure `DebugBordersStandaloneOverlay` is rendered at root level
|
|
294
|
+
2. Tap the icon to cycle modes - you may be in "off" mode
|
|
295
|
+
3. In Labels mode, borders only show for components with `testID` or `accessibilityLabel`
|
|
296
|
+
4. Verify you're in development mode (`__DEV__` is true)
|
|
297
|
+
|
|
298
|
+
### Labels overlapping content?
|
|
299
|
+
|
|
300
|
+
Labels are positioned above component boxes. If they still overlap, they automatically stack upward. Very dense UIs may have many stacked labels.
|
|
301
|
+
|
|
302
|
+
### Can't tap labels?
|
|
303
|
+
|
|
304
|
+
Make sure you're in Labels mode (cyan icon). In Borders mode, labels aren't shown and tapping doesn't work.
|
|
305
|
+
|
|
306
|
+
### Modal not scrolling?
|
|
307
|
+
|
|
308
|
+
The inspection modal uses the standard JsModal component. Swipe up to expand it or drag the handle to resize.
|
|
309
|
+
|
|
310
|
+
## Structure
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
debug-borders/
|
|
314
|
+
├── src/
|
|
315
|
+
│ ├── index.tsx # Main exports
|
|
316
|
+
│ ├── preset.tsx # Preset configuration
|
|
317
|
+
│ └── debug-borders/
|
|
318
|
+
│ ├── components/
|
|
319
|
+
│ │ └── DebugBordersStandaloneOverlay.tsx
|
|
320
|
+
│ └── utils/
|
|
321
|
+
│ ├── DebugBordersManager.js # State manager (3 modes)
|
|
322
|
+
│ ├── fiberTreeTraversal.js # Fiber traversal + filtering
|
|
323
|
+
│ ├── componentMeasurement.js # Component measurements
|
|
324
|
+
│ ├── componentInfo.js # Label extraction
|
|
325
|
+
│ ├── labelPositioning.js # Overlap resolution
|
|
326
|
+
│ ├── ViewTypeMapper.ts # Native → friendly names
|
|
327
|
+
│ └── colorGeneration.js # Color generation
|
|
328
|
+
├── package.json
|
|
329
|
+
└── README.md
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## License
|
|
333
|
+
|
|
334
|
+
MIT
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DebugBordersModal = DebugBordersModal;
|
|
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
|
+
const DebugBordersManager = require("../utils/DebugBordersManager");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Modal component for controlling debug borders.
|
|
16
|
+
* This allows developers to toggle visual layout debugging borders on/off.
|
|
17
|
+
*/
|
|
18
|
+
function DebugBordersModal({
|
|
19
|
+
visible,
|
|
20
|
+
onClose
|
|
21
|
+
}) {
|
|
22
|
+
const [enabled, setEnabled] = (0, _react.useState)(false);
|
|
23
|
+
const [componentCount, setComponentCount] = (0, _react.useState)(0);
|
|
24
|
+
|
|
25
|
+
// Subscribe to manager state
|
|
26
|
+
(0, _react.useEffect)(() => {
|
|
27
|
+
const unsubscribe = DebugBordersManager.subscribe(setEnabled);
|
|
28
|
+
setEnabled(DebugBordersManager.isEnabled());
|
|
29
|
+
return unsubscribe;
|
|
30
|
+
}, []);
|
|
31
|
+
|
|
32
|
+
// Track component count when enabled
|
|
33
|
+
(0, _react.useEffect)(() => {
|
|
34
|
+
if (!enabled) {
|
|
35
|
+
setComponentCount(0);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Update component count periodically
|
|
40
|
+
const updateCount = () => {
|
|
41
|
+
try {
|
|
42
|
+
const {
|
|
43
|
+
getAllHostComponentInstances
|
|
44
|
+
} = require("../utils/fiberTreeTraversal");
|
|
45
|
+
const instances = getAllHostComponentInstances();
|
|
46
|
+
setComponentCount(instances.length);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error("[DebugBorders] Error getting component count:", error);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Initial count
|
|
53
|
+
setTimeout(updateCount, 600);
|
|
54
|
+
|
|
55
|
+
// Update every 2 seconds
|
|
56
|
+
const interval = setInterval(updateCount, 2000);
|
|
57
|
+
return () => clearInterval(interval);
|
|
58
|
+
}, [enabled]);
|
|
59
|
+
const handleToggle = () => {
|
|
60
|
+
DebugBordersManager.toggle();
|
|
61
|
+
};
|
|
62
|
+
if (!visible) return null;
|
|
63
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
64
|
+
style: styles.container,
|
|
65
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
66
|
+
style: styles.content,
|
|
67
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
68
|
+
style: styles.title,
|
|
69
|
+
children: "Debug Borders"
|
|
70
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
71
|
+
style: styles.description,
|
|
72
|
+
children: "Visualize component layout structure with colored borders"
|
|
73
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
74
|
+
style: styles.statusRow,
|
|
75
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
76
|
+
style: styles.statusLabel,
|
|
77
|
+
children: "Status:"
|
|
78
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.StatusBadge, {
|
|
79
|
+
status: enabled ? "active" : "inactive"
|
|
80
|
+
})]
|
|
81
|
+
}), enabled && componentCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
82
|
+
style: styles.statsRow,
|
|
83
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
84
|
+
style: styles.statsLabel,
|
|
85
|
+
children: "Components Tracked:"
|
|
86
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
87
|
+
style: styles.statsValue,
|
|
88
|
+
children: componentCount
|
|
89
|
+
})]
|
|
90
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
91
|
+
style: styles.toggleContainer,
|
|
92
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
93
|
+
style: [styles.button, enabled && styles.buttonActive],
|
|
94
|
+
onPress: handleToggle,
|
|
95
|
+
accessibilityRole: "button",
|
|
96
|
+
accessibilityLabel: `Debug borders ${enabled ? "enabled" : "disabled"}`,
|
|
97
|
+
accessibilityHint: "Tap to toggle debug borders",
|
|
98
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Layers, {
|
|
99
|
+
size: 40,
|
|
100
|
+
color: enabled ? _sharedUi.macOSColors.semantic.success : _sharedUi.macOSColors.text.secondary
|
|
101
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
102
|
+
style: [styles.buttonText, enabled && styles.buttonTextActive],
|
|
103
|
+
children: enabled ? "Disable Borders" : "Enable Borders"
|
|
104
|
+
})]
|
|
105
|
+
})
|
|
106
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
107
|
+
style: styles.infoBox,
|
|
108
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.StatusIndicator, {
|
|
109
|
+
status: enabled ? "success" : "info",
|
|
110
|
+
size: "small"
|
|
111
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
112
|
+
style: styles.infoText,
|
|
113
|
+
children: enabled ? "Borders update every 2 seconds. Tap button to disable." : "Tap button to show colored borders around all components."
|
|
114
|
+
})]
|
|
115
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
116
|
+
style: styles.closeButton,
|
|
117
|
+
onPress: onClose,
|
|
118
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
119
|
+
style: styles.closeButtonText,
|
|
120
|
+
children: "Close"
|
|
121
|
+
})
|
|
122
|
+
})]
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const styles = _reactNative.StyleSheet.create({
|
|
127
|
+
container: {
|
|
128
|
+
flex: 1,
|
|
129
|
+
justifyContent: "center",
|
|
130
|
+
alignItems: "center",
|
|
131
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)"
|
|
132
|
+
},
|
|
133
|
+
content: {
|
|
134
|
+
backgroundColor: _sharedUi.macOSColors.background.card,
|
|
135
|
+
borderRadius: 16,
|
|
136
|
+
padding: 32,
|
|
137
|
+
width: "85%",
|
|
138
|
+
maxWidth: 420,
|
|
139
|
+
alignItems: "center"
|
|
140
|
+
},
|
|
141
|
+
title: {
|
|
142
|
+
fontSize: 24,
|
|
143
|
+
fontWeight: "700",
|
|
144
|
+
color: _sharedUi.macOSColors.text.primary,
|
|
145
|
+
marginBottom: 8
|
|
146
|
+
},
|
|
147
|
+
description: {
|
|
148
|
+
fontSize: 14,
|
|
149
|
+
color: _sharedUi.macOSColors.text.secondary,
|
|
150
|
+
textAlign: "center",
|
|
151
|
+
marginBottom: 24
|
|
152
|
+
},
|
|
153
|
+
statusRow: {
|
|
154
|
+
flexDirection: "row",
|
|
155
|
+
alignItems: "center",
|
|
156
|
+
marginBottom: 16,
|
|
157
|
+
gap: 8
|
|
158
|
+
},
|
|
159
|
+
statusLabel: {
|
|
160
|
+
fontSize: 14,
|
|
161
|
+
color: _sharedUi.macOSColors.text.secondary,
|
|
162
|
+
fontWeight: "600"
|
|
163
|
+
},
|
|
164
|
+
statsRow: {
|
|
165
|
+
flexDirection: "row",
|
|
166
|
+
alignItems: "center",
|
|
167
|
+
marginBottom: 16,
|
|
168
|
+
gap: 8
|
|
169
|
+
},
|
|
170
|
+
statsLabel: {
|
|
171
|
+
fontSize: 14,
|
|
172
|
+
color: _sharedUi.macOSColors.text.secondary,
|
|
173
|
+
fontWeight: "600"
|
|
174
|
+
},
|
|
175
|
+
statsValue: {
|
|
176
|
+
fontSize: 16,
|
|
177
|
+
color: _sharedUi.macOSColors.text.primary,
|
|
178
|
+
fontWeight: "700"
|
|
179
|
+
},
|
|
180
|
+
toggleContainer: {
|
|
181
|
+
alignItems: "center",
|
|
182
|
+
justifyContent: "center",
|
|
183
|
+
marginBottom: 24
|
|
184
|
+
},
|
|
185
|
+
button: {
|
|
186
|
+
alignItems: "center",
|
|
187
|
+
justifyContent: "center",
|
|
188
|
+
padding: 24,
|
|
189
|
+
borderRadius: 16,
|
|
190
|
+
backgroundColor: _sharedUi.macOSColors.background.hover,
|
|
191
|
+
borderWidth: 2,
|
|
192
|
+
borderColor: _sharedUi.macOSColors.border.default,
|
|
193
|
+
minWidth: 200
|
|
194
|
+
},
|
|
195
|
+
buttonActive: {
|
|
196
|
+
borderColor: _sharedUi.macOSColors.semantic.success,
|
|
197
|
+
backgroundColor: `${_sharedUi.macOSColors.semantic.success}15`
|
|
198
|
+
},
|
|
199
|
+
buttonText: {
|
|
200
|
+
marginTop: 12,
|
|
201
|
+
fontSize: 16,
|
|
202
|
+
fontWeight: "600",
|
|
203
|
+
color: _sharedUi.macOSColors.text.secondary
|
|
204
|
+
},
|
|
205
|
+
buttonTextActive: {
|
|
206
|
+
color: _sharedUi.macOSColors.semantic.success
|
|
207
|
+
},
|
|
208
|
+
infoBox: {
|
|
209
|
+
flexDirection: "row",
|
|
210
|
+
alignItems: "flex-start",
|
|
211
|
+
backgroundColor: _sharedUi.macOSColors.background.hover,
|
|
212
|
+
padding: 12,
|
|
213
|
+
borderRadius: 8,
|
|
214
|
+
marginBottom: 24,
|
|
215
|
+
gap: 8
|
|
216
|
+
},
|
|
217
|
+
infoText: {
|
|
218
|
+
flex: 1,
|
|
219
|
+
fontSize: 12,
|
|
220
|
+
color: _sharedUi.macOSColors.text.secondary,
|
|
221
|
+
lineHeight: 16
|
|
222
|
+
},
|
|
223
|
+
closeButton: {
|
|
224
|
+
paddingVertical: 12,
|
|
225
|
+
paddingHorizontal: 32,
|
|
226
|
+
backgroundColor: _sharedUi.macOSColors.semantic.info,
|
|
227
|
+
borderRadius: 8
|
|
228
|
+
},
|
|
229
|
+
closeButtonText: {
|
|
230
|
+
color: _sharedUi.macOSColors.text.primary,
|
|
231
|
+
fontSize: 16,
|
|
232
|
+
fontWeight: "600"
|
|
233
|
+
}
|
|
234
|
+
});
|