react-native-inapp-inspector 2.2.2 → 2.2.4

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 (159) hide show
  1. package/dist/commonjs/components/AnalyticsDetail.js +5 -1
  2. package/dist/commonjs/components/AnalyticsEventCard.js +2 -1
  3. package/dist/commonjs/components/DiffViewer.js +1 -1
  4. package/dist/commonjs/components/Inspector/BundleTab.js +22 -0
  5. package/dist/commonjs/components/Inspector/DeviceInfoTab.d.ts +3 -0
  6. package/dist/commonjs/components/Inspector/DeviceInfoTab.js +835 -0
  7. package/dist/commonjs/components/Inspector/InspectorHeader.js +12 -14
  8. package/dist/commonjs/components/Inspector/LogDetail.js +6 -3
  9. package/dist/commonjs/components/Inspector/MainScreen.js +7 -3
  10. package/dist/commonjs/components/Inspector/NetworkTab.js +92 -15
  11. package/dist/commonjs/components/Inspector/PerformanceTab.js +38 -12
  12. package/dist/commonjs/components/Inspector/SettingsPanel.js +440 -229
  13. package/dist/commonjs/components/Inspector/StorageTab.d.ts +3 -0
  14. package/dist/commonjs/components/Inspector/StorageTab.js +892 -0
  15. package/dist/commonjs/components/Inspector/TabBar.js +14 -0
  16. package/dist/commonjs/components/Inspector/TelemetryConsentModal.js +11 -2
  17. package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +4 -1
  18. package/dist/commonjs/components/NetworkIcons.d.ts +6 -0
  19. package/dist/commonjs/components/NetworkIcons.js +30 -1
  20. package/dist/commonjs/constants/version.d.ts +1 -1
  21. package/dist/commonjs/constants/version.js +1 -1
  22. package/dist/commonjs/customHooks/bundleAnalyzer.js +44 -22
  23. package/dist/commonjs/customHooks/storageInspector.d.ts +67 -0
  24. package/dist/commonjs/customHooks/storageInspector.js +486 -0
  25. package/dist/commonjs/i18n/locales/en.json +8 -2
  26. package/dist/commonjs/index.d.ts +1 -0
  27. package/dist/commonjs/index.js +16 -1
  28. package/dist/commonjs/storage.d.ts +5 -0
  29. package/dist/commonjs/storage.js +18 -0
  30. package/dist/commonjs/types/enums.d.ts +5 -0
  31. package/dist/commonjs/types/enums.js +5 -0
  32. package/dist/esm/components/AnalyticsDetail.js +6 -2
  33. package/dist/esm/components/AnalyticsEventCard.js +2 -1
  34. package/dist/esm/components/DiffViewer.js +1 -1
  35. package/dist/esm/components/Inspector/BundleTab.js +22 -0
  36. package/dist/esm/components/Inspector/DeviceInfoTab.d.ts +3 -0
  37. package/dist/esm/components/Inspector/DeviceInfoTab.js +796 -0
  38. package/dist/esm/components/Inspector/InspectorHeader.js +13 -15
  39. package/dist/esm/components/Inspector/LogDetail.js +7 -4
  40. package/dist/esm/components/Inspector/MainScreen.js +7 -3
  41. package/dist/esm/components/Inspector/NetworkTab.js +93 -16
  42. package/dist/esm/components/Inspector/PerformanceTab.js +39 -13
  43. package/dist/esm/components/Inspector/SettingsPanel.js +441 -230
  44. package/dist/esm/components/Inspector/StorageTab.d.ts +3 -0
  45. package/dist/esm/components/Inspector/StorageTab.js +853 -0
  46. package/dist/esm/components/Inspector/TabBar.js +15 -1
  47. package/dist/esm/components/Inspector/TelemetryConsentModal.js +11 -2
  48. package/dist/esm/components/Inspector/UpdateAvailableModal.js +4 -1
  49. package/dist/esm/components/NetworkIcons.d.ts +6 -0
  50. package/dist/esm/components/NetworkIcons.js +23 -0
  51. package/dist/esm/constants/version.d.ts +1 -1
  52. package/dist/esm/constants/version.js +1 -1
  53. package/dist/esm/customHooks/bundleAnalyzer.js +44 -22
  54. package/dist/esm/customHooks/storageInspector.d.ts +67 -0
  55. package/dist/esm/customHooks/storageInspector.js +469 -0
  56. package/dist/esm/i18n/locales/en.json +8 -2
  57. package/dist/esm/index.d.ts +1 -0
  58. package/dist/esm/index.js +5 -0
  59. package/dist/esm/storage.d.ts +5 -0
  60. package/dist/esm/storage.js +5 -0
  61. package/dist/esm/types/enums.d.ts +5 -0
  62. package/dist/esm/types/enums.js +5 -0
  63. package/package.json +9 -1
  64. package/src/analytics.ts +35 -0
  65. package/src/bundle.ts +25 -0
  66. package/src/components/AnalyticsDetail.tsx +870 -0
  67. package/src/components/AnalyticsEventCard.tsx +442 -0
  68. package/src/components/AnalyticsGraph.tsx +583 -0
  69. package/src/components/AnimatedEntrance.tsx +64 -0
  70. package/src/components/AppHeaderLogo.tsx +109 -0
  71. package/src/components/BrandCircleIcon.tsx +144 -0
  72. package/src/components/BrandSquareIcon.tsx +144 -0
  73. package/src/components/CodeSnippet.tsx +725 -0
  74. package/src/components/ConsoleLogCard.tsx +628 -0
  75. package/src/components/CopyButton.tsx +87 -0
  76. package/src/components/DiffViewer.tsx +82 -0
  77. package/src/components/DomainHeader.tsx +237 -0
  78. package/src/components/EmptyState.tsx +73 -0
  79. package/src/components/EndOfListFooter.tsx +100 -0
  80. package/src/components/ErrorBoundary.tsx +688 -0
  81. package/src/components/HeadersSection.tsx +192 -0
  82. package/src/components/HighlightText.tsx +100 -0
  83. package/src/components/Inspector/AnalyticsFilterModal.tsx +1250 -0
  84. package/src/components/Inspector/AnalyticsTab.tsx +1336 -0
  85. package/src/components/Inspector/BundleTab.tsx +4760 -0
  86. package/src/components/Inspector/ConsoleTab.tsx +702 -0
  87. package/src/components/Inspector/CrashDetail.tsx +941 -0
  88. package/src/components/Inspector/CrashFilterModal.tsx +721 -0
  89. package/src/components/Inspector/CrashTab.tsx +871 -0
  90. package/src/components/Inspector/DeviceInfoTab.tsx +1204 -0
  91. package/src/components/Inspector/FabLauncher.tsx +80 -0
  92. package/src/components/Inspector/InspectorContext.tsx +28 -0
  93. package/src/components/Inspector/InspectorHeader.tsx +972 -0
  94. package/src/components/Inspector/LogDetail.tsx +1431 -0
  95. package/src/components/Inspector/MainScreen.tsx +262 -0
  96. package/src/components/Inspector/NavigationTracker.tsx +13 -0
  97. package/src/components/Inspector/NetworkDetail.tsx +794 -0
  98. package/src/components/Inspector/NetworkTab.tsx +1183 -0
  99. package/src/components/Inspector/NpmUpdateToast.tsx +392 -0
  100. package/src/components/Inspector/PerformanceTab.tsx +1928 -0
  101. package/src/components/Inspector/ReduxDetail.tsx +1651 -0
  102. package/src/components/Inspector/ReduxTab.tsx +954 -0
  103. package/src/components/Inspector/SettingsPanel.tsx +3447 -0
  104. package/src/components/Inspector/StorageTab.tsx +1048 -0
  105. package/src/components/Inspector/TabBar.tsx +207 -0
  106. package/src/components/Inspector/TelemetryConsentModal.tsx +416 -0
  107. package/src/components/Inspector/UpdateAvailableModal.tsx +557 -0
  108. package/src/components/JsonViewer.tsx +486 -0
  109. package/src/components/LogCard.tsx +491 -0
  110. package/src/components/LogSyntaxHighlighter.tsx +178 -0
  111. package/src/components/MetaAccordion.tsx +340 -0
  112. package/src/components/MiniBarChart.tsx +42 -0
  113. package/src/components/MiniLineChart.tsx +33 -0
  114. package/src/components/NetworkIcons.tsx +2221 -0
  115. package/src/components/SectionHeader.tsx +113 -0
  116. package/src/components/SegmentedTabs.tsx +83 -0
  117. package/src/components/Slider.tsx +300 -0
  118. package/src/components/SourcePageCard.tsx +148 -0
  119. package/src/components/Toast.tsx +131 -0
  120. package/src/components/TouchableScale.tsx +91 -0
  121. package/src/components/TreeNode.tsx +186 -0
  122. package/src/console.ts +24 -0
  123. package/src/constants/index.ts +38 -0
  124. package/src/constants/version.ts +3 -0
  125. package/src/crash.ts +32 -0
  126. package/src/customHooks/analyticsLogger.ts +336 -0
  127. package/src/customHooks/bundleAnalyzer.ts +1256 -0
  128. package/src/customHooks/consoleLogger.ts +497 -0
  129. package/src/customHooks/crashHandler.ts +944 -0
  130. package/src/customHooks/logFilters.ts +32 -0
  131. package/src/customHooks/networkLogger.ts +419 -0
  132. package/src/customHooks/performanceTracker.ts +1014 -0
  133. package/src/customHooks/reduxLogger.ts +406 -0
  134. package/src/customHooks/storageInspector.ts +509 -0
  135. package/src/customHooks/useAccordion.tsx +60 -0
  136. package/src/decorators/index.ts +184 -0
  137. package/src/helpers/gaAnalyticsRegistry.ts +204 -0
  138. package/src/helpers/index.ts +860 -0
  139. package/src/helpers/memoryManager.ts +138 -0
  140. package/src/helpers/searchQueryParser.ts +283 -0
  141. package/src/helpers/settingsStore.ts +171 -0
  142. package/src/helpers/telemetry.ts +505 -0
  143. package/src/helpers/toast.ts +17 -0
  144. package/src/i18n/index.ts +69 -0
  145. package/src/i18n/locales/en.json +1058 -0
  146. package/src/index.tsx +2356 -0
  147. package/src/native/NativeInspector.ts +397 -0
  148. package/src/native/NativeNetworkInspector.ts +24 -0
  149. package/src/network.ts +22 -0
  150. package/src/performance.ts +38 -0
  151. package/src/redux.ts +23 -0
  152. package/src/storage.ts +18 -0
  153. package/src/styles/AppColors.ts +408 -0
  154. package/src/styles/AppFonts.ts +8 -0
  155. package/src/styles/common.ts +209 -0
  156. package/src/styles/index.ts +1570 -0
  157. package/src/types/enums.ts +199 -0
  158. package/src/types/index.ts +34 -0
  159. package/src/types/interfaces.ts +515 -0
