react-native-inapp-inspector 1.0.9 → 1.0.11

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 (47) hide show
  1. package/README.md +5 -6
  2. package/dist/commonjs/components/AnalyticsDetail.js +28 -23
  3. package/dist/commonjs/components/AnalyticsEventCard.js +9 -9
  4. package/dist/commonjs/components/BrandSquareIcon.d.ts +5 -0
  5. package/dist/commonjs/components/BrandSquareIcon.js +180 -0
  6. package/dist/commonjs/components/CodeSnippet.js +32 -24
  7. package/dist/commonjs/components/ConsoleLogCard.js +127 -70
  8. package/dist/commonjs/components/JsonViewer.d.ts +2 -1
  9. package/dist/commonjs/components/JsonViewer.js +2 -2
  10. package/dist/commonjs/components/MetaAccordion.d.ts +1 -1
  11. package/dist/commonjs/components/MetaAccordion.js +45 -2
  12. package/dist/commonjs/components/NetworkIcons.d.ts +7 -0
  13. package/dist/commonjs/components/NetworkIcons.js +42 -1
  14. package/dist/commonjs/components/ReduxTreeView.d.ts +17 -0
  15. package/dist/commonjs/components/ReduxTreeView.js +630 -0
  16. package/dist/commonjs/components/TouchableScale.js +15 -1
  17. package/dist/commonjs/components/TreeNode.js +3 -3
  18. package/dist/commonjs/customHooks/reduxLogger.d.ts +12 -0
  19. package/dist/commonjs/customHooks/reduxLogger.js +71 -2
  20. package/dist/commonjs/index.js +1568 -505
  21. package/dist/commonjs/styles/index.d.ts +11 -1
  22. package/dist/commonjs/styles/index.js +19 -9
  23. package/dist/commonjs/types/index.d.ts +4 -0
  24. package/dist/esm/components/AnalyticsDetail.js +28 -23
  25. package/dist/esm/components/AnalyticsEventCard.js +9 -9
  26. package/dist/esm/components/BrandSquareIcon.d.ts +5 -0
  27. package/dist/esm/components/BrandSquareIcon.js +140 -0
  28. package/dist/esm/components/CodeSnippet.js +32 -24
  29. package/dist/esm/components/ConsoleLogCard.js +127 -70
  30. package/dist/esm/components/JsonViewer.d.ts +2 -1
  31. package/dist/esm/components/JsonViewer.js +2 -2
  32. package/dist/esm/components/MetaAccordion.d.ts +1 -1
  33. package/dist/esm/components/MetaAccordion.js +46 -3
  34. package/dist/esm/components/NetworkIcons.d.ts +7 -0
  35. package/dist/esm/components/NetworkIcons.js +34 -0
  36. package/dist/esm/components/ReduxTreeView.d.ts +17 -0
  37. package/dist/esm/components/ReduxTreeView.js +592 -0
  38. package/dist/esm/components/TouchableScale.js +16 -2
  39. package/dist/esm/components/TreeNode.js +3 -3
  40. package/dist/esm/customHooks/reduxLogger.d.ts +12 -0
  41. package/dist/esm/customHooks/reduxLogger.js +64 -1
  42. package/dist/esm/index.js +1571 -508
  43. package/dist/esm/styles/index.d.ts +11 -1
  44. package/dist/esm/styles/index.js +19 -9
  45. package/dist/esm/types/index.d.ts +4 -0
  46. package/example/App.tsx +46 -0
  47. package/package.json +7 -5
