react-native-inapp-inspector 1.1.12 → 1.1.13

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 (45) hide show
  1. package/dist/commonjs/components/AnalyticsDetail.js +64 -21
  2. package/dist/commonjs/components/HighlightText.js +1 -1
  3. package/dist/commonjs/components/JsonViewer.d.ts +3 -1
  4. package/dist/commonjs/components/JsonViewer.js +327 -9
  5. package/dist/commonjs/components/MetaAccordion.d.ts +10 -1
  6. package/dist/commonjs/components/MetaAccordion.js +121 -24
  7. package/dist/commonjs/components/NetworkIcons.d.ts +1 -0
  8. package/dist/commonjs/components/NetworkIcons.js +8 -1
  9. package/dist/commonjs/components/ReduxTreeView.d.ts +12 -3
  10. package/dist/commonjs/components/ReduxTreeView.js +1096 -278
  11. package/dist/commonjs/components/SectionHeader.d.ts +1 -1
  12. package/dist/commonjs/components/SectionHeader.js +7 -1
  13. package/dist/commonjs/constants/version.d.ts +1 -1
  14. package/dist/commonjs/constants/version.js +1 -1
  15. package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -0
  16. package/dist/commonjs/customHooks/reduxLogger.js +2 -0
  17. package/dist/commonjs/helpers/index.d.ts +1 -0
  18. package/dist/commonjs/helpers/index.js +15 -1
  19. package/dist/commonjs/helpers/settingsStore.d.ts +1 -0
  20. package/dist/commonjs/helpers/settingsStore.js +4 -0
  21. package/dist/commonjs/index.js +110 -91
  22. package/dist/commonjs/types/index.d.ts +3 -0
  23. package/dist/esm/components/AnalyticsDetail.js +64 -21
  24. package/dist/esm/components/HighlightText.js +3 -3
  25. package/dist/esm/components/JsonViewer.d.ts +3 -1
  26. package/dist/esm/components/JsonViewer.js +295 -10
  27. package/dist/esm/components/MetaAccordion.d.ts +10 -1
  28. package/dist/esm/components/MetaAccordion.js +90 -26
  29. package/dist/esm/components/NetworkIcons.d.ts +1 -0
  30. package/dist/esm/components/NetworkIcons.js +6 -0
  31. package/dist/esm/components/ReduxTreeView.d.ts +12 -3
  32. package/dist/esm/components/ReduxTreeView.js +1095 -279
  33. package/dist/esm/components/SectionHeader.d.ts +1 -1
  34. package/dist/esm/components/SectionHeader.js +8 -2
  35. package/dist/esm/constants/version.d.ts +1 -1
  36. package/dist/esm/constants/version.js +1 -1
  37. package/dist/esm/customHooks/reduxLogger.d.ts +2 -0
  38. package/dist/esm/customHooks/reduxLogger.js +2 -0
  39. package/dist/esm/helpers/index.d.ts +1 -0
  40. package/dist/esm/helpers/index.js +14 -1
  41. package/dist/esm/helpers/settingsStore.d.ts +1 -0
  42. package/dist/esm/helpers/settingsStore.js +3 -0
  43. package/dist/esm/index.js +111 -92
  44. package/dist/esm/types/index.d.ts +3 -0
  45. package/package.json +1 -1
@@ -32,368 +32,1186 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ReduxTreeView = exports.ReduxStoreIcon = void 0;
39
+ exports.ReduxTreeView = void 0;
37
40
  const react_1 = __importStar(require("react"));
38
41
  const react_native_1 = require("react-native");
39
42
  const AppColors_1 = require("../styles/AppColors");
40
43
  const AppFonts_1 = require("../styles/AppFonts");
41
44
  const NetworkIcons_1 = require("./NetworkIcons");
