react-native-inapp-inspector 2.0.2 → 2.0.3

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 (42) hide show
  1. package/dist/commonjs/components/AppHeaderLogo.js +21 -2
  2. package/dist/commonjs/components/Inspector/InspectorHeader.js +84 -11
  3. package/dist/commonjs/components/Inspector/MainScreen.js +6 -2
  4. package/dist/commonjs/components/Inspector/NpmUpdateToast.d.ts +3 -0
  5. package/dist/commonjs/components/Inspector/NpmUpdateToast.js +288 -0
  6. package/dist/commonjs/components/Inspector/SettingsPanel.js +192 -1
  7. package/dist/commonjs/components/Inspector/TelemetryConsentModal.js +218 -71
  8. package/dist/commonjs/constants/version.d.ts +1 -1
  9. package/dist/commonjs/constants/version.js +1 -1
  10. package/dist/commonjs/helpers/telemetry.js +4 -4
  11. package/dist/commonjs/index.js +14 -2
  12. package/dist/commonjs/types/interfaces.d.ts +5 -0
  13. package/dist/esm/components/AppHeaderLogo.js +21 -2
  14. package/dist/esm/components/Inspector/InspectorHeader.js +85 -12
  15. package/dist/esm/components/Inspector/MainScreen.js +6 -2
  16. package/dist/esm/components/Inspector/NpmUpdateToast.d.ts +3 -0
  17. package/dist/esm/components/Inspector/NpmUpdateToast.js +251 -0
  18. package/dist/esm/components/Inspector/SettingsPanel.js +192 -1
  19. package/dist/esm/components/Inspector/TelemetryConsentModal.js +219 -72
  20. package/dist/esm/constants/version.d.ts +1 -1
  21. package/dist/esm/constants/version.js +1 -1
  22. package/dist/esm/helpers/telemetry.js +4 -4
  23. package/dist/esm/index.js +14 -2
  24. package/dist/esm/types/interfaces.d.ts +5 -0
  25. package/package.json +1 -1
  26. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  27. package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
  28. package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
  29. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  30. package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
  31. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  32. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  33. package/android/.gradle/8.9/gc.properties +0 -0
  34. package/android/.gradle/9.2.0/checksums/checksums.lock +0 -0
  35. package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
  36. package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
  37. package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
  38. package/android/.gradle/9.2.0/gc.properties +0 -0
  39. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  40. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  41. package/android/.gradle/vcs-1/gc.properties +0 -0
  42. package/android/build/reports/problems/problems-report.html +0 -659