@@ -0,0 +1,892 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.StorageTab = void 0;
40
+ const react_1 = __importStar(require("react"));
41
+ const react_native_1 = require("react-native");
42
+ const TouchableScale_1 = __importDefault(require("../TouchableScale"));
43
+ const AppColors_1 = require("../../styles/AppColors");
44
+ const AppFonts_1 = require("../../styles/AppFonts");
45
+ const i18n_1 = require("../../i18n");
46
+ const NetworkIcons_1 = require("../NetworkIcons");
47
+ const storageInspector_1 = require("../../customHooks/storageInspector");
48
+ const helpers_1 = require("../../helpers");
49
+ const toast_1 = require("../../helpers/toast");
50
+ exports.StorageTab = react_1.default.memo(() => {
51
+ const { t } = (0, i18n_1.useTranslation)();
52
+ const [activeDriver, setActiveDriver] = (0, react_1.useState)('asyncStorage');
53
+ const [activeMMKVId, setActiveMMKVId] = (0, react_1.useState)('default');
54
+ const [entries, setEntries] = (0, react_1.useState)([]);
55
+ const [isLoading, setIsLoading] = (0, react_1.useState)(true);
56
+ const [search, setSearch] = (0, react_1.useState)('');
57
+ const [expandedKeys, setExpandedKeys] = (0, react_1.useState)({});
58
+ // Modal State for Create / Edit
59
+ const [modalVisible, setModalVisible] = (0, react_1.useState)(false);
60
+ const [modalMode, setModalMode] = (0, react_1.useState)('create');
61
+ const [editKeyName, setEditKeyName] = (0, react_1.useState)('');
62
+ const [editValue, setEditValue] = (0, react_1.useState)('');
63
+ const [editType, setEditType] = (0, react_1.useState)('string');
64
+ const [jsonError, setJsonError] = (0, react_1.useState)(null);
65
+ const mmkvInstanceIds = (0, react_1.useMemo)(() => (0, storageInspector_1.getRegisteredMMKVInstanceIds)(), []);
66
+ // Fetch entries
67
+ const loadEntries = (0, react_1.useCallback)(async () => {
68
+ setIsLoading(true);
69
+ try {
70
+ const data = await (0, storageInspector_1.fetchStorageEntries)(activeDriver, activeDriver === 'mmkv' ? activeMMKVId : undefined);
71
+ setEntries(data);
72
+ }
73
+ catch {
74
+ setEntries([]);
75
+ }
76
+ finally {
77
+ setIsLoading(false);
78
+ }
79
+ }, [activeDriver, activeMMKVId]);
80
+ (0, react_1.useEffect)(() => {
81
+ loadEntries();
82
+ const unsubscribe = (0, storageInspector_1.subscribeToStorageChanges)(loadEntries);
83
+ return unsubscribe;
84
+ }, [loadEntries]);
85
+ // Toggle JSON accordion
86
+ const toggleExpand = (key) => {
87
+ setExpandedKeys(prev => ({ ...prev, [key]: !prev[key] }));
88
+ };
89
+ // Open Create Modal
90
+ const handleOpenCreate = () => {
91
+ setModalMode('create');
92
+ setEditKeyName('');
93
+ setEditValue('');
94
+ setEditType('string');
95
+ setJsonError(null);
96
+ setModalVisible(true);
97
+ };
98
+ // Open Edit Modal
99
+ const handleOpenEdit = (entry) => {
100
+ setModalMode('edit');
101
+ setEditKeyName(entry.key);
102
+ setEditValue(entry.value);
103
+ setEditType(entry.type === 'json' ? 'json' : entry.type === 'number' ? 'number' : entry.type === 'boolean' ? 'boolean' : 'string');
104
+ setJsonError(null);
105
+ setModalVisible(true);
106
+ };
107
+ // Delete single key
108
+ const handleDeleteKey = (key) => {
109
+ react_native_1.Alert.alert('Delete Storage Key', `Are you sure you want to permanently delete "${key}" from ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'}?`, [
110
+ { text: 'Cancel', style: 'cancel' },
111
+ {
112
+ text: 'Delete',
113
+ style: 'destructive',
114
+ onPress: async () => {
115
+ const ok = await (0, storageInspector_1.removeStorageEntry)(activeDriver, key, activeDriver === 'mmkv' ? activeMMKVId : undefined);
116
+ if (ok) {
117
+ (0, toast_1.showToast)(`Deleted "${key}"`);
118
+ loadEntries();
119
+ }
120
+ else {
121
+ (0, toast_1.showToast)(`Failed to delete "${key}"`);
122
+ }
123
+ },
124
+ },
125
+ ]);
126
+ };
127
+ // Clear all keys
128
+ const handleClearAll = () => {
129
+ react_native_1.Alert.alert('Wipe All Storage Keys', `Are you sure you want to clear all ${entries.length} keys in ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'}? This cannot be undone.`, [
130
+ { text: 'Cancel', style: 'cancel' },
131
+ {
132
+ text: 'Wipe All',
133
+ style: 'destructive',
134
+ onPress: async () => {
135
+ const ok = await (0, storageInspector_1.clearStorageDriver)(activeDriver, activeDriver === 'mmkv' ? activeMMKVId : undefined);
136
+ if (ok) {
137
+ (0, toast_1.showToast)('All storage keys wiped');
138
+ loadEntries();
139
+ }
140
+ },
141
+ },
142
+ ]);
143
+ };
144
+ // Save Modal (Create / Update)
145
+ const handleSaveModal = async () => {
146
+ if (!editKeyName.trim()) {
147
+ (0, toast_1.showToast)('Key name cannot be empty');
148
+ return;
149
+ }
150
+ let finalVal = editValue;
151
+ if (editType === 'json') {
152
+ try {
153
+ // Validate JSON
154
+ const parsed = JSON.parse(editValue);
155
+ finalVal = JSON.stringify(parsed);
156
+ }
157
+ catch (err) {
158
+ setJsonError('Invalid JSON: ' + err.message);
159
+ return;
160
+ }
161
+ }
162
+ else if (editType === 'number') {
163
+ if (isNaN(Number(editValue))) {
164
+ setJsonError('Value must be a valid number');
165
+ return;
166
+ }
167
+ }
168
+ const success = await (0, storageInspector_1.setStorageEntry)(activeDriver, editKeyName.trim(), finalVal, activeDriver === 'mmkv' ? activeMMKVId : undefined);
169
+ if (success) {
170
+ (0, toast_1.showToast)(modalMode === 'create' ? `Added "${editKeyName.trim()}"` : `Updated "${editKeyName.trim()}"`);
171
+ setModalVisible(false);
172
+ loadEntries();
173
+ }
174
+ else {
175
+ (0, toast_1.showToast)('Error saving storage key');
176
+ }
177
+ };
178
+ // Format / Beautify JSON in modal
179
+ const handleBeautifyJson = () => {
180
+ try {
181
+ const parsed = JSON.parse(editValue);
182
+ setEditValue(JSON.stringify(parsed, null, 2));
183
+ setJsonError(null);
184
+ setEditType('json');
185
+ (0, toast_1.showToast)('Formatted JSON');
186
+ }
187
+ catch {
188
+ setJsonError('Cannot format: invalid JSON syntax');
189
+ }
190
+ };
191
+ // Filter entries
192
+ const filteredEntries = (0, react_1.useMemo)(() => {
193
+ if (!search.trim())
194
+ return entries;
195
+ const q = search.toLowerCase().trim();
196
+ return entries.filter(e => e.key.toLowerCase().includes(q) || e.value.toLowerCase().includes(q));
197
+ }, [entries, search]);
198
+ const totalBytes = (0, react_1.useMemo)(() => {
199
+ return entries.reduce((sum, e) => sum + e.byteSize, 0);
200
+ }, [entries]);
201
+ const formattedTotalSize = (0, react_1.useMemo)(() => {
202
+ if (totalBytes < 1024)
203
+ return `${totalBytes} B`;
204
+ if (totalBytes < 1024 * 1024)
205
+ return `${(totalBytes / 1024).toFixed(1)} KB`;
206
+ return `${(totalBytes / (1024 * 1024)).toFixed(2)} MB`;
207
+ }, [totalBytes]);
208
+ const getTypeBadge = (type) => {
209
+ switch (type) {
210
+ case 'json':
211
+ return { label: 'JSON', color: AppColors_1.AppColors.purple, bg: `${AppColors_1.AppColors.purple}16` };
212
+ case 'number':
213
+ return { label: 'NUM', color: AppColors_1.AppColors.warningIconGold, bg: `${AppColors_1.AppColors.warningIconGold}16` };
214
+ case 'boolean':
215
+ return { label: 'BOOL', color: AppColors_1.AppColors.emerald500, bg: `${AppColors_1.AppColors.emerald500}16` };
216
+ case 'null':
217
+ return { label: 'NULL', color: AppColors_1.AppColors.grayTextWeak, bg: `${AppColors_1.AppColors.grayTextWeak}16` };
218
+ default:
219
+ return { label: 'STR', color: AppColors_1.AppColors.blue500, bg: `${AppColors_1.AppColors.blue500}16` };
220
+ }
221
+ };
222
+ const isConnected = activeDriver === 'asyncStorage'
223
+ ? (0, storageInspector_1.isAsyncStorageConnected)()
224
+ : (0, storageInspector_1.isMMKVConnected)();
225
+ return (<react_native_1.View style={styles.container}>
226
+ {/* ── Driver Sub-Tabs ── */}
227
+ <react_native_1.View style={styles.driverTabsWrapper}>
228
+ <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.driverTabsContainer}>
229
+ <TouchableScale_1.default onPress={() => setActiveDriver('asyncStorage')} style={[
230
+ styles.driverTabPill,
231
+ activeDriver === 'asyncStorage' && styles.driverTabPillActive,
232
+ ]}>
233
+ <NetworkIcons_1.DatabaseIcon size={13} color={activeDriver === 'asyncStorage'
234
+ ? AppColors_1.AppColors.white
235
+ : AppColors_1.AppColors.grayText}/>
236
+ <react_native_1.Text style={[
237
+ styles.driverTabText,
238
+ activeDriver === 'asyncStorage' && styles.driverTabTextActive,
239
+ ]}>
240
+ AsyncStorage
241
+ </react_native_1.Text>
242
+ {activeDriver === 'asyncStorage' && entries.length > 0 && (<react_native_1.View style={styles.driverCountBadge}>
243
+ <react_native_1.Text style={styles.driverCountText}>{entries.length}</react_native_1.Text>
244
+ </react_native_1.View>)}
245
+ </TouchableScale_1.default>
246
+
247
+ <TouchableScale_1.default onPress={() => setActiveDriver('mmkv')} style={[
248
+ styles.driverTabPill,
249
+ activeDriver === 'mmkv' && styles.driverTabPillActive,
250
+ ]}>
251
+ <NetworkIcons_1.LayersIcon size={13} color={activeDriver === 'mmkv'
252
+ ? AppColors_1.AppColors.white
253
+ : AppColors_1.AppColors.grayText}/>
254
+ <react_native_1.Text style={[
255
+ styles.driverTabText,
256
+ activeDriver === 'mmkv' && styles.driverTabTextActive,
257
+ ]}>
258
+ MMKV
259
+ </react_native_1.Text>
260
+ {activeDriver === 'mmkv' && entries.length > 0 && (<react_native_1.View style={styles.driverCountBadge}>
261
+ <react_native_1.Text style={styles.driverCountText}>{entries.length}</react_native_1.Text>
262
+ </react_native_1.View>)}
263
+ </TouchableScale_1.default>
264
+
265
+ {/* MMKV Named Instance Dropdown/Pills */}
266
+ {activeDriver === 'mmkv' && mmkvInstanceIds.length > 1 && (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4, marginLeft: 6 }}>
267
+ {mmkvInstanceIds.map(id => (<TouchableScale_1.default key={id} onPress={() => setActiveMMKVId(id)} style={[
268
+ styles.instancePill,
269
+ activeMMKVId === id && styles.instancePillActive,
270
+ ]}>
271
+ <react_native_1.Text style={[
272
+ styles.instancePillText,
273
+ activeMMKVId === id && styles.instancePillTextActive,
274
+ ]}>
275
+ {id}
276
+ </react_native_1.Text>
277
+ </TouchableScale_1.default>))}
278
+ </react_native_1.View>)}
279
+ </react_native_1.ScrollView>
280
+ </react_native_1.View>
281
+
282
+ {/* ── Search & Actions Bar ── */}
283
+ <react_native_1.View style={styles.actionBar}>
284
+ <react_native_1.View style={styles.searchBar}>
285
+ <NetworkIcons_1.SearchIcon size={14} color={AppColors_1.AppColors.grayTextWeak}/>
286
+ <react_native_1.TextInput value={search} onChangeText={setSearch} placeholder={`Search ${entries.length} keys & values...`} placeholderTextColor={AppColors_1.AppColors.grayTextWeak} style={styles.searchInput} clearButtonMode="while-editing"/>
287
+ {search.length > 0 && (<TouchableScale_1.default onPress={() => setSearch('')} hitSlop={8}>
288
+ <NetworkIcons_1.ClearIcon size={13} color={AppColors_1.AppColors.grayTextWeak}/>
289
+ </TouchableScale_1.default>)}
290
+ </react_native_1.View>
291
+
292
+ {/* Action Buttons: Add Key & Refresh */}
293
+ <TouchableScale_1.default onPress={handleOpenCreate} style={styles.addKeyBtn} hitSlop={6}>
294
+ <NetworkIcons_1.PlusIcon size={13} color={AppColors_1.AppColors.white}/>
295
+ <react_native_1.Text style={styles.addKeyBtnText}>Add</react_native_1.Text>
296
+ </TouchableScale_1.default>
297
+
298
+ <TouchableScale_1.default onPress={loadEntries} style={styles.actionIconBtn} hitSlop={6}>
299
+ <NetworkIcons_1.ResetIcon size={13} color={AppColors_1.AppColors.grayText}/>
300
+ </TouchableScale_1.default>
301
+
302
+ {entries.length > 0 && (<TouchableScale_1.default onPress={handleClearAll} style={[styles.actionIconBtn, { borderColor: `${AppColors_1.AppColors.errorColor}33`, backgroundColor: `${AppColors_1.AppColors.errorColor}12` }]} hitSlop={6}>
303
+ <NetworkIcons_1.TrashIcon size={13} color={AppColors_1.AppColors.errorColor}/>
304
+ </TouchableScale_1.default>)}
305
+ </react_native_1.View>
306
+
307
+ {/* ── Stats Strip ── */}
308
+ <react_native_1.View style={styles.statsStrip}>
309
+ <react_native_1.Text style={styles.statsText}>
310
+ {filteredEntries.length} of {entries.length} Keys • {formattedTotalSize}
311
+ </react_native_1.Text>
312
+ <react_native_1.Text style={styles.statsSubtext}>
313
+ {activeDriver === 'asyncStorage' ? 'SQLite Key-Value' : `MMKV (${activeMMKVId})`}
314
+ </react_native_1.Text>
315
+ </react_native_1.View>
316
+
317
+ {/* ── Storage Entries List ── */}
318
+ {isLoading ? (<react_native_1.View style={styles.loadingContainer}>
319
+ <react_native_1.ActivityIndicator size="small" color={AppColors_1.AppColors.purple}/>
320
+ <react_native_1.Text style={styles.loadingText}>Loading storage entries...</react_native_1.Text>
321
+ </react_native_1.View>) : filteredEntries.length === 0 ? (<react_native_1.ScrollView contentContainerStyle={styles.emptyContainer} showsVerticalScrollIndicator={false}>
322
+ <react_native_1.View style={styles.emptyIconWrap}>
323
+ <NetworkIcons_1.DatabaseIcon size={28} color={AppColors_1.AppColors.grayTextWeak}/>
324
+ </react_native_1.View>
325
+ <react_native_1.Text style={styles.emptyTitle}>
326
+ {search ? 'No matching keys found' : `No ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'} Keys`}
327
+ </react_native_1.Text>
328
+ <react_native_1.Text style={styles.emptySubtitle}>
329
+ {search
330
+ ? 'Try modifying your search query'
331
+ : `Storage is auto-detected. Tap "+ Add" above to create your first ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'} key!`}
332
+ </react_native_1.Text>
333
+ </react_native_1.ScrollView>) : (<react_native_1.ScrollView style={styles.scrollArea} contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false}>
334
+ {filteredEntries.map(entry => {
335
+ const isExpanded = Boolean(expandedKeys[entry.key]);
336
+ const badge = getTypeBadge(entry.type);
337
+ const formattedBytes = entry.byteSize < 1024
338
+ ? `${entry.byteSize} B`
339
+ : `${(entry.byteSize / 1024).toFixed(1)} KB`;
340
+ return (<react_native_1.View key={entry.key} style={styles.entryCard}>
341
+ {/* Entry Header: Key name, Type Badge, Size, Actions */}
342
+ <react_native_1.View style={styles.entryHeader}>
343
+ <react_native_1.View style={{ flex: 1, marginRight: 8 }}>
344
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
345
+ <react_native_1.Text style={styles.entryKey} numberOfLines={1} selectable>
346
+ {entry.key}
347
+ </react_native_1.Text>
348
+ <react_native_1.View style={[
349
+ styles.typeBadge,
350
+ { backgroundColor: badge.bg, borderColor: `${badge.color}33` },
351
+ ]}>
352
+ <react_native_1.Text style={[styles.typeBadgeText, { color: badge.color }]}>
353
+ {badge.label}
354
+ </react_native_1.Text>
355
+ </react_native_1.View>
356
+ <react_native_1.Text style={styles.sizeText}>{formattedBytes}</react_native_1.Text>
357
+ </react_native_1.View>
358
+ </react_native_1.View>
359
+
360
+ {/* Actions: Copy, Edit, Delete */}
361
+ <react_native_1.View style={styles.entryActions}>
362
+ <TouchableScale_1.default hitSlop={6} onPress={() => {
363
+ (0, helpers_1.copyToClipboard)(entry.value, entry.key);
364
+ (0, toast_1.showToast)(`Copied value of "${entry.key}"`);
365
+ }} style={styles.entryActionBtn}>
366
+ <NetworkIcons_1.CopyIcon size={12} color={AppColors_1.AppColors.grayText}/>
367
+ </TouchableScale_1.default>
368
+
369
+ <TouchableScale_1.default hitSlop={6} onPress={() => handleOpenEdit(entry)} style={styles.entryActionBtn}>
370
+ <NetworkIcons_1.PencilIcon size={12} color={AppColors_1.AppColors.purple}/>
371
+ </TouchableScale_1.default>
372
+
373
+ <TouchableScale_1.default hitSlop={6} onPress={() => handleDeleteKey(entry.key)} style={[styles.entryActionBtn, { backgroundColor: `${AppColors_1.AppColors.errorColor}12` }]}>
374
+ <NetworkIcons_1.TrashIcon size={12} color={AppColors_1.AppColors.errorColor}/>
375
+ </TouchableScale_1.default>
376
+ </react_native_1.View>
377
+ </react_native_1.View>
378
+
379
+ {/* Entry Value Preview / Viewer */}
380
+ <TouchableScale_1.default onPress={() => toggleExpand(entry.key)} style={styles.valuePreviewBox}>
381
+ <react_native_1.Text style={styles.valuePreviewText} numberOfLines={isExpanded ? undefined : 3} selectable>
382
+ {entry.type === 'json' && entry.parsedValue
383
+ ? isExpanded
384
+ ? JSON.stringify(entry.parsedValue, null, 2)
385
+ : entry.value
386
+ : entry.value}
387
+ </react_native_1.Text>
388
+ {entry.value.length > 80 && (<react_native_1.Text style={styles.expandHint}>
389
+ {isExpanded ? '▲ Collapse' : '▼ Expand'}
390
+ </react_native_1.Text>)}
391
+ </TouchableScale_1.default>
392
+ </react_native_1.View>);
393
+ })}
394
+ <react_native_1.View style={{ height: 60 }}/>
395
+ </react_native_1.ScrollView>)}
396
+
397
+ {/* ── Create / Edit Key Modal ── */}
398
+ <react_native_1.Modal visible={modalVisible} transparent animationType="fade" onRequestClose={() => setModalVisible(false)}>
399
+ <react_native_1.View style={styles.modalOverlay}>
400
+ <react_native_1.View style={styles.modalCard}>
401
+ <react_native_1.View style={styles.modalHeader}>
402
+ <react_native_1.Text style={styles.modalTitle}>
403
+ {modalMode === 'create' ? 'Add Storage Key' : `Edit: ${editKeyName}`}
404
+ </react_native_1.Text>
405
+ <TouchableScale_1.default onPress={() => setModalVisible(false)} hitSlop={8}>
406
+ <NetworkIcons_1.ClearIcon size={16} color={AppColors_1.AppColors.grayText}/>
407
+ </TouchableScale_1.default>
408
+ </react_native_1.View>
409
+
410
+ {/* Key Name Input */}
411
+ <react_native_1.View style={styles.inputGroup}>
412
+ <react_native_1.Text style={styles.inputLabel}>KEY NAME</react_native_1.Text>
413
+ <react_native_1.TextInput value={editKeyName} onChangeText={setEditKeyName} placeholder="e.g. user_session, auth_token" placeholderTextColor={AppColors_1.AppColors.grayTextWeak} editable={modalMode === 'create'} style={[
414
+ styles.textInput,
415
+ modalMode === 'edit' && styles.textInputDisabled,
416
+ ]} autoCapitalize="none"/>
417
+ </react_native_1.View>
418
+
419
+ {/* Type Selector Strip */}
420
+ <react_native_1.View style={styles.inputGroup}>
421
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 4 }}>
422
+ <react_native_1.Text style={styles.inputLabel}>VALUE TYPE</react_native_1.Text>
423
+ {editType === 'json' && (<TouchableScale_1.default onPress={handleBeautifyJson} hitSlop={6}>
424
+ <react_native_1.Text style={styles.formatJsonBtn}>Beautify JSON</react_native_1.Text>
425
+ </TouchableScale_1.default>)}
426
+ </react_native_1.View>
427
+ <react_native_1.View style={styles.typeSelectorStrip}>
428
+ {['string', 'json', 'number', 'boolean'].map(t => {
429
+ const isSel = editType === t;
430
+ return (<TouchableScale_1.default key={t} onPress={() => {
431
+ setEditType(t);
432
+ setJsonError(null);
433
+ }} style={[
434
+ styles.typePill,
435
+ isSel && styles.typePillActive,
436
+ ]}>
437
+ <react_native_1.Text style={[
438
+ styles.typePillText,
439
+ isSel && styles.typePillTextActive,
440
+ ]}>
441
+ {t.toUpperCase()}
442
+ </react_native_1.Text>
443
+ </TouchableScale_1.default>);
444
+ })}
445
+ </react_native_1.View>
446
+ </react_native_1.View>
447
+
448
+ {/* Value Input */}
449
+ <react_native_1.View style={styles.inputGroup}>
450
+ <react_native_1.Text style={styles.inputLabel}>VALUE CONTENT</react_native_1.Text>
451
+ <react_native_1.TextInput value={editValue} onChangeText={v => {
452
+ setEditValue(v);
453
+ if (jsonError)
454
+ setJsonError(null);
455
+ }} placeholder={editType === 'json'
456
+ ? '{"userId": 123, "isLoggedIn": true}'
457
+ : editType === 'number'
458
+ ? '42'
459
+ : editType === 'boolean'
460
+ ? 'true'
461
+ : 'String value...'} placeholderTextColor={AppColors_1.AppColors.grayTextWeak} style={[styles.textInput, styles.textAreaInput]} multiline textAlignVertical="top" autoCapitalize="none"/>
462
+ {jsonError && (<react_native_1.Text style={styles.errorText}>⚠️ {jsonError}</react_native_1.Text>)}
463
+ </react_native_1.View>
464
+
465
+ {/* Modal Actions */}
466
+ <react_native_1.View style={styles.modalActions}>
467
+ <TouchableScale_1.default onPress={() => setModalVisible(false)} style={styles.cancelBtn}>
468
+ <react_native_1.Text style={styles.cancelBtnText}>Cancel</react_native_1.Text>
469
+ </TouchableScale_1.default>
470
+ <TouchableScale_1.default onPress={handleSaveModal} style={styles.saveBtn}>
471
+ <NetworkIcons_1.CheckIcon size={14} color={AppColors_1.AppColors.white}/>
472
+ <react_native_1.Text style={styles.saveBtnText}>Save Key</react_native_1.Text>
473
+ </TouchableScale_1.default>
474
+ </react_native_1.View>
475
+ </react_native_1.View>
476
+ </react_native_1.View>
477
+ </react_native_1.Modal>
478
+ </react_native_1.View>);
479
+ });
480
+ const styles = react_native_1.StyleSheet.create({
481
+ container: {
482
+ flex: 1,
483
+ backgroundColor: AppColors_1.AppColors.grayBackground,
484
+ },
485
+ driverTabsWrapper: {
486
+ backgroundColor: AppColors_1.AppColors.primaryLight,
487
+ borderBottomWidth: 1,
488
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
489
+ paddingVertical: 8,
490
+ },
491
+ driverTabsContainer: {
492
+ paddingHorizontal: 12,
493
+ flexDirection: 'row',
494
+ alignItems: 'center',
495
+ gap: 6,
496
+ },
497
+ driverTabPill: {
498
+ flexDirection: 'row',
499
+ alignItems: 'center',
500
+ gap: 6,
501
+ paddingHorizontal: 11,
502
+ paddingVertical: 6,
503
+ borderRadius: 8,
504
+ backgroundColor: AppColors_1.AppColors.grayBackground,
505
+ borderWidth: 1,
506
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
507
+ },
508
+ driverTabPillActive: {
509
+ backgroundColor: AppColors_1.AppColors.purple,
510
+ borderColor: AppColors_1.AppColors.purple,
511
+ },
512
+ driverTabText: {
513
+ fontFamily: AppFonts_1.AppFonts.interBold,
514
+ fontSize: 11.5,
515
+ color: AppColors_1.AppColors.grayText,
516
+ },
517
+ driverTabTextActive: {
518
+ color: AppColors_1.AppColors.white,
519
+ },
520
+ driverCountBadge: {
521
+ backgroundColor: 'rgba(255, 255, 255, 0.25)',
522
+ paddingHorizontal: 5,
523
+ paddingVertical: 1,
524
+ borderRadius: 6,
525
+ },
526
+ driverCountText: {
527
+ fontFamily: AppFonts_1.AppFonts.interBold,
528
+ fontSize: 9,
529
+ color: AppColors_1.AppColors.white,
530
+ },
531
+ instancePill: {
532
+ paddingHorizontal: 7,
533
+ paddingVertical: 3,
534
+ borderRadius: 6,
535
+ backgroundColor: `${AppColors_1.AppColors.purple}14`,
536
+ borderWidth: 1,
537
+ borderColor: `${AppColors_1.AppColors.purple}30`,
538
+ },
539
+ instancePillActive: {
540
+ backgroundColor: AppColors_1.AppColors.purple,
541
+ borderColor: AppColors_1.AppColors.purple,
542
+ },
543
+ instancePillText: {
544
+ fontFamily: AppFonts_1.AppFonts.interBold,
545
+ fontSize: 10,
546
+ color: AppColors_1.AppColors.purple,
547
+ },
548
+ instancePillTextActive: {
549
+ color: AppColors_1.AppColors.white,
550
+ },
551
+ actionBar: {
552
+ flexDirection: 'row',
553
+ alignItems: 'center',
554
+ paddingHorizontal: 12,
555
+ paddingVertical: 8,
556
+ backgroundColor: AppColors_1.AppColors.primaryLight,
557
+ borderBottomWidth: 1,
558
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
559
+ gap: 6,
560
+ },
561
+ searchBar: {
562
+ flex: 1,
563
+ flexDirection: 'row',
564
+ alignItems: 'center',
565
+ backgroundColor: AppColors_1.AppColors.grayBackground,
566
+ borderRadius: 8,
567
+ paddingHorizontal: 9,
568
+ paddingVertical: react_native_1.Platform.OS === 'ios' ? 6 : 2,
569
+ borderWidth: 1,
570
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
571
+ gap: 6,
572
+ },
573
+ searchInput: {
574
+ flex: 1,
575
+ fontFamily: AppFonts_1.AppFonts.interMedium,
576
+ fontSize: 12,
577
+ color: AppColors_1.AppColors.primaryBlack,
578
+ padding: 0,
579
+ },
580
+ addKeyBtn: {
581
+ flexDirection: 'row',
582
+ alignItems: 'center',
583
+ gap: 4,
584
+ paddingHorizontal: 10,
585
+ paddingVertical: 6,
586
+ borderRadius: 8,
587
+ backgroundColor: AppColors_1.AppColors.purple,
588
+ },
589
+ addKeyBtnText: {
590
+ fontFamily: AppFonts_1.AppFonts.interBold,
591
+ fontSize: 11,
592
+ color: AppColors_1.AppColors.white,
593
+ },
594
+ actionIconBtn: {
595
+ width: 30,
596
+ height: 30,
597
+ borderRadius: 8,
598
+ alignItems: 'center',
599
+ justifyContent: 'center',
600
+ backgroundColor: AppColors_1.AppColors.grayBackground,
601
+ borderWidth: 1,
602
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
603
+ },
604
+ statsStrip: {
605
+ flexDirection: 'row',
606
+ alignItems: 'center',
607
+ justifyContent: 'space-between',
608
+ paddingHorizontal: 12,
609
+ paddingVertical: 5,
610
+ backgroundColor: `${AppColors_1.AppColors.grayBorderSecondary}40`,
611
+ },
612
+ statsText: {
613
+ fontFamily: AppFonts_1.AppFonts.interMedium,
614
+ fontSize: 10,
615
+ color: AppColors_1.AppColors.grayText,
616
+ },
617
+ statsSubtext: {
618
+ fontFamily: AppFonts_1.AppFonts.interBold,
619
+ fontSize: 9.5,
620
+ color: AppColors_1.AppColors.grayTextWeak,
621
+ },
622
+ scrollArea: {
623
+ flex: 1,
624
+ },
625
+ scrollContent: {
626
+ padding: 12,
627
+ gap: 10,
628
+ paddingBottom: 100,
629
+ },
630
+ entryCard: {
631
+ backgroundColor: AppColors_1.AppColors.primaryLight,
632
+ borderRadius: 10,
633
+ borderWidth: 1,
634
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
635
+ padding: 10,
636
+ gap: 8,
637
+ shadowColor: AppColors_1.AppColors.black,
638
+ shadowOpacity: 0.02,
639
+ shadowRadius: 3,
640
+ shadowOffset: { width: 0, height: 1 },
641
+ elevation: 1,
642
+ },
643
+ entryHeader: {
644
+ flexDirection: 'row',
645
+ alignItems: 'center',
646
+ justifyContent: 'space-between',
647
+ },
648
+ entryKey: {
649
+ fontFamily: AppFonts_1.AppFonts.interBold,
650
+ fontSize: 12.5,
651
+ color: AppColors_1.AppColors.primaryBlack,
652
+ },
653
+ typeBadge: {
654
+ paddingHorizontal: 5,
655
+ paddingVertical: 1,
656
+ borderRadius: 4,
657
+ borderWidth: 1,
658
+ },
659
+ typeBadgeText: {
660
+ fontFamily: AppFonts_1.AppFonts.interBold,
661
+ fontSize: 8.5,
662
+ },
663
+ sizeText: {
664
+ fontFamily: AppFonts_1.AppFonts.interRegular,
665
+ fontSize: 10,
666
+ color: AppColors_1.AppColors.grayTextWeak,
667
+ },
668
+ entryActions: {
669
+ flexDirection: 'row',
670
+ alignItems: 'center',
671
+ gap: 5,
672
+ },
673
+ entryActionBtn: {
674
+ padding: 5,
675
+ borderRadius: 5,
676
+ backgroundColor: AppColors_1.AppColors.grayBackground,
677
+ },
678
+ valuePreviewBox: {
679
+ backgroundColor: AppColors_1.AppColors.grayBackground,
680
+ borderRadius: 6,
681
+ padding: 8,
682
+ borderWidth: 1,
683
+ borderColor: `${AppColors_1.AppColors.grayBorderSecondary}80`,
684
+ },
685
+ valuePreviewText: {
686
+ fontFamily: react_native_1.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
687
+ fontSize: 11,
688
+ color: AppColors_1.AppColors.primaryBlack,
689
+ lineHeight: 16,
690
+ },
691
+ expandHint: {
692
+ fontFamily: AppFonts_1.AppFonts.interBold,
693
+ fontSize: 9.5,
694
+ color: AppColors_1.AppColors.purple,
695
+ marginTop: 4,
696
+ },
697
+ loadingContainer: {
698
+ flex: 1,
699
+ alignItems: 'center',
700
+ justifyContent: 'center',
701
+ gap: 8,
702
+ },
703
+ loadingText: {
704
+ fontFamily: AppFonts_1.AppFonts.interMedium,
705
+ fontSize: 12,
706
+ color: AppColors_1.AppColors.grayText,
707
+ },
708
+ emptyContainer: {
709
+ padding: 24,
710
+ alignItems: 'center',
711
+ justifyContent: 'center',
712
+ },
713
+ emptyIconWrap: {
714
+ width: 56,
715
+ height: 56,
716
+ borderRadius: 28,
717
+ backgroundColor: `${AppColors_1.AppColors.grayBorderSecondary}40`,
718
+ alignItems: 'center',
719
+ justifyContent: 'center',
720
+ marginBottom: 12,
721
+ },
722
+ emptyTitle: {
723
+ fontFamily: AppFonts_1.AppFonts.interBold,
724
+ fontSize: 14,
725
+ color: AppColors_1.AppColors.primaryBlack,
726
+ marginBottom: 4,
727
+ },
728
+ emptySubtitle: {
729
+ fontFamily: AppFonts_1.AppFonts.interRegular,
730
+ fontSize: 11.5,
731
+ color: AppColors_1.AppColors.grayText,
732
+ textAlign: 'center',
733
+ maxWidth: 280,
734
+ },
735
+ connectGuideCard: {
736
+ marginTop: 20,
737
+ width: '100%',
738
+ backgroundColor: AppColors_1.AppColors.primaryLight,
739
+ borderRadius: 10,
740
+ borderWidth: 1,
741
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
742
+ padding: 12,
743
+ gap: 6,
744
+ },
745
+ connectGuideTitle: {
746
+ fontFamily: AppFonts_1.AppFonts.interBold,
747
+ fontSize: 11,
748
+ color: AppColors_1.AppColors.purple,
749
+ },
750
+ connectGuideCode: {
751
+ fontFamily: react_native_1.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
752
+ fontSize: 10,
753
+ color: AppColors_1.AppColors.grayText,
754
+ lineHeight: 15,
755
+ },
756
+ modalOverlay: {
757
+ flex: 1,
758
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
759
+ justifyContent: 'center',
760
+ alignItems: 'center',
761
+ padding: 16,
762
+ },
763
+ modalCard: {
764
+ width: '100%',
765
+ maxWidth: 400,
766
+ backgroundColor: AppColors_1.AppColors.primaryLight,
767
+ borderRadius: 14,
768
+ padding: 16,
769
+ gap: 12,
770
+ shadowColor: AppColors_1.AppColors.black,
771
+ shadowOpacity: 0.2,
772
+ shadowRadius: 10,
773
+ shadowOffset: { width: 0, height: 4 },
774
+ elevation: 5,
775
+ },
776
+ modalHeader: {
777
+ flexDirection: 'row',
778
+ alignItems: 'center',
779
+ justifyContent: 'space-between',
780
+ borderBottomWidth: 1,
781
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
782
+ paddingBottom: 10,
783
+ },
784
+ modalTitle: {
785
+ fontFamily: AppFonts_1.AppFonts.interBold,
786
+ fontSize: 14,
787
+ color: AppColors_1.AppColors.primaryBlack,
788
+ },
789
+ inputGroup: {
790
+ gap: 4,
791
+ },
792
+ inputLabel: {
793
+ fontFamily: AppFonts_1.AppFonts.interBold,
794
+ fontSize: 9.5,
795
+ color: AppColors_1.AppColors.grayTextWeak,
796
+ letterSpacing: 0.5,
797
+ },
798
+ textInput: {
799
+ backgroundColor: AppColors_1.AppColors.grayBackground,
800
+ borderRadius: 8,
801
+ paddingHorizontal: 10,
802
+ paddingVertical: 8,
803
+ fontFamily: AppFonts_1.AppFonts.interMedium,
804
+ fontSize: 12,
805
+ color: AppColors_1.AppColors.primaryBlack,
806
+ borderWidth: 1,
807
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
808
+ },
809
+ textInputDisabled: {
810
+ backgroundColor: `${AppColors_1.AppColors.grayBorderSecondary}40`,
811
+ color: AppColors_1.AppColors.grayText,
812
+ },
813
+ textAreaInput: {
814
+ minHeight: 90,
815
+ maxHeight: 160,
816
+ fontFamily: react_native_1.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
817
+ fontSize: 11,
818
+ },
819
+ typeSelectorStrip: {
820
+ flexDirection: 'row',
821
+ alignItems: 'center',
822
+ gap: 6,
823
+ },
824
+ typePill: {
825
+ flex: 1,
826
+ alignItems: 'center',
827
+ paddingVertical: 6,
828
+ borderRadius: 6,
829
+ backgroundColor: AppColors_1.AppColors.grayBackground,
830
+ borderWidth: 1,
831
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
832
+ },
833
+ typePillActive: {
834
+ backgroundColor: AppColors_1.AppColors.purple,
835
+ borderColor: AppColors_1.AppColors.purple,
836
+ },
837
+ typePillText: {
838
+ fontFamily: AppFonts_1.AppFonts.interBold,
839
+ fontSize: 10,
840
+ color: AppColors_1.AppColors.grayText,
841
+ },
842
+ typePillTextActive: {
843
+ color: AppColors_1.AppColors.white,
844
+ },
845
+ formatJsonBtn: {
846
+ fontFamily: AppFonts_1.AppFonts.interBold,
847
+ fontSize: 10,
848
+ color: AppColors_1.AppColors.purple,
849
+ },
850
+ errorText: {
851
+ fontFamily: AppFonts_1.AppFonts.interMedium,
852
+ fontSize: 10,
853
+ color: AppColors_1.AppColors.errorColor,
854
+ marginTop: 2,
855
+ },
856
+ modalActions: {
857
+ flexDirection: 'row',
858
+ alignItems: 'center',
859
+ gap: 10,
860
+ marginTop: 4,
861
+ },
862
+ cancelBtn: {
863
+ flex: 1,
864
+ alignItems: 'center',
865
+ paddingVertical: 10,
866
+ borderRadius: 8,
867
+ backgroundColor: AppColors_1.AppColors.grayBackground,
868
+ borderWidth: 1,
869
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
870
+ },
871
+ cancelBtnText: {
872
+ fontFamily: AppFonts_1.AppFonts.interBold,
873
+ fontSize: 12,
874
+ color: AppColors_1.AppColors.grayText,
875
+ },
876
+ saveBtn: {
877
+ flex: 1.5,
878
+ flexDirection: 'row',
879
+ alignItems: 'center',
880
+ justifyContent: 'center',
881
+ gap: 5,
882
+ paddingVertical: 10,
883
+ borderRadius: 8,
884
+ backgroundColor: AppColors_1.AppColors.purple,
885
+ },
886
+ saveBtnText: {
887
+ fontFamily: AppFonts_1.AppFonts.interBold,
888
+ fontSize: 12,
889
+ color: AppColors_1.AppColors.white,
890
+ },
891
+ });
892
+ exports.default = exports.StorageTab;