42
- const react_native_svg_1 = __importStar(require("react-native-svg"));
43
- const FolderIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12 }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
44
- <react_native_svg_1.Path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
45
- </react_native_svg_1.default>);
46
- const ReduxStoreIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12, }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
47
- <react_native_svg_1.Path d="M3 9l1.5-5h15L21 9M3 9v10a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V9M3 9h18M7 9v3a2 2 0 0 0 4 0V9m2 0v3a2 2 0 0 0 4 0V9" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
48
- </react_native_svg_1.default>);
49
- exports.ReduxStoreIcon = ReduxStoreIcon;
50
- const animateTreeLayout = () => {
51
- if (react_native_1.Platform.OS === 'ios') {
52
- react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut);
45
+ const JsonViewer_1 = __importDefault(require("./JsonViewer"));
46
+ const DiffViewer_1 = __importDefault(require("./DiffViewer"));
47
+ const TouchableScale_1 = __importDefault(require("./TouchableScale"));
48
+ const helpers_1 = require("../helpers");
49
+ const settingsStore_1 = require("../helpers/settingsStore");
50
+ // Enable LayoutAnimation for Android
51
+ if (react_native_1.Platform.OS === 'android') {
52
+ react_native_1.UIManager.setLayoutAnimationEnabledExperimental?.(true);
53
+ }
54
+ const animateLayout = () => {
55
+ react_native_1.LayoutAnimation.configureNext(react_native_1.LayoutAnimation.Presets.easeInEaseOut);
56
+ };
57
+ // Chevron pointing left (for back buttons)
58
+ const BackChevronIcon = ({ color = AppColors_1.AppColors.purple, size = 12 }) => (<react_native_1.View style={{ transform: [{ rotate: '180deg' }], marginRight: 4 }}>
59
+ <NetworkIcons_1.ChevronIcon color={color} size={size}/>
60
+ </react_native_1.View>);
61
+ // Chevron pointing right (for list items)
62
+ const ForwardChevronIcon = ({ color = AppColors_1.AppColors.grayTextWeak, size = 12 }) => (<react_native_1.View style={{ transform: [{ rotate: '0deg' }], marginLeft: 'auto' }}>
63
+ <NetworkIcons_1.ChevronIcon color={color} size={size}/>
64
+ </react_native_1.View>);
65
+ // Helper: check if a value recursively contains a string term
66
+ const valueContainsTerm = (val, term) => {
67
+ if (!term)
68
+ return true;
69
+ const t = term.toLowerCase();
70
+ if (val === null || val === undefined)
71
+ return false;
72
+ if (typeof val !== 'object') {
73
+ return String(val).toLowerCase().includes(t);
53
74
  }
75
+ if (Array.isArray(val)) {
76
+ return val.some(item => valueContainsTerm(item, term));
77
+ }
78
+ return Object.keys(val).some(key => key.toLowerCase().includes(t) || valueContainsTerm(val[key], term));
54
79
  };
55
- const AnimatedChevron = ({ color, expanded, size, style, }) => {
56
- const progress = (0, react_1.useRef)(new react_native_1.Animated.Value(expanded ? 1 : 0)).current;
80
+ const ReduxTreeView = ({ state, actionHistory = [], lastActionMap = {}, search = '', onSearchChange, autoRefresh = true, onToggleAutoRefresh, onClearHistory, onDetailOpenChange, selectedSliceKey = null, onSelectSliceKey, selectedActionId = null, onSelectActionId, }) => {
81
+ const [activeTab, setActiveTab] = (0, react_1.useState)('state');
82
+ const [actionSubTab, setActionSubTab] = (0, react_1.useState)('payload');
83
+ // local fallbacks if props are not provided
84
+ const [localSliceKey, setLocalSliceKey] = (0, react_1.useState)(null);
85
+ const [localActionId, setLocalActionId] = (0, react_1.useState)(null);
86
+ const activeSliceKey = onSelectSliceKey ? selectedSliceKey : localSliceKey;
87
+ const activeActionId = onSelectActionId ? selectedActionId : localActionId;
88
+ const setActiveSliceKey = (key) => {
89
+ if (onSelectSliceKey)
90
+ onSelectSliceKey(key);
91
+ else
92
+ setLocalSliceKey(key);
93
+ };
94
+ const setActiveActionId = (id) => {
95
+ if (onSelectActionId)
96
+ onSelectActionId(id);
97
+ else
98
+ setLocalActionId(id);
99
+ };
100
+ // Expand / collapse all states for detail views
101
+ const [sliceForceOpen, setSliceForceOpen] = (0, react_1.useState)(undefined);
102
+ const [actionForceOpen, setActionForceOpen] = (0, react_1.useState)(undefined);
103
+ const [searchModeType, setSearchModeType] = (0, react_1.useState)(true);
104
+ const [searchModeData, setSearchModeData] = (0, react_1.useState)(true);
105
+ // Sorting directions
106
+ const [stateSortAsc, setStateSortAsc] = (0, react_1.useState)(true);
107
+ const [actionSortAsc, setActionSortAsc] = (0, react_1.useState)(false);
108
+ // Persistence-related states for State Slice details
109
+ const [sliceDetailTab, setSliceDetailTab] = (0, react_1.useState)('live');
110
+ const [isPersisted, setIsPersisted] = (0, react_1.useState)(false);
111
+ const [persistedData, setPersistedData] = (0, react_1.useState)(null);
57
112
  (0, react_1.useEffect)(() => {
58
- react_native_1.Animated.timing(progress, {
59
- toValue: expanded ? 1 : 0,
60
- duration: 180,
61
- useNativeDriver: true,
62
- }).start();
63
- }, [expanded, progress]);
64
- const rotate = progress.interpolate({
65
- inputRange: [0, 1],
66
- outputRange: ['0deg', '90deg'],
67
- });
68
- return (<react_native_1.Animated.View style={[style, { transform: [{ rotate }] }]}>
69
- <NetworkIcons_1.ChevronIcon color={color} size={size}/>
70
- </react_native_1.Animated.View>);
71
- };
72
- const ReduxValueNode = ({ name, value, level, search, lastAction }) => {
73
- const [expanded, setExpanded] = (0, react_1.useState)(level < 1);
74
- const isObject = typeof value === 'object' && value !== null;
75
- const isArray = Array.isArray(value);
76
- const nameStr = String(name);
77
- // Filter check if search query matches key or value
78
- const matchesSearch = (k, val) => {
79
- if (!search)
80
- return true;
81
- const s = search.toLowerCase();
82
- if (k.toLowerCase().includes(s))
83
- return true;
84
- if (typeof val !== 'object' && String(val).toLowerCase().includes(s))
85
- return true;
86
- if (typeof val === 'object' && val !== null) {
87
- return Object.keys(val).some(key => matchesSearch(key, val[key]));
113
+ if (activeSliceKey === null) {
114
+ setIsPersisted(false);
115
+ setPersistedData(null);
116
+ setSliceDetailTab('live');
117
+ return;
88
118
  }
89
- return false;
90
- };
91
- if (!matchesSearch(nameStr, value)) {
92
- return null;
93
- }
94
- if (!isObject) {
95
- const valStr = value === null
96
- ? 'null'
97
- : value === undefined
98
- ? 'undefined'
99
- : String(value);
100
- let valColor = '#0D9488'; // String
101
- if (value === null || value === undefined) {
102
- valColor = AppColors_1.AppColors.grayTextWeak;
119
+ async function checkPersistence() {
120
+ try {
121
+ const storage = (0, settingsStore_1.getCustomStorage)();
122
+ if (!storage) {
123
+ setIsPersisted(false);
124
+ setPersistedData(null);
125
+ return;
126
+ }
127
+ // Check direct key: persist:sliceKey
128
+ let raw = await storage.getItem(`persist:${activeSliceKey}`);
129
+ if (raw) {
130
+ try {
131
+ setPersistedData(JSON.parse(raw));
132
+ }
133
+ catch {
134
+ setPersistedData(raw);
135
+ }
136
+ setIsPersisted(true);
137
+ return;
138
+ }
139
+ // Check root key: persist:root
140
+ let rootRaw = await storage.getItem('persist:root');
141
+ if (rootRaw) {
142
+ const parsedRoot = JSON.parse(rootRaw);
143
+ if (parsedRoot && parsedRoot[activeSliceKey] !== undefined) {
144
+ const nested = parsedRoot[activeSliceKey];
145
+ try {
146
+ setPersistedData(typeof nested === 'string' ? JSON.parse(nested) : nested);
147
+ }
148
+ catch {
149
+ setPersistedData(nested);
150
+ }
151
+ setIsPersisted(true);
152
+ return;
153
+ }
154
+ }
155
+ }
156
+ catch (e) {
157
+ console.log('Error checking Redux persistence:', e);
158
+ }
159
+ setIsPersisted(false);
160
+ setPersistedData(null);
103
161
  }
104
- else if (typeof value === 'number') {
105
- valColor = '#D97706';
162
+ checkPersistence();
163
+ }, [activeSliceKey]);
164
+ const handleClearPersistence = () => {
165
+ react_native_1.Alert.alert('Clear Persisted State', `Are you sure you want to delete the persisted storage item for the slice "${activeSliceKey}"? This will clear the value from device storage, but the current active in-memory Redux state will remain unchanged until the next app reload.`, [
166
+ { text: 'Cancel', style: 'cancel' },
167
+ {
168
+ text: 'Delete',
169
+ style: 'destructive',
170
+ onPress: async () => {
171
+ try {
172
+ const storage = (0, settingsStore_1.getCustomStorage)();
173
+ if (!storage)
174
+ return;
175
+ // Delete direct key
176
+ if (typeof storage.removeItem === 'function') {
177
+ await storage.removeItem(`persist:${activeSliceKey}`);
178
+ }
179
+ else {
180
+ await storage.setItem(`persist:${activeSliceKey}`, '');
181
+ }
182
+ // Delete from root key
183
+ let rootRaw = await storage.getItem('persist:root');
184
+ if (rootRaw) {
185
+ const parsed = JSON.parse(rootRaw);
186
+ if (parsed && parsed[activeSliceKey] !== undefined) {
187
+ delete parsed[activeSliceKey];
188
+ await storage.setItem('persist:root', JSON.stringify(parsed));
189
+ }
190
+ }
191
+ setIsPersisted(false);
192
+ setPersistedData(null);
193
+ setSliceDetailTab('live');
194
+ if (react_native_1.Platform.OS === 'android') {
195
+ react_native_1.ToastAndroid.show('Persisted state cleared', react_native_1.ToastAndroid.SHORT);
196
+ }
197
+ else {
198
+ react_native_1.Alert.alert('Cleared', 'Persisted state has been cleared from device storage.');
199
+ }
200
+ }
201
+ catch (err) {
202
+ react_native_1.Alert.alert('Error', 'Failed to clear persisted state.');
203
+ }
204
+ }
205
+ }
206
+ ]);
207
+ };
208
+ const isSearching = search.trim().length > 0;
209
+ (0, react_1.useEffect)(() => {
210
+ onDetailOpenChange?.(activeSliceKey !== null || activeActionId !== null);
211
+ return () => {
212
+ onDetailOpenChange?.(false);
213
+ };
214
+ }, [activeSliceKey, activeActionId, onDetailOpenChange]);
215
+ // Reset details view when tab changes
216
+ const switchTab = (tab) => {
217
+ animateLayout();
218
+ setActiveTab(tab);
219
+ setActiveSliceKey(null);
220
+ setActiveActionId(null);
221
+ setSliceForceOpen(undefined);
222
+ setActionForceOpen(undefined);
223
+ };
224
+ const handleGoBackSlice = () => {
225
+ animateLayout();
226
+ setActiveSliceKey(null);
227
+ setSliceForceOpen(undefined);
228
+ };
229
+ const handleGoBackAction = () => {
230
+ animateLayout();
231
+ setActiveActionId(null);
232
+ setActionForceOpen(undefined);
233
+ };
234
+ // Filtered state keys based on search query
235
+ const filteredStateKeys = (0, react_1.useMemo)(() => {
236
+ if (!state || typeof state !== 'object')
237
+ return [];
238
+ const keys = Object.keys(state);
239
+ let result = keys;
240
+ if (isSearching) {
241
+ result = keys.filter(key => {
242
+ const typeMatch = searchModeType && key.toLowerCase().includes(search.toLowerCase());
243
+ const dataMatch = searchModeData && valueContainsTerm(state[key], search);
244
+ return typeMatch || dataMatch;
245
+ });
106
246
  }
107
- else if (typeof value === 'boolean') {
108
- valColor = '#4F46E5';
247
+ return [...result].sort((a, b) => {
248
+ const comparison = a.localeCompare(b);
249
+ return stateSortAsc ? comparison : -comparison;
250
+ });
251
+ }, [state, search, isSearching, searchModeType, searchModeData, stateSortAsc]);
252
+ // Filtered action history based on search query
253
+ const filteredActionHistory = (0, react_1.useMemo)(() => {
254
+ if (!actionHistory)
255
+ return [];
256
+ let result = actionHistory;
257
+ if (isSearching) {
258
+ result = actionHistory.filter(action => {
259
+ const typeMatch = searchModeType && action.type.toLowerCase().includes(search.toLowerCase());
260
+ const payloadMatch = searchModeData && action.payload && valueContainsTerm(action.payload, search);
261
+ return typeMatch || payloadMatch;
262
+ });
109
263
  }
110
- return (<react_native_1.View style={[reduxValueStyles.treeRow, { paddingLeft: 12 }]}>
111
- <react_native_1.View style={reduxValueStyles.treeLeafConnector}/>
112
- <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', flex: 1, flexWrap: 'wrap', gap: 6 }}>
113
- <react_native_1.Text style={reduxValueStyles.keyText} selectable={true}>
114
- {nameStr}
115
- <react_native_1.Text style={reduxValueStyles.colonText}>: </react_native_1.Text>
116
- <react_native_1.Text style={[reduxValueStyles.valText, { color: valColor }]} selectable={true}>
117
- {valStr}
118
- </react_native_1.Text>
119
- </react_native_1.Text>
120
- {lastAction && (<react_native_1.View style={styles.actionTypeBadge}>
121
- <react_native_1.Text style={styles.actionTypeText} numberOfLines={1}>
122
- {lastAction.type}
264
+ return [...result].sort((a, b) => {
265
+ const comparison = a.id - b.id;
266
+ return actionSortAsc ? comparison : -comparison;
267
+ });
268
+ }, [actionHistory, search, isSearching, searchModeType, searchModeData, actionSortAsc]);
269
+ // Find currently selected action object
270
+ const selectedAction = (0, react_1.useMemo)(() => {
271
+ if (activeActionId === null)
272
+ return null;
273
+ return actionHistory.find(a => a.id === activeActionId) || null;
274
+ }, [activeActionId, actionHistory]);
275
+ if (!state || typeof state !== 'object') {
276
+ return (<react_native_1.View style={styles.errorContainer}>
277
+ <react_native_1.Text style={styles.errorText}>No connected Redux store state found.</react_native_1.Text>
278
+ </react_native_1.View>);
279
+ }
280
+ // ── Render Detail View: State Slice ──
281
+ if (activeTab === 'state' && activeSliceKey !== null) {
282
+ const sliceData = state[activeSliceKey];
283
+ const fieldsCount = typeof sliceData === 'object' && sliceData !== null
284
+ ? Object.keys(sliceData).length
285
+ : 1;
286
+ return (<react_native_1.View style={{ flex: 1 }}>
287
+ {/* Non-scrollable header */}
288
+ <react_native_1.View style={{ paddingHorizontal: 6, paddingTop: 4 }}>
289
+ <react_native_1.View style={styles.apiLikeInfoBar}>
290
+ <react_native_1.View style={styles.apiBadgeRow}>
291
+ <react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: AppColors_1.AppColors.purple }]}>
292
+ <react_native_1.Text style={styles.apiMethodBadgeText}>REDUX</react_native_1.Text>
293
+ </react_native_1.View>
294
+ <react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: AppColors_1.AppColors.purpleShade50, borderWidth: 1, borderColor: AppColors_1.AppColors.purple + '30' }]}>
295
+ <react_native_1.Text style={[styles.apiMethodBadgeText, { color: AppColors_1.AppColors.purple }]}>SLICE</react_native_1.Text>
296
+ </react_native_1.View>
297
+ {isPersisted && (<react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: '#10B981' }]}>
298
+ <react_native_1.Text style={styles.apiMethodBadgeText}>PERSISTED</react_native_1.Text>
299
+ </react_native_1.View>)}
300
+ <react_native_1.View style={styles.apiChip}>
301
+ <react_native_1.Text style={styles.apiChipText}>{(0, helpers_1.getSize)(sliceData)}</react_native_1.Text>
302
+ </react_native_1.View>
303
+ <react_native_1.View style={styles.apiChip}>
304
+ <react_native_1.Text style={styles.apiChipText}>{fieldsCount} {fieldsCount === 1 ? 'field' : 'fields'}</react_native_1.Text>
305
+ </react_native_1.View>
306
+ </react_native_1.View>
307
+
308
+ <react_native_1.Text style={styles.apiTitleText} selectable={true}>{activeSliceKey}</react_native_1.Text>
309
+
310
+ <react_native_1.View style={styles.apiMetaRow}>
311
+ <NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
312
+ <react_native_1.Text style={styles.apiMetaText}>
313
+ Last updated: {lastActionMap[activeSliceKey] ? lastActionMap[activeSliceKey].timestamp : 'Initial'}
123
314
  </react_native_1.Text>
124
- </react_native_1.View>)}
315
+ </react_native_1.View>
316
+ </react_native_1.View>
317
+ </react_native_1.View>
318
+
319
+ {/* Segment Control */}
320
+ <react_native_1.View style={{
321
+ flexDirection: 'row',
322
+ backgroundColor: AppColors_1.AppColors.grayBackground,
323
+ borderRadius: 10,
324
+ padding: 3,
325
+ marginHorizontal: 6,
326
+ marginBottom: 10,
327
+ marginTop: 6,
328
+ borderWidth: 1,
329
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
330
+ }}>
331
+ {(isPersisted ? ['live', 'persisted'] : ['live']).map(tab => {
332
+ const isActive = sliceDetailTab === tab;
333
+ const getLabel = () => {
334
+ if (tab === 'live')
335
+ return 'Live State';
336
+ return `Persisted (${(0, helpers_1.getSize)(persistedData)})`;
337
+ };
338
+ const getIcon = () => {
339
+ const iconColor = isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText;
340
+ if (tab === 'live')
341
+ return <NetworkIcons_1.LayersIcon color={iconColor} size={11}/>;
342
+ return <NetworkIcons_1.CalendarIcon color={iconColor} size={11}/>;
343
+ };
344
+ return (<react_native_1.Pressable key={tab} onPress={() => {
345
+ animateLayout();
346
+ setSliceDetailTab(tab);
347
+ }} style={{
348
+ flex: 1,
349
+ paddingVertical: 6,
350
+ flexDirection: 'row',
351
+ alignItems: 'center',
352
+ justifyContent: 'center',
353
+ borderRadius: 8,
354
+ backgroundColor: isActive ? AppColors_1.AppColors.purple : 'transparent',
355
+ gap: 4,
356
+ }}>
357
+ {getIcon()}
358
+ <react_native_1.Text style={{
359
+ fontFamily: AppFonts_1.AppFonts.interBold,
360
+ fontSize: 10,
361
+ color: isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText,
362
+ }}>
363
+ {getLabel()}
364
+ </react_native_1.Text>
365
+ </react_native_1.Pressable>);
366
+ })}
367
+ </react_native_1.View>
368
+
369
+ {/* Scrollable Tab Content */}
370
+ <react_native_1.View style={{ flex: 1, paddingHorizontal: 6 }}>
371
+ {/* Back button + controls */}
372
+ <react_native_1.View style={styles.contentDetailSubHeader}>
373
+ <TouchableScale_1.default onPress={handleGoBackSlice} style={styles.backBtn} hitSlop={12}>
374
+ <BackChevronIcon color={AppColors_1.AppColors.purple} size={11}/>
375
+ <react_native_1.Text style={styles.backBtnText}>State Slices</react_native_1.Text>
376
+ </TouchableScale_1.default>
377
+
378
+ <react_native_1.View style={styles.detailHeaderActions}>
379
+ {isPersisted && sliceDetailTab === 'persisted' && (<TouchableScale_1.default onPress={handleClearPersistence} style={[styles.detailHeaderBtn, { marginRight: 8 }]} hitSlop={8}>
380
+ <NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.errorColor} size={14}/>
381
+ </TouchableScale_1.default>)}
382
+
383
+ <TouchableScale_1.default onPress={() => {
384
+ animateLayout();
385
+ setSliceForceOpen(prev => (prev === true ? false : prev === false ? undefined : true));
386
+ }} style={styles.detailHeaderBtn} hitSlop={8}>
387
+ <NetworkIcons_1.ExpandCollapseIcon expanded={sliceForceOpen !== false} color={AppColors_1.AppColors.purple} size={14}/>
388
+ </TouchableScale_1.default>
389
+
390
+ <TouchableScale_1.default onPress={() => {
391
+ const dataToCopy = sliceDetailTab === 'live' ? sliceData : persistedData;
392
+ (0, helpers_1.copyToClipboard)(dataToCopy, `Redux Slice '${activeSliceKey}' (${sliceDetailTab})`);
393
+ }} style={styles.detailHeaderBtn} hitSlop={8}>
394
+ <NetworkIcons_1.CopyIcon color={AppColors_1.AppColors.purple} size={14}/>
395
+ </TouchableScale_1.default>
396
+ </react_native_1.View>
397
+ </react_native_1.View>
398
+
399
+ <react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 24 }} showsVerticalScrollIndicator={true}>
400
+ <react_native_1.View style={{ padding: 12 }}>
401
+ <JsonViewer_1.default data={sliceDetailTab === 'live' ? sliceData : (persistedData ?? 'No persisted data')} search={search} forceOpen={sliceForceOpen !== undefined ? sliceForceOpen : (isSearching ? true : undefined)} fullHeight={true}/>
402
+ </react_native_1.View>
403
+ </react_native_1.ScrollView>
125
404
  </react_native_1.View>