@@ -44,7 +44,23 @@ const AppHeaderLogo = ({ size = 46, customIcon, }) => {
44
44
  const [loadError, setLoadError] = (0, react_1.useState)(false);
45
45
  // 1. If customIcon is explicitly provided, render it directly edge-to-edge
46
46
  if (customIcon) {
47
- return (<react_native_1.View style={[logoStyles.container, { width: size, height: size }]}>
47
+ if (react_1.default.isValidElement(customIcon)) {
48
+ const clonedIcon = react_1.default.cloneElement(customIcon, {
49
+ size,
50
+ width: size,
51
+ height: size,
52
+ });
53
+ return (<react_native_1.View style={[
54
+ logoStyles.container,
55
+ { width: size, height: size, padding: 0, borderRadius: Math.round(size * 0.28) },
56
+ ]}>
57
+ {clonedIcon}
58
+ </react_native_1.View>);
59
+ }
60
+ return (<react_native_1.View style={[
61
+ logoStyles.container,
62
+ { width: size, height: size, borderRadius: Math.round(size * 0.28) },
63
+ ]}>
48
64
  <react_native_1.Image source={customIcon} style={logoStyles.image} resizeMode="cover"/>
49
65
  </react_native_1.View>);
50
66
  }
@@ -60,7 +76,10 @@ const AppHeaderLogo = ({ size = 46, customIcon, }) => {
60
76
  </react_native_1.View>);
61
77
  }
62
78
  // 3. Fallback: Inspector's Signature Owl Brand Logo
63
- return (<react_native_1.View style={[logoStyles.container, { width: size, height: size }]}>
79
+ return (<react_native_1.View style={[
80
+ logoStyles.container,
81
+ { width: size, height: size, padding: 0, borderRadius: Math.round(size * 0.28) },
82
+ ]}>
64
83
  <BrandSquareIcon_1.default size={size}/>
65
84
  </react_native_1.View>);
66
85
  };
@@ -48,9 +48,35 @@ const AppFonts_1 = require("../../styles/AppFonts");
48
48
  const constants_1 = require("../../constants");
49
49
  const constants_2 = require("../../constants");
50
50
  const helpers_1 = require("../../helpers");
51
+ const telemetry_1 = require("../../helpers/telemetry");
51
52
  const NetworkIcons_1 = require("../NetworkIcons");
52
53
  const InspectorHeader = react_1.default.memo(() => {
53
- const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, selectedCrash, setSelectedCrash, } = (0, InspectorContext_1.useInspector)();
54
+ const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, visible, selectedCrash, setSelectedCrash, } = (0, InspectorContext_1.useInspector)();
55
+ const [isTelemetryActive, setIsTelemetryActive] = react_1.default.useState(false);
56
+ const telemetryPulseAnim = react_1.default.useRef(new react_native_1.Animated.Value(1)).current;
57
+ react_1.default.useEffect(() => {
58
+ (0, telemetry_1.getTelemetryConsentStatus)().then(status => {
59
+ setIsTelemetryActive(status === 'granted');
60
+ });
61
+ }, [visible]);
62
+ react_1.default.useEffect(() => {
63
+ if (!isTelemetryActive)
64
+ return;
65
+ const pulse = react_native_1.Animated.loop(react_native_1.Animated.sequence([
66
+ react_native_1.Animated.timing(telemetryPulseAnim, {
67
+ toValue: 2.2,
68
+ duration: 1500,
69
+ useNativeDriver: true,
70
+ }),
71
+ react_native_1.Animated.timing(telemetryPulseAnim, {
72
+ toValue: 1,
73
+ duration: 0,
74
+ useNativeDriver: true,
75
+ }),
76
+ ]));
77
+ pulse.start();
78
+ return () => pulse.stop();
79
+ }, [isTelemetryActive, telemetryPulseAnim]);
54
80
  const envConfig = (0, react_1.useMemo)(() => {
55
81
  const rawEnv = (environment || (__DEV__ ? 'DEV' : 'PROD')).trim();
56
82
  const clean = rawEnv.toUpperCase();
@@ -213,7 +239,7 @@ const InspectorHeader = react_1.default.memo(() => {
213
239
  minWidth: 0,
214
240
  marginRight: 6,
215
241
  }}>
216
- <AppHeaderLogo_1.default size={30} customIcon={appIcon}/>
242
+ <AppHeaderLogo_1.default size={46} customIcon={appIcon}/>
217
243
  <react_native_1.View style={{ gap: 2.5, flex: 1, minWidth: 0 }}>
218
244
  <react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, minWidth: 0 }}>
219
245
  <react_native_1.Text style={[styles_1.default.headerTitle, { flexShrink: 1 }]} numberOfLines={1} ellipsizeMode="tail">
@@ -260,11 +286,11 @@ const InspectorHeader = react_1.default.memo(() => {
260
286
  </react_native_1.Pressable>)}
261
287
  </react_native_1.View>
262
288
 
263
- {/* Clean Bundle Identifier & Version Representation */}
289
+ {/* OS & NPM Version Representation */}
264
290
  <react_native_1.View style={{
265
291
  flexDirection: 'row',
266
292
  alignItems: 'center',
267
- gap: 4.5,
293
+ gap: 5,
268
294
  minWidth: 0,
269
295
  }}>
270
296
  <react_native_1.View style={{
@@ -274,21 +300,21 @@ const InspectorHeader = react_1.default.memo(() => {
274
300
  borderRadius: 5,
275
301
  paddingHorizontal: 6,
276
302
  paddingVertical: 2,
277
- gap: 3.5,
303
+ gap: 4,
278
304
  borderWidth: 1,
279
305
  borderColor: `${AppColors_1.AppColors.white}2E`,
280
- flexShrink: 1,
281
- minWidth: 0,
306
+ flexShrink: 0,
282
307
  }}>
283
- {react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon color={`${AppColors_1.AppColors.white}D9`} size={9}/>) : (<NetworkIcons_1.AndroidIcon color={`${AppColors_1.AppColors.white}D9`} size={9}/>)}
308
+ {react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon color={`${AppColors_1.AppColors.white}E6`} size={10}/>) : (<NetworkIcons_1.AndroidIcon color={`${AppColors_1.AppColors.white}E6`} size={10}/>)}
284
309
  <react_native_1.Text style={{
285
310
  fontFamily: AppFonts_1.AppFonts.interMedium,
286
311
  fontSize: 9.5,
287
312
  color: `${AppColors_1.AppColors.white}EB`,
288
313
  letterSpacing: 0.1,
289
- flexShrink: 1,
290
- }} numberOfLines={1} ellipsizeMode="middle">
291
- {(0, helpers_1.getBundleIdentifier)()}
314
+ }} numberOfLines={1}>
315
+ {react_native_1.Platform.OS === 'ios'
316
+ ? `iOS ${react_native_1.Platform.Version}`
317
+ : `Android ${react_native_1.Platform.Version}`}
292
318
  </react_native_1.Text>
