react-native-inapp-inspector 1.1.13 → 1.1.15

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 (250) hide show
  1. package/README.md +9 -34
  2. package/dist/commonjs/assets/svgAssets.d.ts +3 -0
  3. package/dist/commonjs/assets/svgAssets.js +17 -0
  4. package/dist/commonjs/components/AnalyticsEventCard.d.ts +1 -14
  5. package/dist/commonjs/components/AnalyticsEventCard.js +120 -50
  6. package/dist/commonjs/components/AnalyticsGraph.d.ts +2 -6
  7. package/dist/commonjs/components/AnalyticsGraph.js +8 -8
  8. package/dist/commonjs/components/AnalyticsTabView.d.ts +15 -0
  9. package/dist/commonjs/components/AnalyticsTabView.js +157 -0
  10. package/dist/commonjs/components/AnimatedEntrance.d.ts +1 -1
  11. package/dist/commonjs/components/AnimatedEntrance.js +2 -2
  12. package/dist/commonjs/components/ApiDetailView.d.ts +22 -0
  13. package/dist/commonjs/components/ApiDetailView.js +304 -0
  14. package/dist/commonjs/components/ApisTabView.d.ts +33 -0
  15. package/dist/commonjs/components/ApisTabView.js +235 -0
  16. package/dist/commonjs/components/CodeSnippet.d.ts +1 -5
  17. package/dist/commonjs/components/CodeSnippet.js +34 -34
  18. package/dist/commonjs/components/ConsoleLogCard.d.ts +1 -8
  19. package/dist/commonjs/components/ConsoleLogCard.js +262 -442
  20. package/dist/commonjs/components/ConsoleLogDetailView.d.ts +9 -0
  21. package/dist/commonjs/components/ConsoleLogDetailView.js +278 -0
  22. package/dist/commonjs/components/ConsoleLogsTabView.d.ts +24 -0
  23. package/dist/commonjs/components/ConsoleLogsTabView.js +354 -0
  24. package/dist/commonjs/components/DiffViewer.js +4 -2
  25. package/dist/commonjs/components/DomainHeader.js +66 -41
  26. package/dist/commonjs/components/EmptyState.d.ts +2 -2
  27. package/dist/commonjs/components/EmptyState.js +2 -2
  28. package/dist/commonjs/components/EndOfListFooter.d.ts +8 -0
  29. package/dist/commonjs/components/EndOfListFooter.js +90 -0
  30. package/dist/commonjs/components/ErrorBoundary.d.ts +5 -14
  31. package/dist/commonjs/components/ErrorBoundary.js +28 -28
  32. package/dist/commonjs/components/FloatingBubble.d.ts +14 -0
  33. package/dist/commonjs/components/FloatingBubble.js +75 -0
  34. package/dist/commonjs/components/HeadersSection.js +5 -3
  35. package/dist/commonjs/components/HighlightText.d.ts +1 -1
  36. package/dist/commonjs/components/HighlightText.js +5 -7
  37. package/dist/commonjs/components/Inspector/AnalyticsTab.d.ts +3 -0
  38. package/dist/commonjs/components/Inspector/AnalyticsTab.js +232 -0
  39. package/dist/commonjs/components/Inspector/ConsoleTab.d.ts +3 -0
  40. package/dist/commonjs/components/Inspector/ConsoleTab.js +410 -0
  41. package/dist/commonjs/components/Inspector/FabLauncher.d.ts +3 -0
  42. package/dist/commonjs/components/Inspector/FabLauncher.js +54 -0
  43. package/dist/commonjs/components/Inspector/InsightsDashboard.d.ts +3 -0
  44. package/dist/commonjs/components/Inspector/InsightsDashboard.js +619 -0
  45. package/dist/commonjs/components/Inspector/InspectorContext.d.ts +5 -0
  46. package/dist/commonjs/components/Inspector/InspectorContext.js +18 -0
  47. package/dist/commonjs/components/Inspector/InspectorHeader.d.ts +3 -0
  48. package/dist/commonjs/components/Inspector/InspectorHeader.js +452 -0
  49. package/dist/commonjs/components/Inspector/LogDetail.d.ts +3 -0
  50. package/dist/commonjs/components/Inspector/LogDetail.js +963 -0
  51. package/dist/commonjs/components/Inspector/MainScreen.d.ts +3 -0
  52. package/dist/commonjs/components/Inspector/MainScreen.js +68 -0
  53. package/dist/commonjs/components/Inspector/NavigationTracker.d.ts +3 -0
  54. package/dist/commonjs/components/Inspector/NavigationTracker.js +12 -0
  55. package/dist/commonjs/components/Inspector/NetworkDetail.d.ts +3 -0
  56. package/dist/commonjs/components/Inspector/NetworkDetail.js +405 -0
  57. package/dist/commonjs/components/Inspector/NetworkTab.d.ts +3 -0
  58. package/dist/commonjs/components/Inspector/NetworkTab.js +281 -0
  59. package/dist/commonjs/components/Inspector/ReduxTab.d.ts +3 -0
  60. package/dist/commonjs/components/Inspector/ReduxTab.js +75 -0
  61. package/dist/commonjs/components/Inspector/SettingsPanel.d.ts +3 -0
  62. package/dist/commonjs/components/Inspector/SettingsPanel.js +1476 -0
  63. package/dist/commonjs/components/Inspector/TabBar.d.ts +3 -0
  64. package/dist/commonjs/components/Inspector/TabBar.js +95 -0
  65. package/dist/commonjs/components/Inspector/WebViewTab.d.ts +3 -0
  66. package/dist/commonjs/components/Inspector/WebViewTab.js +757 -0
  67. package/dist/commonjs/components/InspectorHeader.d.ts +19 -0
  68. package/dist/commonjs/components/InspectorHeader.js +329 -0
  69. package/dist/commonjs/components/InspectorTabBar.d.ts +16 -0
  70. package/dist/commonjs/components/InspectorTabBar.js +90 -0
  71. package/dist/commonjs/components/JsonViewer.d.ts +4 -1
  72. package/dist/commonjs/components/JsonViewer.js +110 -171
  73. package/dist/commonjs/components/LogCard.js +109 -86
  74. package/dist/commonjs/components/MetaAccordion.d.ts +1 -10
  75. package/dist/commonjs/components/MetaAccordion.js +23 -21
  76. package/dist/commonjs/components/NavigationTracker.d.ts +7 -0
  77. package/dist/commonjs/components/NavigationTracker.js +76 -0
  78. package/dist/commonjs/components/NetworkIcons.d.ts +6 -0
  79. package/dist/commonjs/components/NetworkIcons.js +54 -8
  80. package/dist/commonjs/components/ReduxTabView.d.ts +9 -0
  81. package/dist/commonjs/components/ReduxTabView.js +56 -0
  82. package/dist/commonjs/components/ReduxTreeView.js +241 -200
  83. package/dist/commonjs/components/SegmentedTabs.d.ts +15 -0
  84. package/dist/commonjs/components/SegmentedTabs.js +52 -0
  85. package/dist/commonjs/components/SettingsView.d.ts +13 -0
  86. package/dist/commonjs/components/SettingsView.js +328 -0
  87. package/dist/commonjs/components/TouchableScale.d.ts +2 -2
  88. package/dist/commonjs/components/TouchableScale.js +2 -2
  89. package/dist/commonjs/components/TreeNode.js +2 -2
  90. package/dist/commonjs/constants/index.js +1 -12
  91. package/dist/commonjs/constants/version.d.ts +1 -1
  92. package/dist/commonjs/constants/version.js +1 -1
  93. package/dist/commonjs/customHooks/analyticsLogger.d.ts +8 -0
  94. package/dist/commonjs/customHooks/analyticsLogger.js +42 -1
  95. package/dist/commonjs/customHooks/consoleLogger.js +137 -13
  96. package/dist/commonjs/customHooks/networkLogger.d.ts +0 -1
  97. package/dist/commonjs/customHooks/networkLogger.js +0 -1
  98. package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -9
  99. package/dist/commonjs/enums/index.d.ts +39 -0
  100. package/dist/commonjs/enums/index.js +50 -0
  101. package/dist/commonjs/helpers/index.d.ts +27 -1
  102. package/dist/commonjs/helpers/index.js +187 -12
  103. package/dist/commonjs/helpers/settingsStore.d.ts +2 -24
  104. package/dist/commonjs/i18n/en.json +144 -0
  105. package/dist/commonjs/i18n/index.d.ts +2 -0
  106. package/dist/commonjs/i18n/index.js +27 -0
  107. package/dist/commonjs/i18n/locales/en.json +314 -0
  108. package/dist/commonjs/index.d.ts +2 -3
  109. package/dist/commonjs/index.js +207 -4927
  110. package/dist/commonjs/styles/AppColors.d.ts +148 -0
  111. package/dist/commonjs/styles/AppColors.js +176 -0
  112. package/dist/commonjs/styles/common.d.ts +3 -0
  113. package/dist/commonjs/styles/common.js +201 -0
  114. package/dist/commonjs/styles/index.d.ts +219 -435
  115. package/dist/commonjs/styles/index.js +312 -488
  116. package/dist/commonjs/types/enums.d.ts +9 -0
  117. package/dist/commonjs/types/enums.js +4 -0
  118. package/dist/commonjs/types/index.d.ts +4 -111
  119. package/dist/commonjs/types/index.js +16 -0
  120. package/dist/commonjs/types/interfaces.d.ts +337 -0
  121. package/dist/commonjs/types/interfaces.js +2 -0
  122. package/dist/esm/assets/svgAssets.d.ts +3 -0
  123. package/dist/esm/assets/svgAssets.js +14 -0
  124. package/dist/esm/components/AnalyticsEventCard.d.ts +1 -14
  125. package/dist/esm/components/AnalyticsEventCard.js +118 -48
  126. package/dist/esm/components/AnalyticsGraph.d.ts +2 -6
  127. package/dist/esm/components/AnalyticsGraph.js +8 -8
  128. package/dist/esm/components/AnalyticsTabView.d.ts +15 -0
  129. package/dist/esm/components/AnalyticsTabView.js +151 -0
  130. package/dist/esm/components/AnimatedEntrance.d.ts +1 -1
  131. package/dist/esm/components/AnimatedEntrance.js +2 -2
  132. package/dist/esm/components/ApiDetailView.d.ts +22 -0
  133. package/dist/esm/components/ApiDetailView.js +264 -0
  134. package/dist/esm/components/ApisTabView.d.ts +33 -0
  135. package/dist/esm/components/ApisTabView.js +196 -0
  136. package/dist/esm/components/CodeSnippet.d.ts +1 -5
  137. package/dist/esm/components/CodeSnippet.js +34 -34
  138. package/dist/esm/components/ConsoleLogCard.d.ts +1 -8
  139. package/dist/esm/components/ConsoleLogCard.js +262 -409
  140. package/dist/esm/components/ConsoleLogDetailView.d.ts +9 -0
  141. package/dist/esm/components/ConsoleLogDetailView.js +271 -0
  142. package/dist/esm/components/ConsoleLogsTabView.d.ts +24 -0
  143. package/dist/esm/components/ConsoleLogsTabView.js +348 -0
  144. package/dist/esm/components/DiffViewer.js +4 -2
  145. package/dist/esm/components/DomainHeader.js +66 -41
  146. package/dist/esm/components/EmptyState.d.ts +2 -2
  147. package/dist/esm/components/EmptyState.js +2 -2
  148. package/dist/esm/components/EndOfListFooter.d.ts +8 -0
  149. package/dist/esm/components/EndOfListFooter.js +83 -0
  150. package/dist/esm/components/ErrorBoundary.d.ts +5 -14
  151. package/dist/esm/components/ErrorBoundary.js +29 -29
  152. package/dist/esm/components/FloatingBubble.d.ts +14 -0
  153. package/dist/esm/components/FloatingBubble.js +68 -0
  154. package/dist/esm/components/HeadersSection.js +5 -3
  155. package/dist/esm/components/HighlightText.d.ts +1 -1
  156. package/dist/esm/components/HighlightText.js +5 -7
  157. package/dist/esm/components/Inspector/AnalyticsTab.d.ts +3 -0
  158. package/dist/esm/components/Inspector/AnalyticsTab.js +194 -0
  159. package/dist/esm/components/Inspector/ConsoleTab.d.ts +3 -0
  160. package/dist/esm/components/Inspector/ConsoleTab.js +372 -0
  161. package/dist/esm/components/Inspector/FabLauncher.d.ts +3 -0
  162. package/dist/esm/components/Inspector/FabLauncher.js +49 -0
  163. package/dist/esm/components/Inspector/InsightsDashboard.d.ts +3 -0
  164. package/dist/esm/components/Inspector/InsightsDashboard.js +614 -0
  165. package/dist/esm/components/Inspector/InspectorContext.d.ts +5 -0
  166. package/dist/esm/components/Inspector/InspectorContext.js +13 -0
  167. package/dist/esm/components/Inspector/InspectorHeader.d.ts +3 -0
  168. package/dist/esm/components/Inspector/InspectorHeader.js +447 -0
  169. package/dist/esm/components/Inspector/LogDetail.d.ts +3 -0
  170. package/dist/esm/components/Inspector/LogDetail.js +925 -0
  171. package/dist/esm/components/Inspector/MainScreen.d.ts +3 -0
  172. package/dist/esm/components/Inspector/MainScreen.js +63 -0
  173. package/dist/esm/components/Inspector/NavigationTracker.d.ts +3 -0
  174. package/dist/esm/components/Inspector/NavigationTracker.js +10 -0
  175. package/dist/esm/components/Inspector/NetworkDetail.d.ts +3 -0
  176. package/dist/esm/components/Inspector/NetworkDetail.js +367 -0
  177. package/dist/esm/components/Inspector/NetworkTab.d.ts +3 -0
  178. package/dist/esm/components/Inspector/NetworkTab.js +243 -0
  179. package/dist/esm/components/Inspector/ReduxTab.d.ts +3 -0
  180. package/dist/esm/components/Inspector/ReduxTab.js +70 -0
  181. package/dist/esm/components/Inspector/SettingsPanel.d.ts +3 -0
  182. package/dist/esm/components/Inspector/SettingsPanel.js +1438 -0
  183. package/dist/esm/components/Inspector/TabBar.d.ts +3 -0
  184. package/dist/esm/components/Inspector/TabBar.js +90 -0
  185. package/dist/esm/components/Inspector/WebViewTab.d.ts +3 -0
  186. package/dist/esm/components/Inspector/WebViewTab.js +752 -0
  187. package/dist/esm/components/InspectorHeader.d.ts +19 -0
  188. package/dist/esm/components/InspectorHeader.js +323 -0
  189. package/dist/esm/components/InspectorTabBar.d.ts +16 -0
  190. package/dist/esm/components/InspectorTabBar.js +84 -0
  191. package/dist/esm/components/JsonViewer.d.ts +4 -1
  192. package/dist/esm/components/JsonViewer.js +111 -172
  193. package/dist/esm/components/LogCard.js +111 -88
  194. package/dist/esm/components/MetaAccordion.d.ts +1 -10
  195. package/dist/esm/components/MetaAccordion.js +23 -21
  196. package/dist/esm/components/NavigationTracker.d.ts +7 -0
  197. package/dist/esm/components/NavigationTracker.js +39 -0
  198. package/dist/esm/components/NetworkIcons.d.ts +6 -0
  199. package/dist/esm/components/NetworkIcons.js +46 -6
  200. package/dist/esm/components/ReduxTabView.d.ts +9 -0
  201. package/dist/esm/components/ReduxTabView.js +50 -0
  202. package/dist/esm/components/ReduxTreeView.js +243 -202
  203. package/dist/esm/components/SegmentedTabs.d.ts +15 -0
  204. package/dist/esm/components/SegmentedTabs.js +47 -0
  205. package/dist/esm/components/SettingsView.d.ts +13 -0
  206. package/dist/esm/components/SettingsView.js +321 -0
  207. package/dist/esm/components/TouchableScale.d.ts +2 -2
  208. package/dist/esm/components/TouchableScale.js +2 -2
  209. package/dist/esm/components/TreeNode.js +2 -2
  210. package/dist/esm/constants/index.js +1 -12
  211. package/dist/esm/constants/version.d.ts +1 -1
  212. package/dist/esm/constants/version.js +1 -1
  213. package/dist/esm/customHooks/analyticsLogger.d.ts +8 -0
  214. package/dist/esm/customHooks/analyticsLogger.js +37 -0
  215. package/dist/esm/customHooks/consoleLogger.js +137 -13
  216. package/dist/esm/customHooks/networkLogger.d.ts +0 -1
  217. package/dist/esm/customHooks/networkLogger.js +0 -1
  218. package/dist/esm/customHooks/reduxLogger.d.ts +2 -9
  219. package/dist/esm/enums/index.d.ts +39 -0
  220. package/dist/esm/enums/index.js +47 -0
  221. package/dist/esm/helpers/index.d.ts +27 -1
  222. package/dist/esm/helpers/index.js +180 -11
  223. package/dist/esm/helpers/settingsStore.d.ts +2 -24
  224. package/dist/esm/i18n/en.json +144 -0
  225. package/dist/esm/i18n/index.d.ts +2 -0
  226. package/dist/esm/i18n/index.js +22 -0
  227. package/dist/esm/i18n/locales/en.json +314 -0
  228. package/dist/esm/index.d.ts +2 -3
  229. package/dist/esm/index.js +207 -4923
  230. package/dist/esm/styles/AppColors.d.ts +148 -0
  231. package/dist/esm/styles/AppColors.js +176 -0
  232. package/dist/esm/styles/common.d.ts +3 -0
  233. package/dist/esm/styles/common.js +197 -0
  234. package/dist/esm/styles/index.d.ts +219 -435
  235. package/dist/esm/styles/index.js +312 -488
  236. package/dist/esm/types/enums.d.ts +9 -0
  237. package/dist/esm/types/enums.js +3 -0
  238. package/dist/esm/types/index.d.ts +4 -111
  239. package/dist/esm/types/index.js +2 -1
  240. package/dist/esm/types/interfaces.d.ts +337 -0
  241. package/dist/esm/types/interfaces.js +1 -0
  242. package/example/App.tsx +88 -1
  243. package/example/android/app/build.gradle +29 -1
  244. package/example/android/app/src/main/java/com/example/MainApplication.kt +25 -0
  245. package/example/android/build.gradle +31 -4
  246. package/example/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  247. package/example/android/gradle.properties +1 -0
  248. package/example/android/settings.gradle +20 -1
  249. package/example/package-lock.json +1 -1
  250. package/package.json +3 -1