126
405
  </react_native_1.View>);
127
406
  }
128
- const keys = Object.keys(value);
129
- const summaryText = isArray
130
- ? `Array [${keys.length}]`
131
- : `Object {${keys.length}}`;
132
- return (<react_native_1.View style={reduxValueStyles.treeNodeBlock}>
133
- <react_native_1.Pressable onPress={() => {
134
- animateTreeLayout();
135
- setExpanded(!expanded);
136
- }} style={reduxValueStyles.treeRow}>
137
- <react_native_1.View style={reduxValueStyles.treeLeafConnector}/>
138
- <AnimatedChevron color={AppColors_1.AppColors.grayTextWeak} expanded={expanded} size={10} style={reduxValueStyles.chevronWrap}/>
139
- <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', flex: 1, flexWrap: 'wrap', gap: 6 }}>
140
- <react_native_1.Text style={reduxValueStyles.keyText} selectable={true}>
141
- {nameStr}
142
- <react_native_1.Text style={reduxValueStyles.colonText}>: </react_native_1.Text>
143
- <react_native_1.Text style={reduxValueStyles.summaryText}>{summaryText}</react_native_1.Text>
144
- </react_native_1.Text>
145
- {lastAction && (<react_native_1.View style={styles.actionTypeBadge}>
146
- <react_native_1.Text style={styles.actionTypeText} numberOfLines={1}>
147
- {lastAction.type}
148
- </react_native_1.Text>
149
- </react_native_1.View>)}
407
+ // ── Render Detail View: Timeline Action ──
408
+ if (activeTab === 'timeline' && selectedAction !== null) {
409
+ const affectedSlices = selectedAction.affectedSlices || [];
410
+ return (<react_native_1.View style={{ flex: 1 }}>
411
+ {/* Non-scrollable header */}
412
+ <react_native_1.View style={{ paddingHorizontal: 6, paddingTop: 4 }}>
413
+ <react_native_1.View style={styles.apiLikeInfoBar}>
414
+ <react_native_1.View style={styles.apiBadgeRow}>
415
+ <react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: AppColors_1.AppColors.purple }]}>
416
+ <react_native_1.Text style={styles.apiMethodBadgeText}>REDUX</react_native_1.Text>
417
+ </react_native_1.View>
418
+ <react_native_1.View style={[styles.apiMethodBadge, { backgroundColor: '#F59E0B' }]}>
419
+ <react_native_1.Text style={styles.apiMethodBadgeText}>ACTION</react_native_1.Text>
420
+ </react_native_1.View>
421
+ <react_native_1.View style={styles.apiChip}>
422
+ <react_native_1.Text style={styles.apiChipText}>#{selectedAction.id}</react_native_1.Text>
423
+ </react_native_1.View>
424
+ <react_native_1.View style={styles.apiChip}>
425
+ <react_native_1.Text style={styles.apiChipText}>{(0, helpers_1.getSize)(selectedAction.payload)}</react_native_1.Text>
426
+ </react_native_1.View>
427
+ </react_native_1.View>
428
+
429
+ <react_native_1.Text style={styles.apiTitleText} selectable={true}>{selectedAction.type}</react_native_1.Text>
430
+
431
+ <react_native_1.View style={styles.apiMetaRow}>
432
+ <NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
433
+ <react_native_1.Text style={styles.apiMetaText}>Dispatched: {selectedAction.timestamp}</react_native_1.Text>
434
+ </react_native_1.View>
435
+ </react_native_1.View>
150
436
  </react_native_1.View>
