@umituz/react-native-onboarding 2.6.3 → 2.6.5

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": "2.6.3",
3
+ "version": "2.6.5",
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",
@@ -12,11 +12,12 @@ import type { OnboardingSlide as OnboardingSlideType } from "../../domain/entiti
12
12
 
13
13
  export interface OnboardingSlideProps {
14
14
  slide: OnboardingSlideType;
15
+ useGradient?: boolean;
15
16
  }
16
17
 
17
- export const OnboardingSlide: React.FC<OnboardingSlideProps> = ({ slide }) => {
18
+ export const OnboardingSlide: React.FC<OnboardingSlideProps> = ({ slide, useGradient = false }) => {
18
19
  const tokens = useAppDesignTokens();
19
- const styles = useMemo(() => getStyles(tokens), [tokens]);
20
+ const styles = useMemo(() => getStyles(tokens, useGradient), [tokens, useGradient]);
20
21
 
21
22
  // Check if icon is an emoji (contains emoji characters) or Lucide icon name
22
23
  const isEmoji = /[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/u.test(slide.icon);
@@ -25,8 +26,37 @@ export const OnboardingSlide: React.FC<OnboardingSlideProps> = ({ slide }) => {
25
26
  const IconComponent = !isEmoji ? (LucideIcons as any)[slide.icon] : null;
26
27
 
27
28
  return (
28
- <View style={styles.container}>
29
- <View style={styles.content}>
29
+ <ScrollView
30
+ contentContainerStyle={styles.content}
31
+ showsVerticalScrollIndicator={false}
32
+ >
33
+ {useGradient ? (
34
+ // Gradient kullanıldığında card olmadan direkt içerik
35
+ <>
36
+ <View style={styles.iconContainer}>
37
+ {isEmoji ? (
38
+ <Text style={styles.icon}>{slide.icon}</Text>
39
+ ) : IconComponent ? (
40
+ <IconComponent size={60} color="#FFFFFF" />
41
+ ) : (
42
+ <Text style={styles.icon}>📱</Text>
43
+ )}
44
+ </View>
45
+ <Text style={styles.title}>{slide.title}</Text>
46
+ <Text style={styles.description}>{slide.description}</Text>
47
+ {slide.features && slide.features.length > 0 && (
48
+ <View style={styles.featuresContainer}>
49
+ {slide.features.map((feature, index) => (
50
+ <View key={index} style={styles.featureItem}>
51
+ <Text style={styles.featureBullet}>•</Text>
52
+ <Text style={styles.featureText}>{feature}</Text>
53
+ </View>
54
+ ))}
55
+ </View>
56
+ )}
57
+ </>
58
+ ) : (
59
+ // Normal modda card ile
30
60
  <View style={styles.slideContent}>
31
61
  <View style={styles.iconContainer}>
32
62
  {isEmoji ? (
@@ -50,18 +80,15 @@ export const OnboardingSlide: React.FC<OnboardingSlideProps> = ({ slide }) => {
50
80
  </View>
51
81
  )}
52
82
  </View>
53
- </View>
54
- </View>
83
+ )}
84
+ </ScrollView>
55
85
  );
56
86
  };
57
87
 
58
- const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
88
+ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>, useGradient: boolean) =>
59
89
  StyleSheet.create({
60
- container: {
61
- flex: 1,
62
- },
63
90
  content: {
64
- flex: 1,
91
+ flexGrow: 1,
65
92
  justifyContent: "center",
66
93
  alignItems: "center",
67
94
  paddingHorizontal: 30,
@@ -71,7 +98,6 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
71
98
  alignItems: "center",
72
99
  maxWidth: 400,
73
100
  width: "100%",
74
- // Add background for readability with theme colors
75
101
  backgroundColor: tokens.colors.surface,
76
102
  padding: 30,
77
103
  borderRadius: 24,
@@ -90,12 +116,16 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
90
116
  width: 120,
91
117
  height: 120,
92
118
  borderRadius: 60,
93
- backgroundColor: withAlpha(tokens.colors.primary, 0.2),
119
+ backgroundColor: useGradient
120
+ ? "rgba(255, 255, 255, 0.25)"
121
+ : withAlpha(tokens.colors.primary, 0.2),
94
122
  alignItems: "center",
95
123
  justifyContent: "center",
96
124
  marginBottom: 40,
97
125
  borderWidth: 2,
98
- borderColor: withAlpha(tokens.colors.primary, 0.4),
126
+ borderColor: useGradient
127
+ ? "rgba(255, 255, 255, 0.4)"
128
+ : withAlpha(tokens.colors.primary, 0.4),
99
129
  },
100
130
  icon: {
101
131
  fontSize: 60,
@@ -103,13 +133,13 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
103
133
  title: {
104
134
  fontSize: 28,
105
135
  fontWeight: "bold",
106
- color: tokens.colors.textPrimary,
136
+ color: useGradient ? "#FFFFFF" : tokens.colors.textPrimary,
107
137
  textAlign: "center",
108
138
  marginBottom: 16,
109
139
  },
110
140
  description: {
111
141
  fontSize: 16,
112
- color: tokens.colors.textSecondary,
142
+ color: useGradient ? "rgba(255, 255, 255, 0.9)" : tokens.colors.textSecondary,
113
143
  textAlign: "center",
114
144
  lineHeight: 24,
115
145
  marginBottom: 20,
@@ -124,7 +154,7 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
124
154
  marginBottom: 12,
125
155
  },
126
156
  featureBullet: {
127
- color: tokens.colors.primary,
157
+ color: useGradient ? "#FFFFFF" : tokens.colors.primary,
128
158
  fontSize: 20,
129
159
  marginRight: 12,
130
160
  marginTop: 2,
@@ -132,7 +162,7 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>) =>
132
162
  featureText: {
133
163
  flex: 1,
134
164
  fontSize: 15,
135
- color: tokens.colors.textSecondary,
165
+ color: useGradient ? "rgba(255, 255, 255, 0.9)" : tokens.colors.textSecondary,
136
166
  lineHeight: 22,
137
167
  },
138
168
  });
@@ -91,36 +91,71 @@ export const QuestionSlide: React.FC<QuestionSlideProps> = ({
91
91
  contentContainerStyle={styles.content}
92
92
  showsVerticalScrollIndicator={false}
93
93
  >
94
- <View style={styles.slideContent}>
95
- {/* Icon */}
96
- <View style={styles.iconContainer}>
97
- {isEmoji ? (
98
- <Text style={styles.icon}>{slide.icon}</Text>
99
- ) : (
100
- <AtomicIcon
101
- name={slide.icon as any}
102
- customSize={48}
103
- customColor={useGradient ? "#FFFFFF" : tokens.colors.textPrimary}
104
- />
94
+ {useGradient ? (
95
+ // Gradient kullanıldığında card olmadan direkt içerik
96
+ <>
97
+ {/* Icon */}
98
+ <View style={styles.iconContainer}>
99
+ {isEmoji ? (
100
+ <Text style={styles.icon}>{slide.icon}</Text>
101
+ ) : (
102
+ <AtomicIcon
103
+ name={slide.icon as any}
104
+ customSize={48}
105
+ customColor="#FFFFFF"
106
+ />
107
+ )}
108
+ </View>
109
+
110
+ {/* Title */}
111
+ <Text style={styles.title}>{slide.title}</Text>
112
+
113
+ {/* Description */}
114
+ {slide.description && (
115
+ <Text style={styles.description}>{slide.description}</Text>
105
116
  )}
106
- </View>
107
117
 
108
- {/* Title */}
109
- <Text style={styles.title}>{slide.title}</Text>
118
+ {/* Question */}
119
+ <View style={styles.questionContainer}>{renderQuestion()}</View>
110
120
 
111
- {/* Description */}
112
- {slide.description && (
113
- <Text style={styles.description}>{slide.description}</Text>
114
- )}
121
+ {/* Validation hint */}
122
+ {question.validation?.required && !value && (
123
+ <Text style={styles.requiredHint}>* This field is required</Text>
124
+ )}
125
+ </>
126
+ ) : (
127
+ // Normal modda card ile
128
+ <View style={styles.slideContent}>
129
+ {/* Icon */}
130
+ <View style={styles.iconContainer}>
131
+ {isEmoji ? (
132
+ <Text style={styles.icon}>{slide.icon}</Text>
133
+ ) : (
134
+ <AtomicIcon
135
+ name={slide.icon as any}
136
+ customSize={48}
137
+ customColor={tokens.colors.textPrimary}
138
+ />
139
+ )}
140
+ </View>
115
141
 
116
- {/* Question */}
117
- <View style={styles.questionContainer}>{renderQuestion()}</View>
142
+ {/* Title */}
143
+ <Text style={styles.title}>{slide.title}</Text>
118
144
 
119
- {/* Validation hint */}
120
- {question.validation?.required && !value && (
121
- <Text style={styles.requiredHint}>* This field is required</Text>
122
- )}
123
- </View>
145
+ {/* Description */}
146
+ {slide.description && (
147
+ <Text style={styles.description}>{slide.description}</Text>
148
+ )}
149
+
150
+ {/* Question */}
151
+ <View style={styles.questionContainer}>{renderQuestion()}</View>
152
+
153
+ {/* Validation hint */}
154
+ {question.validation?.required && !value && (
155
+ <Text style={styles.requiredHint}>* This field is required</Text>
156
+ )}
157
+ </View>
158
+ )}
124
159
  </ScrollView>
125
160
  );
126
161
  };
@@ -138,20 +173,19 @@ const getStyles = (tokens: ReturnType<typeof useAppDesignTokens>, useGradient: b
138
173
  alignItems: "center",
139
174
  maxWidth: 500,
140
175
  width: "100%",
141
- // Gradient kullanıldığında tamamen şeffaf, değilse solid
142
- backgroundColor: useGradient ? "transparent" : tokens.colors.surface,
176
+ backgroundColor: tokens.colors.surface,
143
177
  padding: 30,
144
178
  borderRadius: 24,
145
- borderWidth: useGradient ? 0 : 1,
146
- borderColor: useGradient ? "transparent" : tokens.colors.borderLight,
179
+ borderWidth: 1,
180
+ borderColor: tokens.colors.borderLight,
147
181
  shadowColor: tokens.colors.textPrimary,
148
182
  shadowOffset: {
149
183
  width: 0,
150
184
  height: 4,
151
185
  },
152
- shadowOpacity: useGradient ? 0 : 0.1,
186
+ shadowOpacity: 0.1,
153
187
  shadowRadius: 8,
154
- elevation: useGradient ? 0 : 4,
188
+ elevation: 4,
155
189
  },
156
190
  iconContainer: {
157
191
  width: 96,
@@ -233,7 +233,7 @@ export const OnboardingScreen: React.FC<OnboardingScreenProps> = ({
233
233
  useGradient={useGradient}
234
234
  />
235
235
  ) : (
236
- <OnboardingSlideComponent slide={currentSlide} />
236
+ <OnboardingSlideComponent slide={currentSlide} useGradient={useGradient} />
237
237
  )
238
238
  )}
239
239
  {renderFooter ? (