@@ -2,11 +2,13 @@ import React, { useEffect, useState, useMemo } from 'react';
2
2
  import { LayoutAnimation, Platform, Pressable, StyleSheet, Text, TextInput, UIManager, View, ScrollView, ToastAndroid, Alert, } from 'react-native';
3
3
  import { AppColors } from '../styles/AppColors';
4
4
  import { AppFonts } from '../styles/AppFonts';
5
- import { ChevronIcon, FolderIcon, TrashIcon, HeaderPauseIcon, CopyIcon, SearchIcon, ClearIcon, ClockIcon, ExpandCollapseIcon, SignalIcon, LayersIcon, TerminalIcon, RequestIcon, DiffIcon, SortIcon, CalendarIcon, } from './NetworkIcons';
5
+ import { ChevronIcon, FolderIcon, TrashIcon, HeaderPauseIcon, SearchIcon, ClearIcon, ClockIcon, SignalIcon, LayersIcon, TerminalIcon, SortIcon, } from './NetworkIcons';
6
6
  import JsonViewer from './JsonViewer';
7
7
  import DiffViewer from './DiffViewer';
8
8
  import TouchableScale from './TouchableScale';
9
- import { copyToClipboard, getSize } from '../helpers';
9
+ import SegmentedTabs from './SegmentedTabs';
10
+ import CopyButton from './CopyButton';
11
+ import { getSize } from '../helpers';
10
12
  import { getCustomStorage } from '../helpers/settingsStore';