@@ -0,0 +1,592 @@
1
+ import React, { useState } from 'react';
2
+ import { View, Text, Pressable, StyleSheet } from 'react-native';
3
+ import { AppColors } from '../styles/AppColors';
4
+ import { AppFonts } from '../styles/AppFonts';
5
+ import { ChevronIcon } from './NetworkIcons';
6
+ import Svg, { Path } from 'react-native-svg';
7
+ // Custom icons
8
+ const DatabaseIcon = ({ color = AppColors.grayTextWeak, size = 12 }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
9
+ <Path d="M12 2C6.5 2 2 4.2 2 7v10c0 2.8 4.5 5 10 5s10-2.2 10-5V7c0-2.8-4.5-5-10-5z" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
10
+ <Path d="M2 12c0 2.8 4.5 5 10 5s10-2.2 10-5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
11
+ <Path d="M2 7c0 2.8 4.5 5 10 5s10-2.2 10-5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
12
+ </Svg>);
13
+ const BoltIcon = ({ color = AppColors.grayTextWeak, size = 12 }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
14
+ <Path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" fill={color} stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
15
+ </Svg>);
16
+ const FolderIcon = ({ color = AppColors.grayTextWeak, size = 12 }) => (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
17
+ <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"/>
18
+ </Svg>);
19
+ const ReduxValueNode = ({ name, value, level, search }) => {
20
+ const [expanded, setExpanded] = useState(level < 1);
21
+ const isObject = typeof value === 'object' && value !== null;
22
+ const isArray = Array.isArray(value);
23
+ const nameStr = String(name);
24
+ // Filter check if search query matches key or value
25
+ const matchesSearch = (k, val) => {
26
+ if (!search)
27
+ return true;
28
+ const s = search.toLowerCase();
29
+ if (k.toLowerCase().includes(s))
30
+ return true;
31
+ if (typeof val !== 'object' && String(val).toLowerCase().includes(s))
32
+ return true;
33
+ if (typeof val === 'object' && val !== null) {
34
+ return Object.keys(val).some(key => matchesSearch(key, val[key]));
35
+ }
36
+ return false;
37
+ };
38
+ if (!matchesSearch(nameStr, value)) {
39
+ return null;
40
+ }
41
+ if (!isObject) {
42
+ const valStr = value === null ? 'null' : value === undefined ? 'undefined' : String(value);
43
+ // Pick different colors for primitives
44
+ let valColor = '#0D9488'; // String
45
+ if (value === null || value === undefined) {
46
+ valColor = AppColors.grayTextWeak;
47
+ }
48
+ else if (typeof value === 'number') {
49
+ valColor = '#D97706';
50
+ }
51
+ else if (typeof value === 'boolean') {
52
+ valColor = '#4F46E5';
53
+ }
54
+ return (<View style={[reduxValueStyles.treeRow, { paddingLeft: 12 }]}>
55
+ <View style={reduxValueStyles.treeLeafConnector}/>
56
+ <Text style={reduxValueStyles.keyText} selectable={true}>
57
+ {nameStr}
58
+ <Text style={reduxValueStyles.colonText}>: </Text>
59
+ <Text style={[reduxValueStyles.valText, { color: valColor }]} selectable={true}>
60
+ {valStr}
61
+ </Text>
62
+ </Text>
63
+ </View>);
64
+ }
65
+ const keys = Object.keys(value);
66
+ const summaryText = isArray ? `Array [${keys.length}]` : `Object {${keys.length}}`;
67
+ return (<View style={reduxValueStyles.treeNodeBlock}>
68
+ <Pressable onPress={() => setExpanded(!expanded)} style={reduxValueStyles.treeRow}>
69
+ <View style={reduxValueStyles.treeLeafConnector}/>
70
+ <View style={[reduxValueStyles.chevronWrap, { transform: [{ rotate: expanded ? '90deg' : '0deg' }] }]}>
71
+ <ChevronIcon color={AppColors.grayTextWeak} size={10}/>
72
+ </View>
73
+ <Text style={reduxValueStyles.keyText} selectable={true}>
74
+ {nameStr}
75
+ <Text style={reduxValueStyles.colonText}>: </Text>
76
+ <Text style={reduxValueStyles.summaryText}>{summaryText}</Text>
77
+ </Text>
78
+ </Pressable>
79
+ {expanded && (<View style={reduxValueStyles.treeChildrenContainer}>
80
+ {keys.map(key => (<ReduxValueNode key={key} name={key} value={value[key]} level={level + 1} search={search}/>))}
81
+ </View>)}
82
+ </View>);
83
+ };
84
+ export const ReduxTreeView = ({ state, lastActionMap, search, }) => {
85
+ const [storeExpanded, setStoreExpanded] = useState(true);
86
+ const [reducerExpanded, setReducerExpanded] = useState({});
87
+ if (!state || typeof state !== 'object') {
88
+ return (<Text style={{ fontFamily: AppFonts.interRegular, fontSize: 12, color: AppColors.grayTextWeak, padding: 12 }}>
89
+ No state object to display.
90
+ </Text>);
91
+ }
92
+ const reducers = Object.keys(state);
93
+ const toggleReducer = (key) => {
94
+ setReducerExpanded(prev => ({
95
+ ...prev,
96
+ [key]: !prev[key],
97
+ }));
98
+ };
99
+ return (<View style={styles.container}>
100
+ {/* Root Node: Store */}
101
+ <Pressable onPress={() => setStoreExpanded(!storeExpanded)} style={styles.storeHeader}>
102
+ <View style={[styles.chevronWrap, { transform: [{ rotate: storeExpanded ? '90deg' : '0deg' }] }]}>
103
+ <ChevronIcon color="#FFFFFF" size={12}/>
104
+ </View>
105
+ <Text style={styles.storeTitle}>🏪 Redux Store</Text>
106
+ <View style={styles.badge}>
107
+ <Text style={styles.badgeText}>{reducers.length} Reducers</Text>
108
+ </View>
109
+ </Pressable>
110
+
111
+ {storeExpanded && (<View style={styles.storeChildren}>
112
+ {reducers.map((reducerKey, index) => {
113
+ const isLastReducer = index === reducers.length - 1;
114
+ const isExpanded = !!reducerExpanded[reducerKey];
115
+ const sliceData = state[reducerKey];
116
+ const lastAction = lastActionMap[reducerKey];
117
+ return (<View key={reducerKey} style={styles.reducerContainer}>
118
+ {/* Visual Branch Line for Reducer */}
119
+ <View style={[styles.reducerVerticalLine, isLastReducer && { bottom: '50%' }]}/>
120
+
121
+ {/* Reducer Header */}
122
+ <Pressable onPress={() => toggleReducer(reducerKey)} style={styles.reducerHeader}>
123
+ <View style={styles.reducerHorizontalLine}/>
124
+ <View style={[styles.chevronWrap, { transform: [{ rotate: isExpanded ? '90deg' : '0deg' }] }]}>
125
+ <ChevronIcon color={AppColors.purple} size={10}/>
126
+ </View>
127
+ <View style={styles.iconWrap}>
128
+ <FolderIcon color={AppColors.purple} size={11}/>
129
+ </View>
130
+ <Text style={styles.reducerText}>{reducerKey}</Text>
131
+ </Pressable>
132
+
133
+ {isExpanded && (<View style={styles.reducerChildren}>
134
+ {/* Vertical line connecting children */}
135
+ <View style={styles.childrenVerticalLine}/>
136
+
137
+ {/* Node 1: Last Action */}
138
+ <View style={styles.childItem}>
139
+ <View style={styles.childHorizontalLine}/>
140
+ <View style={[styles.iconWrap, { backgroundColor: '#FDF2F8' }]}>
141
+ <BoltIcon color="#DB2777" size={11}/>
142
+ </View>
143
+ <View style={{ flex: 1 }}>
144
+ <View style={{ flexDirection: 'row', alignItems: 'center', flexWrap: 'wrap', gap: 6 }}>
145
+ <Text style={styles.childLabel}>Last Action:</Text>
146
+ {lastAction ? (<View style={styles.actionTypeBadge}>
147
+ <Text style={styles.actionTypeText}>{lastAction.type}</Text>
148
+ </View>) : (<Text style={styles.noActionText}>None dispatched</Text>)}
149
+ </View>
150
+ {lastAction && (<Text style={styles.timestampText}>Dispatched: {lastAction.timestamp}</Text>)}
151
+ {lastAction && lastAction.payload !== null && (<View style={{ marginTop: 6 }}>
152
+ <ReduxValueNode name="payload" value={lastAction.payload} level={0} search={search}/>
153
+ </View>)}
154
+ </View>
155
+ </View>
156
+
157
+ {/* Node 2: State Data */}
158
+ <View style={styles.childItem}>
159
+ <View style={[styles.childHorizontalLine, { bottom: '50%' }]}/>
160
+ <View style={[styles.iconWrap, { backgroundColor: '#ECFDF5' }]}>
161
+ <DatabaseIcon color="#059669" size={11}/>
162
+ </View>
163
+ <View style={{ flex: 1 }}>
164
+ <Text style={styles.childLabel}>State Slice Data</Text>
165
+ <View style={{ marginTop: 6 }}>
166
+ <ReduxValueNode name="state" value={sliceData} level={0} search={search}/>
167
+ </View>
168
+ </View>
169
+ </View>
170
+ </View>)}
171
+ </View>);
172
+ })}
173
+ </View>)}
174
+ </View>);
175
+ };
176
+ export const ReduxActionTimeline = ({ history, onClear, search, }) => {
177
+ const [expandedActionId, setExpandedActionId] = useState(null);
178
+ const toggleExpand = (id) => {
179
+ setExpandedActionId(prev => (prev === id ? null : id));
180
+ };
181
+ const filteredHistory = history.filter(action => {
182
+ if (!search)
183
+ return true;
184
+ const s = search.toLowerCase();
185
+ if (action.type.toLowerCase().includes(s))
186
+ return true;
187
+ if (action.affectedSlices.some(slice => slice.toLowerCase().includes(s)))
188
+ return true;
189
+ if (action.payload && typeof action.payload === 'object') {
190
+ return JSON.stringify(action.payload).toLowerCase().includes(s);
191
+ }
192
+ return false;
193
+ });
194
+ return (<View style={timelineStyles.container}>
195
+ <View style={timelineStyles.headerRow}>
196
+ <Text style={timelineStyles.headerTitle}>⚡ Dispatched Actions ({filteredHistory.length})</Text>
197
+ {history.length > 0 && (<Pressable onPress={onClear} style={timelineStyles.clearBtn}>
198
+ <Text style={timelineStyles.clearBtnText}>Clear Log</Text>
199
+ </Pressable>)}
200
+ </View>
201
+
202
+ {filteredHistory.length === 0 ? (<View style={timelineStyles.emptyContainer}>
203
+ <Text style={timelineStyles.emptyText}>
204
+ {history.length === 0
205
+ ? 'No actions dispatched yet.\nDispatch actions in your application to see the timeline.'
206
+ : 'No matching actions found.'}
207
+ </Text>
208
+ </View>) : (<View style={timelineStyles.listContainer}>
209
+ {filteredHistory.map((item, index) => {
210
+ const isLast = index === filteredHistory.length - 1;
211
+ const isExpanded = expandedActionId === item.id;
212
+ return (<View key={item.id} style={timelineStyles.timelineItem}>
213
+ {/* Visual Line */}
214
+ <View style={[timelineStyles.verticalLine, isLast && { bottom: '50%' }]}/>
215
+ <View style={timelineStyles.circleIndicator}>
216
+ <View style={timelineStyles.circleInner}/>
217
+ </View>
218
+
219
+ {/* Card */}
220
+ <Pressable onPress={() => toggleExpand(item.id)} style={[
221
+ timelineStyles.card,
222
+ isExpanded && { borderColor: AppColors.purple, backgroundColor: AppColors.purpleShade50 },
223
+ ]}>
224
+ <View style={timelineStyles.cardHeader}>
225
+ <View style={timelineStyles.typeBadge}>
226
+ <Text style={timelineStyles.typeText}>{item.type}</Text>
227
+ </View>
228
+ <Text style={timelineStyles.timestamp}>{item.timestamp}</Text>
229
+ </View>
230
+
231
+ {item.affectedSlices.length > 0 && (<View style={timelineStyles.slicesRow}>
232
+ <Text style={timelineStyles.slicesLabel}>Affected:</Text>
233
+ {item.affectedSlices.map(slice => (<View key={slice} style={timelineStyles.slicePill}>
234
+ <Text style={timelineStyles.sliceText}>{slice}</Text>
235
+ </View>))}
236
+ </View>)}
237
+
238
+ {isExpanded && (<View style={timelineStyles.payloadContainer}>
239
+ <Text style={timelineStyles.payloadTitle}>Payload</Text>
240
+ {item.payload !== null && typeof item.payload === 'object' ? (<ReduxValueNode name="action.payload" value={item.payload} level={0} search={search}/>) : (<Text style={timelineStyles.primitivePayload}>
241
+ {item.payload === null ? 'null' : String(item.payload)}
242
+ </Text>)}
243
+ </View>)}
244
+ </Pressable>
245
+ </View>);
246
+ })}
247
+ </View>)}
248
+ </View>);
249
+ };
250
+ const reduxValueStyles = StyleSheet.create({
251
+ treeNodeBlock: {
252
+ marginTop: 4,
253
+ },
254
+ treeRow: {
255
+ flexDirection: 'row',
256
+ alignItems: 'center',
257
+ paddingVertical: 3,
258
+ gap: 4,
259
+ position: 'relative',
260
+ },
261
+ treeLeafConnector: {
262
+ position: 'absolute',
263
+ left: -12,
264
+ top: '50%',
265
+ width: 8,
266
+ height: 1,
267
+ borderBottomWidth: 1,
268
+ borderBottomColor: AppColors.dividerColor,
269
+ opacity: 0.5,
270
+ },
271
+ treeChildrenContainer: {
272
+ paddingLeft: 14,
273
+ borderLeftWidth: 1,
274
+ borderLeftColor: AppColors.dividerColor,
275
+ marginLeft: 6,
276
+ },
277
+ chevronWrap: {
278
+ width: 10,
279
+ height: 10,
280
+ alignItems: 'center',
281
+ justifyContent: 'center',
282
+ },
283
+ keyText: {
284
+ fontFamily: AppFonts.interMedium,
285
+ fontSize: 11.5,
286
+ color: AppColors.grayTextStrong,
287
+ },
288
+ colonText: {
289
+ color: AppColors.grayTextWeak,
290
+ },
291
+ valText: {
292
+ fontFamily: AppFonts.interRegular,
293
+ fontSize: 11.5,
294
+ },
295
+ summaryText: {
296
+ fontFamily: AppFonts.interRegular,
297
+ fontSize: 11,
298
+ color: AppColors.grayTextWeak,
299
+ },
300
+ });
301
+ const timelineStyles = StyleSheet.create({
302
+ container: {
303
+ flex: 1,
304
+ },
305
+ headerRow: {
306
+ flexDirection: 'row',
307
+ alignItems: 'center',
308
+ justifyContent: 'space-between',
309
+ marginBottom: 12,
310
+ },
311
+ headerTitle: {
312
+ fontFamily: AppFonts.interBold,
313
+ fontSize: 14,
314
+ color: AppColors.primaryBlack,
315
+ },
316
+ clearBtn: {
317
+ backgroundColor: 'rgba(239, 68, 68, 0.08)',
318
+ borderColor: 'rgba(239, 68, 68, 0.2)',
319
+ borderWidth: 1,
320
+ paddingHorizontal: 8,
321
+ paddingVertical: 4,
322
+ borderRadius: 6,
323
+ },
324
+ clearBtnText: {
325
+ fontFamily: AppFonts.interBold,
326
+ fontSize: 10,
327
+ color: '#EF4444',
328
+ },
329
+ emptyContainer: {
330
+ paddingVertical: 32,
331
+ alignItems: 'center',
332
+ justifyContent: 'center',
333
+ },
334
+ emptyText: {
335
+ fontFamily: AppFonts.interRegular,
336
+ fontSize: 12,
337
+ color: AppColors.grayTextWeak,
338
+ textAlign: 'center',
339
+ lineHeight: 18,
340
+ },
341
+ listContainer: {
342
+ paddingLeft: 12,
343
+ },
344
+ timelineItem: {
345
+ position: 'relative',
346
+ paddingLeft: 20,
347
+ marginBottom: 12,
348
+ },
349
+ verticalLine: {
350
+ position: 'absolute',
351
+ left: 4,
352
+ top: 0,
353
+ bottom: -12,
354
+ width: 1,
355
+ backgroundColor: AppColors.dividerColor,
356
+ },
357
+ circleIndicator: {
358
+ position: 'absolute',
359
+ left: 0,
360
+ top: 10,
361
+ width: 9,
362
+ height: 9,
363
+ borderRadius: 4.5,
364
+ backgroundColor: AppColors.purpleShade50,
365
+ borderWidth: 1,
366
+ borderColor: AppColors.purple,
367
+ alignItems: 'center',
368
+ justifyContent: 'center',
369
+ },
370
+ circleInner: {
371
+ width: 3,
372
+ height: 3,
373
+ borderRadius: 1.5,
374
+ backgroundColor: AppColors.purple,
375
+ },
376
+ card: {
377
+ backgroundColor: AppColors.primaryLight,
378
+ borderWidth: 1,
379
+ borderColor: AppColors.grayBorderSecondary,
380
+ borderRadius: 8,
381
+ padding: 10,
382
+ },
383
+ cardHeader: {
384
+ flexDirection: 'row',
385
+ alignItems: 'center',
386
+ justifyContent: 'space-between',
387
+ gap: 12,
388
+ },
389
+ typeBadge: {
390
+ backgroundColor: 'rgba(104,75,155,0.08)',
391
+ borderColor: 'rgba(104,75,155,0.18)',
392
+ borderWidth: 1,
393
+ borderRadius: 6,
394
+ paddingHorizontal: 6,
395
+ paddingVertical: 2.5,
396
+ flexShrink: 1,
397
+ },
398
+ typeText: {
399
+ fontFamily: AppFonts.interBold,
400
+ fontSize: 11,
401
+ color: AppColors.purple,
402
+ },
403
+ timestamp: {
404
+ fontFamily: AppFonts.interRegular,
405
+ fontSize: 10,
406
+ color: AppColors.grayTextWeak,
407
+ },
408
+ slicesRow: {
409
+ flexDirection: 'row',
410
+ alignItems: 'center',
411
+ flexWrap: 'wrap',
412
+ gap: 4,
413
+ marginTop: 6,
414
+ },
415
+ slicesLabel: {
416
+ fontFamily: AppFonts.interMedium,
417
+ fontSize: 10,
418
+ color: AppColors.grayTextWeak,
419
+ marginRight: 2,
420
+ },
421
+ slicePill: {
422
+ backgroundColor: AppColors.grayBackground,
423
+ borderColor: AppColors.dividerColor,
424
+ borderWidth: 1,
425
+ borderRadius: 4,
426
+ paddingHorizontal: 4,
427
+ paddingVertical: 1,
428
+ },
429
+ sliceText: {
430
+ fontFamily: AppFonts.interMedium,
431
+ fontSize: 9,
432
+ color: AppColors.grayText,
433
+ },
434
+ payloadContainer: {
435
+ marginTop: 10,
436
+ borderTopWidth: 1,
437
+ borderTopColor: AppColors.dividerColor,
438
+ paddingTop: 8,
439
+ },
440
+ payloadTitle: {
441
+ fontFamily: AppFonts.interBold,
442
+ fontSize: 10,
443
+ color: AppColors.grayTextWeak,
444
+ textTransform: 'uppercase',
445
+ marginBottom: 4,
446
+ },
447
+ primitivePayload: {
448
+ fontFamily: AppFonts.interRegular,
449
+ fontSize: 11,
450
+ color: AppColors.grayTextStrong,
451
+ },
452
+ });
453
+ const styles = StyleSheet.create({
454
+ container: {
455
+ flex: 1,
456
+ },
457
+ storeHeader: {
458
+ flexDirection: 'row',
459
+ alignItems: 'center',
460
+ backgroundColor: AppColors.purple,
461
+ borderRadius: 8,
462
+ paddingVertical: 10,
463
+ paddingHorizontal: 12,
464
+ gap: 8,
465
+ },
466
+ chevronWrap: {
467
+ width: 12,
468
+ height: 12,
469
+ alignItems: 'center',
470
+ justifyContent: 'center',
471
+ },
472
+ storeTitle: {
473
+ fontFamily: AppFonts.interBold,
474
+ fontSize: 14,
475
+ color: '#FFFFFF',
476
+ },
477
+ badge: {
478
+ backgroundColor: 'rgba(255,255,255,0.2)',
479
+ paddingHorizontal: 8,
480
+ paddingVertical: 2,
481
+ borderRadius: 12,
482
+ marginLeft: 'auto',
483
+ },
484
+ badgeText: {
485
+ fontFamily: AppFonts.interBold,
486
+ fontSize: 10,
487
+ color: '#FFFFFF',
488
+ },
489
+ storeChildren: {
490
+ paddingLeft: 12,
491
+ marginTop: 4,
492
+ },
493
+ reducerContainer: {
494
+ position: 'relative',
495
+ paddingLeft: 16,
496
+ paddingVertical: 4,
497
+ },
498
+ reducerVerticalLine: {
499
+ position: 'absolute',
500
+ left: 0,
501
+ top: 0,
502
+ bottom: 0,
503
+ width: 1,
504
+ backgroundColor: AppColors.dividerColor,
505
+ },
506
+ reducerHorizontalLine: {
507
+ position: 'absolute',
508
+ left: -16,
509
+ top: '50%',
510
+ width: 16,
511
+ height: 1,
512
+ backgroundColor: AppColors.dividerColor,
513
+ },
514
+ reducerHeader: {
515
+ flexDirection: 'row',
516
+ alignItems: 'center',
517
+ paddingVertical: 6,
518
+ gap: 6,
519
+ },
520
+ iconWrap: {
521
+ width: 18,
522
+ height: 18,
523
+ borderRadius: 4,
524
+ backgroundColor: AppColors.purpleShade50,
525
+ alignItems: 'center',
526
+ justifyContent: 'center',
527
+ },
528
+ reducerText: {
529
+ fontFamily: AppFonts.interBold,
530
+ fontSize: 13,
531
+ color: AppColors.primaryBlack,
532
+ },
533
+ reducerChildren: {
534
+ paddingLeft: 20,
535
+ position: 'relative',
536
+ marginTop: 4,
537
+ gap: 10,
538
+ },
539
+ childrenVerticalLine: {
540
+ position: 'absolute',
541
+ left: 8,
542
+ top: 0,
543
+ bottom: 16,
544
+ width: 1,
545
+ backgroundColor: AppColors.dividerColor,
546
+ },
547
+ childItem: {
548
+ flexDirection: 'row',
549
+ alignItems: 'flex-start',
550
+ gap: 8,
551
+ position: 'relative',
552
+ paddingLeft: 12,
553
+ },
554
+ childHorizontalLine: {
555
+ position: 'absolute',
556
+ left: -12,
557
+ top: 10,
558
+ width: 12,
559
+ height: 1,
560
+ backgroundColor: AppColors.dividerColor,
561
+ },
562
+ childLabel: {
563
+ fontFamily: AppFonts.interBold,
564
+ fontSize: 11.5,
565
+ color: AppColors.grayText,
566
+ marginTop: 2,
567
+ },
568
+ actionTypeBadge: {
569
+ backgroundColor: '#FCE7F3',
570
+ borderColor: '#FBCFE8',
571
+ borderWidth: 1,
572
+ borderRadius: 6,
573
+ paddingHorizontal: 6,
574
+ paddingVertical: 2,
575
+ },
576
+ actionTypeText: {
577
+ fontFamily: AppFonts.interBold,
578
+ fontSize: 10.5,
579
+ color: '#BE185D',
580
+ },
581
+ noActionText: {
582
+ fontFamily: AppFonts.interRegular,
583
+ fontSize: 11,
584
+ color: AppColors.grayTextWeak,
585
+ },
586
+ timestampText: {
587
+ fontFamily: AppFonts.interRegular,
588
+ fontSize: 9.5,
589
+ color: AppColors.grayTextWeak,
590
+ marginTop: 2,
591
+ },
592
+ });
@@ -1,9 +1,23 @@
1
1
  import React, { useRef } from 'react';
