react-native-inapp-inspector 1.1.22 → 1.1.23

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 (27) hide show
  1. package/dist/commonjs/components/AnalyticsEventCard.js +5 -2
  2. package/dist/commonjs/components/ErrorBoundary.js +17 -8
  3. package/dist/commonjs/components/Inspector/BundleTab.d.ts +1 -0
  4. package/dist/commonjs/components/Inspector/BundleTab.js +135 -48
  5. package/dist/commonjs/components/Inspector/LogDetail.js +12 -6
  6. package/dist/commonjs/components/Inspector/PerformanceTab.js +12 -12
  7. package/dist/commonjs/components/Inspector/ReduxTab.js +6 -3
  8. package/dist/commonjs/components/NetworkIcons.d.ts +12 -0
  9. package/dist/commonjs/components/NetworkIcons.js +92 -1
  10. package/dist/commonjs/components/TreeNode.js +1 -1
  11. package/dist/commonjs/constants/version.d.ts +1 -1
  12. package/dist/commonjs/constants/version.js +1 -1
  13. package/dist/commonjs/i18n/locales/en.json +22 -22
  14. package/dist/esm/components/AnalyticsEventCard.js +5 -2
  15. package/dist/esm/components/ErrorBoundary.js +17 -8
  16. package/dist/esm/components/Inspector/BundleTab.d.ts +1 -0
  17. package/dist/esm/components/Inspector/BundleTab.js +137 -50
  18. package/dist/esm/components/Inspector/LogDetail.js +13 -7
  19. package/dist/esm/components/Inspector/PerformanceTab.js +13 -13
  20. package/dist/esm/components/Inspector/ReduxTab.js +7 -4
  21. package/dist/esm/components/NetworkIcons.d.ts +12 -0
  22. package/dist/esm/components/NetworkIcons.js +79 -0
  23. package/dist/esm/components/TreeNode.js +2 -2
  24. package/dist/esm/constants/version.d.ts +1 -1
  25. package/dist/esm/constants/version.js +1 -1
  26. package/dist/esm/i18n/locales/en.json +22 -22
  27. package/package.json +1 -1
@@ -6,8 +6,8 @@ import CopyButton from '../CopyButton';
6
6
  import HighlightText from '../HighlightText';
7
7
  import { AppColors } from '../../styles/AppColors';
8
8
  import { AppFonts } from '../../styles/AppFonts';
9
- import { PackageIcon, SearchIcon, ClearIcon, CircleAlertIcon, LayersIcon, LiveStateIcon, StorageIcon, MetadataIcon, } from '../NetworkIcons';
10
- import Svg, { Path, Rect, Circle, Ellipse, Defs, LinearGradient, Stop, } from 'react-native-svg';
9
+ import { PackageIcon, SearchIcon, ClearIcon, CircleAlertIcon, LayersIcon, LiveStateIcon, StorageIcon, MetadataIcon, FolderIcon, FolderOpenIcon, TrashIcon, LightbulbIcon, SparkleIcon, ClockIcon, } from '../NetworkIcons';
10
+ import Svg, { Path, Rect, Circle, Ellipse, G, Defs, LinearGradient, Stop, } from 'react-native-svg';
11
11
  import { analyzeHostAppBundle, getCachedBundleAnalysis, } from '../../customHooks/bundleAnalyzer';
12
12
  // ─── High-Fidelity Vector Package & NPM Logos ────────────────────────────────
13
13
  const PackageLogoRenderer = ({ name, size = 28 }) => {
@@ -124,6 +124,77 @@ const PackageLogoRenderer = ({ name, size = 28 }) => {
124
124
  </Svg>
125
125
  </View>);
126
126
  };
