@umituz/react-native-onboarding 3.2.1 → 3.3.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.
|
|
3
|
+
"version": "3.3.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",
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
"@umituz/react-native-design-system": "latest",
|
|
39
39
|
"@umituz/react-native-design-system-atoms": "latest",
|
|
40
40
|
"@expo/vector-icons": ">=14.0.0",
|
|
41
|
+
"expo-av": "~15.0.0",
|
|
42
|
+
"expo-image": "~2.0.0",
|
|
41
43
|
"expo-linear-gradient": "^15.0.0",
|
|
42
44
|
"react": ">=18.2.0",
|
|
43
45
|
"react-native": ">=0.74.0",
|
|
@@ -53,6 +55,8 @@
|
|
|
53
55
|
"@umituz/react-native-design-system-theme": "latest",
|
|
54
56
|
"@umituz/react-native-design-system-atoms": "latest",
|
|
55
57
|
"@expo/vector-icons": ">=14.0.0",
|
|
58
|
+
"expo-av": "~15.0.0",
|
|
59
|
+
"expo-image": "~2.0.0",
|
|
56
60
|
"expo-linear-gradient": "^15.0.7",
|
|
57
61
|
"react": "^18.2.0",
|
|
58
62
|
"react-native": "^0.74.0",
|
|
@@ -58,7 +58,25 @@ export interface OnboardingSlide {
|
|
|
58
58
|
/**
|
|
59
59
|
* Optional image URL (alternative to icon)
|
|
60
60
|
*/
|
|
61
|
-
image?:
|
|
61
|
+
image?: any;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Optional background image (URL or require path)
|
|
65
|
+
* Stretches to fill the screen behind content
|
|
66
|
+
*/
|
|
67
|
+
backgroundImage?: any;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Optional background video (URL or require path)
|
|
71
|
+
* Plays in loop behind content
|
|
72
|
+
*/
|
|
73
|
+
backgroundVideo?: any;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Opacity of the overlay gradient/color on top of background media
|
|
77
|
+
* Range: 0.0 to 1.0 (Default: 0.5)
|
|
78
|
+
*/
|
|
79
|
+
overlayOpacity?: number;
|
|
62
80
|
|
|
63
81
|
/**
|
|
64
82
|
* Optional features list to display
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { View, StyleSheet, StatusBar } from "react-native";
|
|
8
8
|
import { LinearGradient } from "expo-linear-gradient";
|
|
9
|
+
import { Image } from "expo-image";
|
|
10
|
+
import { Video, ResizeMode } from "expo-av";
|
|
9
11
|
import { useTheme } from "@umituz/react-native-design-system-theme";
|
|
10
12
|
import type { OnboardingSlide } from "../../domain/entities/OnboardingSlide";
|
|
11
13
|
import { OnboardingHeader } from "./OnboardingHeader";
|
|
@@ -85,17 +87,74 @@ export const OnboardingScreenContent: React.FC<OnboardingScreenContentProps> = (
|
|
|
85
87
|
}) => {
|
|
86
88
|
const { themeMode } = useTheme();
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
const hasMedia = !!currentSlide?.backgroundImage || !!currentSlide?.backgroundVideo;
|
|
91
|
+
const overlayOpacity = currentSlide?.overlayOpacity ?? 0.5;
|
|
92
|
+
// If media is present, valid gradient mode is enforced (white text)
|
|
93
|
+
const effectivelyUseGradient = useGradient || hasMedia;
|
|
94
|
+
|
|
95
|
+
const renderBackground = () => {
|
|
96
|
+
if (!currentSlide) return null;
|
|
97
|
+
|
|
98
|
+
if (currentSlide.backgroundVideo) {
|
|
99
|
+
return (
|
|
100
|
+
<View style={StyleSheet.absoluteFill}>
|
|
101
|
+
<Video
|
|
102
|
+
source={currentSlide.backgroundVideo}
|
|
103
|
+
style={StyleSheet.absoluteFill}
|
|
104
|
+
resizeMode={ResizeMode.COVER}
|
|
105
|
+
isLooping
|
|
106
|
+
shouldPlay
|
|
107
|
+
isMuted
|
|
108
|
+
/>
|
|
109
|
+
<View
|
|
110
|
+
style={[
|
|
111
|
+
StyleSheet.absoluteFill,
|
|
112
|
+
{ backgroundColor: `rgba(0,0,0,${overlayOpacity})` }
|
|
113
|
+
]}
|
|
114
|
+
/>
|
|
115
|
+
</View>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (currentSlide.backgroundImage) {
|
|
120
|
+
return (
|
|
121
|
+
<View style={StyleSheet.absoluteFill}>
|
|
122
|
+
<Image
|
|
123
|
+
source={currentSlide.backgroundImage}
|
|
124
|
+
style={StyleSheet.absoluteFill}
|
|
125
|
+
contentFit="cover"
|
|
126
|
+
transition={500}
|
|
127
|
+
/>
|
|
128
|
+
<View
|
|
129
|
+
style={[
|
|
130
|
+
StyleSheet.absoluteFill,
|
|
131
|
+
{ backgroundColor: `rgba(0,0,0,${overlayOpacity})` }
|
|
132
|
+
]}
|
|
133
|
+
/>
|
|
134
|
+
</View>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (useGradient && currentSlide.gradient) {
|
|
139
|
+
return (
|
|
92
140
|
<LinearGradient
|
|
93
141
|
colors={currentSlide.gradient as [string, string, ...string[]]}
|
|
94
142
|
start={{ x: 0, y: 0 }}
|
|
95
143
|
end={{ x: 1, y: 1 }}
|
|
96
144
|
style={StyleSheet.absoluteFill}
|
|
97
145
|
/>
|
|
98
|
-
)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return null;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<View style={[styles.container, containerStyle]}>
|
|
154
|
+
<StatusBar barStyle={themeMode === "dark" || effectivelyUseGradient ? "light-content" : "dark-content"} />
|
|
155
|
+
|
|
156
|
+
{renderBackground()}
|
|
157
|
+
|
|
99
158
|
{renderHeader ? (
|
|
100
159
|
renderHeader({
|
|
101
160
|
isFirstSlide,
|
|
@@ -110,7 +169,7 @@ export const OnboardingScreenContent: React.FC<OnboardingScreenContentProps> = (
|
|
|
110
169
|
showBackButton={showBackButton}
|
|
111
170
|
showSkipButton={showSkipButton}
|
|
112
171
|
skipButtonText={skipButtonText}
|
|
113
|
-
useGradient={
|
|
172
|
+
useGradient={effectivelyUseGradient}
|
|
114
173
|
/>
|
|
115
174
|
)}
|
|
116
175
|
{currentSlide &&
|
|
@@ -121,13 +180,13 @@ export const OnboardingScreenContent: React.FC<OnboardingScreenContentProps> = (
|
|
|
121
180
|
slide={currentSlide}
|
|
122
181
|
value={currentAnswer}
|
|
123
182
|
onChange={onAnswerChange}
|
|
124
|
-
useGradient={
|
|
183
|
+
useGradient={effectivelyUseGradient}
|
|
125
184
|
variant={variant}
|
|
126
185
|
/>
|
|
127
186
|
) : (
|
|
128
187
|
<OnboardingSlideComponent
|
|
129
188
|
slide={currentSlide}
|
|
130
|
-
useGradient={
|
|
189
|
+
useGradient={effectivelyUseGradient}
|
|
131
190
|
variant={variant}
|
|
132
191
|
/>
|
|
133
192
|
))}
|
|
@@ -152,7 +211,7 @@ export const OnboardingScreenContent: React.FC<OnboardingScreenContentProps> = (
|
|
|
152
211
|
nextButtonText={nextButtonText}
|
|
153
212
|
getStartedButtonText={getStartedButtonText}
|
|
154
213
|
disabled={!isAnswerValid}
|
|
155
|
-
useGradient={
|
|
214
|
+
useGradient={effectivelyUseGradient}
|
|
156
215
|
/>
|
|
157
216
|
)}
|
|
158
217
|
</View>
|
|
@@ -165,3 +224,4 @@ const styles = StyleSheet.create({
|
|
|
165
224
|
},
|
|
166
225
|
});
|
|
167
226
|
|
|
227
|
+
|