151
- </react_native_1.Pressable>
152
- {expanded && (<react_native_1.View style={reduxValueStyles.treeChildrenContainer}>
153
- {keys.map(key => (<ReduxValueNode key={key} name={key} value={value[key]} level={level + 1} search={search}/>))}
154
- </react_native_1.View>)}
155
- </react_native_1.View>);
156
- };
157
- const ReduxTreeView = ({ state, lastActionMap, search, }) => {
158
- const [storeExpanded, setStoreExpanded] = (0, react_1.useState)(true);
159
- const [reducerExpanded, setReducerExpanded] = (0, react_1.useState)({});
160
- (0, react_1.useEffect)(() => {
161
- if (react_native_1.Platform.OS === 'android') {
162
- react_native_1.UIManager.setLayoutAnimationEnabledExperimental?.(true);
163
- }
164
- }, []);
165
- if (!state || typeof state !== 'object') {
166
- return (<react_native_1.Text style={{
167
- fontFamily: AppFonts_1.AppFonts.interRegular,
168
- fontSize: 12,
169
- color: AppColors_1.AppColors.grayTextWeak,
170
- padding: 12,
437
+
438
+ {/* Affected Slices Tags list */}
439
+ {affectedSlices.length > 0 && (<react_native_1.View style={styles.detailAffectedTags}>
440
+ <react_native_1.Text style={styles.affectedTagsLabel}>AFFECTED SLICES:</react_native_1.Text>
441
+ <react_native_1.View style={styles.detailTagsList}>
442
+ {affectedSlices.map(slice => (<react_native_1.View key={slice} style={styles.sliceTag}>
443
+ <react_native_1.Text style={styles.sliceTagText}>{slice}</react_native_1.Text>
444
+ </react_native_1.View>))}
445
+ </react_native_1.View>
446
+ </react_native_1.View>)}
447
+
448
+ {/* Segment Control */}
449
+ <react_native_1.View style={{
450
+ flexDirection: 'row',
451
+ backgroundColor: AppColors_1.AppColors.grayBackground,
452
+ borderRadius: 10,
453
+ padding: 3,
454
+ marginHorizontal: 6,
455
+ marginBottom: 10,
456
+ marginTop: 6,
457
+ borderWidth: 1,
458
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
171
459
  }}>
172
- No state object to display.
173
- </react_native_1.Text>);
460
+ {['payload', 'diff', 'state'].map(tab => {
461
+ const isActive = actionSubTab === tab;
462
+ const getLabel = () => {
463
+ if (tab === 'payload')
464
+ return 'Payload';
465
+ if (tab === 'diff')
466
+ return 'Diff Changes';
467
+ return 'Snapshot';
468
+ };
469
+ const getIcon = () => {
470
+ const iconColor = isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText;
471
+ if (tab === 'payload')
472
+ return <NetworkIcons_1.RequestIcon color={iconColor} size={11}/>;
473
+ if (tab === 'diff')
474
+ return <NetworkIcons_1.DiffIcon color={iconColor} size={11}/>;
475
+ return <NetworkIcons_1.LayersIcon color={iconColor} size={11}/>;
476
+ };
477
+ return (<react_native_1.Pressable key={tab} onPress={() => {
478
+ animateLayout();
479
+ setActionSubTab(tab);
480
+ }} style={{
481
+ flex: 1,
482
+ paddingVertical: 6,
483
+ flexDirection: 'row',
484
+ alignItems: 'center',
485
+ justifyContent: 'center',
486
+ borderRadius: 8,
487
+ backgroundColor: isActive ? AppColors_1.AppColors.purple : 'transparent',
488
+ gap: 4,
489
+ }}>
490
+ {getIcon()}
491
+ <react_native_1.Text style={{
492
+ fontFamily: AppFonts_1.AppFonts.interBold,
493
+ fontSize: 10,
494
+ color: isActive ? '#FFFFFF' : AppColors_1.AppColors.grayText,
495
+ }}>
496
+ {getLabel()}
497
+ </react_native_1.Text>
498
+ </react_native_1.Pressable>);
499
+ })}
500
+ </react_native_1.View>
501
+
502
+ {/* Scrollable Tab Content */}
503
+ <react_native_1.View style={{ flex: 1, paddingHorizontal: 6 }}>
504
+ {/* Back button + controls */}
505
+ <react_native_1.View style={styles.contentDetailSubHeader}>
506
+ <TouchableScale_1.default onPress={handleGoBackAction} style={styles.backBtn} hitSlop={12}>
507
+ <BackChevronIcon color={AppColors_1.AppColors.purple} size={11}/>
508
+ <react_native_1.Text style={styles.backBtnText}>Actions</react_native_1.Text>
509
+ </TouchableScale_1.default>
510
+
511
+ {(actionSubTab === 'payload' || actionSubTab === 'state') && (<react_native_1.View style={styles.detailHeaderActions}>
512
+ <TouchableScale_1.default onPress={() => {
513
+ animateLayout();
514
+ setActionForceOpen(prev => (prev === true ? false : prev === false ? undefined : true));
515
+ }} style={styles.detailHeaderBtn} hitSlop={8}>
516
+ <NetworkIcons_1.ExpandCollapseIcon expanded={actionForceOpen !== false} color={AppColors_1.AppColors.purple} size={14}/>
517
+ </TouchableScale_1.default>
518
+
519
+ <TouchableScale_1.default onPress={() => {
520
+ const dataToCopy = actionSubTab === 'payload' ? selectedAction.payload : selectedAction.nextState;
521
+ (0, helpers_1.copyToClipboard)(dataToCopy, actionSubTab === 'payload' ? 'Action payload' : 'State snapshot');
522
+ }} style={styles.detailHeaderBtn} hitSlop={8}>
523
+ <NetworkIcons_1.CopyIcon color={AppColors_1.AppColors.purple} size={14}/>
524
+ </TouchableScale_1.default>
525
+ </react_native_1.View>)}
526
+ </react_native_1.View>
527
+
528
+ <react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 24 }} showsVerticalScrollIndicator={true}>
529
+ {actionSubTab === 'payload' && (<react_native_1.View style={{ padding: 12 }}>
530
+ <JsonViewer_1.default data={selectedAction.payload ?? 'No payload data'} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>
531
+ </react_native_1.View>)}
532
+
533
+ {actionSubTab === 'diff' && (<react_native_1.View style={{ padding: 12 }}>
534
+ <DiffViewer_1.default oldData={selectedAction.prevState} newData={selectedAction.nextState}/>
535
+ </react_native_1.View>)}
536
+
537
+ {actionSubTab === 'state' && (<react_native_1.View style={{ padding: 12 }}>
538
+ <JsonViewer_1.default data={selectedAction.nextState} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>
539
+ </react_native_1.View>)}
540
+ </react_native_1.ScrollView>
541
+ </react_native_1.View>
542
+ </react_native_1.View>);
174
543
  }
