@umituz/react-native-onboarding 3.0.4 → 3.1.0
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-onboarding",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Advanced onboarding flow for React Native apps with personalization questions, theme-aware colors, animations, and customizable slides. SOLID, DRY, KISS principles applied.",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"url": "https://github.com/umituz/react-native-onboarding"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
+
"@umituz/react-native-icons": "latest",
|
|
34
35
|
"@umituz/react-native-storage": "latest",
|
|
35
36
|
"@umituz/react-native-localization": "latest",
|
|
36
37
|
"@umituz/react-native-design-system-theme": "latest",
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@types/react": "^18.2.45",
|
|
48
49
|
"@types/react-native": "^0.73.0",
|
|
50
|
+
"@umituz/react-native-icons": "latest",
|
|
49
51
|
"@umituz/react-native-storage": "^1.1.0",
|
|
50
52
|
"@umituz/react-native-localization": "latest",
|
|
51
53
|
"@umituz/react-native-design-system-theme": "latest",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useMemo } from "react";
|
|
8
8
|
import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
|
|
9
|
-
import {
|
|
9
|
+
import { AtomicIcon } from "@umituz/react-native-design-system-atoms";
|
|
10
10
|
import { useLocalization } from "@umituz/react-native-localization";
|
|
11
11
|
import { useAppDesignTokens } from "@umituz/react-native-design-system-theme";
|
|
12
12
|
|
|
@@ -58,10 +58,10 @@ export const OnboardingHeader: React.FC<OnboardingHeaderProps> = ({
|
|
|
58
58
|
activeOpacity={0.7}
|
|
59
59
|
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
60
60
|
>
|
|
61
|
-
<
|
|
62
|
-
name="
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
<AtomicIcon
|
|
62
|
+
name="chevron-back"
|
|
63
|
+
customSize={20}
|
|
64
|
+
customColor={useGradient ? "#FFFFFF" : tokens.colors.textPrimary}
|
|
65
65
|
/>
|
|
66
66
|
</TouchableOpacity>
|
|
67
67
|
) : (
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Onboarding Slide Component
|
|
3
3
|
*
|
|
4
4
|
* Displays a single onboarding slide with icon, title, and description
|
|
5
|
+
* Uses AtomicIcon from design system for consistent icon rendering
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import React, { useMemo } from "react";
|
|
8
9
|
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
|
9
|
-
import {
|
|
10
|
+
import { AtomicIcon } from "@umituz/react-native-design-system-atoms";
|
|
10
11
|
import { useAppDesignTokens, withAlpha } from "@umituz/react-native-design-system-theme";
|
|
11
12
|
import type { OnboardingSlide as OnboardingSlideType } from "../../domain/entities/OnboardingSlide";
|
|
12
13
|
|
|
@@ -15,15 +16,40 @@ export interface OnboardingSlideProps {
|
|
|
15
16
|
useGradient?: boolean;
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
const EMOJI_REGEX = /[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/u;
|
|
20
|
+
|
|
18
21
|
export const OnboardingSlide: React.FC<OnboardingSlideProps> = ({ slide, useGradient = false }) => {
|
|
19
22
|
const tokens = useAppDesignTokens();
|
|
20
23
|
const styles = useMemo(() => getStyles(tokens, useGradient), [tokens, useGradient]);
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
const
|
|
25
|
+
const isEmoji = EMOJI_REGEX.test(slide.icon);
|
|
26
|
+
const isValidIconName = !isEmoji && typeof slide.icon === "string";
|
|
27
|
+
|
|
28
|
+
const renderIcon = (color: string) => {
|
|
29
|
+
if (isEmoji) {
|
|
30
|
+
return <Text style={styles.icon}>{slide.icon}</Text>;
|
|
31
|
+
}
|
|
32
|
+
if (isValidIconName) {
|
|
33
|
+
return <AtomicIcon name={slide.icon} customSize={60} customColor={color} />;
|
|
34
|
+
}
|
|
35
|
+
return <Text style={styles.icon}>📱</Text>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const renderFeatures = () => {
|
|
39
|
+
if (!slide.features || slide.features.length === 0) return null;
|
|
40
|
+
return (
|
|
41
|
+
<View style={styles.featuresContainer}>
|
|
42
|
+
{slide.features.map((feature, index) => (
|
|
43
|
+
<View key={index} style={styles.featureItem}>
|
|
44
|
+
<Text style={styles.featureBullet}>•</Text>
|
|
45
|
+
<Text style={styles.featureText}>{feature}</Text>
|
|
46
|
+
</View>
|
|
47
|
+
))}
|
|
48
|
+
</View>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
24
51
|
|
|
25
|
-
|
|
26
|
-
const isValidFeatherIcon = !isEmoji && typeof slide.icon === 'string';
|
|
52
|
+
const iconColor = useGradient ? "#FFFFFF" : tokens.colors.textPrimary;
|
|
27
53
|
|
|
28
54
|
return (
|
|
29
55
|
<ScrollView
|
|
@@ -31,62 +57,18 @@ export const OnboardingSlide: React.FC<OnboardingSlideProps> = ({ slide, useGrad
|
|
|
31
57
|
showsVerticalScrollIndicator={false}
|
|
32
58
|
>
|
|
33
59
|
{useGradient ? (
|
|
34
|
-
// Gradient kullanıldığında card olmadan direkt içerik
|
|
35
60
|
<>
|
|
36
|
-
<View style={styles.iconContainer}>
|
|
37
|
-
{isEmoji ? (
|
|
38
|
-
<Text style={styles.icon}>{slide.icon}</Text>
|
|
39
|
-
) : isValidFeatherIcon ? (
|
|
40
|
-
<Feather
|
|
41
|
-
name={slide.icon as any}
|
|
42
|
-
size={60}
|
|
43
|
-
color="#FFFFFF"
|
|
44
|
-
/>
|
|
45
|
-
) : (
|
|
46
|
-
<Text style={styles.icon}>📱</Text>
|
|
47
|
-
)}
|
|
48
|
-
</View>
|
|
61
|
+
<View style={styles.iconContainer}>{renderIcon(iconColor)}</View>
|
|
49
62
|
<Text style={styles.title}>{slide.title}</Text>
|
|
50
63
|
<Text style={styles.description}>{slide.description}</Text>
|
|
51
|
-
{
|
|
52
|
-
<View style={styles.featuresContainer}>
|
|
53
|
-
{slide.features.map((feature, index) => (
|
|
54
|
-
<View key={index} style={styles.featureItem}>
|
|
55
|
-
<Text style={styles.featureBullet}>•</Text>
|
|
56
|
-
<Text style={styles.featureText}>{feature}</Text>
|
|
57
|
-
</View>
|
|
58
|
-
))}
|
|
59
|
-
</View>
|
|
60
|
-
)}
|
|
64
|
+
{renderFeatures()}
|
|
61
65
|
</>
|
|
62
66
|
) : (
|
|
63
|
-
// Normal modda card ile
|
|
64
67
|
<View style={styles.slideContent}>
|
|
65
|
-
<View style={styles.iconContainer}>
|
|
66
|
-
{isEmoji ? (
|
|
67
|
-
<Text style={styles.icon}>{slide.icon}</Text>
|
|
68
|
-
) : isValidFeatherIcon ? (
|
|
69
|
-
<Feather
|
|
70
|
-
name={slide.icon as any}
|
|
71
|
-
size={60}
|
|
72
|
-
color={tokens.colors.textPrimary}
|
|
73
|
-
/>
|
|
74
|
-
) : (
|
|
75
|
-
<Text style={styles.icon}>📱</Text>
|
|
76
|
-
)}
|
|
77
|
-
</View>
|
|
68
|
+
<View style={styles.iconContainer}>{renderIcon(iconColor)}</View>
|
|
78
69
|
<Text style={styles.title}>{slide.title}</Text>
|
|
79
70
|
<Text style={styles.description}>{slide.description}</Text>
|
|
80
|
-
{
|
|
81
|
-
<View style={styles.featuresContainer}>
|
|
82
|
-
{slide.features.map((feature, index) => (
|
|
83
|
-
<View key={index} style={styles.featureItem}>
|
|
84
|
-
<Text style={styles.featureBullet}>•</Text>
|
|
85
|
-
<Text style={styles.featureText}>{feature}</Text>
|
|
86
|
-
</View>
|
|
87
|
-
))}
|
|
88
|
-
</View>
|
|
89
|
-
)}
|
|
71
|
+
{renderFeatures()}
|
|
90
72
|
</View>
|
|
91
73
|
)}
|
|
92
74
|
</ScrollView>
|
|
@@ -74,6 +74,10 @@ export const OnboardingScreen: React.FC<OnboardingScreenProps> = ({
|
|
|
74
74
|
showPaywallOnComplete = false,
|
|
75
75
|
useGradient: globalUseGradient = false,
|
|
76
76
|
}) => {
|
|
77
|
+
if (__DEV__) {
|
|
78
|
+
console.log("[OnboardingScreen] Rendering with slides:", slides?.length);
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
const {
|
|
78
82
|
filteredSlides,
|
|
79
83
|
currentSlide,
|
|
@@ -96,8 +100,15 @@ export const OnboardingScreen: React.FC<OnboardingScreenProps> = ({
|
|
|
96
100
|
globalUseGradient,
|
|
97
101
|
});
|
|
98
102
|
|
|
103
|
+
if (__DEV__) {
|
|
104
|
+
console.log("[OnboardingScreen] filteredSlides:", filteredSlides?.length);
|
|
105
|
+
}
|
|
106
|
+
|
|
99
107
|
// Early return if no slides - prevents rendering empty/broken screen
|
|
100
108
|
if (filteredSlides.length === 0) {
|
|
109
|
+
if (__DEV__) {
|
|
110
|
+
console.log("[OnboardingScreen] No slides, returning null");
|
|
111
|
+
}
|
|
101
112
|
return null;
|
|
102
113
|
}
|
|
103
114
|
|