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.
- package/README.md +9 -34
- package/dist/commonjs/assets/svgAssets.d.ts +3 -0
- package/dist/commonjs/assets/svgAssets.js +17 -0
- package/dist/commonjs/components/AnalyticsEventCard.d.ts +1 -14
- package/dist/commonjs/components/AnalyticsEventCard.js +120 -50
- package/dist/commonjs/components/AnalyticsGraph.d.ts +2 -6
- package/dist/commonjs/components/AnalyticsGraph.js +8 -8
- package/dist/commonjs/components/AnalyticsTabView.d.ts +15 -0
- package/dist/commonjs/components/AnalyticsTabView.js +157 -0
- package/dist/commonjs/components/AnimatedEntrance.d.ts +1 -1
- package/dist/commonjs/components/AnimatedEntrance.js +2 -2
- package/dist/commonjs/components/ApiDetailView.d.ts +22 -0
- package/dist/commonjs/components/ApiDetailView.js +304 -0
- package/dist/commonjs/components/ApisTabView.d.ts +33 -0
- package/dist/commonjs/components/ApisTabView.js +235 -0
- package/dist/commonjs/components/CodeSnippet.d.ts +1 -5
- package/dist/commonjs/components/CodeSnippet.js +34 -34
- package/dist/commonjs/components/ConsoleLogCard.d.ts +1 -8
- package/dist/commonjs/components/ConsoleLogCard.js +262 -442
- package/dist/commonjs/components/ConsoleLogDetailView.d.ts +9 -0
- package/dist/commonjs/components/ConsoleLogDetailView.js +278 -0
- package/dist/commonjs/components/ConsoleLogsTabView.d.ts +24 -0
- package/dist/commonjs/components/ConsoleLogsTabView.js +354 -0
- package/dist/commonjs/components/DiffViewer.js +4 -2
- package/dist/commonjs/components/DomainHeader.js +66 -41
- package/dist/commonjs/components/EmptyState.d.ts +2 -2
- package/dist/commonjs/components/EmptyState.js +2 -2
- package/dist/commonjs/components/EndOfListFooter.d.ts +8 -0
- package/dist/commonjs/components/EndOfListFooter.js +90 -0
- package/dist/commonjs/components/ErrorBoundary.d.ts +5 -14
- package/dist/commonjs/components/ErrorBoundary.js +28 -28
- package/dist/commonjs/components/FloatingBubble.d.ts +14 -0
- package/dist/commonjs/components/FloatingBubble.js +75 -0
- package/dist/commonjs/components/HeadersSection.js +5 -3
- package/dist/commonjs/components/HighlightText.d.ts +1 -1
- package/dist/commonjs/components/HighlightText.js +5 -7
- package/dist/commonjs/components/Inspector/AnalyticsTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +232 -0
- package/dist/commonjs/components/Inspector/ConsoleTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/ConsoleTab.js +410 -0
- package/dist/commonjs/components/Inspector/FabLauncher.d.ts +3 -0
- package/dist/commonjs/components/Inspector/FabLauncher.js +54 -0
- package/dist/commonjs/components/Inspector/InsightsDashboard.d.ts +3 -0
- package/dist/commonjs/components/Inspector/InsightsDashboard.js +619 -0
- package/dist/commonjs/components/Inspector/InspectorContext.d.ts +5 -0
- package/dist/commonjs/components/Inspector/InspectorContext.js +18 -0
- package/dist/commonjs/components/Inspector/InspectorHeader.d.ts +3 -0
- package/dist/commonjs/components/Inspector/InspectorHeader.js +452 -0
- package/dist/commonjs/components/Inspector/LogDetail.d.ts +3 -0
- package/dist/commonjs/components/Inspector/LogDetail.js +963 -0
- package/dist/commonjs/components/Inspector/MainScreen.d.ts +3 -0
- package/dist/commonjs/components/Inspector/MainScreen.js +68 -0
- package/dist/commonjs/components/Inspector/NavigationTracker.d.ts +3 -0
- package/dist/commonjs/components/Inspector/NavigationTracker.js +12 -0
- package/dist/commonjs/components/Inspector/NetworkDetail.d.ts +3 -0
- package/dist/commonjs/components/Inspector/NetworkDetail.js +405 -0
- package/dist/commonjs/components/Inspector/NetworkTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/NetworkTab.js +281 -0
- package/dist/commonjs/components/Inspector/ReduxTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/ReduxTab.js +75 -0
- package/dist/commonjs/components/Inspector/SettingsPanel.d.ts +3 -0
- package/dist/commonjs/components/Inspector/SettingsPanel.js +1476 -0
- package/dist/commonjs/components/Inspector/TabBar.d.ts +3 -0
- package/dist/commonjs/components/Inspector/TabBar.js +95 -0
- package/dist/commonjs/components/Inspector/WebViewTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/WebViewTab.js +757 -0
- package/dist/commonjs/components/InspectorHeader.d.ts +19 -0
- package/dist/commonjs/components/InspectorHeader.js +329 -0
- package/dist/commonjs/components/InspectorTabBar.d.ts +16 -0
- package/dist/commonjs/components/InspectorTabBar.js +90 -0
- package/dist/commonjs/components/JsonViewer.d.ts +4 -1
- package/dist/commonjs/components/JsonViewer.js +110 -171
- package/dist/commonjs/components/LogCard.js +109 -86
- package/dist/commonjs/components/MetaAccordion.d.ts +1 -10
- package/dist/commonjs/components/MetaAccordion.js +23 -21
- package/dist/commonjs/components/NavigationTracker.d.ts +7 -0
- package/dist/commonjs/components/NavigationTracker.js +76 -0
- package/dist/commonjs/components/NetworkIcons.d.ts +6 -0
- package/dist/commonjs/components/NetworkIcons.js +54 -8
- package/dist/commonjs/components/ReduxTabView.d.ts +9 -0
- package/dist/commonjs/components/ReduxTabView.js +56 -0
- package/dist/commonjs/components/ReduxTreeView.js +241 -200
- package/dist/commonjs/components/SegmentedTabs.d.ts +15 -0
- package/dist/commonjs/components/SegmentedTabs.js +52 -0
- package/dist/commonjs/components/SettingsView.d.ts +13 -0
- package/dist/commonjs/components/SettingsView.js +328 -0
- package/dist/commonjs/components/TouchableScale.d.ts +2 -2
- package/dist/commonjs/components/TouchableScale.js +2 -2
- package/dist/commonjs/components/TreeNode.js +2 -2
- package/dist/commonjs/constants/index.js +1 -12
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +8 -0
- package/dist/commonjs/customHooks/analyticsLogger.js +42 -1
- package/dist/commonjs/customHooks/consoleLogger.js +137 -13
- package/dist/commonjs/customHooks/networkLogger.d.ts +0 -1
- package/dist/commonjs/customHooks/networkLogger.js +0 -1
- package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -9
- package/dist/commonjs/enums/index.d.ts +39 -0
- package/dist/commonjs/enums/index.js +50 -0
- package/dist/commonjs/helpers/index.d.ts +27 -1
- package/dist/commonjs/helpers/index.js +187 -12
- package/dist/commonjs/helpers/settingsStore.d.ts +2 -24
- package/dist/commonjs/i18n/en.json +144 -0
- package/dist/commonjs/i18n/index.d.ts +2 -0
- package/dist/commonjs/i18n/index.js +27 -0
- package/dist/commonjs/i18n/locales/en.json +314 -0
- package/dist/commonjs/index.d.ts +2 -3
- package/dist/commonjs/index.js +207 -4927
- package/dist/commonjs/styles/AppColors.d.ts +148 -0
- package/dist/commonjs/styles/AppColors.js +176 -0
- package/dist/commonjs/styles/common.d.ts +3 -0
- package/dist/commonjs/styles/common.js +201 -0
- package/dist/commonjs/styles/index.d.ts +219 -435
- package/dist/commonjs/styles/index.js +312 -488
- package/dist/commonjs/types/enums.d.ts +9 -0
- package/dist/commonjs/types/enums.js +4 -0
- package/dist/commonjs/types/index.d.ts +4 -111
- package/dist/commonjs/types/index.js +16 -0
- package/dist/commonjs/types/interfaces.d.ts +337 -0
- package/dist/commonjs/types/interfaces.js +2 -0
- package/dist/esm/assets/svgAssets.d.ts +3 -0
- package/dist/esm/assets/svgAssets.js +14 -0
- package/dist/esm/components/AnalyticsEventCard.d.ts +1 -14
- package/dist/esm/components/AnalyticsEventCard.js +118 -48
- package/dist/esm/components/AnalyticsGraph.d.ts +2 -6
- package/dist/esm/components/AnalyticsGraph.js +8 -8
- package/dist/esm/components/AnalyticsTabView.d.ts +15 -0
- package/dist/esm/components/AnalyticsTabView.js +151 -0
- package/dist/esm/components/AnimatedEntrance.d.ts +1 -1
- package/dist/esm/components/AnimatedEntrance.js +2 -2
- package/dist/esm/components/ApiDetailView.d.ts +22 -0
- package/dist/esm/components/ApiDetailView.js +264 -0
- package/dist/esm/components/ApisTabView.d.ts +33 -0
- package/dist/esm/components/ApisTabView.js +196 -0
- package/dist/esm/components/CodeSnippet.d.ts +1 -5
- package/dist/esm/components/CodeSnippet.js +34 -34
- package/dist/esm/components/ConsoleLogCard.d.ts +1 -8
- package/dist/esm/components/ConsoleLogCard.js +262 -409
- package/dist/esm/components/ConsoleLogDetailView.d.ts +9 -0
- package/dist/esm/components/ConsoleLogDetailView.js +271 -0
- package/dist/esm/components/ConsoleLogsTabView.d.ts +24 -0
- package/dist/esm/components/ConsoleLogsTabView.js +348 -0
- package/dist/esm/components/DiffViewer.js +4 -2
- package/dist/esm/components/DomainHeader.js +66 -41
- package/dist/esm/components/EmptyState.d.ts +2 -2
- package/dist/esm/components/EmptyState.js +2 -2
- package/dist/esm/components/EndOfListFooter.d.ts +8 -0
- package/dist/esm/components/EndOfListFooter.js +83 -0
- package/dist/esm/components/ErrorBoundary.d.ts +5 -14
- package/dist/esm/components/ErrorBoundary.js +29 -29
- package/dist/esm/components/FloatingBubble.d.ts +14 -0
- package/dist/esm/components/FloatingBubble.js +68 -0
- package/dist/esm/components/HeadersSection.js +5 -3
- package/dist/esm/components/HighlightText.d.ts +1 -1
- package/dist/esm/components/HighlightText.js +5 -7
- package/dist/esm/components/Inspector/AnalyticsTab.d.ts +3 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +194 -0
- package/dist/esm/components/Inspector/ConsoleTab.d.ts +3 -0
- package/dist/esm/components/Inspector/ConsoleTab.js +372 -0
- package/dist/esm/components/Inspector/FabLauncher.d.ts +3 -0
- package/dist/esm/components/Inspector/FabLauncher.js +49 -0
- package/dist/esm/components/Inspector/InsightsDashboard.d.ts +3 -0
- package/dist/esm/components/Inspector/InsightsDashboard.js +614 -0
- package/dist/esm/components/Inspector/InspectorContext.d.ts +5 -0
- package/dist/esm/components/Inspector/InspectorContext.js +13 -0
- package/dist/esm/components/Inspector/InspectorHeader.d.ts +3 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +447 -0
- package/dist/esm/components/Inspector/LogDetail.d.ts +3 -0
- package/dist/esm/components/Inspector/LogDetail.js +925 -0
- package/dist/esm/components/Inspector/MainScreen.d.ts +3 -0
- package/dist/esm/components/Inspector/MainScreen.js +63 -0
- package/dist/esm/components/Inspector/NavigationTracker.d.ts +3 -0
- package/dist/esm/components/Inspector/NavigationTracker.js +10 -0
- package/dist/esm/components/Inspector/NetworkDetail.d.ts +3 -0
- package/dist/esm/components/Inspector/NetworkDetail.js +367 -0
- package/dist/esm/components/Inspector/NetworkTab.d.ts +3 -0
- package/dist/esm/components/Inspector/NetworkTab.js +243 -0
- package/dist/esm/components/Inspector/ReduxTab.d.ts +3 -0
- package/dist/esm/components/Inspector/ReduxTab.js +70 -0
- package/dist/esm/components/Inspector/SettingsPanel.d.ts +3 -0
- package/dist/esm/components/Inspector/SettingsPanel.js +1438 -0
- package/dist/esm/components/Inspector/TabBar.d.ts +3 -0
- package/dist/esm/components/Inspector/TabBar.js +90 -0
- package/dist/esm/components/Inspector/WebViewTab.d.ts +3 -0
- package/dist/esm/components/Inspector/WebViewTab.js +752 -0
- package/dist/esm/components/InspectorHeader.d.ts +19 -0
- package/dist/esm/components/InspectorHeader.js +323 -0
- package/dist/esm/components/InspectorTabBar.d.ts +16 -0
- package/dist/esm/components/InspectorTabBar.js +84 -0
- package/dist/esm/components/JsonViewer.d.ts +4 -1
- package/dist/esm/components/JsonViewer.js +111 -172
- package/dist/esm/components/LogCard.js +111 -88
- package/dist/esm/components/MetaAccordion.d.ts +1 -10
- package/dist/esm/components/MetaAccordion.js +23 -21
- package/dist/esm/components/NavigationTracker.d.ts +7 -0
- package/dist/esm/components/NavigationTracker.js +39 -0
- package/dist/esm/components/NetworkIcons.d.ts +6 -0
- package/dist/esm/components/NetworkIcons.js +46 -6
- package/dist/esm/components/ReduxTabView.d.ts +9 -0
- package/dist/esm/components/ReduxTabView.js +50 -0
- package/dist/esm/components/ReduxTreeView.js +243 -202
- package/dist/esm/components/SegmentedTabs.d.ts +15 -0
- package/dist/esm/components/SegmentedTabs.js +47 -0
- package/dist/esm/components/SettingsView.d.ts +13 -0
- package/dist/esm/components/SettingsView.js +321 -0
- package/dist/esm/components/TouchableScale.d.ts +2 -2
- package/dist/esm/components/TouchableScale.js +2 -2
- package/dist/esm/components/TreeNode.js +2 -2
- package/dist/esm/constants/index.js +1 -12
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.d.ts +8 -0
- package/dist/esm/customHooks/analyticsLogger.js +37 -0
- package/dist/esm/customHooks/consoleLogger.js +137 -13
- package/dist/esm/customHooks/networkLogger.d.ts +0 -1
- package/dist/esm/customHooks/networkLogger.js +0 -1
- package/dist/esm/customHooks/reduxLogger.d.ts +2 -9
- package/dist/esm/enums/index.d.ts +39 -0
- package/dist/esm/enums/index.js +47 -0
- package/dist/esm/helpers/index.d.ts +27 -1
- package/dist/esm/helpers/index.js +180 -11
- package/dist/esm/helpers/settingsStore.d.ts +2 -24
- package/dist/esm/i18n/en.json +144 -0
- package/dist/esm/i18n/index.d.ts +2 -0
- package/dist/esm/i18n/index.js +22 -0
- package/dist/esm/i18n/locales/en.json +314 -0
- package/dist/esm/index.d.ts +2 -3
- package/dist/esm/index.js +207 -4923
- package/dist/esm/styles/AppColors.d.ts +148 -0
- package/dist/esm/styles/AppColors.js +176 -0
- package/dist/esm/styles/common.d.ts +3 -0
- package/dist/esm/styles/common.js +197 -0
- package/dist/esm/styles/index.d.ts +219 -435
- package/dist/esm/styles/index.js +312 -488
- package/dist/esm/types/enums.d.ts +9 -0
- package/dist/esm/types/enums.js +3 -0
- package/dist/esm/types/index.d.ts +4 -111
- package/dist/esm/types/index.js +2 -1
- package/dist/esm/types/interfaces.d.ts +337 -0
- package/dist/esm/types/interfaces.js +1 -0
- package/example/App.tsx +88 -1
- package/example/android/app/build.gradle +29 -1
- package/example/android/app/src/main/java/com/example/MainApplication.kt +25 -0
- package/example/android/build.gradle +31 -4
- package/example/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/example/android/gradle.properties +1 -0
- package/example/android/settings.gradle +20 -1
- package/example/package-lock.json +1 -1
- 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,
|
|
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
|
|
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
|
-
{/*
|
|
249
|
-
<View style={
|
|
250
|
-
<View style={
|
|
251
|
-
|
|
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={[
|
|
256
|
-
|
|
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:
|
|
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}>
|
|
288
|
+
<Text style={styles.apiChipText}>
|
|
289
|
+
{fieldsCount} {fieldsCount === 1 ? 'field' : 'fields'}
|
|
290
|
+
</Text>
|
|
266
291
|
</View>
|
|
267
292
|
</View>
|
|
268
293
|
|
|
269
|
-
<
|
|
294
|
+
<CopyButton value={JSON.stringify(sliceDetailTab === 'live' ? sliceData : persistedData, null, 2)} label={`Slice '${activeSliceKey}'`}/>
|
|
295
|
+
</View>
|
|
270
296
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
-
{/*
|
|
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
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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={
|
|
318
|
+
<BackChevronIcon color={AppColors.purple} size={12}/>
|
|
336
319
|
<Text style={styles.backBtnText}>State Slices</Text>
|
|
337
320
|
</TouchableScale>
|
|
338
321
|
|
|
339
|
-
<
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
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
|
-
|
|
327
|
+
<SegmentedTabs tabs={sliceTabs} activeKey={sliceDetailTab} onChange={key => {
|
|
345
328
|
animateLayout();
|
|
346
|
-
|
|
347
|
-
}}
|
|
348
|
-
|
|
349
|
-
</TouchableScale>
|
|
329
|
+
setSliceDetailTab(key);
|
|
330
|
+
}}/>
|
|
331
|
+
</View>
|
|
350
332
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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
|
-
{/*
|
|
373
|
-
<View style={
|
|
374
|
-
<View style={
|
|
375
|
-
|
|
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:
|
|
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
|
-
<
|
|
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
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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
|
-
{/*
|
|
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
|
-
|
|
413
|
-
|
|
414
|
-
|
|
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={
|
|
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
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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
|
-
|
|
481
|
-
|
|
482
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
1181
|
+
backgroundColor: `${AppColors.purple}0F`,
|
|
1141
1182
|
borderWidth: 1,
|
|
1142
|
-
borderColor:
|
|
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;
|