175
- const reducers = Object.keys(state);
176
- const toggleReducer = (key) => {
177
- animateTreeLayout();
178
- setReducerExpanded(prev => ({
179
- ...prev,
180
- [key]: !prev[key],
181
- }));
182
- };
544
+ // ── Render List Views (Default) ──
183
545
  return (<react_native_1.View style={styles.container}>
184
- {/* Root Node: Store */}
185
- <react_native_1.Pressable onPress={() => {
186
- animateTreeLayout();
187
- setStoreExpanded(!storeExpanded);
188
- }} style={styles.storeHeader}>
189
- <AnimatedChevron color="#FFFFFF" expanded={storeExpanded} size={12} style={styles.chevronWrap}/>
190
- <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
191
- <exports.ReduxStoreIcon color="#FFFFFF" size={14}/>
192
- <react_native_1.Text style={styles.storeTitle}>Redux Store</react_native_1.Text>
546
+ {/* ── Control Bar ── */}
547
+ <react_native_1.View style={styles.toolbar}>
548
+ <react_native_1.View style={styles.statusSection}>
549
+ <react_native_1.View style={[styles.statusBadge, autoRefresh ? styles.statusBadgeActive : styles.statusBadgePaused]}>
550
+ <react_native_1.View style={[styles.statusDot, autoRefresh ? styles.statusDotActive : styles.statusDotPaused]}/>
551
+ <react_native_1.Text style={[styles.statusBadgeText, autoRefresh ? styles.statusTextActive : styles.statusTextPaused]}>
552
+ {autoRefresh ? 'LIVE' : 'PAUSED'}
553
+ </react_native_1.Text>
554
+ </react_native_1.View>
193
555
  </react_native_1.View>
194
- <react_native_1.View style={styles.badge}>
195
- <react_native_1.Text style={styles.badgeText}>{reducers.length} Slices</react_native_1.Text>
556
+
557
+ <react_native_1.View style={styles.toolbarActions}>
558
+ {/* Sorting Toggle Button */}
559
+ <TouchableScale_1.default onPress={() => {
560
+ animateLayout();
561
+ if (activeTab === 'state') {
562
+ setStateSortAsc(prev => !prev);
563
+ }
564
+ else {
565
+ setActionSortAsc(prev => !prev);
566
+ }
567
+ }} style={styles.iconBtn} hitSlop={8}>
568
+ <NetworkIcons_1.SortIcon ascending={activeTab === 'state' ? stateSortAsc : actionSortAsc} color={AppColors_1.AppColors.purple} size={15}/>
569
+ </TouchableScale_1.default>
570
+
571
+ {onToggleAutoRefresh && (<TouchableScale_1.default onPress={onToggleAutoRefresh} style={styles.iconBtn} hitSlop={8}>
572
+ <NetworkIcons_1.HeaderPauseIcon isPaused={!autoRefresh} color={AppColors_1.AppColors.purple} size={15}/>
573
+ </TouchableScale_1.default>)}
574
+ {onClearHistory && (<TouchableScale_1.default onPress={onClearHistory} style={[styles.iconBtn, { borderColor: AppColors_1.AppColors.errorColor + '40', backgroundColor: AppColors_1.AppColors.errorColor + '08' }]} hitSlop={8}>
575
+ <NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.errorColor} size={15}/>
576
+ </TouchableScale_1.default>)}
196
577
  </react_native_1.View>