127
+ const BundleCategoryIcon = ({ type, size = 16, color = AppColors.purple }) => {
128
+ const stroke = { stroke: color, strokeWidth: 1.7, strokeLinecap: 'round', strokeLinejoin: 'round' };
129
+ const renderGlyph = () => {
130
+ switch (type) {
131
+ case 'folder':
132
+ return (<G>
133
+ <Path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" {...stroke}/>
134
+ </G>);
135
+ case 'ban':
136
+ return (<G>
137
+ <Circle cx="12" cy="12" r="8.5" {...stroke}/>
138
+ <Path d="M5.5 5.5 18.5 18.5" {...stroke}/>
139
+ </G>);
140
+ case 'bolt':
141
+ return (<G>
142
+ <Path d="M13 2 4.5 13.5 H10.5 L9 22 19.5 9.5 H13.5 Z" {...stroke}/>
143
+ </G>);
144
+ case 'source':
145
+ return (<G>
146
+ <Path d="M8.5 7 L4 12 L8.5 17" {...stroke}/>
147
+ <Path d="M15.5 7 L20 12 L15.5 17" {...stroke}/>
148
+ <Path d="M13.5 4.5 L10.5 19.5" {...stroke}/>
149
+ </G>);
150
+ case 'deps':
151
+ return (<G>
152
+ <Rect x="4" y="4" width="16" height="16" rx="2.5" {...stroke}/>
153
+ <Path d="M4 9.5 H20" {...stroke}/>
154
+ <Path d="M9.5 9.5 V20" {...stroke}/>
155
+ </G>);
156
+ case 'media':
157
+ case 'image':
158
+ return (<G>
159
+ <Rect x="3.5" y="4.5" width="17" height="15" rx="2" {...stroke}/>
160
+ <Circle cx="9" cy="10" r="1.5" {...stroke}/>
161
+ <Path d="M3.5 17.5 L9.5 12.5 L14 16.5 L17 13.5 L20.5 17.5" {...stroke}/>
162
+ </G>);
163
+ case 'overhead':
164
+ return (<G>
165
+ <Circle cx="12" cy="12" r="3.2" {...stroke}/>
166
+ <Path d="M12 2.5 V5.5 M12 18.5 V21.5 M2.5 12 H5.5 M18.5 12 H21.5 M5.3 5.3 L7.4 7.4 M16.6 16.6 L18.7 18.7 M18.7 5.3 L16.6 7.4 M7.4 16.6 L5.3 18.7" {...stroke}/>
167
+ </G>);
168
+ case 'typescript':
169
+ return (<G>
170
+ <Path d="M6.5 3.5 H14 L18.5 8 V20.5 H6.5 Z" {...stroke}/>
171
+ <Path d="M14 3.5 V8 H18.5" {...stroke}/>
172
+ <Path d="M9.5 13.5 H15 M12 13.5 V16.5 M9.5 16.5 H13" {...stroke}/>
173
+ </G>);
174
+ case 'javascript':
175
+ return (<G>
176
+ <Path d="M9.5 3.5 C7.5 3.5 7.5 6.5 7.5 9 C7.5 11 6.5 12 5 12 C6.5 12 7.5 13 7.5 15 C7.5 17.5 7.5 20.5 9.5 20.5" {...stroke}/>
177
+ <Path d="M14.5 3.5 C16.5 3.5 16.5 6.5 16.5 9 C16.5 11 17.5 12 19 12 C17.5 12 16.5 13 16.5 15 C16.5 17.5 16.5 20.5 14.5 20.5" {...stroke}/>
178
+ </G>);
179
+ case 'font':
180
+ return (<G>
181
+ <Path d="M8 19 L12 5.5 L16 19" {...stroke}/>
182
+ <Path d="M9.4 14.5 H14.6" {...stroke}/>
183
+ </G>);
184
+ case 'json':
185
+ return (<G>
186
+ <Path d="M9 3.5 C7 3.5 7 6 7 8.5 C7 10.5 6 11.5 5 12 C6 12.5 7 13.5 7 15.5 C7 18 7 20.5 9 20.5" {...stroke}/>
187
+ <Circle cx="12" cy="12" r="1.1" fill={color}/>
188
+ <Path d="M15 3.5 C17 3.5 17 6 17 8.5 C17 10.5 18 11.5 19 12 C18 12.5 17 13.5 17 15.5 C17 18 17 20.5 15 20.5" {...stroke}/>
189
+ </G>);
190
+ default:
191
+ return null;
192
+ }
193
+ };
194
+ return (<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
195
+ {renderGlyph()}
196
+ </Svg>);
197
+ };
127
198
  // ─── Media File Thumbnail Component ──────────────────────────────────────────
128
199
  const MediaPreviewThumbnail = ({ file }) => {
129
200
  const [loadError, setLoadError] = useState(false);
@@ -244,7 +315,7 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
244
315
  {isCollapsed ? '▶' : '▼'}
245
316
  </Text>
246
317
  </View>
247
- <Text style={{ fontSize: 16 }}>{isCollapsed ? '📁' : '📂'}</Text>
318
+ {isCollapsed ? (<FolderIcon color={AppColors.amber500} size={16}/>) : (<FolderOpenIcon color={AppColors.amber500} size={16}/>)}
248
319
  <HighlightText text={node.name + '/'} search={search} style={bundleStyles.treeFolderName} highlightStyle={bundleStyles.searchHighlight}/>
249
320
  <View style={bundleStyles.treeCountBadge}>
250
321
  <Text style={bundleStyles.treeCountBadgeText}>
@@ -322,27 +393,29 @@ const BundleTreeNodeView = ({ node, level, search, totalBundleKb, collapsedFolde
322
393
  isUnused && bundleStyles.adviceUnused,
323
394
  { marginLeft: 26, marginTop: 4 },
324
395
  ]}>
325
- <Text style={[
396
+ <View style={{ flexDirection: 'row', alignItems: 'flex-start', gap: 5 }}>
397
+ {isUnused ? (<TrashIcon color={AppColors.red600} size={12}/>) : file.status === 'warning' ? (<LightbulbIcon color={AppColors.amber800Warm} size={12}/>) : (<SparkleIcon color={AppColors.emerald700} size={12}/>)}
398
+ <Text style={[
326
399
  bundleStyles.adviceText,
327
400
  file.status === 'warning' && { color: AppColors.amber800Warm },
328
401
  file.status === 'optimal' && { color: AppColors.emerald700 },
329
402
  isUnused && { color: AppColors.red600 },
330
403
  ]}>
331
- {isUnused ? '🗑️ ' : file.status === 'warning' ? '💡 ' : '✨ '}
332
- {file.advice}
333
- </Text>
404
+ {file.advice}
405
+ </Text>
406
+ </View>
334
407
  </View>)}
335
408
  </View>);