293
319
  </react_native_1.View>
294
320
 
@@ -317,6 +343,53 @@ const InspectorHeader = react_1.default.memo(() => {
317
343
  v{constants_2.LIB_VERSION}
318
344
  </react_native_1.Text>
319
345
  </react_native_1.Pressable>
346
+
347
+ {isTelemetryActive && (<react_native_1.Pressable onPress={() => react_native_1.Alert.alert('Anonymous Telemetry Active', 'Anonymous diagnostics (such as React Native version, JavaScript engine, and device model) are currently enabled to help improve library tooling.\n\nNo user data or network payloads are captured. You can toggle this anytime in Settings.', [{ text: 'Got it' }])} style={{
348
+ flexDirection: 'row',
349
+ alignItems: 'center',
350
+ backgroundColor: 'rgba(16, 185, 129, 0.22)',
351
+ borderRadius: 5,
352
+ paddingHorizontal: 5.5,
353
+ paddingVertical: 2,
354
+ gap: 4.5,
355
+ borderWidth: 1,
356
+ borderColor: 'rgba(52, 211, 153, 0.45)',
357
+ flexShrink: 0,
358
+ }}>
359
+ <react_native_1.View style={{
360
+ width: 6,
361
+ height: 6,
362
+ alignItems: 'center',
363
+ justifyContent: 'center',
364
+ }}>
365
+ <react_native_1.Animated.View style={{
366
+ position: 'absolute',
367
+ width: 6,
368
+ height: 6,
369
+ borderRadius: 3,
370
+ backgroundColor: '#34D399',
371
+ opacity: telemetryPulseAnim.interpolate({
372
+ inputRange: [1, 2.2],
373
+ outputRange: [0.8, 0],
374
+ }),
375
+ transform: [{ scale: telemetryPulseAnim }],
376
+ }}/>
377
+ <react_native_1.View style={{
378
+ width: 4,
379
+ height: 4,
380
+ borderRadius: 2,
381
+ backgroundColor: '#10B981',
382
+ }}/>
383
+ </react_native_1.View>
384
+ <react_native_1.Text style={{
385
+ fontFamily: AppFonts_1.AppFonts.interBold,
386
+ fontSize: 9,
387
+ color: '#6EE7B7',
388
+ letterSpacing: 0.2,
389
+ }}>
390
+ LIVE
391
+ </react_native_1.Text>
392
+ </react_native_1.Pressable>)}
320
393
  </react_native_1.View>
321
394
  </react_native_1.View>
322
395
  </react_native_1.View>) : null}
