@buoy-gg/network 7.0.12 → 7.0.14

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 (136) hide show
  1. package/lib/commonjs/index.js +52 -0
  2. package/lib/commonjs/network/components/NetworkDetailStepper.js +26 -14
  3. package/lib/commonjs/network/components/NetworkEventDetailView.js +86 -14
  4. package/lib/commonjs/network/components/NetworkEventItemCompact.js +4 -0
  5. package/lib/commonjs/network/components/NetworkHeaderLive.js +32 -7
  6. package/lib/commonjs/network/components/NetworkHeaderMenu.js +183 -0
  7. package/lib/commonjs/network/components/NetworkListScreen.js +134 -8
  8. package/lib/commonjs/network/components/NetworkModal.js +198 -51
  9. package/lib/commonjs/network/components/NetworkNumberPrompt.js +178 -0
  10. package/lib/commonjs/network/components/NetworkOverrideEditor.js +797 -0
  11. package/lib/commonjs/network/components/NetworkOverrideHeaderButton.js +102 -0
  12. package/lib/commonjs/network/components/NetworkOverridesButton.js +88 -0
  13. package/lib/commonjs/network/components/NetworkOverridesScreen.js +489 -0
  14. package/lib/commonjs/network/components/response-editor/Explorer.js +973 -0
  15. package/lib/commonjs/network/components/response-editor/deleteNestedDataByPath.js +56 -0
  16. package/lib/commonjs/network/components/response-editor/editorContext.js +33 -0
  17. package/lib/commonjs/network/components/response-editor/updateNestedDataByPath.js +61 -0
  18. package/lib/commonjs/network/hooks/useNetworkSelection.js +53 -0
  19. package/lib/commonjs/network/hooks/useOverrideRules.js +36 -0
  20. package/lib/commonjs/network/overrides/applyToFetch.js +80 -0
  21. package/lib/commonjs/network/overrides/applyToXhr.js +190 -0
  22. package/lib/commonjs/network/overrides/engine.js +70 -0
  23. package/lib/commonjs/network/overrides/matchRule.js +81 -0
  24. package/lib/commonjs/network/overrides/overrideRulesStore.js +550 -0
  25. package/lib/commonjs/network/overrides/presets.js +70 -0
  26. package/lib/commonjs/network/overrides/resolveOverride.js +158 -0
  27. package/lib/commonjs/network/overrides/types.js +85 -0
  28. package/lib/commonjs/network/sync/networkSyncAdapter.js +230 -1
  29. package/lib/commonjs/network/types/index.js +5 -1
  30. package/lib/commonjs/network/utils/networkEventStore.js +52 -6
  31. package/lib/commonjs/network/utils/networkListener.js +90 -10
  32. package/lib/commonjs/network/utils/networkSelectionStore.js +193 -0
  33. package/lib/commonjs/preset.js +11 -0
  34. package/lib/module/index.js +19 -0
  35. package/lib/module/network/components/NetworkDetailStepper.js +27 -15
  36. package/lib/module/network/components/NetworkEventDetailView.js +87 -15
  37. package/lib/module/network/components/NetworkEventItemCompact.js +5 -1
  38. package/lib/module/network/components/NetworkHeaderLive.js +32 -7
  39. package/lib/module/network/components/NetworkHeaderMenu.js +177 -0
  40. package/lib/module/network/components/NetworkListScreen.js +135 -9
  41. package/lib/module/network/components/NetworkModal.js +200 -53
  42. package/lib/module/network/components/NetworkNumberPrompt.js +174 -0
  43. package/lib/module/network/components/NetworkOverrideEditor.js +794 -0
  44. package/lib/module/network/components/NetworkOverrideHeaderButton.js +99 -0
  45. package/lib/module/network/components/NetworkOverridesButton.js +85 -0
  46. package/lib/module/network/components/NetworkOverridesScreen.js +485 -0
  47. package/lib/module/network/components/response-editor/Explorer.js +972 -0
  48. package/lib/module/network/components/response-editor/deleteNestedDataByPath.js +51 -0
  49. package/lib/module/network/components/response-editor/editorContext.js +29 -0
  50. package/lib/module/network/components/response-editor/updateNestedDataByPath.js +56 -0
  51. package/lib/module/network/hooks/useNetworkSelection.js +46 -0
  52. package/lib/module/network/hooks/useOverrideRules.js +32 -0
  53. package/lib/module/network/overrides/applyToFetch.js +72 -0
  54. package/lib/module/network/overrides/applyToXhr.js +185 -0
  55. package/lib/module/network/overrides/engine.js +64 -0
  56. package/lib/module/network/overrides/matchRule.js +75 -0
  57. package/lib/module/network/overrides/overrideRulesStore.js +547 -0
  58. package/lib/module/network/overrides/presets.js +65 -0
  59. package/lib/module/network/overrides/resolveOverride.js +152 -0
  60. package/lib/module/network/overrides/types.js +80 -0
  61. package/lib/module/network/sync/networkSyncAdapter.js +230 -1
  62. package/lib/module/network/types/index.js +3 -1
  63. package/lib/module/network/utils/networkEventStore.js +52 -6
  64. package/lib/module/network/utils/networkListener.js +91 -10
  65. package/lib/module/network/utils/networkSelectionStore.js +188 -0
  66. package/lib/module/preset.js +13 -1
  67. package/lib/typescript/index.d.ts +9 -0
  68. package/lib/typescript/index.d.ts.map +1 -1
  69. package/lib/typescript/network/components/NetworkDetailStepper.d.ts +8 -5
  70. package/lib/typescript/network/components/NetworkDetailStepper.d.ts.map +1 -1
  71. package/lib/typescript/network/components/NetworkEventDetailView.d.ts +36 -1
  72. package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +1 -1
  73. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts +6 -0
  74. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +1 -1
  75. package/lib/typescript/network/components/NetworkHeaderLive.d.ts +13 -3
  76. package/lib/typescript/network/components/NetworkHeaderLive.d.ts.map +1 -1
  77. package/lib/typescript/network/components/NetworkHeaderMenu.d.ts +46 -0
  78. package/lib/typescript/network/components/NetworkHeaderMenu.d.ts.map +1 -0
  79. package/lib/typescript/network/components/NetworkListScreen.d.ts.map +1 -1
  80. package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -1
  81. package/lib/typescript/network/components/NetworkNumberPrompt.d.ts +33 -0
  82. package/lib/typescript/network/components/NetworkNumberPrompt.d.ts.map +1 -0
  83. package/lib/typescript/network/components/NetworkOverrideEditor.d.ts +17 -0
  84. package/lib/typescript/network/components/NetworkOverrideEditor.d.ts.map +1 -0
  85. package/lib/typescript/network/components/NetworkOverrideHeaderButton.d.ts +27 -0
  86. package/lib/typescript/network/components/NetworkOverrideHeaderButton.d.ts.map +1 -0
  87. package/lib/typescript/network/components/NetworkOverridesButton.d.ts +17 -0
  88. package/lib/typescript/network/components/NetworkOverridesButton.d.ts.map +1 -0
  89. package/lib/typescript/network/components/NetworkOverridesScreen.d.ts +29 -0
  90. package/lib/typescript/network/components/NetworkOverridesScreen.d.ts.map +1 -0
  91. package/lib/typescript/network/components/response-editor/Explorer.d.ts +17 -0
  92. package/lib/typescript/network/components/response-editor/Explorer.d.ts.map +1 -0
  93. package/lib/typescript/network/components/response-editor/deleteNestedDataByPath.d.ts +9 -0
  94. package/lib/typescript/network/components/response-editor/deleteNestedDataByPath.d.ts.map +1 -0
  95. package/lib/typescript/network/components/response-editor/editorContext.d.ts +29 -0
  96. package/lib/typescript/network/components/response-editor/editorContext.d.ts.map +1 -0
  97. package/lib/typescript/network/components/response-editor/updateNestedDataByPath.d.ts +10 -0
  98. package/lib/typescript/network/components/response-editor/updateNestedDataByPath.d.ts.map +1 -0
  99. package/lib/typescript/network/hooks/useNetworkSelection.d.ts +26 -0
  100. package/lib/typescript/network/hooks/useNetworkSelection.d.ts.map +1 -0
  101. package/lib/typescript/network/hooks/useOverrideRules.d.ts +29 -0
  102. package/lib/typescript/network/hooks/useOverrideRules.d.ts.map +1 -0
  103. package/lib/typescript/network/overrides/__tests__/applyToFetch.test.d.ts +16 -0
  104. package/lib/typescript/network/overrides/__tests__/applyToFetch.test.d.ts.map +1 -0
  105. package/lib/typescript/network/overrides/__tests__/applyToXhr.test.d.ts +19 -0
  106. package/lib/typescript/network/overrides/__tests__/applyToXhr.test.d.ts.map +1 -0
  107. package/lib/typescript/network/overrides/__tests__/resolveOverride.test.d.ts +22 -0
  108. package/lib/typescript/network/overrides/__tests__/resolveOverride.test.d.ts.map +1 -0
  109. package/lib/typescript/network/overrides/applyToFetch.d.ts +50 -0
  110. package/lib/typescript/network/overrides/applyToFetch.d.ts.map +1 -0
  111. package/lib/typescript/network/overrides/applyToXhr.d.ts +43 -0
  112. package/lib/typescript/network/overrides/applyToXhr.d.ts.map +1 -0
  113. package/lib/typescript/network/overrides/engine.d.ts +47 -0
  114. package/lib/typescript/network/overrides/engine.d.ts.map +1 -0
  115. package/lib/typescript/network/overrides/matchRule.d.ts +22 -0
  116. package/lib/typescript/network/overrides/matchRule.d.ts.map +1 -0
  117. package/lib/typescript/network/overrides/overrideRulesStore.d.ts +205 -0
  118. package/lib/typescript/network/overrides/overrideRulesStore.d.ts.map +1 -0
  119. package/lib/typescript/network/overrides/presets.d.ts +38 -0
  120. package/lib/typescript/network/overrides/presets.d.ts.map +1 -0
  121. package/lib/typescript/network/overrides/resolveOverride.d.ts +46 -0
  122. package/lib/typescript/network/overrides/resolveOverride.d.ts.map +1 -0
  123. package/lib/typescript/network/overrides/types.d.ts +169 -0
  124. package/lib/typescript/network/overrides/types.d.ts.map +1 -0
  125. package/lib/typescript/network/sync/networkSyncAdapter.d.ts +73 -0
  126. package/lib/typescript/network/sync/networkSyncAdapter.d.ts.map +1 -1
  127. package/lib/typescript/network/types/index.d.ts +10 -0
  128. package/lib/typescript/network/types/index.d.ts.map +1 -1
  129. package/lib/typescript/network/utils/networkEventStore.d.ts +14 -0
  130. package/lib/typescript/network/utils/networkEventStore.d.ts.map +1 -1
  131. package/lib/typescript/network/utils/networkListener.d.ts +3 -0
  132. package/lib/typescript/network/utils/networkListener.d.ts.map +1 -1
  133. package/lib/typescript/network/utils/networkSelectionStore.d.ts +117 -0
  134. package/lib/typescript/network/utils/networkSelectionStore.d.ts.map +1 -0
  135. package/lib/typescript/preset.d.ts.map +1 -1
  136. package/package.json +2 -2