336
409
  };
337
410
  const CATEGORY_TABS = [
338
- { key: 'ALL', labelKey: 'bundle.catAll', icon: '📁' },
339
- { key: 'UNUSED', labelKey: 'bundle.catUnused', icon: '🚫' },
340
- { key: 'CONSUMED', labelKey: 'bundle.catConsumed', icon: '' },
341
- { key: 'image', labelKey: 'bundle.catImages', icon: '🖼️' },
342
- { key: 'typescript', labelKey: 'bundle.catTypescript', icon: '📜' },
343
- { key: 'javascript', labelKey: 'bundle.catJavascript', icon: '⚙️' },
344
- { key: 'font', labelKey: 'bundle.catFonts', icon: '🔤' },
345
- { key: 'json', labelKey: 'bundle.catJson', icon: '📄' },
411
+ { key: 'ALL', labelKey: 'bundle.catAll', iconType: 'folder' },
412
+ { key: 'UNUSED', labelKey: 'bundle.catUnused', iconType: 'ban' },
413
+ { key: 'CONSUMED', labelKey: 'bundle.catConsumed', iconType: 'bolt' },
414
+ { key: 'image', labelKey: 'bundle.catImages', iconType: 'image' },
415
+ { key: 'typescript', labelKey: 'bundle.catTypescript', iconType: 'typescript' },
416
+ { key: 'javascript', labelKey: 'bundle.catJavascript', iconType: 'javascript' },
417
+ { key: 'font', labelKey: 'bundle.catFonts', iconType: 'font' },
418
+ { key: 'json', labelKey: 'bundle.catJson', iconType: 'json' },
346
419
  ];