2
- import { Animated, Pressable } from 'react-native';
2
+ import { Animated, Pressable, StyleSheet } from 'react-native';
3
3
  const TouchableScale = ({ onPress, style, children, hitSlop, disabled, }) => {
4
4
  const scale = useRef(new Animated.Value(1)).current;
5
+ const flattenedStyle = StyleSheet.flatten(style) || {};
6
+ const layoutStyle = {
7
+ flex: flattenedStyle.flex,
8
+ flexDirection: flattenedStyle.flexDirection,
9
+ alignItems: flattenedStyle.alignItems,
10
+ justifyContent: flattenedStyle.justifyContent,
11
+ flexWrap: flattenedStyle.flexWrap,
12
+ alignSelf: flattenedStyle.alignSelf,
13
+ flexGrow: flattenedStyle.flexGrow,
14
+ flexShrink: flattenedStyle.flexShrink,
15
+ gap: flattenedStyle.gap,
16
+ };
5
17
  return (<Pressable disabled={disabled} style={style} onPressIn={() => Animated.spring(scale, { toValue: 0.94, useNativeDriver: true }).start()} onPressOut={() => Animated.spring(scale, { toValue: 1, useNativeDriver: true }).start()} onPress={onPress} hitSlop={hitSlop}>
6
- <Animated.View style={{ transform: [{ scale }] }}>{children}</Animated.View>
18
+ <Animated.View style={[{ transform: [{ scale }] }, layoutStyle]}>
19
+ {children}
20
+ </Animated.View>
7
21
  </Pressable>);
8
22
  };