@@ -0,0 +1,973 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = Explorer;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _sharedUi = require("@buoy-gg/shared-ui");
10
+ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
11
+ var _updateNestedDataByPath = require("./updateNestedDataByPath");
12
+ var _deleteNestedDataByPath = require("./deleteNestedDataByPath");
13
+ var _editorContext = require("./editorContext");
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ /**
16
+ * The response-body tree: preview and editor as ONE surface.
17
+ *
18
+ * A 1:1 port of the React Query tool's `Explorer` — deliberately, because that
19
+ * is the interaction that already works: there is no read mode and no edit
20
+ * mode, no button that swaps one for the other. A string renders AS its input,
21
+ * a boolean AS its toggle, and typing into what you are reading is the edit.
22
+ *
23
+ * The only thing changed from the original is where an edit LANDS. There it was
24
+ * `queryClient.setQueryData(activeQuery.queryKey, …)`; here it's the `onChange`
25
+ * from `ResponseEditorContext`, which turns the rebuilt body into an override
26
+ * rule. Everything else — the chunked pages, the focus handling, the
27
+ * local-input-state race note below — is carried over unchanged so the two
28
+ * trees behave identically.
29
+ */
30
+
31
+ // Stable constants to prevent re-renders [[memory:4875251]]
32
+ const CHUNK_SIZE = 100;
33
+ const HIT_SLOP_OPTIMIZED = {
34
+ top: 8,
35
+ bottom: 8,
36
+ left: 8,
37
+ right: 8
38
+ };
39
+ const EXPANDER_SIZE = 12;
40
+
41
+ // Optimized chunking function moved to module scope [[memory:4875251]]
42
+ const chunkArray = (array, size = CHUNK_SIZE) => {
43
+ if (size < 1 || array.length === 0) return [];
44
+ const result = [];
45
+ for (let i = 0; i < array.length; i += size) {
46
+ result.push(array.slice(i, i + size));
47
+ }
48
+ return result;
49
+ };
50
+ // Memoized Expander component for performance [[memory:4875251]]
51
+ const Expander = /*#__PURE__*/(0, _react.memo)(({
52
+ expanded,
53
+ isFocused = false,
54
+ isMain = false
55
+ }) => {
56
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
57
+ style: [styles.expanderIcon, isMain && styles.expanderIconMain, expanded ? styles.expanded : styles.collapsed],
58
+ children: expanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
59
+ size: isMain ? 14 : EXPANDER_SIZE,
60
+ color: isFocused ? _sharedUi.buoyColors.primary : isMain ? _sharedUi.buoyColors.text : _sharedUi.buoyColors.textSecondary,
61
+ strokeWidth: 2.5
62
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRight, {
63
+ size: isMain ? 14 : EXPANDER_SIZE,
64
+ color: isFocused ? _sharedUi.buoyColors.primary : isMain ? _sharedUi.buoyColors.text : _sharedUi.buoyColors.textSecondary,
65
+ strokeWidth: 2.5
66
+ })
67
+ });
68
+ });
69
+ Expander.displayName = "Expander";
70
+ // Local wrapper for the shared CopyButton to maintain backward compatibility
71
+ const CopyButton = /*#__PURE__*/(0, _react.memo)(({
72
+ value,
73
+ isFocused = false
74
+ }) => {
75
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CopyButton, {
76
+ value: value,
77
+ isFocused: isFocused,
78
+ buttonStyle: isFocused ? {
79
+ ...styles.buttonStyle,
80
+ ...styles.buttonStyleFocused
81
+ } : styles.buttonStyle
82
+ });
83
+ });
84
+ CopyButton.displayName = "CopyButton";
85
+
86
+ // Memoized DeleteItemButton component [[memory:4875251]]
87
+ const DeleteItemButton = /*#__PURE__*/(0, _react.memo)(({
88
+ dataPath,
89
+ isFocused = false
90
+ }) => {
91
+ const editor = (0, _editorContext.useResponseEditor)();
92
+ const handleDelete = (0, _react.useCallback)(() => {
93
+ if (!editor) return;
94
+ editor.onChange((0, _deleteNestedDataByPath.deleteNestedDataByPath)(editor.root, dataPath));
95
+ }, [editor, dataPath]);
96
+ if (!editor) return null;
97
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
98
+ "sentry-label": "ignore devtools explorer delete button",
99
+ onPress: handleDelete,
100
+ style: [styles.deleteButton, isFocused && styles.deleteButtonFocused],
101
+ accessibilityLabel: "Delete item",
102
+ hitSlop: HIT_SLOP_OPTIMIZED,
103
+ activeOpacity: 0.7,
104
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash, {
105
+ size: 14,
106
+ strokeWidth: 2,
107
+ color: isFocused ? _sharedUi.buoyColors.error : _sharedUi.buoyColors.error + "CC"
108
+ })
109
+ });
110
+ });
111
+ DeleteItemButton.displayName = "DeleteItemButton";
112
+ // Memoized ClearArrayButton component [[memory:4875251]]
113
+ const ClearArrayButton = /*#__PURE__*/(0, _react.memo)(({
114
+ dataPath,
115
+ isFocused = false
116
+ }) => {
117
+ const editor = (0, _editorContext.useResponseEditor)();
118
+ const handleClear = (0, _react.useCallback)(() => {
119
+ if (!editor) return;
120
+ editor.onChange((0, _updateNestedDataByPath.updateNestedDataByPath)(editor.root, dataPath, []));
121
+ }, [editor, dataPath]);
122
+ if (!editor) return null;
123
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
124
+ "sentry-label": "ignore devtools explorer clear button",
125
+ style: [styles.clearButton, isFocused && styles.clearButtonFocused],
126
+ "aria-label": "Remove all items",
127
+ onPress: handleClear,
128
+ hitSlop: HIT_SLOP_OPTIMIZED,
129
+ activeOpacity: 0.7,
130
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
131
+ style: [styles.clearButtonText, {
132
+ color: isFocused ? _sharedUi.buoyColors.warning : _sharedUi.buoyColors.warning + "CC"
133
+ }],
134
+ children: "[]"
135
+ })
136
+ });
137
+ });
138
+ ClearArrayButton.displayName = "ClearArrayButton";
139
+ // ToggleValueButton - not memoized because parent Explorer passes new dataPath array each render
140
+ // which defeats memo anyway, and we need reliable re-renders when value changes
141
+ function ToggleValueButton({
142
+ dataPath,
143
+ value,
144
+ itemsDeletable
145
+ }) {
146
+ const editor = (0, _editorContext.useResponseEditor)();
147
+ const handleClick = (0, _react.useCallback)(() => {
148
+ if (!editor) return;
149
+ const currentValue = typeof value === "boolean" ? value : false;
150
+ editor.onChange((0, _updateNestedDataByPath.updateNestedDataByPath)(editor.root, dataPath, !currentValue));
151
+ }, [editor, dataPath, value]);
152
+ const handleDelete = (0, _react.useCallback)(() => {
153
+ if (!editor) return;
154
+ editor.onChange((0, _deleteNestedDataByPath.deleteNestedDataByPath)(editor.root, dataPath));
155
+ }, [editor, dataPath]);
156
+ if (!editor) return null;
157
+
158
+ // Pre-compute styles based on value state
159
+ const badgeStyle = value ? styles.toggleBadgeTrue : styles.toggleBadgeFalse;
160
+ const textStyle = value ? styles.toggleTextTrue : styles.toggleTextFalse;
161
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
162
+ "sentry-label": "ignore devtools explorer toggle button",
163
+ style: styles.modernToggleButton,
164
+ onPress: handleClick,
165
+ hitSlop: HIT_SLOP_OPTIMIZED,
166
+ activeOpacity: 0.8,
167
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
168
+ style: [styles.toggleBadge, badgeStyle],
169
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
170
+ style: [styles.toggleBadgeText, textStyle],
171
+ children: value ? "TRUE" : "FALSE"
172
+ })
173
+ }), itemsDeletable && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
174
+ "sentry-label": "ignore devtools explorer delete button in toggle",
175
+ onPress: handleDelete,
176
+ style: styles.deleteButtonInToggle,
177
+ accessibilityLabel: "Delete item",
178
+ hitSlop: HIT_SLOP_OPTIMIZED,
179
+ activeOpacity: 0.7,
180
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash, {
181
+ size: 14,
182
+ strokeWidth: 2,
183
+ color: _sharedUi.buoyColors.error + "CC"
184
+ })
185
+ })]
186
+ });
187
+ }
188
+ // Optimized Explorer component following rule2 guidelines [[memory:4875251]]
189
+ /**
190
+ * Recursive data explorer component used for both editable and read-only JSON trees inside the
191
+ * React Query dev tools.
192
+ */
193
+ function Explorer({
194
+ editable,
195
+ label,
196
+ value,
197
+ defaultExpanded,
198
+ dataPath,
199
+ itemsDeletable,
200
+ dataVersion = 0
201
+ }) {
202
+ const editor = (0, _editorContext.useResponseEditor)();
203
+ const [isRowFocused, setIsRowFocused] = (0, _react.useState)(false);
204
+
205
+ // Local state for input value to handle typing properly
206
+ const [localInputValue, setLocalInputValue] = (0, _react.useState)("");
207
+
208
+ // Sync local state with prop value
209
+ // ⚠️ CRITICAL: Do NOT add localInputValue to the dependency array!
210
+ // Adding localInputValue causes a race condition where user edits get reverted:
211
+ // 1. User types "5101" → setLocalInputValue("5101")
212
+ // 2. Cache updates
213
+ // 3. useEffect fires because localInputValue changed
214
+ // 4. At this moment, value prop is still old (5100)
215
+ // 5. Syncs back to 5100, reverting user's change ❌
216
+ // Only sync when EXTERNAL changes happen (value, label, dataVersion)
217
+ (0, _react.useEffect)(() => {
218
+ if (value !== null && value !== undefined && (typeof value === "string" || typeof value === "number")) {
219
+ const newValue = value.toString();
220
+ setLocalInputValue(newValue);
221
+ }
222
+ }, [value, label, dataVersion]); // ⚠️ DO NOT add localInputValue here!
223
+
224
+ // Determine if this is a main section
225
+ const isMainSection = (0, _react.useMemo)(() => {
226
+ const upperLabel = label.toUpperCase();
227
+ return ["DATA", "QUERY", "QUERYKEY", "TYPES", "STATS", "OPTIONS", "OBSERVERS"].includes(upperLabel);
228
+ }, [label]);
229
+
230
+ // Explorer's section is expanded or collapsed
231
+ const [isExpanded, setIsExpanded] = (0, _react.useState)((defaultExpanded || []).includes(label));
232
+ // Remove unnecessary useCallback - simple state setter [[memory:4875251]]
233
+ const toggleExpanded = () => setIsExpanded(old => !old);
234
+ const [expandedPages, setExpandedPages] = (0, _react.useState)([]);
235
+
236
+ // Optimized subEntries computation with early returns and limited processing [[memory:4875251]]
237
+ const subEntries = (0, _react.useMemo)(() => {
238
+ // Early return for primitive values to avoid unnecessary computation
239
+ if (value === null || value === undefined || typeof value !== "object") {
240
+ return [];
241
+ }
242
+ if (Array.isArray(value)) {
243
+ // Limit array processing for performance [[memory:4875251]]
244
+ const limitedValue = value.length > 1000 ? value.slice(0, 1000) : value;
245
+ return limitedValue.map((d, i) => ({
246
+ label: i.toString(),
247
+ value: d
248
+ }));
249
+ }
250
+ if (value instanceof Map) {
251
+ // Limit Map entries for performance
252
+ const entries = Array.from(value.entries()).slice(0, 1000);
253
+ return entries.map(([key, val]) => ({
254
+ label: key.toString(),
255
+ value: val
256
+ }));
257
+ }
258
+ if (value instanceof Set) {
259
+ // Limit Set entries for performance
260
+ const entries = Array.from(value).slice(0, 1000);
261
+ return entries.map((val, i) => ({
262
+ label: i.toString(),
263
+ value: val
264
+ }));
265
+ }
266
+
267
+ // Handle regular objects with key limiting
268
+ const entries = Object.entries(value).slice(0, 1000);
269
+ return entries.map(([key, val]) => ({
270
+ label: key,
271
+ value: val
272
+ }));
273
+ }, [value]);
274
+
275
+ // Optimized valueType computation with early returns [[memory:4875251]]
276
+ const valueType = (0, _react.useMemo)(() => {
277
+ if (Array.isArray(value)) return "array";
278
+ if (value === null || typeof value !== "object") return typeof value;
279
+ if (value instanceof Map || value instanceof Set) return "Iterable";
280
+ return "object";
281
+ }, [value]);
282
+
283
+ // Optimized chunking with stable chunk size [[memory:4875251]]
284
+ const subEntryPages = (0, _react.useMemo)(() => {
285
+ return chunkArray(subEntries, CHUNK_SIZE);
286
+ }, [subEntries]);
287
+ const currentDataPath = dataPath ?? [];
288
+
289
+ // Optimize handleChange using refs to avoid dependency arrays [[memory:4875251]]
290
+ const editorRef = (0, _react.useRef)(editor);
291
+ const dataPathRef = (0, _react.useRef)(currentDataPath);
292
+ const valueTypeRef = (0, _react.useRef)(valueType);
293
+ editorRef.current = editor;
294
+ dataPathRef.current = currentDataPath;
295
+ valueTypeRef.current = valueType;
296
+ const handleChange = (0, _react.useCallback)((isNumber, newValue) => {
297
+ // Update local state immediately for responsive typing
298
+ setLocalInputValue(newValue);
299
+ const current = editorRef.current;
300
+ if (!current) return;
301
+ if (isNumber && isNaN(Number(newValue))) return;
302
+ const updatedValue = valueTypeRef.current === "number" ? Number(newValue) : newValue;
303
+ current.onChange((0, _updateNestedDataByPath.updateNestedDataByPath)(current.root, dataPathRef.current, updatedValue));
304
+ }, [setLocalInputValue]);
305
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
306
+ style: styles.minWidthWrapper,
307
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
308
+ style: styles.fullWidthMarginRight,
309
+ children: [subEntryPages.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
310
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
311
+ style: [styles.flexRowItemsCenterGap, isMainSection && styles.flexRowItemsCenterGapMain],
312
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
313
+ "sentry-label": "ignore devtools explorer expander button",
314
+ style: styles.expanderButton,
315
+ onPress: toggleExpanded,
316
+ hitSlop: HIT_SLOP_OPTIMIZED,
317
+ activeOpacity: 0.6,
318
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Expander, {
319
+ expanded: isExpanded,
320
+ isFocused: isRowFocused,
321
+ isMain: isMainSection
322
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
323
+ style: [styles.labelText, isRowFocused && styles.labelTextFocused, isMainSection && styles.labelTextMain],
324
+ children: label
325
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
326
+ style: styles.textGray500,
327
+ children: `${String(valueType).toLowerCase() === "iterable" ? "(Iterable) " : ""}${subEntries.length} ${subEntries.length > 1 ? `items` : `item`}`
328
+ })]
329
+ }), editable && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
330
+ style: styles.flexRowGapItemsCenter,
331
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(CopyButton, {
332
+ value: value,
333
+ isFocused: isRowFocused
334
+ }), itemsDeletable && editor !== null && /*#__PURE__*/(0, _jsxRuntime.jsx)(DeleteItemButton, {
335
+ dataPath: currentDataPath,
336
+ isFocused: isRowFocused
337
+ }), valueType === "array" && editor !== null && /*#__PURE__*/(0, _jsxRuntime.jsx)(ClearArrayButton, {
338
+ dataPath: currentDataPath,
339
+ isFocused: isRowFocused
340
+ })]
341
+ })]
342
+ }), isExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
343
+ children: [subEntryPages.length === 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
344
+ style: [styles.singleEntryContainer, isMainSection && styles.singleEntryContainerMain],
345
+ children: subEntries.map((entry, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(Explorer, {
346
+ defaultExpanded: defaultExpanded,
347
+ label: entry.label,
348
+ value: entry.value,
349
+ editable: editable,
350
+ dataPath: [...currentDataPath, entry.label],
351
+ itemsDeletable: valueType === "array" || valueType === "Iterable" || valueType === "object",
352
+ dataVersion: dataVersion
353
+ }, entry.label + index))
354
+ }), subEntryPages.length > 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
355
+ style: styles.multiEntryContainer,
356
+ children: subEntryPages.map((entries, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
357
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
358
+ style: styles.relativeOutlineNone,
359
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
360
+ "sentry-label": "ignore devtools explorer page toggle",
361
+ onPress: () => setExpandedPages(old => old.includes(index) ? old.filter(d => d !== index) : [...old, index]),
362
+ style: styles.pageExpanderButton,
363
+ hitSlop: HIT_SLOP_OPTIMIZED,
364
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Expander, {
365
+ expanded: expandedPages.includes(index)
366
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
367
+ style: styles.pageRangeText,
368
+ children: ["[", index * CHUNK_SIZE, "...", index * CHUNK_SIZE + CHUNK_SIZE - 1, "]"]
369
+ })]
370
+ }), expandedPages.includes(index) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
371
+ style: styles.entriesContainer,
372
+ children: entries.map(entry => /*#__PURE__*/(0, _jsxRuntime.jsx)(Explorer, {
373
+ defaultExpanded: defaultExpanded,
374
+ label: entry.label,
375
+ value: entry.value,
376
+ editable: editable,
377
+ dataPath: [...currentDataPath, entry.label],
378
+ dataVersion: dataVersion
379
+ }, entry.label))
380
+ })]
381
+ })
382
+ }, index))
383
+ })]
384
+ })]
385
+ }), subEntryPages.length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
386
+ style: styles.flexRowGapFullWidth,
387
+ children: [editable && editor !== null && (valueType === "string" || valueType === "number" || valueType === "boolean") ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
388
+ children: [editable && editor && (valueType === "string" || valueType === "number") && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
389
+ style: styles.nebulaInputWrapper,
390
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.CyberpunkInput, {
391
+ label: label,
392
+ accessibilityLabel: "Data input field for editing values",
393
+ style: [valueType === "number" ? styles.textNumber : styles.textString],
394
+ keyboardType: valueType === "number" ? "numeric" : "default",
395
+ value: localInputValue,
396
+ onChangeText: newValue => handleChange(valueType === "number", newValue),
397
+ onFocus: () => setIsRowFocused(true),
398
+ onBlur: () => setIsRowFocused(false),
399
+ showNumberControls: valueType === "number",
400
+ onIncrement: () => {
401
+ const currentNum = Number(localInputValue) || 0;
402
+ handleChange(true, String(currentNum + 1));
403
+ },
404
+ onDecrement: () => {
405
+ const currentNum = Number(localInputValue) || 0;
406
+ handleChange(true, String(currentNum - 1));
407
+ },
408
+ showDeleteButton: itemsDeletable,
409
+ onDelete: () => {
410
+ editor.onChange((0, _deleteNestedDataByPath.deleteNestedDataByPath)(editor.root, currentDataPath));
411
+ }
412
+ })
413
+ }), valueType === "boolean" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
414
+ style: styles.booleanRowContainer,
415
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
416
+ style: styles.booleanLabel,
417
+ children: label
418
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
419
+ style: styles.booleanToggleWrapper,
420
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ToggleValueButton, {
421
+ dataPath: currentDataPath,
422
+ value: value,
423
+ itemsDeletable: itemsDeletable
424
+ })
425
+ })]
426
+ })]
427
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
428
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
429
+ style: styles.text344054,
430
+ children: label
431
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
432
+ style: styles.displayValueText,
433
+ children: (0, _sharedUi.displayValue)(value)
434
+ })]
435
+ }), editable && itemsDeletable && editor !== null && valueType !== "string" && valueType !== "number" && valueType !== "boolean" && /*#__PURE__*/(0, _jsxRuntime.jsx)(DeleteItemButton, {
436
+ dataPath: currentDataPath,
437
+ isFocused: isRowFocused
438
+ })]
439
+ })]
440
+ })
441
+ });
442
+ }
443
+ const styles = _reactNative.StyleSheet.create({
444
+ buttonStyle: {
445
+ backgroundColor: _sharedUi.buoyColors.card + "E6",
446
+ borderWidth: 1,
447
+ borderColor: _sharedUi.buoyColors.textSecondary + "33",
448
+ borderRadius: 6,
449
+ flexDirection: "row",
450
+ alignItems: "center",
451
+ justifyContent: "center",
452
+ width: 28,
453
+ height: 28,
454
+ position: "relative",
455
+ shadowColor: "#000",
456
+ shadowOffset: {
457
+ width: 0,
458
+ height: 1
459
+ },
460
+ shadowOpacity: 0.2,
461
+ shadowRadius: 2
462
+ },
463
+ buttonStyleFocused: {
464
+ borderColor: _sharedUi.buoyColors.primary + "CC",
465
+ backgroundColor: _sharedUi.buoyColors.primary + "26",
466
+ shadowColor: _sharedUi.buoyColors.primary,
467
+ shadowOpacity: 0.3,
468
+ shadowRadius: 4
469
+ },
470
+ deleteButton: {
471
+ backgroundColor: _sharedUi.buoyColors.error + "1A",
472
+ borderColor: _sharedUi.buoyColors.error + "4D",
473
+ borderWidth: 1,
474
+ borderRadius: 6,
475
+ padding: 0,
476
+ alignItems: "center",
477
+ justifyContent: "center",
478
+ width: 28,
479
+ height: 28,
480
+ position: "relative",
481
+ shadowColor: _sharedUi.buoyColors.error,
482
+ shadowOffset: {
483
+ width: 0,
484
+ height: 0
485
+ },
486
+ shadowOpacity: 0.15,
487
+ shadowRadius: 3
488
+ },
489
+ deleteButtonFocused: {
490
+ borderColor: _sharedUi.buoyColors.error + "CC",
491
+ backgroundColor: _sharedUi.buoyColors.error + "33",
492
+ shadowOpacity: 0.3,
493
+ shadowRadius: 5
494
+ },
495
+ deleteButtonInToggle: {
496
+ backgroundColor: _sharedUi.buoyColors.error + "1A",
497
+ borderColor: _sharedUi.buoyColors.error + "4D",
498
+ borderWidth: 1,
499
+ borderRadius: 6,
500
+ padding: 0,
501
+ alignItems: "center",
502
+ justifyContent: "center",
503
+ width: 28,
504
+ height: 28,
505
+ shadowColor: _sharedUi.buoyColors.error,
506
+ shadowOffset: {
507
+ width: 0,
508
+ height: 0
509
+ },
510
+ shadowOpacity: 0.15,
511
+ shadowRadius: 3
512
+ },
513
+ clearButton: {
514
+ backgroundColor: _sharedUi.buoyColors.warning + "1A",
515
+ borderWidth: 1,
516
+ borderColor: _sharedUi.buoyColors.warning + "4D",
517
+ borderRadius: 6,
518
+ flexDirection: "row",
519
+ padding: 0,
520
+ alignItems: "center",
521
+ justifyContent: "center",
522
+ width: 28,
523
+ height: 28,
524
+ position: "relative",
525
+ zIndex: 10,
526
+ shadowColor: _sharedUi.buoyColors.warning,
527
+ shadowOffset: {
528
+ width: 0,
529
+ height: 0
530
+ },
531
+ shadowOpacity: 0.15,
532
+ shadowRadius: 3
533
+ },
534
+ clearButtonFocused: {
535
+ borderColor: _sharedUi.buoyColors.warning + "CC",
536
+ backgroundColor: _sharedUi.buoyColors.warning + "33",
537
+ shadowOpacity: 0.3,
538
+ shadowRadius: 5
539
+ },
540
+ clearButtonText: {
541
+ fontSize: 12,
542
+ fontWeight: "700",
543
+ fontFamily: "monospace"
544
+ },
545
+ expanderIcon: {
546
+ width: 18,
547
+ height: 18,
548
+ alignItems: "center",
549
+ justifyContent: "center",
550
+ marginRight: 1,
551
+ backgroundColor: _sharedUi.buoyColors.textSecondary + "14",
552
+ borderRadius: 3
553
+ },
554
+ expanderIconMain: {
555
+ backgroundColor: _sharedUi.buoyColors.textSecondary + "1A",
556
+ width: 20,
557
+ height: 20,
558
+ borderRadius: 4,
559
+ borderWidth: 0.5,
560
+ borderColor: _sharedUi.buoyColors.textSecondary + "33"
561
+ },
562
+ expanded: {
563
+ transform: [{
564
+ rotate: "0deg"
565
+ }]
566
+ },
567
+ collapsed: {
568
+ transform: [{
569
+ rotate: "0deg"
570
+ }]
571
+ },
572
+ minWidthWrapper: {
573
+ minWidth: 180,
574
+ fontSize: 11,
575
+ flexDirection: "row",
576
+ flexWrap: "wrap",
577
+ width: "100%",
578
+ marginVertical: 0.5
579
+ },
580
+ fullWidthMarginRight: {
581
+ position: "relative",
582
+ width: "100%",
583
+ marginRight: 1
584
+ },
585
+ flexRowItemsCenterGap: {
586
+ flexDirection: "row",
587
+ alignItems: "center",
588
+ justifyContent: "space-between",
589
+ paddingVertical: 3,
590
+ paddingHorizontal: 6,
591
+ marginVertical: 1,
592
+ borderRadius: 4,
593
+ backgroundColor: _sharedUi.buoyColors.card + "66",
594
+ borderWidth: 0.5,
595
+ borderColor: _sharedUi.buoyColors.textSecondary + "1A"
596
+ },
597
+ flexRowItemsCenterGapMain: {
598
+ backgroundColor: _sharedUi.buoyColors.card + "E6",
599
+ borderLeftWidth: 2.5,
600
+ borderLeftColor: _sharedUi.buoyColors.textSecondary + "80",
601
+ borderColor: _sharedUi.buoyColors.textSecondary + "26",
602
+ paddingVertical: 5,
603
+ paddingHorizontal: 8,
604
+ marginBottom: 3,
605
+ borderWidth: 1,
606
+ shadowColor: "#000",
607
+ shadowOffset: {
608
+ width: 0,
609
+ height: 0
610
+ },
611
+ shadowOpacity: 0.08,
612
+ shadowRadius: 3
613
+ },
614
+ expanderButton: {
615
+ flexDirection: "row",
616
+ alignItems: "center",
617
+ backgroundColor: "transparent",
618
+ paddingVertical: 1,
619
+ paddingHorizontal: 2,
620
+ gap: 6,
621
+ borderWidth: 0,
622
+ minHeight: 24,
623
+ flex: 1
624
+ },
625
+ labelText: {
626
+ color: _sharedUi.buoyColors.textSecondary,
627
+ fontSize: 10,
628
+ fontWeight: "600",
629
+ marginRight: 4,
630
+ fontFamily: "monospace",
631
+ letterSpacing: 0.4
632
+ },
633
+ labelTextFocused: {
634
+ color: _sharedUi.buoyColors.text
635
+ },
636
+ labelTextMain: {
637
+ color: _sharedUi.buoyColors.text,
638
+ fontSize: 11,
639
+ fontWeight: "700",
640
+ letterSpacing: 0.6
641
+ },
642
+ textGray500: {
643
+ color: _sharedUi.buoyColors.textMuted,
644
+ fontSize: 10,
645
+ fontWeight: "400",
646
+ fontFamily: "monospace",
647
+ opacity: 0.7
648
+ },
649
+ pageRangeText: {
650
+ color: _sharedUi.buoyColors.textSecondary,
651
+ fontSize: 10,
652
+ fontWeight: "600",
653
+ fontFamily: "monospace"
654
+ },
655
+ flexRowGapItemsCenter: {
656
+ flexDirection: "row",
657
+ alignItems: "center",
658
+ gap: 4,
659
+ paddingLeft: 2
660
+ },
661
+ singleEntryContainer: {
662
+ marginLeft: 2,
663
+ marginTop: 2,
664
+ paddingLeft: 8,
665
+ borderLeftWidth: 1.5,
666
+ borderLeftColor: _sharedUi.buoyColors.textSecondary + "40"
667
+ },
668
+ singleEntryContainerMain: {
669
+ borderLeftColor: _sharedUi.buoyColors.textSecondary + "4D",
670
+ marginLeft: 4,
671
+ paddingLeft: 10
672
+ },
673
+ multiEntryContainer: {
674
+ marginLeft: 2,
675
+ marginTop: 2,
676
+ paddingLeft: 8,
677
+ borderLeftWidth: 1.5,
678
+ borderLeftColor: _sharedUi.buoyColors.textSecondary + "40"
679
+ },
680
+ multiEntryContainerMain: {
681
+ borderLeftColor: _sharedUi.buoyColors.textSecondary + "4D",
682
+ marginLeft: 4,
683
+ paddingLeft: 10
684
+ },
685
+ relativeOutlineNone: {
686
+ position: "relative"
687
+ },
688
+ pageExpanderButton: {
689
+ flexDirection: "row",
690
+ alignItems: "center",
691
+ backgroundColor: _sharedUi.buoyColors.card + "66",
692
+ paddingVertical: 3,
693
+ paddingHorizontal: 6,
694
+ gap: 6,
695
+ borderRadius: 4,
696
+ borderWidth: 0.5,
697
+ borderColor: _sharedUi.buoyColors.textSecondary + "1A",
698
+ marginBottom: 2,
699
+ minHeight: 24
700
+ },
701
+ entriesContainer: {
702
+ marginLeft: 2,
703
+ paddingLeft: 8,
704
+ marginTop: 2,
705
+ borderLeftWidth: 1.5,
706
+ borderLeftColor: _sharedUi.buoyColors.textSecondary + "40"
707
+ },
708
+ textNumber: {
709
+ color: _sharedUi.buoyColors.text,
710
+ fontWeight: "600",
711
+ fontFamily: "monospace"
712
+ },
713
+ textString: {
714
+ color: _sharedUi.buoyColors.text,
715
+ fontFamily: "monospace"
716
+ },
717
+ flexRowGapFullWidth: {
718
+ flexDirection: "row",
719
+ width: "100%",
720
+ alignItems: "center",
721
+ marginVertical: 1,
722
+ gap: 6,
723
+ paddingHorizontal: 4,
724
+ paddingVertical: 2,
725
+ borderRadius: 3
726
+ },
727
+ text344054: {
728
+ color: _sharedUi.buoyColors.textSecondary,
729
+ fontWeight: "600",
730
+ fontSize: 9,
731
+ minWidth: 50,
732
+ fontFamily: "monospace",
733
+ letterSpacing: 0.4,
734
+ opacity: 0.8
735
+ },
736
+ numberInputButtons: {
737
+ position: "absolute",
738
+ right: 8,
739
+ top: "50%",
740
+ transform: [{
741
+ translateY: -18
742
+ }],
743
+ flexDirection: "row",
744
+ gap: 4,
745
+ zIndex: 10
746
+ },
747
+ touchableButton: {
748
+ width: 32,
749
+ height: 32,
750
+ borderRadius: 6,
751
+ backgroundColor: _sharedUi.buoyColors.card + "E6",
752
+ borderWidth: 1,
753
+ borderColor: _sharedUi.buoyColors.textSecondary + "33",
754
+ alignItems: "center",
755
+ justifyContent: "center",
756
+ marginLeft: 2,
757
+ shadowColor: "#000",
758
+ shadowOffset: {
759
+ width: 0,
760
+ height: 1
761
+ },
762
+ shadowOpacity: 0.2,
763
+ shadowRadius: 2
764
+ },
765
+ touchableButtonFocused: {
766
+ borderColor: _sharedUi.buoyColors.primary + "CC",
767
+ backgroundColor: _sharedUi.buoyColors.primary + "26",
768
+ shadowColor: _sharedUi.buoyColors.primary,
769
+ shadowOffset: {
770
+ width: 0,
771
+ height: 0
772
+ },
773
+ shadowOpacity: 0.3,
774
+ shadowRadius: 4,
775
+ elevation: 3
776
+ },
777
+ nebulaInputWrapper: {
778
+ flex: 1,
779
+ width: "100%",
780
+ position: "relative"
781
+ },
782
+ displayValueText: {
783
+ flex: 1,
784
+ color: _sharedUi.buoyColors.text,
785
+ fontWeight: "400",
786
+ fontFamily: "monospace",
787
+ fontSize: 12,
788
+ paddingVertical: 6,
789
+ paddingHorizontal: 10,
790
+ borderRadius: 6,
791
+ borderWidth: 1,
792
+ borderColor: _sharedUi.buoyColors.textMuted + "66",
793
+ minHeight: 34
794
+ },
795
+ // New redesigned styles (kept for future use)
796
+ dataRow: {
797
+ flexDirection: "row",
798
+ alignItems: "center",
799
+ paddingVertical: 4,
800
+ paddingHorizontal: 8,
801
+ minHeight: 44,
802
+ gap: 12
803
+ },
804
+ dataLabel: {
805
+ color: _sharedUi.buoyColors.textSecondary,
806
+ fontSize: 13,
807
+ fontWeight: "500",
808
+ minWidth: 80,
809
+ flexShrink: 0
810
+ },
811
+ dataValueContainer: {
812
+ flex: 1,
813
+ flexDirection: "row",
814
+ alignItems: "center"
815
+ },
816
+ inputWithActions: {
817
+ flex: 1,
818
+ position: "relative"
819
+ },
820
+ numberControls: {
821
+ position: "absolute",
822
+ right: 8,
823
+ top: "50%",
824
+ transform: [{
825
+ translateY: -16
826
+ }],
827
+ flexDirection: "column",
828
+ gap: 2
829
+ },
830
+ numberButton: {
831
+ width: 32,
832
+ height: 16,
833
+ borderRadius: 4,
834
+ alignItems: "center",
835
+ justifyContent: "center",
836
+ borderWidth: 1,
837
+ borderColor: _sharedUi.buoyColors.primary + "0F"
838
+ },
839
+ readOnlyValue: {
840
+ color: _sharedUi.buoyColors.text,
841
+ fontSize: 13,
842
+ fontFamily: "monospace",
843
+ paddingVertical: 8,
844
+ paddingHorizontal: 12,
845
+ borderRadius: 6,
846
+ borderWidth: 1,
847
+ borderColor: _sharedUi.buoyColors.textMuted + "33",
848
+ flex: 1
849
+ },
850
+ actionButtons: {
851
+ flexDirection: "row",
852
+ gap: 6,
853
+ paddingLeft: 8
854
+ },
855
+ booleanContainer: {
856
+ flexDirection: "row",
857
+ alignItems: "center",
858
+ padding: 8,
859
+ borderRadius: 6,
860
+ borderWidth: 1,
861
+ borderColor: _sharedUi.buoyColors.textMuted + "4D",
862
+ flex: 1
863
+ },
864
+ booleanText: {
865
+ marginLeft: 8,
866
+ color: _sharedUi.buoyColors.warning,
867
+ fontWeight: "500",
868
+ fontFamily: "monospace"
869
+ },
870
+ modernToggleButton: {
871
+ flexDirection: "row",
872
+ alignItems: "center",
873
+ justifyContent: "space-between",
874
+ borderRadius: 6,
875
+ borderWidth: 1,
876
+ borderColor: _sharedUi.buoyColors.textMuted + "99",
877
+ paddingHorizontal: 8,
878
+ paddingVertical: 6,
879
+ marginVertical: 2,
880
+ minHeight: 34,
881
+ gap: 8
882
+ },
883
+ toggleIconContainer: {
884
+ marginRight: 6
885
+ },
886
+ toggleIcon: {
887
+ padding: 8,
888
+ borderRadius: 8,
889
+ alignItems: "center",
890
+ justifyContent: "center",
891
+ width: 32,
892
+ height: 32
893
+ },
894
+ toggleIconSmall: {
895
+ width: 8,
896
+ height: 8,
897
+ borderRadius: 4
898
+ },
899
+ toggleContent: {
900
+ flex: 1,
901
+ minWidth: 0
902
+ },
903
+ toggleLabel: {
904
+ color: "#E5E7EB",
905
+ fontSize: 11,
906
+ fontWeight: "600",
907
+ fontFamily: "monospace",
908
+ letterSpacing: 0.3
909
+ },
910
+ toggleStatus: {
911
+ color: "#9CA3AF",
912
+ fontSize: 11
913
+ },
914
+ toggleBadge: {
915
+ marginLeft: 6,
916
+ paddingHorizontal: 6,
917
+ paddingVertical: 3,
918
+ borderRadius: 4,
919
+ borderWidth: 1
920
+ },
921
+ toggleBadgeText: {
922
+ fontSize: 9,
923
+ fontWeight: "700",
924
+ textTransform: "uppercase",
925
+ letterSpacing: 0.8,
926
+ fontFamily: "monospace"
927
+ },
928
+ // Pre-computed toggle icon styles to avoid inline objects [[memory:4875251]]
929
+ toggleIconTrue: {
930
+ backgroundColor: _sharedUi.buoyColors.primary
931
+ },
932
+ toggleIconFalse: {
933
+ backgroundColor: _sharedUi.buoyColors.textMuted
934
+ },
935
+ // Pre-computed toggle badge styles [[memory:4875251]]
936
+ toggleBadgeTrue: {
937
+ backgroundColor: _sharedUi.buoyColors.primary + "1A",
938
+ borderColor: _sharedUi.buoyColors.primary + "4D"
939
+ },
940
+ toggleBadgeFalse: {
941
+ backgroundColor: _sharedUi.buoyColors.textMuted + "1A",
942
+ borderColor: _sharedUi.buoyColors.textMuted + "4D"
943
+ },
944
+ // Pre-computed toggle text styles [[memory:4875251]]
945
+ toggleTextTrue: {
946
+ color: _sharedUi.buoyColors.primary,
947
+ fontWeight: "600"
948
+ },
949
+ toggleTextFalse: {
950
+ color: _sharedUi.buoyColors.textSecondary,
951
+ fontWeight: "500"
952
+ },
953
+ // Boolean row container styles
954
+ booleanRowContainer: {
955
+ flexDirection: "row",
956
+ alignItems: "center",
957
+ width: "100%",
958
+ gap: 8,
959
+ paddingVertical: 2
960
+ },
961
+ booleanLabel: {
962
+ color: _sharedUi.buoyColors.textSecondary,
963
+ fontSize: 10,
964
+ fontWeight: "600",
965
+ fontFamily: "monospace",
966
+ letterSpacing: 0.4,
967
+ minWidth: 60,
968
+ flexShrink: 0
969
+ },
970
+ booleanToggleWrapper: {
971
+ flex: 1
972
+ }
973
+ });