@@ -57,6 +57,7 @@ const CrashTab_1 = __importDefault(require("./CrashTab"));
57
57
  const CrashDetail_1 = __importDefault(require("./CrashDetail"));
58
58
  const SettingsPanel_1 = __importDefault(require("./SettingsPanel"));
59
59
  const TelemetryConsentModal_1 = __importDefault(require("./TelemetryConsentModal"));
60
+ const NpmUpdateToast_1 = __importDefault(require("./NpmUpdateToast"));
60
61
  const Toast_1 = __importDefault(require("../Toast"));
61
62
  const styles_1 = __importDefault(require("../../styles"));
62
63
  const AppColors_1 = require("../../styles/AppColors");
@@ -206,13 +207,16 @@ const MainScreen = () => {
206
207
  {/* Bottom floating toast notification */}
207
208
  <Toast_1.default />
208
209
 
209
- {/* Anonymous Telemetry Consent Dialog */}
210
- <TelemetryConsentModal_1.default />
210
+ {/* NPM Version Update Toast with timeout progress bar */}
211
+ <NpmUpdateToast_1.default />
211
212
  </react_native_1.View>
212
213
  </react_native_1.View>
213
214
  </ErrorBoundary_1.default>)}
214
215
  {hasNavigationContext && (<NavigationTracker_1.default onStateChange={setNavState}/>)}
215
216
  </react_native_1.Modal>
217
+
218
+ {/* Anonymous Telemetry Consent Dialog at root viewport */}
219
+ <TelemetryConsentModal_1.default />
216
220
  </>);
217
221
  };
218
222
  exports.default = MainScreen;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const NpmUpdateToast: () => React.JSX.Element;