347
420
  const CATEGORY_COLORS = {
348
421
  image: { label: 'Images & Media', color: AppColors.pink500, bg: AppColors.pink100 },
@@ -669,28 +742,32 @@ const BundleTab = React.memo(() => {
669
742
 
670
743
  {[
671
744
  {
745
+ iconType: 'source',
672
746
  label: t('bundle.splitAppSource'),
673
747
  color: AppColors.sky500,
674
748
  ...analysis.splitUp.appSource,
675
749
  },
676
750
  {
751
+ iconType: 'deps',
677
752
  label: t('bundle.splitNodeModules'),
678
753
  color: AppColors.indigo500,
679
754
  ...analysis.splitUp.nodeModules,
680
755
  },
681
756
  {
757
+ iconType: 'media',
682
758
  label: t('bundle.splitAssetsMedia'),
683
759
  color: AppColors.pink500,
684
760
  ...analysis.splitUp.assetsMedia,
685
761
  },
686
762
  {
763
+ iconType: 'overhead',
687
764
  label: t('bundle.splitMetroOverhead'),
688
765
  color: AppColors.amber500,
689
766
  ...analysis.splitUp.metroDevOverhead,
690
767
  },
691
768
  ].map((part, idx) => (<View key={idx} style={bundleStyles.catRowCard}>
692
769
  <View style={bundleStyles.catRowTop}>
693
- <Text style={bundleStyles.catRowIcon}>{['📦', '🧩', '🖼️', '⚙️'][idx]}</Text>
770
+ <BundleCategoryIcon type={part.iconType} size={18} color={part.color}/>
694
771
  <View style={{ flex: 1 }}>
695
772
  <Text style={bundleStyles.catRowTitle}>{part.label}</Text>
696
773
  <Text style={bundleStyles.catRowDesc}>
@@ -767,7 +844,7 @@ const BundleTab = React.memo(() => {
767
844
  {/* Legend Grid */}
768
845
  <View style={bundleStyles.legendGrid}>
769
846
  <View style={bundleStyles.legendItem}>
770
- <View style={[bundleStyles.legendDot, { backgroundColor: AppColors.pink500 }]}/>
847
+ <BundleCategoryIcon type="image" size={13} color={AppColors.pink500}/>
771
848
  <Text style={bundleStyles.legendText}>
772
849
  {t('bundle.legendImages')}{' '}
773
850
  <Text style={bundleStyles.legendVal}>
@@ -776,7 +853,7 @@ const BundleTab = React.memo(() => {
776
853
  </Text>
777
854
  </View>
778
855
  <View style={bundleStyles.legendItem}>
779
- <View style={[bundleStyles.legendDot, { backgroundColor: AppColors.sky500 }]}/>
856
+ <BundleCategoryIcon type="typescript" size={13} color={AppColors.sky500}/>
780
857
  <Text style={bundleStyles.legendText}>
781
858
  {t('bundle.legendTs')}{' '}
782
859
  <Text style={bundleStyles.legendVal}>
@@ -785,7 +862,7 @@ const BundleTab = React.memo(() => {
785
862
  </Text>
786
863
  </View>
787
864
  <View style={bundleStyles.legendItem}>
788
- <View style={[bundleStyles.legendDot, { backgroundColor: AppColors.indigo500 }]}/>
865
+ <BundleCategoryIcon type="javascript" size={13} color={AppColors.indigo500}/>
789
866
  <Text style={bundleStyles.legendText}>
790
867
  {t('bundle.legendJs')}{' '}
791
868
  <Text style={bundleStyles.legendVal}>
@@ -794,7 +871,7 @@ const BundleTab = React.memo(() => {
794
871
  </Text>
795
872
  </View>
796
873
  <View style={bundleStyles.legendItem}>
797
- <View style={[bundleStyles.legendDot, { backgroundColor: AppColors.purple500 }]}/>
874
+ <BundleCategoryIcon type="font" size={13} color={AppColors.purple500}/>
798
875
  <Text style={bundleStyles.legendText}>
799
876
  {t('bundle.legendFonts')}{' '}
800
877
  <Text style={bundleStyles.legendVal}>
@@ -803,7 +880,7 @@ const BundleTab = React.memo(() => {
803
880
  </Text>
804
881
  </View>
805
882
  <View style={bundleStyles.legendItem}>
806
- <View style={[bundleStyles.legendDot, { backgroundColor: AppColors.emerald500 }]}/>
883
+ <BundleCategoryIcon type="json" size={13} color={AppColors.emerald500}/>
807
884
  <Text style={bundleStyles.legendText}>
808
885
  {t('bundle.legendJson')}{' '}
809
886
  <Text style={bundleStyles.legendVal}>
@@ -833,7 +910,7 @@ const BundleTab = React.memo(() => {
833
910
 
834
911
  {[
835
912
  {
836
- icon: '🖼️',
913
+ iconType: 'image',
837
914
  title: t('bundle.catImagesTitle'),
838
915
  count: summary.images.count,
839
916
  size: t('bundle.fileSizeKb', { size: summary.images.kb }),
@@ -842,7 +919,7 @@ const BundleTab = React.memo(() => {
842
919
  desc: t('bundle.catImagesDesc'),
843
920
  },
844
921
  {
845
- icon: '⚙️',
922
+ iconType: 'javascript',
846
923
  title: t('bundle.catJsTitle'),
847
924
  count: summary.js.count,
848
925
  size: t('bundle.fileSizeKb', { size: summary.js.kb }),
@@ -851,7 +928,7 @@ const BundleTab = React.memo(() => {
851
928
  desc: t('bundle.catJsDesc'),
852
929
  },
853
930
  {
854
- icon: '🔤',
931
+ iconType: 'font',
855
932
  title: t('bundle.catFontsTitle'),
856
933
  count: summary.fonts.count,
857
934
  size: t('bundle.fileSizeKb', { size: summary.fonts.kb }),
@@ -863,7 +940,7 @@ const BundleTab = React.memo(() => {
863
940
  .join(', ') || t('bundle.catFontsDesc'),
864
941
  },
865
942
  {
866
- icon: '📜',
943
+ iconType: 'typescript',
867
944
  title: t('bundle.catTsTitle'),
868
945
  count: summary.ts.count,
869
946
  size: t('bundle.fileSizeKb', { size: summary.ts.kb }),
@@ -872,7 +949,7 @@ const BundleTab = React.memo(() => {
872
949
  desc: t('bundle.catTsDesc'),
873
950
  },
874
951
  {
875
- icon: '📄',
952
+ iconType: 'json',
876
953
  title: t('bundle.catJsonTitle'),
877
954
  count: summary.json.count,
878
955
  size: t('bundle.fileSizeKb', { size: summary.json.kb }),
@@ -882,7 +959,7 @@ const BundleTab = React.memo(() => {
882
959
  },
883
960
  ].map((cat, cIdx) => (<View key={cIdx} style={bundleStyles.catRowCard}>
884
961
  <View style={bundleStyles.catRowTop}>
885
- <Text style={bundleStyles.catRowIcon}>{cat.icon}</Text>
962
+ <BundleCategoryIcon type={cat.iconType} size={18} color={cat.color}/>
886
963
  <View style={{ flex: 1 }}>
887
964
  <Text style={bundleStyles.catRowTitle}>{cat.title}</Text>
888
965
  <Text style={bundleStyles.catRowDesc}>
@@ -962,7 +1039,7 @@ const BundleTab = React.memo(() => {
962
1039
  tab.key === 'UNUSED' && isActive && { backgroundColor: AppColors.red500, borderColor: AppColors.red600 },
963
1040
  tab.key === 'CONSUMED' && isActive && { backgroundColor: AppColors.emerald600, borderColor: AppColors.emerald700 },
964
1041
  ]}>
965
- <Text style={bundleStyles.catPillIcon}>{tab.icon}</Text>
1042
+ <BundleCategoryIcon type={tab.iconType} size={12} color={isActive ? AppColors.white : AppColors.grayTextStrong}/>
966
1043
  <Text style={[
967
1044
  bundleStyles.catPillText,
968
1045
  isActive && bundleStyles.catPillTextActive,
@@ -1080,15 +1157,17 @@ const BundleTab = React.memo(() => {
1080
1157
  file.status === 'optimal' && bundleStyles.adviceOptimal,
1081
1158
  isUnused && bundleStyles.adviceUnused,
1082
1159
  ]}>
1160
+ <View style={{ flexDirection: 'row', alignItems: 'flex-start', gap: 5 }}>
1161
+ {isUnused ? (<TrashIcon color={AppColors.red600} size={12}/>) : file.status === 'warning' ? (<LightbulbIcon color={AppColors.amber800Warm} size={12}/>) : (<SparkleIcon color={AppColors.emerald700} size={12}/>)}
1083
1162
  <Text style={[
1084
1163
  bundleStyles.adviceText,
1085
1164
  file.status === 'warning' && { color: AppColors.amber800Warm },
1086
1165
  file.status === 'optimal' && { color: AppColors.emerald700 },
1087
1166
  isUnused && { color: AppColors.red600 },
1088
1167
  ]}>
1089
- {isUnused ? '🗑️ ' : file.status === 'warning' ? '💡 ' : '✨ '}
1090
1168
  {file.advice}
1091
1169
  </Text>
1170
+ </View>
1092
1171
  </View>)}
1093
1172
  </View>
1094
1173
  </View>);
@@ -1205,9 +1284,12 @@ const BundleTab = React.memo(() => {
1205
1284
 
1206
1285
  {/* Deprecation Warning Banner if deprecated */}
1207
1286
  {pkg.isDeprecated && pkg.deprecationReason && (<View style={bundleStyles.deprecationBox}>
1208
- <Text style={bundleStyles.deprecationText}>
1209
- ⚠️ {pkg.deprecationReason}
1210
- </Text>
1287
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
1288
+ <CircleAlertIcon color={AppColors.errorColor} size={12}/>
1289
+ <Text style={bundleStyles.deprecationText}>
1290
+ {pkg.deprecationReason}
1291
+ </Text>
1292
+ </View>
1211
1293
  </View>)}
1212
1294
 
1213
1295
  <View style={bundleStyles.fileProgressTrack}>
@@ -1225,9 +1307,12 @@ const BundleTab = React.memo(() => {
1225
1307
  {pkg.type === 'direct' ? t('bundle.direct') : t('bundle.transitive')}
1226
1308
  </Text>
1227
1309
  </View>
1228
- {pkg.lastActive && (<Text style={bundleStyles.lastActiveText}>
1229
- 🕒 {pkg.lastActive}
1230
- </Text>)}
1310
+ {pkg.lastActive && (<View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
1311
+ <ClockIcon color={AppColors.grayTextWeak} size={11}/>
1312
+ <Text style={bundleStyles.lastActiveText}>
1313
+ {pkg.lastActive}
1314
+ </Text>
1315
+ </View>)}
1231
1316
  </View>
1232
1317
 
1233
1318
  <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
@@ -1324,14 +1409,16 @@ const BundleTab = React.memo(() => {
1324
1409
  file.status === 'warning' && bundleStyles.adviceWarning,
1325
1410
  file.status === 'optimal' && bundleStyles.adviceOptimal,
1326
1411
  ]}>
1327
- <Text style={[
1412
+ <View style={{ flexDirection: 'row', alignItems: 'flex-start', gap: 5 }}>
1413
+ {file.status === 'warning' ? (<LightbulbIcon color={AppColors.amber800Warm} size={12}/>) : (<SparkleIcon color={AppColors.emerald700} size={12}/>)}
1414
+ <Text style={[
1328
1415
  bundleStyles.adviceText,
1329
1416
  file.status === 'warning' && { color: AppColors.amber800Warm },
1330
1417
  file.status === 'optimal' && { color: AppColors.emerald700 },
1331
1418
  ]}>
1332
- {file.status === 'warning' ? '💡 ' : '✨ '}
1333
- {file.advice}
1334
- </Text>
1419
+ {file.advice}
1420
+ </Text>
1421
+ </View>
1335
1422
  </View>)}
1336
1423
  </View>
1337
1424
  </View>))}
@@ -1376,12 +1463,16 @@ const BundleTab = React.memo(() => {
1376
1463
 
1377
1464
  {[
1378
1465
  {
1466
+ iconType: 'image',
1467
+ iconColor: AppColors.pink500,
1379
1468
  title: t('bundle.optTip1Title'),
1380
1469
  desc: t('bundle.optTip1Desc'),
1381
1470
  badge: t('bundle.highImpact'),
1382
1471
  badgeColor: AppColors.pink500,
1383
1472
  },
1384
1473
  {
1474
+ iconType: 'bolt',
1475
+ iconColor: isHermes ? AppColors.emerald500 : AppColors.amber500,
1385
1476
  title: t('bundle.optTip2Title'),
1386
1477
  desc: isHermes
1387
1478
  ? t('bundle.optTip2DescActive')
@@ -1390,18 +1481,24 @@ const BundleTab = React.memo(() => {
1390
1481
  badgeColor: isHermes ? AppColors.emerald500 : AppColors.amber500,
1391
1482
  },
1392
1483
  {
1484
+ iconType: 'font',
1485
+ iconColor: AppColors.purple500,
1393
1486
  title: t('bundle.optTip3Title'),
1394
1487
  desc: t('bundle.optTip3Desc'),
1395
1488
  badge: t('bundle.mediumImpact'),
1396
1489
  badgeColor: AppColors.purple500,
1397
1490
  },
1398
1491
  {
1492
+ iconType: 'source',
1493
+ iconColor: AppColors.sky500,
1399
1494
  title: t('bundle.optTip4Title'),
1400
1495
  desc: t('bundle.optTip4Desc'),
1401
1496
  badge: t('bundle.bestPractice'),
1402
1497
  badgeColor: AppColors.sky500,
1403
1498
  },
1404
1499
  {
1500
+ iconType: 'overhead',
1501
+ iconColor: AppColors.indigo500,
1405
1502
  title: t('bundle.optTip5Title'),
1406
1503
  desc: t('bundle.optTip5Desc'),
1407
1504
  badge: t('bundle.bestPractice'),
@@ -1413,6 +1510,7 @@ const BundleTab = React.memo(() => {
1413
1510
  <View style={bundleStyles.sNoBadge}>
1414
1511
  <Text style={bundleStyles.sNoText}>#{tIdx + 1}</Text>
1415
1512
  </View>
1513
+ <BundleCategoryIcon type={tip.iconType} size={14} color={tip.iconColor}/>
1416
1514
  <Text style={bundleStyles.tipTitle}>{tip.title}</Text>
1417
1515
  </View>
1418
1516
  <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
@@ -1612,11 +1710,6 @@ const bundleStyles = StyleSheet.create({
1612
1710
  gap: 5,
1613
1711
  minWidth: '45%',
1614
1712
  },
1615
- legendDot: {
1616
- width: 8,
1617
- height: 8,
1618
- borderRadius: 4,
1619
- },
1620
1713
  legendText: {
1621
1714
  fontFamily: AppFonts.interMedium,
1622
1715
  fontSize: 11,
@@ -1640,9 +1733,6 @@ const bundleStyles = StyleSheet.create({
1640
1733
  gap: 8,
1641
1734
  marginBottom: 8,
1642
1735
  },
1643
- catRowIcon: {
1644
- fontSize: 16,
1645
- },
1646
1736
  catRowTitle: {
1647
1737
  fontFamily: AppFonts.interBold,
1648
1738
  fontSize: 12,
@@ -1718,9 +1808,6 @@ const bundleStyles = StyleSheet.create({
1718
1808
  backgroundColor: AppColors.brandPurple,
1719
1809
  borderColor: AppColors.brandPurple,
1720
1810
  },
1721
- catPillIcon: {
1722
- fontSize: 11,
1723
- },
1724
1811
  catPillText: {
1725
1812
  fontFamily: AppFonts.interMedium,
1726
1813
  fontSize: 11,
@@ -6,7 +6,7 @@ import HighlightText from '../HighlightText';
6
6
  import JsonViewer from '../JsonViewer';
7
7
  import CopyButton from '../CopyButton';
8
8
  import SegmentedTabs from '../SegmentedTabs';
9
- import { ClearIcon, SearchIcon, PrettyIcon, RawIcon, TableIcon, LayersIcon, TerminalIcon, RequestIcon, InfoCircleIcon, } from '../NetworkIcons';
9
+ import { ClearIcon, SearchIcon, PrettyIcon, RawIcon, TableIcon, LayersIcon, TerminalIcon, RequestIcon, InfoCircleIcon, DocIcon, } from '../NetworkIcons';
10
10
  import { AppColors } from '../../styles/AppColors';
11
11
  import { AppFonts } from '../../styles/AppFonts';
12
12
  import styles from '../../styles';
@@ -268,14 +268,17 @@ const LogDetail = React.memo(() => {
268
268
  paddingVertical: 2,
269
269
  },
270
270
  ]}>
271
- <Text style={[
271
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 3 }}>
272
+ <DocIcon color={AppColors.brandPurple} size={10}/>
273
+ <Text style={[
272
274
  styles.metaChipText,
273
275
  { color: AppColors.brandPurple, fontSize: 10, fontFamily: AppFonts.interBold },
274
276
  ]}>
275
- 📄 {originFrame.fileName}
276
- {originFrame.lineNumber ? `:${originFrame.lineNumber}` : ''}
277
- {originFrame.columnNumber ? `:${originFrame.columnNumber}` : ''}
278
- </Text>
277
+ {originFrame.fileName}
278
+ {originFrame.lineNumber ? `:${originFrame.lineNumber}` : ''}
279
+ {originFrame.columnNumber ? `:${originFrame.columnNumber}` : ''}
280
+ </Text>
281
+ </View>
279
282
  </View>)}
280
283
  </View>
281
284
 
@@ -711,6 +714,8 @@ const LogDetail = React.memo(() => {
711
714
  {frame.fileExt.toUpperCase()}
712
715
  </Text>
713
716
  </View>)}
717
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 3 }}>
718
+ <DocIcon color={isTopFrame ? AppColors.brandPurple : AppColors.grayTextWeak} size={10}/>
714
719
  <Text style={{
715
720
  fontFamily: AppFonts.interMedium,
716
721
  fontSize: 10.5,
@@ -718,9 +723,10 @@ const LogDetail = React.memo(() => {
718
723
  ? AppColors.brandPurple
719
724
  : AppColors.grayTextWeak,
720
725
  }}>
721
- 📄 {frame.fileName}
726
+ {frame.fileName}
722
727
  </Text>
723
728
  </View>
729
+ </View>
724
730
 
725
731
  {/* Full path */}
726
732
  {frame.fullPath && frame.fullPath !== frame.fileName && (<Text selectable style={{
@@ -8,7 +8,7 @@ import { AppColors } from '../../styles/AppColors';
8
8
  import { AppFonts } from '../../styles/AppFonts';
9
9
  import { useTranslation } from '../../i18n';
10
10
  import { getRuntimeDiagnostics } from '../../helpers';
11
- import { SearchIcon, CircleXIcon, PerformanceIcon } from '../NetworkIcons';
11
+ import { SearchIcon, CircleXIcon, PerformanceIcon, BoltIcon, LightbulbIcon, WarningTriangleIcon, MapIcon, AtomIcon, BrainIcon, GlobeIcon, } from '../NetworkIcons';
12
12
  const PerformanceTab = React.memo(() => {
13
13
  const { t } = useTranslation();
14
14
  // ─── Real-Time FPS Tracking ────────────────────────────────────────────────
@@ -257,35 +257,35 @@ const PerformanceTab = React.memo(() => {
257
257
  <View style={perfStyles.filterRow}>
258
258
  <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ gap: 6, paddingHorizontal: 12, paddingVertical: 4 }}>
259
259
  {[
260
- { key: 'ALL', label: t('performance.allLogs'), icon: '⚡', count: events.length },
260
+ { key: 'ALL', label: t('performance.allLogs'), Icon: BoltIcon, count: events.length },
261
261
  {
262
262
  key: 'JANKY',
263
263
  label: t('performance.jankySlow'),
264
- icon: '⚠️',
264
+ Icon: WarningTriangleIcon,
265
265
  count: events.filter(e => e.severity === 'warning' || e.severity === 'critical').length,
266
266
  },
267
267
  {
268
268
  key: 'NAVIGATION',
269
269
  label: t('performance.navigation'),
270
- icon: '🗺️',
270
+ Icon: MapIcon,
271
271
  count: events.filter(e => e.category === 'navigation').length,
272
272
  },
273
273
  {
274
274
  key: 'RENDER',
275
275
  label: t('performance.components'),
276
- icon: '⚛️',
276
+ Icon: AtomIcon,
277
277
  count: events.filter(e => e.category === 'render').length,
278
278
  },
279
279
  {
280
280
  key: 'MEMORY',
281
281
  label: t('performance.memoryGc'),
282
- icon: '🧠',
282
+ Icon: BrainIcon,
283
283
  count: events.filter(e => e.category === 'memory').length,
284
284
  },
285
285
  {
286
286
  key: 'IO',
287
287
  label: t('performance.networkIo'),
288
- icon: '🌐',
288
+ Icon: GlobeIcon,
289
289
  count: events.filter(e => e.category === 'io' || e.category === 'bridge').length,
290
290
  },
291
291
  ].map(tab => {
@@ -294,7 +294,7 @@ const PerformanceTab = React.memo(() => {
294
294
  perfStyles.filterPill,
295
295
  isActive && perfStyles.filterPillActive,
296
296
  ]}>
297
- <Text style={perfStyles.filterPillIcon}>{tab.icon}</Text>
297
+ <tab.Icon color={isActive ? AppColors.white : AppColors.grayTextStrong} size={12}/>
298
298
  <Text style={[
299
299
  perfStyles.filterPillText,
300
300
  isActive && perfStyles.filterPillTextActive,
@@ -487,7 +487,7 @@ const PerformanceTab = React.memo(() => {
487
487
  </View>
488
488
 
489
489
  {filteredEvents.length === 0 ? (<View style={perfStyles.emptyCard}>
490
- <Text style={{ fontSize: 28 }}>⚡</Text>
490
+ <BoltIcon color={AppColors.amber500} size={30}/>
491
491
  <Text style={perfStyles.emptyTitle}>{t('performance.emptyTitle')}</Text>
492
492
  <Text style={perfStyles.emptySub}>
493
493
  {t('performance.emptySubtitle')}
@@ -574,7 +574,10 @@ const PerformanceTab = React.memo(() => {
574
574
 
575
575
  {/* Actionable Optimization Tip */}
576
576
  {event.advice && (<View style={perfStyles.adviceCard}>
577
- <Text style={perfStyles.adviceHeading}>💡 {t('performance.optimizationTip')}</Text>
577
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
578
+ <LightbulbIcon color={AppColors.purpleShade700} size={12}/>
579
+ <Text style={perfStyles.adviceHeading}>{t('performance.optimizationTip')}</Text>
580
+ </View>
578
581
  <Text style={perfStyles.adviceBodyText}>{event.advice}</Text>
579
582
  </View>)}
580
583
  </View>)}
@@ -665,9 +668,6 @@ const perfStyles = StyleSheet.create({
665
668
  backgroundColor: AppColors.brandPurple,
666
669
  borderColor: AppColors.brandPurple,
667
670
  },
668
- filterPillIcon: {
669
- fontSize: 11,
670
- },
671
671
  filterPillText: {
672
672
  fontFamily: AppFonts.interMedium,
673
673
  fontSize: 11,
@@ -10,7 +10,7 @@ import { getSize } from '../../helpers';
10
10
  import styles from '../../styles';
11
11
  import { AppColors } from '../../styles/AppColors';
12
12
  import { AppFonts } from '../../styles/AppFonts';
13
- import { TerminalIcon, SearchIcon, ClearIcon, ClockIcon, ForwardChevronIcon, SortArrowIcon, } from '../NetworkIcons';
13
+ import { TerminalIcon, SearchIcon, ClearIcon, ClockIcon, ForwardChevronIcon, SortArrowIcon, BoltIcon, TextAaIcon, } from '../NetworkIcons';
14
14
  const ReduxTab = React.memo(() => {
15
15
  const { reduxState, reduxLastActionMap, reduxSearch, setReduxSearch, setSelectedReduxSlice, } = useInspector();
16
16
  // Sort mode: 'latest' (newest updated first) vs 'alpha' (A-Z)
@@ -183,9 +183,12 @@ const ReduxTab = React.memo(() => {
183
183
  <Text style={reduxTabStyles.resultCount}>
184
184
  Showing {filteredSlices.length} of {sliceItems.length} state slices
185
185
  </Text>
186
- <Text style={reduxTabStyles.sortLabel}>
187
- {sortMode === 'latest' ? '⚡ Newest Updates First' : '🔤 Alphabetical (A-Z)'}
188
- </Text>
186
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
187
+ {sortMode === 'latest' ? (<BoltIcon color={AppColors.brandPurple} size={11}/>) : (<TextAaIcon color={AppColors.brandPurple} size={11}/>)}
188
+ <Text style={reduxTabStyles.sortLabel}>
189
+ {sortMode === 'latest' ? 'Newest Updates First' : 'Alphabetical (A-Z)'}
190
+ </Text>
191
+ </View>
189
192
  </View>
190
193
  </View>
191
194
 
@@ -66,3 +66,15 @@ export declare const StorageIcon: ({ color, size, }: any) => React.JSX.Element;
66
66
  export declare const MetadataIcon: ({ color, size, }: any) => React.JSX.Element;
67
67
  export declare const ReduxIcon: ({ color, size, }: any) => React.JSX.Element;
68
68
  export declare const PerformanceIcon: ({ color, size, }: any) => React.JSX.Element;
69
+ export declare const BoltIcon: ({ color, size }: any) => React.JSX.Element;
70
+ export declare const BanIcon: ({ color, size }: any) => React.JSX.Element;
71
+ export declare const FolderOpenIcon: ({ color, size }: any) => React.JSX.Element;
72
+ export declare const DocIcon: ({ color, size }: any) => React.JSX.Element;
73
+ export declare const LightbulbIcon: ({ color, size }: any) => React.JSX.Element;
74
+ export declare const SparkleIcon: ({ color, size }: any) => React.JSX.Element;
75
+ export declare const MapIcon: ({ color, size }: any) => React.JSX.Element;
76
+ export declare const AtomIcon: ({ color, size }: any) => React.JSX.Element;
77
+ export declare const BrainIcon: ({ color, size }: any) => React.JSX.Element;
78
+ export declare const TextAaIcon: ({ color, size }: any) => React.JSX.Element;
79
+ export declare const CartIcon: ({ color, size }: any) => React.JSX.Element;
80
+ export declare const MoneyIcon: ({ color, size }: any) => React.JSX.Element;