11
13
  // Enable LayoutAnimation for Android
12
14
  if (Platform.OS === 'android') {
@@ -244,139 +246,192 @@ export const ReduxTreeView = ({ state, actionHistory = [], lastActionMap = {}, s
244
246
  const fieldsCount = typeof sliceData === 'object' && sliceData !== null
245
247
  ? Object.keys(sliceData).length
246
248
  : 1;
249
+ const sliceTabs = [
250
+ { key: 'live', label: 'Live State' },
251
+ ...(isPersisted
252
+ ? [{ key: 'persisted', label: `Persisted (${getSize(persistedData)})` }]
253
+ : []),
254
+ { key: 'metadata', label: 'Metadata' },
255
+ ];
247
256
  return (<View style={{ flex: 1 }}>
248
- {/* Non-scrollable header */}
249
- <View style={{ paddingHorizontal: 6, paddingTop: 4 }}>
250
- <View style={styles.apiLikeInfoBar}>
251
- <View style={styles.apiBadgeRow}>
257
+ {/* Detail info header bar */}
258
+ <View style={styles.apiLikeInfoBar}>
259
+ <View style={{
260
+ flexDirection: 'row',
261
+ alignItems: 'center',
262
+ justifyContent: 'space-between',
263
+ marginBottom: 8,
264
+ }}>
265
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
252
266
  <View style={[styles.apiMethodBadge, { backgroundColor: AppColors.purple }]}>
253
267
  <Text style={styles.apiMethodBadgeText}>REDUX</Text>
254
268
  </View>
255
- <View style={[styles.apiMethodBadge, { backgroundColor: AppColors.purpleShade50, borderWidth: 1, borderColor: AppColors.purple + '30' }]}>
256
- <Text style={[styles.apiMethodBadgeText, { color: AppColors.purple }]}>SLICE</Text>
269
+ <View style={[
270
+ styles.apiMethodBadge,
271
+ {
272
+ backgroundColor: `${AppColors.brandPurple}18`,
273
+ borderWidth: 1,
274
+ borderColor: `${AppColors.brandPurple}40`,
275
+ },
276
+ ]}>
277
+ <Text style={[styles.apiMethodBadgeText, { color: AppColors.brandPurple }]}>
278
+ SLICE
279
+ </Text>
257
280
  </View>
258
- {isPersisted && (<View style={[styles.apiMethodBadge, { backgroundColor: '#10B981' }]}>
281
+ {isPersisted && (<View style={[styles.apiMethodBadge, { backgroundColor: AppColors.emerald500 }]}>
259
282
  <Text style={styles.apiMethodBadgeText}>PERSISTED</Text>
260
283
  </View>)}
261
284
  <View style={styles.apiChip}>
262
285
  <Text style={styles.apiChipText}>{getSize(sliceData)}</Text>
263
286
  </View>
264
287
  <View style={styles.apiChip}>
265
- <Text style={styles.apiChipText}>{fieldsCount} {fieldsCount === 1 ? 'field' : 'fields'}</Text>
288
+ <Text style={styles.apiChipText}>
289
+ {fieldsCount} {fieldsCount === 1 ? 'field' : 'fields'}
290
+ </Text>
266
291
  </View>
267
292
  </View>
268
293
 
269
- <Text style={styles.apiTitleText} selectable={true}>{activeSliceKey}</Text>
294
+ <CopyButton value={JSON.stringify(sliceDetailTab === 'live' ? sliceData : persistedData, null, 2)} label={`Slice '${activeSliceKey}'`}/>
295
+ </View>
270
296
 
271
- <View style={styles.apiMetaRow}>
272
- <ClockIcon color={AppColors.grayTextWeak} size={10}/>
273
- <Text style={styles.apiMetaText}>
274
- Last updated: {lastActionMap[activeSliceKey] ? lastActionMap[activeSliceKey].timestamp : 'Initial'}
275
- </Text>
276
- </View>
297
+ <Text style={styles.apiTitleText} selectable={true}>
298
+ {activeSliceKey}
299
+ </Text>
300
+
301
+ <View style={styles.apiMetaRow}>
302
+ <ClockIcon color={AppColors.grayTextWeak} size={11}/>
303
+ <Text style={styles.apiMetaText}>
304
+ Last updated: {lastActionMap[activeSliceKey] ? lastActionMap[activeSliceKey].timestamp : 'Initial'}
305
+ </Text>
277
306
  </View>
278
307
  </View>
279
308
 
280
- {/* Segment Control */}
281
- <View style={{
309
+ {/* Back button row + sub-tabs */}
310
+ <View style={{ paddingHorizontal: 12, paddingTop: 8, paddingBottom: 4 }}>
311
+ <View style={{
282
312
  flexDirection: 'row',
283
- backgroundColor: AppColors.grayBackground,
284
- borderRadius: 10,
285
- padding: 3,
286
- marginHorizontal: 6,
287
- marginBottom: 10,
288
- marginTop: 6,
289
- borderWidth: 1,
290
- borderColor: AppColors.grayBorderSecondary,
313
+ alignItems: 'center',
314
+ justifyContent: 'space-between',
315
+ marginBottom: 8,
291
316
  }}>
292
- {(isPersisted ? ['live', 'persisted'] : ['live']).map(tab => {
293
- const isActive = sliceDetailTab === tab;
294
- const getLabel = () => {
295
- if (tab === 'live')
296
- return 'Live State';
297
- return `Persisted (${getSize(persistedData)})`;
298
- };
299
- const getIcon = () => {
300
- const iconColor = isActive ? '#FFFFFF' : AppColors.grayText;
301
- if (tab === 'live')
302
- return <LayersIcon color={iconColor} size={11}/>;
303
- return <CalendarIcon color={iconColor} size={11}/>;
304
- };
305
- return (<Pressable key={tab} onPress={() => {
306
- animateLayout();
307
- setSliceDetailTab(tab);
308
- }} style={{
309
- flex: 1,
310
- paddingVertical: 6,
311
- flexDirection: 'row',
312
- alignItems: 'center',
313
- justifyContent: 'center',
314
- borderRadius: 8,
315
- backgroundColor: isActive ? AppColors.purple : 'transparent',
316
- gap: 4,
317
- }}>
318
- {getIcon()}
319
- <Text style={{
320
- fontFamily: AppFonts.interBold,
321
- fontSize: 10,
322
- color: isActive ? '#FFFFFF' : AppColors.grayText,
323
- }}>
324
- {getLabel()}
325
- </Text>
326
- </Pressable>);
327
- })}
328
- </View>
329
-
330
- {/* Scrollable Tab Content */}
331
- <View style={{ flex: 1, paddingHorizontal: 6 }}>
332
- {/* Back button + controls */}
333
- <View style={styles.contentDetailSubHeader}>
334
317
  <TouchableScale onPress={handleGoBackSlice} style={styles.backBtn} hitSlop={12}>
335
- <BackChevronIcon color={AppColors.purple} size={11}/>
318
+ <BackChevronIcon color={AppColors.purple} size={12}/>
336
319
  <Text style={styles.backBtnText}>State Slices</Text>
337
320
  </TouchableScale>
338
321
 
339
- <View style={styles.detailHeaderActions}>
340
- {isPersisted && sliceDetailTab === 'persisted' && (<TouchableScale onPress={handleClearPersistence} style={[styles.detailHeaderBtn, { marginRight: 8 }]} hitSlop={8}>
341
- <TrashIcon color={AppColors.errorColor} size={14}/>
342
- </TouchableScale>)}
322
+ {isPersisted && sliceDetailTab === 'persisted' && (<TouchableScale onPress={handleClearPersistence} style={[styles.detailHeaderBtn, { borderColor: `${AppColors.errorColor}40` }]} hitSlop={8}>
323
+ <TrashIcon color={AppColors.errorColor} size={14}/>
324
+ </TouchableScale>)}
325
+ </View>
343
326
 
344
- <TouchableScale onPress={() => {
327
+ <SegmentedTabs tabs={sliceTabs} activeKey={sliceDetailTab} onChange={key => {
345
328
  animateLayout();
346
- setSliceForceOpen(prev => (prev === true ? false : prev === false ? undefined : true));
347
- }} style={styles.detailHeaderBtn} hitSlop={8}>
348
- <ExpandCollapseIcon expanded={sliceForceOpen !== false} color={AppColors.purple} size={14}/>
349
- </TouchableScale>
329
+ setSliceDetailTab(key);
330
+ }}/>
331
+ </View>
350
332
 
351
- <TouchableScale onPress={() => {
352
- const dataToCopy = sliceDetailTab === 'live' ? sliceData : persistedData;
353
- copyToClipboard(dataToCopy, `Redux Slice '${activeSliceKey}' (${sliceDetailTab})`);
354
- }} style={styles.detailHeaderBtn} hitSlop={8}>
355
- <CopyIcon color={AppColors.purple} size={14}/>
356
- </TouchableScale>
333
+ {/* Search row (for live/persisted tabs) */}
334
+ {sliceDetailTab !== 'metadata' && (<View style={{ paddingHorizontal: 12, paddingTop: 4, paddingBottom: 4 }}>
335
+ <View style={{
336
+ flexDirection: 'row',
337
+ alignItems: 'center',
338
+ backgroundColor: AppColors.purpleShade50,
339
+ borderRadius: 8,
340
+ paddingHorizontal: 10,
341
+ borderWidth: 1,
342
+ borderColor: AppColors.dividerColor,
343
+ height: 36,
344
+ }}>
345
+ <SearchIcon color={AppColors.grayTextWeak} size={15}/>
346
+ <TextInput placeholder="Search in slice keys or values..." placeholderTextColor={AppColors.grayTextWeak} value={search} onChangeText={onSearchChange} style={{
347
+ flex: 1,
348
+ fontFamily: AppFonts.interRegular,
349
+ fontSize: 12,
350
+ color: AppColors.grayTextStrong,
351
+ paddingHorizontal: 8,
352
+ paddingVertical: 0,
353
+ }} autoCorrect={false} autoCapitalize="none"/>
354
+ {search.length > 0 && (<Pressable onPress={() => onSearchChange?.('')} hitSlop={10}>
355
+ <ClearIcon color={AppColors.grayTextWeak} size={13}/>
356
+ </Pressable>)}
357
357
  </View>
358
- </View>
358
+ </View>)}
359
359
 
360
- <ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 24 }} showsVerticalScrollIndicator={true}>
361
- <View style={{ padding: 12 }}>
362
- <JsonViewer data={sliceDetailTab === 'live' ? sliceData : (persistedData ?? 'No persisted data')} search={search} forceOpen={sliceForceOpen !== undefined ? sliceForceOpen : (isSearching ? true : undefined)} fullHeight={true}/>
363
- </View>
364
- </ScrollView>
365
- </View>
360
+ {/* Scrollable Tab Content */}
361
+ <ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingHorizontal: 12, paddingTop: 6, paddingBottom: 28, flexGrow: 1 }} showsVerticalScrollIndicator={true} keyboardShouldPersistTaps="handled">
362
+ {sliceDetailTab === 'metadata' ? (<View style={{
363
+ backgroundColor: AppColors.primaryLight,
364
+ borderRadius: 10,
365
+ borderWidth: 1,
366
+ borderColor: AppColors.dividerColor,
367
+ overflow: 'hidden',
368
+ paddingHorizontal: 12,
369
+ paddingVertical: 4,
370
+ }}>
371
+ {[
372
+ { label: 'Slice Name', value: activeSliceKey },
373
+ { label: 'Fields Count', value: `${fieldsCount} root keys` },
374
+ { label: 'State Size', value: getSize(sliceData) },
375
+ {
376
+ label: 'Persistence',
377
+ value: isPersisted ? `Persisted (${getSize(persistedData)})` : 'Not Persisted',
378
+ },
379
+ {
380
+ label: 'Last Dispatched Action',
381
+ value: lastActionMap[activeSliceKey] ? lastActionMap[activeSliceKey].type : 'None',
382
+ },
383
+ {
384
+ label: 'Last Updated At',
385
+ value: lastActionMap[activeSliceKey] ? lastActionMap[activeSliceKey].timestamp : 'Initial',
386
+ },
387
+ ].map((row, rIdx) => (<View key={rIdx} style={{
388
+ flexDirection: 'row',
389
+ justifyContent: 'space-between',
390
+ alignItems: 'center',
391
+ paddingVertical: 9,
392
+ borderBottomWidth: rIdx < 5 ? 1 : 0,
393
+ borderBottomColor: AppColors.grayBorderSecondary,
394
+ }}>
395
+ <Text style={{ fontFamily: AppFonts.interMedium, fontSize: 11.5, color: AppColors.grayTextWeak }}>
396
+ {row.label}
397
+ </Text>
398
+ <Text selectable style={{
399
+ fontFamily: AppFonts.interBold,
400
+ fontSize: 11.5,
401
+ color: AppColors.primaryBlack,
402
+ maxWidth: '60%',
403
+ textAlign: 'right',
404
+ }}>
405
+ {row.value}
406
+ </Text>
407
+ </View>))}
408
+ </View>) : (<JsonViewer data={sliceDetailTab === 'live' ? sliceData : (persistedData ?? 'No persisted data')} search={search} forceOpen={sliceForceOpen !== undefined ? sliceForceOpen : (isSearching ? true : undefined)} fullHeight={true}/>)}
409
+ </ScrollView>
366
410
  </View>);
367
411
  }
368
412
  // ── Render Detail View: Timeline Action ──
369
413
  if (activeTab === 'timeline' && selectedAction !== null) {
370
414
  const affectedSlices = selectedAction.affectedSlices || [];
415
+ const actionTabs = [
416
+ { key: 'payload', label: 'Payload' },
417
+ { key: 'diff', label: 'Diff Changes' },
418
+ { key: 'state', label: 'Snapshot' },
419
+ { key: 'metadata', label: 'Metadata' },
420
+ ];
371
421
  return (<View style={{ flex: 1 }}>
372
- {/* Non-scrollable header */}
373
- <View style={{ paddingHorizontal: 6, paddingTop: 4 }}>
374
- <View style={styles.apiLikeInfoBar}>
375
- <View style={styles.apiBadgeRow}>
422
+ {/* Detail info header bar */}
423
+ <View style={styles.apiLikeInfoBar}>
424
+ <View style={{
425
+ flexDirection: 'row',
426
+ alignItems: 'center',
427
+ justifyContent: 'space-between',
428
+ marginBottom: 8,
429
+ }}>
430
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
376
431
  <View style={[styles.apiMethodBadge, { backgroundColor: AppColors.purple }]}>
377
432
  <Text style={styles.apiMethodBadgeText}>REDUX</Text>
378
433
  </View>
379
- <View style={[styles.apiMethodBadge, { backgroundColor: '#F59E0B' }]}>
434
+ <View style={[styles.apiMethodBadge, { backgroundColor: AppColors.amber500 }]}>
380
435
  <Text style={styles.apiMethodBadgeText}>ACTION</Text>
381
436
  </View>
382
437
  <View style={styles.apiChip}>
@@ -387,119 +442,105 @@ export const ReduxTreeView = ({ state, actionHistory = [], lastActionMap = {}, s
387
442
  </View>
388
443
  </View>
389
444
 
390
- <Text style={styles.apiTitleText} selectable={true}>{selectedAction.type}</Text>
445
+ <CopyButton value={JSON.stringify(actionSubTab === 'payload'
446
+ ? selectedAction.payload
447
+ : actionSubTab === 'diff'
448
+ ? { prev: selectedAction.prevState, next: selectedAction.nextState }
449
+ : selectedAction.nextState, null, 2)} label={actionSubTab === 'payload' ? 'Action Payload' : 'State Snapshot'}/>
450
+ </View>
391
451
 
392
- <View style={styles.apiMetaRow}>
393
- <ClockIcon color={AppColors.grayTextWeak} size={10}/>
394
- <Text style={styles.apiMetaText}>Dispatched: {selectedAction.timestamp}</Text>
395
- </View>
452
+ <Text style={styles.apiTitleText} selectable={true}>
453
+ {selectedAction.type}
454
+ </Text>
455
+
456
+ <View style={styles.apiMetaRow}>
457
+ <ClockIcon color={AppColors.grayTextWeak} size={11}/>
458
+ <Text style={styles.apiMetaText}>
459
+ Dispatched: {selectedAction.timestamp}
460
+ </Text>
396
461
  </View>
397
- </View>
398
462
 
399
- {/* Affected Slices Tags list */}
400
- {affectedSlices.length > 0 && (<View style={styles.detailAffectedTags}>
401
- <Text style={styles.affectedTagsLabel}>AFFECTED SLICES:</Text>
402
- <View style={styles.detailTagsList}>
403
- {affectedSlices.map(slice => (<View key={slice} style={styles.sliceTag}>
404
- <Text style={styles.sliceTagText}>{slice}</Text>
405
- </View>))}
406
- </View>
407
- </View>)}
463
+ {/* Affected Slices Tags list */}
464
+ {affectedSlices.length > 0 && (<View style={[styles.detailAffectedTags, { marginTop: 6, paddingHorizontal: 0, paddingBottom: 0 }]}>
465
+ <Text style={styles.affectedTagsLabel}>AFFECTED SLICES:</Text>
466
+ <View style={styles.detailTagsList}>
467
+ {affectedSlices.map(slice => (<View key={slice} style={styles.sliceTag}>
468
+ <Text style={styles.sliceTagText}>{slice}</Text>
469
+ </View>))}
470
+ </View>
471
+ </View>)}
472
+ </View>
408
473
 
409
- {/* Segment Control */}
410
- <View style={{
474
+ {/* Back button row + sub-tabs */}
475
+ <View style={{ paddingHorizontal: 12, paddingTop: 8, paddingBottom: 4 }}>
476
+ <View style={{
411
477
  flexDirection: 'row',
412
- backgroundColor: AppColors.grayBackground,
413
- borderRadius: 10,
414
- padding: 3,
415
- marginHorizontal: 6,
416
- marginBottom: 10,
417
- marginTop: 6,
418
- borderWidth: 1,
419
- borderColor: AppColors.grayBorderSecondary,
478
+ alignItems: 'center',
479
+ justifyContent: 'space-between',
480
+ marginBottom: 8,
420
481
  }}>
421
- {['payload', 'diff', 'state'].map(tab => {
422
- const isActive = actionSubTab === tab;
423
- const getLabel = () => {
424
- if (tab === 'payload')
425
- return 'Payload';
426
- if (tab === 'diff')
427
- return 'Diff Changes';
428
- return 'Snapshot';
429
- };
430
- const getIcon = () => {
431
- const iconColor = isActive ? '#FFFFFF' : AppColors.grayText;
432
- if (tab === 'payload')
433
- return <RequestIcon color={iconColor} size={11}/>;
434
- if (tab === 'diff')
435
- return <DiffIcon color={iconColor} size={11}/>;
436
- return <LayersIcon color={iconColor} size={11}/>;
437
- };
438
- return (<Pressable key={tab} onPress={() => {
439
- animateLayout();
440
- setActionSubTab(tab);
441
- }} style={{
442
- flex: 1,
443
- paddingVertical: 6,
444
- flexDirection: 'row',
445
- alignItems: 'center',
446
- justifyContent: 'center',
447
- borderRadius: 8,
448
- backgroundColor: isActive ? AppColors.purple : 'transparent',
449
- gap: 4,
450
- }}>
451
- {getIcon()}
452
- <Text style={{
453
- fontFamily: AppFonts.interBold,
454
- fontSize: 10,
455
- color: isActive ? '#FFFFFF' : AppColors.grayText,
456
- }}>
457
- {getLabel()}
458
- </Text>
459
- </Pressable>);
460
- })}
461
- </View>
462
-
463
- {/* Scrollable Tab Content */}
464
- <View style={{ flex: 1, paddingHorizontal: 6 }}>
465
- {/* Back button + controls */}
466
- <View style={styles.contentDetailSubHeader}>
467
482
  <TouchableScale onPress={handleGoBackAction} style={styles.backBtn} hitSlop={12}>
468
- <BackChevronIcon color={AppColors.purple} size={11}/>
469
- <Text style={styles.backBtnText}>Actions</Text>
483
+ <BackChevronIcon color={AppColors.purple} size={12}/>
484
+ <Text style={styles.backBtnText}>Actions Timeline</Text>
470
485
  </TouchableScale>
486
+ </View>
471
487
 
472
- {(actionSubTab === 'payload' || actionSubTab === 'state') && (<View style={styles.detailHeaderActions}>
473
- <TouchableScale onPress={() => {
474
- animateLayout();
475
- setActionForceOpen(prev => (prev === true ? false : prev === false ? undefined : true));
476
- }} style={styles.detailHeaderBtn} hitSlop={8}>
477
- <ExpandCollapseIcon expanded={actionForceOpen !== false} color={AppColors.purple} size={14}/>
478
- </TouchableScale>
488
+ <SegmentedTabs tabs={actionTabs} activeKey={actionSubTab} onChange={key => {
489
+ animateLayout();
490
+ setActionSubTab(key);
491
+ }}/>
492
+ </View>
479
493
 
480
- <TouchableScale onPress={() => {
481
- const dataToCopy = actionSubTab === 'payload' ? selectedAction.payload : selectedAction.nextState;
482
- copyToClipboard(dataToCopy, actionSubTab === 'payload' ? 'Action payload' : 'State snapshot');
483
- }} style={styles.detailHeaderBtn} hitSlop={8}>
484
- <CopyIcon color={AppColors.purple} size={14}/>
485
- </TouchableScale>
486
- </View>)}
487
- </View>
494
+ {/* Scrollable Tab Content */}
495
+ <ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingHorizontal: 12, paddingTop: 6, paddingBottom: 28, flexGrow: 1 }} showsVerticalScrollIndicator={true} keyboardShouldPersistTaps="handled">
496
+ {actionSubTab === 'payload' && (<JsonViewer data={selectedAction.payload ?? 'No payload data'} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>)}
488
497
 
489
- <ScrollView style={{ flex: 1 }} contentContainerStyle={{ paddingBottom: 24 }} showsVerticalScrollIndicator={true}>
490
- {actionSubTab === 'payload' && (<View style={{ padding: 12 }}>
491
- <JsonViewer data={selectedAction.payload ?? 'No payload data'} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>
492
- </View>)}
498
+ {actionSubTab === 'diff' && (<DiffViewer oldData={selectedAction.prevState} newData={selectedAction.nextState}/>)}
493
499
 
494
- {actionSubTab === 'diff' && (<View style={{ padding: 12 }}>
495
- <DiffViewer oldData={selectedAction.prevState} newData={selectedAction.nextState}/>
496
- </View>)}
500
+ {actionSubTab === 'state' && (<JsonViewer data={selectedAction.nextState} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>)}
497
501
 
498
- {actionSubTab === 'state' && (<View style={{ padding: 12 }}>
499
- <JsonViewer data={selectedAction.nextState} wrap forceOpen={actionForceOpen !== undefined ? actionForceOpen : undefined} fullHeight={true}/>
500
- </View>)}
501
- </ScrollView>
502
- </View>
502
+ {actionSubTab === 'metadata' && (<View style={{
503
+ backgroundColor: AppColors.primaryLight,
504
+ borderRadius: 10,
505
+ borderWidth: 1,
506
+ borderColor: AppColors.dividerColor,
507
+ overflow: 'hidden',
508
+ paddingHorizontal: 12,
509
+ paddingVertical: 4,
510
+ }}>
511
+ {[
512
+ { label: 'Action Type', value: selectedAction.type },
513
+ { label: 'Action ID', value: `#${selectedAction.id}` },
514
+ { label: 'Dispatched At', value: selectedAction.timestamp },
515
+ { label: 'Payload Size', value: getSize(selectedAction.payload) },
516
+ { label: 'Snapshot Size', value: getSize(selectedAction.nextState) },
517
+ {
518
+ label: 'Affected Slices',
519
+ value: affectedSlices.length > 0 ? affectedSlices.join(', ') : 'None',
520
+ },
521
+ ].map((row, rIdx) => (<View key={rIdx} style={{
522
+ flexDirection: 'row',
523
+ justifyContent: 'space-between',
524
+ alignItems: 'center',
525
+ paddingVertical: 9,
526
+ borderBottomWidth: rIdx < 5 ? 1 : 0,
527
+ borderBottomColor: AppColors.grayBorderSecondary,
528
+ }}>
529
+ <Text style={{ fontFamily: AppFonts.interMedium, fontSize: 11.5, color: AppColors.grayTextWeak }}>
530
+ {row.label}
531
+ </Text>
532
+ <Text selectable style={{
533
+ fontFamily: AppFonts.interBold,
534
+ fontSize: 11.5,
535
+ color: AppColors.primaryBlack,
536
+ maxWidth: '60%',
537
+ textAlign: 'right',
538
+ }}>
539
+ {row.value}
540
+ </Text>
541
+ </View>))}
542
+ </View>)}
543
+ </ScrollView>
503
544
  </View>);
504
545
  }
505
546
  // ── Render List Views (Default) ──
@@ -637,7 +678,7 @@ export const ReduxTreeView = ({ state, actionHistory = [], lastActionMap = {}, s
637
678
  ? 'No actions match your search.'
638
679
  : 'No actions dispatched yet. Trigger an action in the app to populate history.'}
639
680
  </Text>
640
- </View>) : (filteredActionHistory.map((action, index) => {
681
+ </View>) : (filteredActionHistory.map(action => {
641
682
  const id = action.id;
642
683
  const affectedSlices = action.affectedSlices || [];
643
684
  return (<TouchableScale key={id} onPress={() => {
@@ -1080,7 +1121,7 @@ const styles = StyleSheet.create({
1080
1121
  color: AppColors.grayText,
1081
1122
  },
1082
1123
  subTabPillTextActive: {
1083
- color: '#FFFFFF',
1124
+ color: AppColors.white,
1084
1125
  fontFamily: AppFonts.interBold,
1085
1126
  },
1086
1127
  detailScrollContent: {
@@ -1130,16 +1171,16 @@ const styles = StyleSheet.create({
1130
1171
  apiMethodBadgeText: {
1131
1172
  fontFamily: AppFonts.interBold,
1132
1173
  fontSize: 9.5,
1133
- color: '#FFFFFF',
1174
+ color: AppColors.white,
1134
1175
  letterSpacing: 0.5,
1135
1176
  },
1136
1177
  apiChip: {
1137
1178
  paddingHorizontal: 7,
1138
1179
  paddingVertical: 2,
1139
1180
  borderRadius: 4,
1140
- backgroundColor: 'rgba(104,75,155,0.06)',
1181
+ backgroundColor: `${AppColors.purple}0F`,
1141
1182
  borderWidth: 1,
1142
- borderColor: 'rgba(104,75,155,0.15)',
1183
+ borderColor: `${AppColors.purple}26`,
1143
1184
  alignItems: 'center',
1144
1185
  justifyContent: 'center',
1145
1186
  },
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+ export interface SegmentedTab {
4
+ key: string;
5
+ label: string;
6
+ icon?: (isActive: boolean) => React.ReactNode;
7
+ }
8
+ interface SegmentedTabsProps {
9
+ tabs: SegmentedTab[];
10
+ activeKey: string;
11
+ onChange: (key: string) => void;
12
+ style?: ViewStyle | ViewStyle[];
13
+ }
14
+ declare const SegmentedTabs: ({ tabs, activeKey, onChange, style }: SegmentedTabsProps) => React.JSX.Element;
15
+ export default SegmentedTabs;
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { Pressable, Text, View } from 'react-native';
3
+ import { AppColors } from '../styles/AppColors';
4
+ import { AppFonts } from '../styles/AppFonts';
5
+ const SegmentedTabs = ({ tabs, activeKey, onChange, style }) => (<View style={[
6
+ {
7
+ flexDirection: 'row',
8
+ borderRadius: 8,
9
+ overflow: 'hidden',
10
+ borderWidth: 1,
11
+ borderColor: AppColors.dividerColor,
12
+ backgroundColor: AppColors.primaryLight,
13
+ },
14
+ style,
15
+ ]}>
16
+ {tabs.map((tab, index) => {
17
+ const isActive = activeKey === tab.key;
18
+ return (<Pressable key={tab.key} onPress={() => onChange(tab.key)} style={{
19
+ flex: 1,
20
+ paddingVertical: 8,
21
+ paddingHorizontal: 8,
22
+ backgroundColor: isActive
23
+ ? AppColors.brandPurple
24
+ : AppColors.primaryLight,
25
+ borderRightWidth: index < tabs.length - 1 ? 1 : 0,
26
+ borderRightColor: AppColors.dividerColor,
27
+ alignItems: 'center',
28
+ justifyContent: 'center',
29
+ gap: 4,
30
+ flexDirection: 'row',
31
+ }}>
32
+ {tab.icon ? tab.icon(isActive) : null}
33
+ <Text style={{
34
+ fontFamily: AppFonts.interBold,
35
+ fontSize: 10,
36
+ color: isActive
37
+ ? AppColors.white
38
+ : AppColors.grayTextWeak,
39
+ textTransform: 'capitalize',
40
+ letterSpacing: 0.3,
41
+ }}>
42
+ {tab.label}
43
+ </Text>
44
+ </Pressable>);
45
+ })}
46
+ </View>);
47
+ export default SegmentedTabs;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { ActiveTab } from '../types';
3
+ interface SettingsViewProps {
4
+ headerTopPadding: number;
5
+ activeTab?: ActiveTab;
6
+ defaultTab: ActiveTab;
7
+ tabVisibility: Record<string, boolean>;
8
+ onCloseSettings: () => void;
9
+ onUpdateTabVisibility: (key: ActiveTab, val: boolean) => void;
10
+ onSetDefaultTab: (key: ActiveTab) => void;
11
+ }
12
+ export declare const SettingsView: React.FC<SettingsViewProps>;
13
+ export default SettingsView;