197
- </react_native_1.Pressable>
578
+ </react_native_1.View>
579
+
580
+ {/* ── Search Bar ── */}
581
+ {onSearchChange && (<react_native_1.View style={styles.searchContainer}>
582
+ <react_native_1.View style={styles.searchBar}>
583
+ <NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
584
+ <react_native_1.TextInput placeholder="Search keys, values, or action payloads..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={search} onChangeText={onSearchChange} style={styles.searchInput} autoCorrect={false} autoCapitalize="none"/>
585
+ {search.length > 0 && (<TouchableScale_1.default onPress={() => onSearchChange('')} hitSlop={10}>
586
+ <NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
587
+ </TouchableScale_1.default>)}
588
+ </react_native_1.View>
589
+ <react_native_1.View style={styles.filterChipRow}>
590
+ <react_native_1.Text style={styles.filterChipLabel}>FILTER BY:</react_native_1.Text>
591
+ <react_native_1.Pressable onPress={() => {
592
+ animateLayout();
593
+ if (searchModeType && !searchModeData)
594
+ return; // Prevent disabling both
595
+ setSearchModeType(!searchModeType);
596
+ }} style={[styles.filterChip, searchModeType && styles.filterChipActive]}>
597
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
598
+ <NetworkIcons_1.SignalIcon color={searchModeType ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={11}/>
599
+ <react_native_1.Text style={[styles.filterChipText, searchModeType && styles.filterChipTextActive]}>
600
+ Type / Key
601
+ </react_native_1.Text>
602
+ </react_native_1.View>
603
+ </react_native_1.Pressable>
604
+ <react_native_1.Pressable onPress={() => {
605
+ animateLayout();
606
+ if (!searchModeType && searchModeData)
607
+ return; // Prevent disabling both
608
+ setSearchModeData(!searchModeData);
609
+ }} style={[styles.filterChip, searchModeData && styles.filterChipActive]}>
610
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
611
+ <NetworkIcons_1.LayersIcon color={searchModeData ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={11}/>
612
+ <react_native_1.Text style={[styles.filterChipText, searchModeData && styles.filterChipTextActive]}>
613
+ Payload Data
614
+ </react_native_1.Text>
615
+ </react_native_1.View>
616
+ </react_native_1.Pressable>
617
+ </react_native_1.View>
618
+ </react_native_1.View>)}
619
+
620
+ {/* ── Tab Selector ── */}
621
+ <react_native_1.View style={styles.tabContainer}>
622
+ <react_native_1.Pressable style={[styles.tabButton, activeTab === 'state' && styles.tabButtonActive]} onPress={() => switchTab('state')}>
623
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
624
+ <NetworkIcons_1.LayersIcon color={activeTab === 'state' ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={12}/>
625
+ <react_native_1.Text style={[styles.tabButtonText, activeTab === 'state' && styles.tabButtonTextActive]}>
626
+ State Slices ({filteredStateKeys.length})
627
+ </react_native_1.Text>
628
+ </react_native_1.View>
629
+ </react_native_1.Pressable>
630
+ <react_native_1.Pressable style={[styles.tabButton, activeTab === 'timeline' && styles.tabButtonActive]} onPress={() => switchTab('timeline')}>
631
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
632
+ <NetworkIcons_1.TerminalIcon color={activeTab === 'timeline' ? AppColors_1.AppColors.purple : AppColors_1.AppColors.grayText} size={12}/>
633
+ <react_native_1.Text style={[styles.tabButtonText, activeTab === 'timeline' && styles.tabButtonTextActive]}>
634
+ Actions ({filteredActionHistory.length})
635
+ </react_native_1.Text>
636
+ </react_native_1.View>
637
+ </react_native_1.Pressable>
638
+ </react_native_1.View>
198
639
 
199
- {storeExpanded && (<react_native_1.View style={styles.storeChildren}>
200
- {reducers.map((reducerKey, index) => {
201
- const isLastReducer = index === reducers.length - 1;
202
- const isExpanded = !!reducerExpanded[reducerKey];
640
+ {/* ── State List View ── */}
641
+ {activeTab === 'state' && (<react_native_1.ScrollView style={styles.scrollList} contentContainerStyle={styles.scrollContent}>
642
+ {filteredStateKeys.length === 0 ? (<react_native_1.View style={styles.emptyState}>
643
+ <react_native_1.Text style={styles.emptyStateText}>
644
+ {isSearching ? 'No store slices match your search.' : 'Redux store contains no state.'}
645
+ </react_native_1.Text>
646
+ </react_native_1.View>) : (filteredStateKeys.map(reducerKey => {
203
647
  const sliceData = state[reducerKey];
648
+ const fieldsCount = typeof sliceData === 'object' && sliceData !== null
649
+ ? Object.keys(sliceData).length
650
+ : 1;
204
651
  const lastAction = lastActionMap[reducerKey];
205
- return (<react_native_1.View key={reducerKey} style={styles.reducerContainer}>
206
- {/* Visual Branch Line for Reducer */}
207
- <react_native_1.View style={[
208
- styles.reducerVerticalLine,
209
- isLastReducer && !isExpanded && { bottom: '50%' },
210
- ]}/>
652
+ const lastUpdatedTime = lastAction ? lastAction.timestamp : 'Initial';
653
+ return (<TouchableScale_1.default key={reducerKey} onPress={() => {
654
+ animateLayout();
655
+ setActiveSliceKey(reducerKey);
656
+ }} style={styles.listRow}>
657
+ <react_native_1.View style={styles.sliceIcon}>
658
+ <NetworkIcons_1.FolderIcon color={AppColors_1.AppColors.purple} size={11}/>
659
+ </react_native_1.View>
660
+ <react_native_1.View style={styles.rowMain}>
661
+ <react_native_1.Text style={styles.rowTitle}>{reducerKey}</react_native_1.Text>
662
+ <react_native_1.Text style={styles.rowSub}>
663
+ {(0, helpers_1.getSize)(sliceData)} • {fieldsCount} {fieldsCount === 1 ? 'field' : 'fields'} • Updated: {lastUpdatedTime}
664
+ </react_native_1.Text>
665
+ </react_native_1.View>
666
+ <ForwardChevronIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
667
+ </TouchableScale_1.default>);
668
+ }))}
669
+ </react_native_1.ScrollView>)}
211
670
 
212
- {/* Reducer Header */}
213
- <react_native_1.Pressable onPress={() => toggleReducer(reducerKey)} style={styles.reducerHeader}>
214
- <react_native_1.View style={styles.reducerHorizontalLine}/>
215
- <AnimatedChevron color={AppColors_1.AppColors.purple} expanded={isExpanded} size={10} style={styles.chevronWrap}/>
216
- <react_native_1.View style={styles.iconWrap}>
217
- <FolderIcon color={AppColors_1.AppColors.purple} size={11}/>
671
+ {/* ── Timeline List View ── */}
672
+ {activeTab === 'timeline' && (<react_native_1.ScrollView style={styles.scrollList} contentContainerStyle={styles.scrollContent}>
673
+ {filteredActionHistory.length === 0 ? (<react_native_1.View style={styles.emptyState}>
674
+ <react_native_1.Text style={styles.emptyStateText}>
675
+ {isSearching
676
+ ? 'No actions match your search.'
677
+ : 'No actions dispatched yet. Trigger an action in the app to populate history.'}
678
+ </react_native_1.Text>
679
+ </react_native_1.View>) : (filteredActionHistory.map((action, index) => {
680
+ const id = action.id;
681
+ const affectedSlices = action.affectedSlices || [];
682
+ return (<TouchableScale_1.default key={id} onPress={() => {
683
+ animateLayout();
684
+ setActiveActionId(id);
685
+ }} style={styles.listRow}>
686
+ <react_native_1.View style={styles.seqBadge}>
687
+ <react_native_1.Text style={styles.seqText}>#{action.id}</react_native_1.Text>
218
688
  </react_native_1.View>
219
- <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', flex: 1, flexWrap: 'wrap', gap: 6 }}>
220
- <react_native_1.Text style={styles.reducerText}>{reducerKey}</react_native_1.Text>
221
- {lastAction && (<react_native_1.View style={styles.actionTypeBadge}>
222
- <react_native_1.Text style={styles.actionTypeText} numberOfLines={1}>
223
- {lastAction.type}
224
- </react_native_1.Text>
689
+ <react_native_1.View style={styles.rowMain}>
690
+ <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
691
+ <NetworkIcons_1.TerminalIcon color={AppColors_1.AppColors.purple} size={11}/>
692
+ <react_native_1.Text style={styles.actionTitleText} numberOfLines={1}>{action.type}</react_native_1.Text>
693
+ </react_native_1.View>
694
+ <react_native_1.View style={styles.actionMetaRow}>
695
+ <NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.grayTextWeak} size={9}/>
696
+ <react_native_1.Text style={styles.actionTimeText}>{action.timestamp} • {(0, helpers_1.getSize)(action.payload)}</react_native_1.Text>
697
+ </react_native_1.View>
698
+ {affectedSlices.length > 0 && (<react_native_1.View style={styles.tagsContainer}>
699
+ {affectedSlices.map(slice => (<react_native_1.View key={slice} style={styles.sliceTagMini}>
700
+ <react_native_1.Text style={styles.sliceTagMiniText}>{slice}</react_native_1.Text>
701
+ </react_native_1.View>))}
225
702
  </react_native_1.View>)}
226
703
  </react_native_1.View>
227
- </react_native_1.Pressable>
228
-
229
- {isExpanded && (<react_native_1.View style={styles.reducerChildren}>
230
- {/* Vertical line connecting children */}
231
- <react_native_1.View style={styles.childrenVerticalLine}/>
232
- {typeof sliceData === 'object' && sliceData !== null ? (Object.keys(sliceData).map(k => (<ReduxValueNode key={k} name={k} value={sliceData[k]} level={0} search={search}/>))) : (<ReduxValueNode name={reducerKey} value={sliceData} level={0} search={search} lastAction={lastAction}/>)}
233
- </react_native_1.View>)}
234
- </react_native_1.View>);
235
- })}
236
- </react_native_1.View>)}
704
+ <ForwardChevronIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
705
+ </TouchableScale_1.default>);
706
+ }))}
707
+ </react_native_1.ScrollView>)}
237
708
  </react_native_1.View>);
238
709
  };
239
710
  exports.ReduxTreeView = ReduxTreeView;
240
- const reduxValueStyles = react_native_1.StyleSheet.create({
241
- treeNodeBlock: {
242
- marginTop: 4,
711
+ const styles = react_native_1.StyleSheet.create({
712
+ container: {
713
+ flex: 1,
714
+ backgroundColor: AppColors_1.AppColors.grayBackground,
715
+ },
716
+ scrollList: {
717
+ flex: 1,
718
+ },
719
+ errorContainer: {
720
+ padding: 24,
721
+ alignItems: 'center',
722
+ },
723
+ errorText: {
724
+ fontFamily: AppFonts_1.AppFonts.interRegular,
725
+ fontSize: 12,
726
+ color: AppColors_1.AppColors.grayTextWeak,
727
+ },
728
+ toolbar: {
729
+ flexDirection: 'row',
730
+ alignItems: 'center',
731
+ justifyContent: 'space-between',
732
+ paddingHorizontal: 12,
733
+ paddingVertical: 10,
734
+ backgroundColor: AppColors_1.AppColors.primaryLight,
735
+ borderBottomWidth: 1,
736
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
243
737
  },
244
- treeRow: {
738
+ statusSection: {
245
739
  flexDirection: 'row',
246
740
  alignItems: 'center',
741
+ },
742
+ statusBadge: {
743
+ flexDirection: 'row',
744
+ alignItems: 'center',
745
+ paddingHorizontal: 8,
247
746
  paddingVertical: 3,
248
- gap: 4,
249
- position: 'relative',
250
- },
251
- treeLeafConnector: {
252
- position: 'absolute',
253
- left: -12,
254
- top: '50%',
255
- width: 8,
256
- height: 1,
747
+ borderRadius: 12,
748
+ borderWidth: 1,
749
+ },
750
+ statusBadgeActive: {
751
+ backgroundColor: AppColors_1.AppColors.greenStatus,
752
+ borderColor: AppColors_1.AppColors.greenColor + '30',
753
+ },
754
+ statusBadgePaused: {
755
+ backgroundColor: AppColors_1.AppColors.grayBackground,
756
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
757
+ },
758
+ statusDot: {
759
+ width: 6,
760
+ height: 6,
761
+ borderRadius: 3,
762
+ marginRight: 6,
763
+ },
764
+ statusDotActive: {
765
+ backgroundColor: AppColors_1.AppColors.greenBaggageText,
766
+ },
767
+ statusDotPaused: {
768
+ backgroundColor: AppColors_1.AppColors.grayTextWeak,
769
+ },
770
+ statusBadgeText: {
771
+ fontFamily: AppFonts_1.AppFonts.interBold,
772
+ fontSize: 9,
773
+ letterSpacing: 0.5,
774
+ },
775
+ statusTextActive: {
776
+ color: AppColors_1.AppColors.greenBaggageText,
777
+ },
778
+ statusTextPaused: {
779
+ color: AppColors_1.AppColors.grayText,
780
+ },
781
+ toolbarActions: {
782
+ flexDirection: 'row',
783
+ alignItems: 'center',
784
+ gap: 8,
785
+ },
786
+ iconBtn: {
787
+ width: 28,
788
+ height: 28,
789
+ borderRadius: 6,
790
+ borderWidth: 1,
791
+ borderColor: AppColors_1.AppColors.purple + '40',
792
+ backgroundColor: AppColors_1.AppColors.purpleShade50,
793
+ alignItems: 'center',
794
+ justifyContent: 'center',
795
+ },
796
+ searchContainer: {
797
+ backgroundColor: AppColors_1.AppColors.primaryLight,
257
798
  borderBottomWidth: 1,
258
799
  borderBottomColor: AppColors_1.AppColors.dividerColor,
259
- opacity: 0.5,
800
+ paddingBottom: 10,
801
+ },
802
+ searchBar: {
803
+ flexDirection: 'row',
804
+ alignItems: 'center',
805
+ backgroundColor: AppColors_1.AppColors.grayBackground,
806
+ borderRadius: 8,
807
+ marginHorizontal: 12,
808
+ marginTop: 10,
809
+ marginBottom: 8,
810
+ paddingHorizontal: 10,
811
+ borderWidth: 1,
812
+ borderColor: AppColors_1.AppColors.dividerColor,
813
+ height: 36,
260
814
  },
261
- treeChildrenContainer: {
262
- paddingLeft: 14,
263
- borderLeftWidth: 1,
264
- borderLeftColor: AppColors_1.AppColors.dividerColor,
815
+ filterChipRow: {
816
+ flexDirection: 'row',
817
+ alignItems: 'center',
818
+ paddingHorizontal: 12,
819
+ gap: 8,
820
+ },
821
+ filterChipLabel: {
822
+ fontFamily: AppFonts_1.AppFonts.interBold,
823
+ fontSize: 9,
824
+ color: AppColors_1.AppColors.grayTextWeak,
825
+ letterSpacing: 0.5,
826
+ marginRight: 2,
827
+ },
828
+ filterChip: {
829
+ paddingHorizontal: 10,
830
+ paddingVertical: 4,
831
+ borderRadius: 12,
832
+ backgroundColor: AppColors_1.AppColors.grayBackground,
833
+ borderWidth: 1,
834
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
835
+ },
836
+ filterChipActive: {
837
+ backgroundColor: AppColors_1.AppColors.purpleShade50,
838
+ borderColor: AppColors_1.AppColors.purple,
839
+ },
840
+ filterChipText: {
841
+ fontFamily: AppFonts_1.AppFonts.interMedium,
842
+ fontSize: 10,
843
+ color: AppColors_1.AppColors.grayText,
844
+ },
845
+ filterChipTextActive: {
846
+ color: AppColors_1.AppColors.purple,
847
+ fontFamily: AppFonts_1.AppFonts.interBold,
848
+ },
849
+ searchInput: {
850
+ flex: 1,
851
+ fontFamily: AppFonts_1.AppFonts.interRegular,
852
+ fontSize: 12,
853
+ color: AppColors_1.AppColors.grayTextStrong,
265
854
  marginLeft: 6,
855
+ padding: 0,
856
+ },
857
+ tabContainer: {
858
+ flexDirection: 'row',
859
+ backgroundColor: AppColors_1.AppColors.dividerColor,
860
+ borderRadius: 8,
861
+ padding: 3,
862
+ marginHorizontal: 12,
863
+ marginTop: 10,
864
+ marginBottom: 10,
266
865
  },
267
- chevronWrap: {
268
- width: 10,
269
- height: 10,
866
+ tabButton: {
867
+ flex: 1,
868
+ paddingVertical: 7,
270
869
  alignItems: 'center',
271
870
  justifyContent: 'center',
871
+ borderRadius: 6,
272
872
  },
273
- keyText: {
873
+ tabButtonActive: {
874
+ backgroundColor: AppColors_1.AppColors.primaryLight,
875
+ shadowColor: AppColors_1.AppColors.shadowColorString,
876
+ shadowOffset: { width: 0, height: 1 },
877
+ shadowOpacity: 0.08,
878
+ shadowRadius: 2,
879
+ elevation: 2,
880
+ },
881
+ tabButtonText: {
274
882
  fontFamily: AppFonts_1.AppFonts.interMedium,
275
- fontSize: 11.5,
276
- color: AppColors_1.AppColors.grayTextStrong,
883
+ fontSize: 12,
884
+ color: AppColors_1.AppColors.grayText,
277
885
  },
278
- colonText: {
279
- color: AppColors_1.AppColors.grayTextWeak,
886
+ tabButtonTextActive: {
887
+ color: AppColors_1.AppColors.purple,
888
+ fontFamily: AppFonts_1.AppFonts.interBold,
280
889
  },
281
- valText: {
282
- fontFamily: AppFonts_1.AppFonts.interRegular,
283
- fontSize: 11.5,
890
+ scrollContent: {
891
+ paddingBottom: 24,
892
+ paddingHorizontal: 12,
893
+ },
894
+ emptyState: {
895
+ padding: 24,
896
+ alignItems: 'center',
284
897
  },
285
- summaryText: {
898
+ emptyStateText: {
286
899
  fontFamily: AppFonts_1.AppFonts.interRegular,
287
- fontSize: 11,
900
+ fontSize: 12,
288
901
  color: AppColors_1.AppColors.grayTextWeak,
902
+ textAlign: 'center',
289
903
  },
290
- });
291
- const styles = react_native_1.StyleSheet.create({
292
- container: {
293
- flex: 1,
294
- },
295
- storeHeader: {
904
+ listRow: {
296
905
  flexDirection: 'row',
297
906
  alignItems: 'center',
298
- backgroundColor: AppColors_1.AppColors.purple,
299
- borderRadius: 8,
300
- paddingVertical: 10,
907
+ backgroundColor: AppColors_1.AppColors.primaryLight,
301
908
  paddingHorizontal: 12,
302
- gap: 8,
909
+ paddingVertical: 14,
910
+ borderRadius: 10,
911
+ borderWidth: 1,
912
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
913
+ marginBottom: 8,
914
+ shadowColor: AppColors_1.AppColors.shadowColorString,
915
+ shadowOffset: { width: 0, height: 1 },
916
+ shadowOpacity: 0.03,
917
+ shadowRadius: 2,
918
+ elevation: 1,
303
919
  },
304
- chevronWrap: {
305
- width: 12,
306
- height: 12,
307
- alignItems: 'center',
308
- justifyContent: 'center',
920
+ rowMain: {
921
+ flex: 1,
922
+ marginLeft: 10,
309
923
  },
310
- storeTitle: {
924
+ rowTitle: {
311
925
  fontFamily: AppFonts_1.AppFonts.interBold,
312
- fontSize: 14,
313
- color: '#FFFFFF',
926
+ fontSize: 13.5,
927
+ color: AppColors_1.AppColors.primaryBlack,
314
928
  },
315
- badge: {
316
- backgroundColor: 'rgba(255,255,255,0.2)',
317
- paddingHorizontal: 8,
929
+ rowSub: {
930
+ fontFamily: AppFonts_1.AppFonts.interRegular,
931
+ fontSize: 10,
932
+ color: AppColors_1.AppColors.grayTextWeak,
933
+ marginTop: 2,
934
+ },
935
+ sliceIcon: {
936
+ width: 22,
937
+ height: 22,
938
+ borderRadius: 6,
939
+ backgroundColor: AppColors_1.AppColors.purpleShade50,
940
+ alignItems: 'center',
941
+ justifyContent: 'center',
942
+ },
943
+ seqBadge: {
944
+ backgroundColor: AppColors_1.AppColors.grayBackground,
945
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
946
+ borderWidth: 1,
947
+ borderRadius: 4,
948
+ paddingHorizontal: 5,
318
949
  paddingVertical: 2,
319
- borderRadius: 12,
320
- marginLeft: 'auto',
950
+ alignItems: 'center',
951
+ justifyContent: 'center',
952
+ minWidth: 28,
321
953
  },
322
- badgeText: {
954
+ seqText: {
323
955
  fontFamily: AppFonts_1.AppFonts.interBold,
324
- fontSize: 10,
325
- color: '#FFFFFF',
956
+ fontSize: 9.5,
957
+ color: AppColors_1.AppColors.grayText,
958
+ },
959
+ actionTitleText: {
960
+ fontFamily: AppFonts_1.AppFonts.interBold,
961
+ fontSize: 13,
962
+ color: AppColors_1.AppColors.purple,
963
+ },
964
+ actionMetaRow: {
965
+ flexDirection: 'row',
966
+ alignItems: 'center',
967
+ gap: 4,
968
+ marginTop: 2,
969
+ },
970
+ actionTimeText: {
971
+ fontFamily: AppFonts_1.AppFonts.interRegular,
972
+ fontSize: 9.5,
973
+ color: AppColors_1.AppColors.grayTextWeak,
326
974
  },
327
- storeChildren: {
328
- paddingLeft: 12,
975
+ tagsContainer: {
976
+ flexDirection: 'row',
977
+ flexWrap: 'wrap',
978
+ gap: 4,
329
979
  marginTop: 4,
330
980
  },
331
- reducerContainer: {
332
- position: 'relative',
333
- paddingLeft: 16,
334
- paddingVertical: 4,
981
+ sliceTagMini: {
982
+ backgroundColor: AppColors_1.AppColors.purpleShade50,
983
+ borderColor: AppColors_1.AppColors.purple + '20',
984
+ borderWidth: 1,
985
+ borderRadius: 3,
986
+ paddingHorizontal: 4,
987
+ paddingVertical: 0.5,
335
988
  },
336
- reducerVerticalLine: {
337
- position: 'absolute',
338
- left: 0,
339
- top: 0,
340
- bottom: 0,
341
- width: 1,
342
- backgroundColor: AppColors_1.AppColors.dividerColor,
989
+ sliceTagMiniText: {
990
+ fontFamily: AppFonts_1.AppFonts.interMedium,
991
+ fontSize: 8.5,
992
+ color: AppColors_1.AppColors.purple,
343
993
  },
344
- reducerHorizontalLine: {
345
- position: 'absolute',
346
- left: -16,
347
- top: '50%',
348
- width: 16,
349
- height: 1,
350
- backgroundColor: AppColors_1.AppColors.dividerColor,
994
+ // ── Detail Views Styles ──
995
+ detailHeaderBar: {
996
+ flexDirection: 'row',
997
+ alignItems: 'center',
998
+ paddingHorizontal: 12,
999
+ paddingVertical: 12,
1000
+ backgroundColor: AppColors_1.AppColors.primaryLight,
1001
+ borderBottomWidth: 1,
1002
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
351
1003
  },
352
- reducerHeader: {
1004
+ backBtn: {
353
1005
  flexDirection: 'row',
354
1006
  alignItems: 'center',
355
1007
  paddingVertical: 6,
1008
+ paddingRight: 8,
1009
+ },
1010
+ backBtnText: {
1011
+ fontFamily: AppFonts_1.AppFonts.interBold,
1012
+ fontSize: 12.5,
1013
+ color: AppColors_1.AppColors.purple,
1014
+ },
1015
+ detailHeaderInfo: {
1016
+ flex: 1,
1017
+ marginLeft: 10,
1018
+ marginRight: 10,
1019
+ },
1020
+ detailTitle: {
1021
+ fontFamily: AppFonts_1.AppFonts.interBold,
1022
+ fontSize: 13.5,
1023
+ color: AppColors_1.AppColors.primaryBlack,
1024
+ },
1025
+ detailSub: {
1026
+ fontFamily: AppFonts_1.AppFonts.interRegular,
1027
+ fontSize: 10,
1028
+ color: AppColors_1.AppColors.grayTextWeak,
1029
+ marginTop: 2,
1030
+ },
1031
+ detailHeaderActions: {
1032
+ flexDirection: 'row',
1033
+ alignItems: 'center',
356
1034
  gap: 6,
357
1035
  },
358
- iconWrap: {
359
- width: 18,
360
- height: 18,
361
- borderRadius: 4,
1036
+ detailHeaderBtn: {
1037
+ padding: 6,
1038
+ borderRadius: 6,
1039
+ borderWidth: 1,
1040
+ borderColor: AppColors_1.AppColors.purple + '20',
362
1041
  backgroundColor: AppColors_1.AppColors.purpleShade50,
363
1042
  alignItems: 'center',
364
1043
  justifyContent: 'center',
1044
+ width: 28,
1045
+ height: 28,
1046
+ },
1047
+ detailCopyBtn: {
1048
+ padding: 6,
1049
+ borderRadius: 6,
1050
+ borderWidth: 1,
1051
+ borderColor: AppColors_1.AppColors.purple + '20',
1052
+ backgroundColor: AppColors_1.AppColors.purpleShade50,
1053
+ },
1054
+ detailTimeRow: {
1055
+ flexDirection: 'row',
1056
+ alignItems: 'center',
1057
+ gap: 4,
1058
+ marginTop: 1,
1059
+ },
1060
+ detailTimeText: {
1061
+ fontFamily: AppFonts_1.AppFonts.interRegular,
1062
+ fontSize: 10,
1063
+ color: AppColors_1.AppColors.grayTextWeak,
365
1064
  },
366
- reducerText: {
1065
+ detailAffectedTags: {
1066
+ paddingHorizontal: 12,
1067
+ paddingVertical: 8,
1068
+ backgroundColor: AppColors_1.AppColors.grayBackground,
1069
+ borderBottomWidth: 1,
1070
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
1071
+ },
1072
+ affectedTagsLabel: {
367
1073
  fontFamily: AppFonts_1.AppFonts.interBold,
368
- fontSize: 13,
369
- color: AppColors_1.AppColors.primaryBlack,
1074
+ fontSize: 9,
1075
+ color: AppColors_1.AppColors.grayTextWeak,
1076
+ letterSpacing: 0.5,
1077
+ marginBottom: 4,
370
1078
  },
371
- reducerChildren: {
372
- paddingLeft: 20,
373
- position: 'relative',
374
- marginTop: 4,
375
- gap: 10,
376
- },
377
- childrenVerticalLine: {
378
- position: 'absolute',
379
- left: 8,
380
- top: 0,
381
- bottom: 16,
382
- width: 1,
383
- backgroundColor: AppColors_1.AppColors.dividerColor,
1079
+ detailTagsList: {
1080
+ flexDirection: 'row',
1081
+ flexWrap: 'wrap',
1082
+ gap: 4,
384
1083
  },
385
- actionTypeBadge: {
386
- backgroundColor: '#FCE7F3',
387
- borderColor: '#FBCFE8',
1084
+ sliceTag: {
1085
+ backgroundColor: AppColors_1.AppColors.purpleShade50,
1086
+ borderColor: AppColors_1.AppColors.purple + '20',
388
1087
  borderWidth: 1,
389
- borderRadius: 6,
1088
+ borderRadius: 4,
390
1089
  paddingHorizontal: 6,
391
- paddingVertical: 2,
392
- alignSelf: 'flex-start',
1090
+ paddingVertical: 1.5,
1091
+ },
1092
+ sliceTagText: {
1093
+ fontFamily: AppFonts_1.AppFonts.interMedium,
1094
+ fontSize: 9.5,
1095
+ color: AppColors_1.AppColors.purple,
1096
+ },
1097
+ subTabRow: {
1098
+ flexDirection: 'row',
1099
+ padding: 8,
1100
+ gap: 8,
1101
+ backgroundColor: AppColors_1.AppColors.primaryLight,
1102
+ borderBottomWidth: 1,
1103
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
1104
+ },
1105
+ subTabPill: {
1106
+ paddingHorizontal: 12,
1107
+ paddingVertical: 5,
1108
+ borderRadius: 12,
1109
+ backgroundColor: AppColors_1.AppColors.grayBackground,
1110
+ borderWidth: 1,
1111
+ borderColor: AppColors_1.AppColors.grayBorderSecondary,
1112
+ },
1113
+ subTabPillActive: {
1114
+ backgroundColor: AppColors_1.AppColors.purple,
1115
+ borderColor: AppColors_1.AppColors.purple,
1116
+ },
1117
+ subTabPillText: {
1118
+ fontFamily: AppFonts_1.AppFonts.interMedium,
1119
+ fontSize: 10.5,
1120
+ color: AppColors_1.AppColors.grayText,
1121
+ },
1122
+ subTabPillTextActive: {
1123
+ color: '#FFFFFF',
1124
+ fontFamily: AppFonts_1.AppFonts.interBold,
393
1125
  },
394
- actionTypeText: {
1126
+ detailScrollContent: {
1127
+ paddingBottom: 24,
1128
+ },
1129
+ jsonViewerContainer: {
1130
+ paddingHorizontal: 12,
1131
+ paddingVertical: 8,
1132
+ },
1133
+ detailBox: {
1134
+ padding: 10,
1135
+ },
1136
+ detailBoxHeader: {
1137
+ flexDirection: 'row',
1138
+ alignItems: 'center',
1139
+ justifyContent: 'space-between',
1140
+ marginBottom: 8,
1141
+ paddingHorizontal: 4,
1142
+ },
1143
+ detailBoxTitle: {
395
1144
  fontFamily: AppFonts_1.AppFonts.interBold,
396
1145
  fontSize: 10,
397
- color: '#BE185D',
1146
+ color: AppColors_1.AppColors.grayTextWeak,
1147
+ letterSpacing: 0.5,
1148
+ textTransform: 'uppercase',
1149
+ },
1150
+ apiLikeInfoBar: {
1151
+ paddingHorizontal: 16,
1152
+ paddingVertical: 14,
1153
+ backgroundColor: AppColors_1.AppColors.primaryLight,
1154
+ borderBottomWidth: 1,
1155
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
1156
+ },
1157
+ apiBadgeRow: {
1158
+ flexDirection: 'row',
1159
+ alignItems: 'center',
1160
+ gap: 6,
1161
+ marginBottom: 8,
1162
+ },
1163
+ apiMethodBadge: {
1164
+ paddingHorizontal: 8,
1165
+ paddingVertical: 2,
1166
+ borderRadius: 4,
1167
+ alignItems: 'center',
1168
+ justifyContent: 'center',
1169
+ },
1170
+ apiMethodBadgeText: {
1171
+ fontFamily: AppFonts_1.AppFonts.interBold,
1172
+ fontSize: 9.5,
1173
+ color: '#FFFFFF',
1174
+ letterSpacing: 0.5,
1175
+ },
1176
+ apiChip: {
1177
+ paddingHorizontal: 7,
1178
+ paddingVertical: 2,
1179
+ borderRadius: 4,
1180
+ backgroundColor: 'rgba(104,75,155,0.06)',
1181
+ borderWidth: 1,
1182
+ borderColor: 'rgba(104,75,155,0.15)',
1183
+ alignItems: 'center',
1184
+ justifyContent: 'center',
1185
+ },
1186
+ apiChipText: {
1187
+ fontFamily: AppFonts_1.AppFonts.interBold,
1188
+ fontSize: 9.5,
1189
+ color: AppColors_1.AppColors.purple,
1190
+ },
1191
+ apiTitleText: {
1192
+ fontFamily: AppFonts_1.AppFonts.interBold,
1193
+ fontSize: 16,
1194
+ color: AppColors_1.AppColors.primaryBlack,
1195
+ marginBottom: 8,
1196
+ },
1197
+ apiMetaRow: {
1198
+ flexDirection: 'row',
1199
+ alignItems: 'center',
1200
+ gap: 4,
1201
+ },
1202
+ apiMetaText: {
1203
+ fontFamily: AppFonts_1.AppFonts.interRegular,
1204
+ fontSize: 11,
1205
+ color: AppColors_1.AppColors.grayTextWeak,
1206
+ },
1207
+ contentDetailSubHeader: {
1208
+ flexDirection: 'row',
1209
+ alignItems: 'center',
1210
+ justifyContent: 'space-between',
1211
+ paddingHorizontal: 12,
1212
+ paddingVertical: 10,
1213
+ borderBottomWidth: 1,
1214
+ borderBottomColor: AppColors_1.AppColors.dividerColor,
1215
+ backgroundColor: AppColors_1.AppColors.primaryLight,
398
1216
  },
399
1217
  });