3
+ export default NpmUpdateToast;
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.NpmUpdateToast = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const react_native_svg_1 = __importStar(require("react-native-svg"));
40
+ const InspectorContext_1 = require("./InspectorContext");
41
+ const constants_1 = require("../../constants");
42
+ const NetworkIcons_1 = require("../NetworkIcons");
43
+ const CloseSvg = ({ size = 13, color = '#94A3B8' }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
44
+ <react_native_svg_1.Path d="M18 6L6 18M6 6l12 12" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
45
+ </react_native_svg_1.default>);
46
+ const ExternalLinkSvg = ({ size = 12, color = '#FFFFFF' }) => (<react_native_svg_1.default width={size} height={size} viewBox="0 0 24 24" fill="none">
47
+ <react_native_svg_1.Path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
48
+ <react_native_svg_1.Path d="M15 3h6v6" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
49
+ <react_native_svg_1.Path d="M10 14L21 3" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
50
+ </react_native_svg_1.default>);
51
+ const TOAST_TIMEOUT_MS = 6500;
52
+ const NpmUpdateToast = () => {
53
+ const { updateAvailable, latestNpmVersion, showUpdateToast } = (0, InspectorContext_1.useInspector)();
54
+ const [dismissed, setDismissed] = (0, react_1.useState)(false);
55
+ const [visible, setVisible] = (0, react_1.useState)(false);
56
+ const translateYAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(50)).current;
57
+ const opacityAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
58
+ const progressAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
59
+ const timerRef = (0, react_1.useRef)(null);
60
+ (0, react_1.useEffect)(() => {
61
+ if (showUpdateToast && updateAvailable && latestNpmVersion && !dismissed) {
62
+ setVisible(true);
63
+ // Slide and fade in
64
+ react_native_1.Animated.parallel([
65
+ react_native_1.Animated.spring(translateYAnim, {
66
+ toValue: 0,
67
+ friction: 8,
68
+ tension: 40,
69
+ useNativeDriver: true,
70
+ }),
71
+ react_native_1.Animated.timing(opacityAnim, {
72
+ toValue: 1,
73
+ duration: 250,
74
+ useNativeDriver: true,
75
+ }),
76
+ ]).start();
77
+ // Progress bar countdown from 1 to 0
78
+ progressAnim.setValue(1);
79
+ react_native_1.Animated.timing(progressAnim, {
80
+ toValue: 0,
81
+ duration: TOAST_TIMEOUT_MS,
82
+ useNativeDriver: false,
83
+ }).start();
84
+ // Auto-hide after timeout
85
+ timerRef.current = setTimeout(() => {
86
+ handleDismiss();
87
+ }, TOAST_TIMEOUT_MS);
88
+ }
89
+ return () => {
90
+ if (timerRef.current) {
91
+ clearTimeout(timerRef.current);
92
+ }
93
+ };
94
+ }, [showUpdateToast, updateAvailable, latestNpmVersion, dismissed]);
95
+ const handleDismiss = () => {
96
+ react_native_1.Animated.parallel([
97
+ react_native_1.Animated.timing(opacityAnim, {
98
+ toValue: 0,
99
+ duration: 200,
100
+ useNativeDriver: true,
101
+ }),
102
+ react_native_1.Animated.timing(translateYAnim, {
103
+ toValue: 50,
104
+ duration: 200,
105
+ useNativeDriver: true,
106
+ }),
107
+ ]).start(() => {
108
+ setVisible(false);
109
+ setDismissed(true);
110
+ });
111
+ };
112
+ const handleOpenNpm = () => {
113
+ react_native_1.Linking.openURL('https://www.npmjs.com/package/react-native-inapp-inspector').catch(() => { });
114
+ handleDismiss();
115
+ };
116
+ if (!showUpdateToast || !visible || !updateAvailable || !latestNpmVersion)
117
+ return null;
118
+ const progressWidth = progressAnim.interpolate({
119
+ inputRange: [0, 1],
120
+ outputRange: ['0%', '100%'],
121
+ });
122
+ return (<react_native_1.Animated.View style={[
123
+ styles.container,
124
+ {
125
+ opacity: opacityAnim,
126
+ transform: [{ translateY: translateYAnim }],
127
+ },
128
+ ]}>
129
+ <react_native_1.View style={styles.contentRow}>
130
+ {/* Left NPM Badge Icon */}
131
+ <react_native_1.View style={styles.npmIconContainer}>
132
+ <NetworkIcons_1.NpmIcon size={14} color="#CB3837"/>
133
+ </react_native_1.View>
134
+
135
+ {/* Text Details */}
136
+ <react_native_1.View style={styles.textContainer}>
137
+ <react_native_1.View style={styles.titleRow}>
138
+ <react_native_1.Text style={styles.titleText}>Update Available</react_native_1.Text>
139
+ <react_native_1.View style={styles.versionPill}>
140
+ <react_native_1.Text style={styles.versionPillText}>v{latestNpmVersion}</react_native_1.Text>
141
+ </react_native_1.View>
142
+ </react_native_1.View>
143
+ <react_native_1.Text style={styles.subtitleText} numberOfLines={1}>
144
+ Installed: v{constants_1.LIB_VERSION} • New version is ready
145
+ </react_native_1.Text>
146
+ </react_native_1.View>
147
+
148
+ {/* Action Button: View */}
149
+ <react_native_1.TouchableOpacity style={styles.actionButton} onPress={handleOpenNpm} activeOpacity={0.8}>
150
+ <react_native_1.Text style={styles.actionButtonText}>View</react_native_1.Text>
151
+ <ExternalLinkSvg size={10} color="#FFFFFF"/>
152
+ </react_native_1.TouchableOpacity>
153
+
154
+ {/* Close Button */}
155
+ <react_native_1.TouchableOpacity style={styles.closeButton} onPress={handleDismiss} hitSlop={8} activeOpacity={0.7}>
156
+ <CloseSvg size={12} color="#94A3B8"/>
157
+ </react_native_1.TouchableOpacity>
158
+ </react_native_1.View>
159
+
160
+ {/* Animated Linear Timeout Progress Bar */}
161
+ <react_native_1.View style={styles.progressBarTrack}>
162
+ <react_native_1.Animated.View style={[styles.progressBarFill, { width: progressWidth }]}/>
163
+ </react_native_1.View>
164
+ </react_native_1.Animated.View>);
165
+ };
166
+ exports.NpmUpdateToast = NpmUpdateToast;
167
+ const fontStack = react_native_1.Platform.select({
168
+ ios: {
169
+ fontFamily: 'System',
170
+ },
171
+ android: {
172
+ fontFamily: 'sans-serif',
173
+ },
174
+ default: {},
175
+ });
176
+ const styles = react_native_1.StyleSheet.create({
177
+ container: {
178
+ position: 'absolute',
179
+ bottom: 24,
180
+ left: 16,
181
+ right: 16,
182
+ backgroundColor: '#0F172A',
183
+ borderRadius: 16,
184
+ borderWidth: 1,
185
+ borderColor: '#334155',
186
+ shadowColor: '#000000',
187
+ shadowOffset: { width: 0, height: 10 },
188
+ shadowOpacity: 0.35,
189
+ shadowRadius: 20,
190
+ elevation: 20,
191
+ overflow: 'hidden',
192
+ zIndex: 99999,
193
+ },
194
+ contentRow: {
195
+ flexDirection: 'row',
196
+ alignItems: 'center',
197
+ paddingVertical: 12,
198
+ paddingHorizontal: 14,
199
+ gap: 10,
200
+ },
201
+ npmIconContainer: {
202
+ width: 32,
203
+ height: 32,
204
+ borderRadius: 10,
205
+ backgroundColor: '#FFFFFF',
206
+ justifyContent: 'center',
207
+ alignItems: 'center',
208
+ borderWidth: 1,
209
+ borderColor: '#CBD5E1',
210
+ flexShrink: 0,
211
+ },
212
+ textContainer: {
213
+ flex: 1,
214
+ minWidth: 0,
215
+ },
216
+ titleRow: {
217
+ flexDirection: 'row',
218
+ alignItems: 'center',
219
+ gap: 6,
220
+ },
221
+ titleText: {
222
+ fontSize: 13,
223
+ fontWeight: '700',
224
+ color: '#F8FAFC',
225
+ letterSpacing: -0.2,
226
+ ...fontStack,
227
+ },
228
+ versionPill: {
229
+ backgroundColor: '#7C3AED26',
230
+ paddingHorizontal: 6,
231
+ paddingVertical: 1.5,
232
+ borderRadius: 6,
233
+ borderWidth: 1,
234
+ borderColor: '#7C3AED59',
235
+ },
236
+ versionPillText: {
237
+ fontSize: 10.5,
238
+ fontWeight: '700',
239
+ color: '#A78BFA',
240
+ ...fontStack,
241
+ },
242
+ subtitleText: {
243
+ fontSize: 11,
244
+ color: '#94A3B8',
245
+ marginTop: 1.5,
246
+ ...fontStack,
247
+ },
248
+ actionButton: {
249
+ flexDirection: 'row',
250
+ alignItems: 'center',
251
+ gap: 4,
252
+ backgroundColor: '#7C3AED',
253
+ paddingVertical: 6,
254
+ paddingHorizontal: 10,
255
+ borderRadius: 8,
256
+ flexShrink: 0,
257
+ shadowColor: '#7C3AED',
258
+ shadowOffset: { width: 0, height: 2 },
259
+ shadowOpacity: 0.3,
260
+ shadowRadius: 4,
261
+ elevation: 3,
262
+ },
263
+ actionButtonText: {
264
+ fontSize: 11.5,
265
+ fontWeight: '700',
266
+ color: '#FFFFFF',
267
+ ...fontStack,
268
+ },
269
+ closeButton: {
270
+ width: 24,
271
+ height: 24,
272
+ borderRadius: 12,
273
+ backgroundColor: '#1E293B',
274
+ justifyContent: 'center',
275
+ alignItems: 'center',
276
+ flexShrink: 0,
277
+ },
278
+ progressBarTrack: {
279
+ height: 3,
280
+ width: '100%',
281
+ backgroundColor: '#1E293B',
282
+ },
283
+ progressBarFill: {
284
+ height: '100%',
285
+ backgroundColor: '#7C3AED',
286
+ },
287
+ });
288
+ exports.default = exports.NpmUpdateToast;