9
23
  export default TouchableScale;
@@ -7,8 +7,8 @@ import { ChevronIcon } from './NetworkIcons';
7
7
  // Stylesheet
8
8
  import { AppColors } from '../styles/AppColors';
9
9
  import styles from '../styles';
10
- const TreeNode = React.memo(function TreeNode({ data, name, level = 0, search, forceOpen, }) {
11
- const [localOpen, setLocalOpen] = useState(level < 1);
10
+ const TreeNode = React.memo(function TreeNode({ data, name, level = 0, search, forceOpen, defaultExpandDepth, }) {
11
+ const [localOpen, setLocalOpen] = useState(level < (defaultExpandDepth ?? 1));
12
12
  const open = forceOpen !== undefined ? forceOpen : localOpen;
13
13
  const isObject = typeof data === 'object' && data !== null;
14
14
  const isArray = Array.isArray(data);
@@ -94,7 +94,7 @@ const TreeNode = React.memo(function TreeNode({ data, name, level = 0, search, f
94
94
  </Pressable>
95
95
 
96
96
  {open &&
97
- entries.map(([k, v]) => (<TreeNode key={String(k)} name={k} data={v} level={level + 1} search={search} forceOpen={forceOpen}/>))}
97
+ entries.map(([k, v]) => (<TreeNode key={String(k)} name={k} data={v} level={level + 1} search={search} forceOpen={forceOpen} defaultExpandDepth={defaultExpandDepth}/>))}
98
98
 
99
99
  {open && <Text style={styles.codeSyntax}>{isArray ? ']' : '}'}</Text>}
100
100
  </View>);
@@ -1,4 +1,16 @@
1
1
  export declare const getReduxState: () => any;
2
+ export declare const setReduxAutoRefresh: (val: boolean) => void;
3
+ export declare const getReduxAutoRefresh: () => boolean;
4
+ export declare const getLastActionForReducer: () => Record<string, any>;
5
+ export declare const clearLastActionForReducer: () => void;
6
+ export declare const getActionHistory: () => {
7
+ id: number;
8
+ type: string;
9
+ payload: any;
10
+ timestamp: string;
11
+ affectedSlices: string[];
12
+ }[];
13
+ export declare const clearActionHistory: () => void;
2
14
  export declare const setReduxState: (state: any) => void;
3
15
  export declare const subscribeReduxState: (cb: () => void) => () => void;
4
16
  export declare const connectReduxStore: (store: any) => void;