@rubixscript/react-native-onboarding 1.1.2 → 1.2.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/dist/components/SimpleOnboardingScreen.d.ts +33 -3
- package/dist/components/SimpleOnboardingScreen.d.ts.map +1 -1
- package/dist/components/SimpleOnboardingScreen.js +141 -20
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/SimpleOnboardingScreen.tsx +223 -26
- package/src/components/index.ts +1 -1
- package/src/index.ts +1 -1
|
@@ -3,25 +3,35 @@
|
|
|
3
3
|
* @description A simple, beautiful onboarding screen with customizable slides, colors, and styling
|
|
4
4
|
*
|
|
5
5
|
* @props
|
|
6
|
-
* - onComplete: () => void - Handler called when onboarding is finished
|
|
6
|
+
* - onComplete: (userData?: UserData) => void - Handler called when onboarding is finished with optional user data
|
|
7
7
|
* - slides: SimpleSlide[] - Array of slides to display (optional, has default)
|
|
8
|
+
* - showForm: boolean - Whether to show a form slide at the end (default: true)
|
|
9
|
+
* - formFields: FormField[] - Custom form fields (optional, has default)
|
|
10
|
+
* - allowSkipForm: boolean - Allow skipping the form (default: true)
|
|
8
11
|
* - primaryColor: string - Primary color for buttons and active dots (default: '#FF6B6B')
|
|
9
12
|
* - backgroundColor: string - Background color of the screen (default: '#F6F6F6')
|
|
10
13
|
* - iconBackgroundColor: string - Background color for icon container (default: 'rgba(255, 107, 107, 0.1)')
|
|
11
14
|
* - textColor: string - Color for titles (default: '#000000')
|
|
12
15
|
* - descriptionColor: string - Color for descriptions (default: '#666666')
|
|
16
|
+
* - inputBackgroundColor: string - Background color for form inputs (default: '#FFFFFF')
|
|
17
|
+
* - inputBorderColor: string - Border color for form inputs (default: '#E0E0E0')
|
|
13
18
|
* - buttonTextNext: string - Text for next button (default: 'Next')
|
|
14
19
|
* - buttonTextDone: string - Text for done button (default: 'Get Started')
|
|
20
|
+
* - buttonTextSkip: string - Text for skip button (default: 'Skip')
|
|
21
|
+
* - buttonTextSubmit: string - Text for submit button (default: 'Get Started')
|
|
15
22
|
* - testID?: string - Test identifier for testing
|
|
16
23
|
*
|
|
17
24
|
* @states
|
|
18
25
|
* - currentIndex: number - Current onboarding screen index
|
|
26
|
+
* - formData: UserData - Form data collected from user
|
|
19
27
|
*
|
|
20
28
|
* @features
|
|
21
29
|
* - Step-by-step app introduction
|
|
22
30
|
* - Interactive animations
|
|
23
31
|
* - Feature highlights
|
|
24
32
|
* - Progress indication
|
|
33
|
+
* - User data collection (name, purpose)
|
|
34
|
+
* - Skip functionality
|
|
25
35
|
* - Fully customizable styling
|
|
26
36
|
*
|
|
27
37
|
* @dependencies
|
|
@@ -37,18 +47,38 @@ export interface SimpleSlide {
|
|
|
37
47
|
description: string;
|
|
38
48
|
icon: keyof typeof MaterialCommunityIcons.glyphMap;
|
|
39
49
|
}
|
|
50
|
+
export interface FormField {
|
|
51
|
+
key: string;
|
|
52
|
+
label: string;
|
|
53
|
+
placeholder: string;
|
|
54
|
+
multiline?: boolean;
|
|
55
|
+
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters';
|
|
56
|
+
}
|
|
57
|
+
export interface UserData {
|
|
58
|
+
name?: string;
|
|
59
|
+
purpose?: string;
|
|
60
|
+
[key: string]: string | undefined;
|
|
61
|
+
}
|
|
40
62
|
interface SimpleOnboardingScreenProps {
|
|
41
|
-
onComplete: () => Promise<void>;
|
|
63
|
+
onComplete: (userData?: UserData) => Promise<void>;
|
|
42
64
|
slides?: SimpleSlide[];
|
|
65
|
+
showForm?: boolean;
|
|
66
|
+
formFields?: FormField[];
|
|
67
|
+
allowSkipForm?: boolean;
|
|
43
68
|
primaryColor?: string;
|
|
44
69
|
backgroundColor?: string;
|
|
45
70
|
iconBackgroundColor?: string;
|
|
46
71
|
textColor?: string;
|
|
47
72
|
descriptionColor?: string;
|
|
73
|
+
inputBackgroundColor?: string;
|
|
74
|
+
inputBorderColor?: string;
|
|
75
|
+
inputTextColor?: string;
|
|
48
76
|
buttonTextNext?: string;
|
|
49
77
|
buttonTextDone?: string;
|
|
78
|
+
buttonTextSkip?: string;
|
|
79
|
+
buttonTextSubmit?: string;
|
|
50
80
|
testID?: string;
|
|
51
81
|
}
|
|
52
|
-
export default function SimpleOnboardingScreen({ onComplete, slides, primaryColor, backgroundColor, iconBackgroundColor, textColor, descriptionColor, buttonTextNext, buttonTextDone, testID, }: SimpleOnboardingScreenProps): React.JSX.Element;
|
|
82
|
+
export default function SimpleOnboardingScreen({ onComplete, slides, showForm, formFields, allowSkipForm, primaryColor, backgroundColor, iconBackgroundColor, textColor, descriptionColor, inputBackgroundColor, inputBorderColor, inputTextColor, buttonTextNext, buttonTextDone, buttonTextSkip, buttonTextSubmit, testID, }: SimpleOnboardingScreenProps): React.JSX.Element;
|
|
53
83
|
export {};
|
|
54
84
|
//# sourceMappingURL=SimpleOnboardingScreen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimpleOnboardingScreen.d.ts","sourceRoot":"","sources":["../../src/components/SimpleOnboardingScreen.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"SimpleOnboardingScreen.d.ts","sourceRoot":"","sources":["../../src/components/SimpleOnboardingScreen.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAA2B,MAAM,OAAO,CAAC;AAgBhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAK5D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,OAAO,sBAAsB,CAAC,QAAQ,CAAC;CACpD;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,YAAY,CAAC;CAChE;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAuCD,UAAU,2BAA2B;IACnC,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAC7C,UAAU,EACV,MAAsB,EACtB,QAAe,EACf,UAA8B,EAC9B,aAAoB,EACpB,YAAwB,EACxB,eAA2B,EAC3B,mBAAgD,EAChD,SAAqB,EACrB,gBAA4B,EAC5B,oBAAgC,EAChC,gBAA4B,EAC5B,cAA0B,EAC1B,cAAuB,EACvB,cAA8B,EAC9B,cAAuB,EACvB,gBAAgC,EAChC,MAAM,GACP,EAAE,2BAA2B,qBAuL7B"}
|
|
@@ -3,25 +3,35 @@
|
|
|
3
3
|
* @description A simple, beautiful onboarding screen with customizable slides, colors, and styling
|
|
4
4
|
*
|
|
5
5
|
* @props
|
|
6
|
-
* - onComplete: () => void - Handler called when onboarding is finished
|
|
6
|
+
* - onComplete: (userData?: UserData) => void - Handler called when onboarding is finished with optional user data
|
|
7
7
|
* - slides: SimpleSlide[] - Array of slides to display (optional, has default)
|
|
8
|
+
* - showForm: boolean - Whether to show a form slide at the end (default: true)
|
|
9
|
+
* - formFields: FormField[] - Custom form fields (optional, has default)
|
|
10
|
+
* - allowSkipForm: boolean - Allow skipping the form (default: true)
|
|
8
11
|
* - primaryColor: string - Primary color for buttons and active dots (default: '#FF6B6B')
|
|
9
12
|
* - backgroundColor: string - Background color of the screen (default: '#F6F6F6')
|
|
10
13
|
* - iconBackgroundColor: string - Background color for icon container (default: 'rgba(255, 107, 107, 0.1)')
|
|
11
14
|
* - textColor: string - Color for titles (default: '#000000')
|
|
12
15
|
* - descriptionColor: string - Color for descriptions (default: '#666666')
|
|
16
|
+
* - inputBackgroundColor: string - Background color for form inputs (default: '#FFFFFF')
|
|
17
|
+
* - inputBorderColor: string - Border color for form inputs (default: '#E0E0E0')
|
|
13
18
|
* - buttonTextNext: string - Text for next button (default: 'Next')
|
|
14
19
|
* - buttonTextDone: string - Text for done button (default: 'Get Started')
|
|
20
|
+
* - buttonTextSkip: string - Text for skip button (default: 'Skip')
|
|
21
|
+
* - buttonTextSubmit: string - Text for submit button (default: 'Get Started')
|
|
15
22
|
* - testID?: string - Test identifier for testing
|
|
16
23
|
*
|
|
17
24
|
* @states
|
|
18
25
|
* - currentIndex: number - Current onboarding screen index
|
|
26
|
+
* - formData: UserData - Form data collected from user
|
|
19
27
|
*
|
|
20
28
|
* @features
|
|
21
29
|
* - Step-by-step app introduction
|
|
22
30
|
* - Interactive animations
|
|
23
31
|
* - Feature highlights
|
|
24
32
|
* - Progress indication
|
|
33
|
+
* - User data collection (name, purpose)
|
|
34
|
+
* - Skip functionality
|
|
25
35
|
* - Fully customizable styling
|
|
26
36
|
*
|
|
27
37
|
* @dependencies
|
|
@@ -30,7 +40,7 @@
|
|
|
30
40
|
* - react-native components
|
|
31
41
|
*/
|
|
32
42
|
import React, { useRef, useState } from 'react';
|
|
33
|
-
import { View, Text, StyleSheet, Dimensions, TouchableOpacity, FlatList, Platform, StatusBar, } from 'react-native';
|
|
43
|
+
import { View, Text, StyleSheet, Dimensions, TouchableOpacity, FlatList, Platform, StatusBar, TextInput, KeyboardAvoidingView, ScrollView, } from 'react-native';
|
|
34
44
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
35
45
|
import { BlurView } from 'expo-blur';
|
|
36
46
|
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
|
@@ -56,10 +66,33 @@ const defaultSlides = [
|
|
|
56
66
|
icon: 'chart-line',
|
|
57
67
|
},
|
|
58
68
|
];
|
|
59
|
-
|
|
69
|
+
const defaultFormFields = [
|
|
70
|
+
{
|
|
71
|
+
key: 'name',
|
|
72
|
+
label: 'What should we call you?',
|
|
73
|
+
placeholder: 'Enter your name',
|
|
74
|
+
autoCapitalize: 'words',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: 'purpose',
|
|
78
|
+
label: 'What are you looking to use this app for?',
|
|
79
|
+
placeholder: 'e.g., Focus on work, Study, Track goals...',
|
|
80
|
+
multiline: true,
|
|
81
|
+
autoCapitalize: 'sentences',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
export default function SimpleOnboardingScreen({ onComplete, slides = defaultSlides, showForm = true, formFields = defaultFormFields, allowSkipForm = true, primaryColor = '#FF6B6B', backgroundColor = '#F6F6F6', iconBackgroundColor = 'rgba(255, 107, 107, 0.1)', textColor = '#000000', descriptionColor = '#666666', inputBackgroundColor = '#FFFFFF', inputBorderColor = '#E0E0E0', inputTextColor = '#000000', buttonTextNext = 'Next', buttonTextDone = 'Get Started', buttonTextSkip = 'Skip', buttonTextSubmit = 'Get Started', testID, }) {
|
|
60
85
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
86
|
+
const [formData, setFormData] = useState({});
|
|
61
87
|
const flatListRef = useRef(null);
|
|
62
|
-
|
|
88
|
+
// Create display data: info slides + optional form slide
|
|
89
|
+
const displaySlides = showForm
|
|
90
|
+
? [...slides, { id: 'form', type: 'form' }]
|
|
91
|
+
: slides;
|
|
92
|
+
const totalSlides = displaySlides.length;
|
|
93
|
+
const isLastSlide = currentIndex === totalSlides - 1;
|
|
94
|
+
const isFormSlide = showForm && isLastSlide;
|
|
95
|
+
const renderInfoSlide = ({ item }) => (<View style={styles.slide}>
|
|
63
96
|
<Animated.View entering={FadeIn.duration(500)} style={[styles.iconContainer, { backgroundColor: iconBackgroundColor }]}>
|
|
64
97
|
<MaterialCommunityIcons name={item.icon} size={80} color={textColor}/>
|
|
65
98
|
</Animated.View>
|
|
@@ -70,8 +103,41 @@ export default function SimpleOnboardingScreen({ onComplete, slides = defaultSli
|
|
|
70
103
|
{item.description}
|
|
71
104
|
</Text>
|
|
72
105
|
</View>);
|
|
106
|
+
const renderFormSlide = () => (<KeyboardAvoidingView style={styles.slide} behavior="padding" keyboardVerticalOffset={100}>
|
|
107
|
+
<ScrollView style={styles.formContainer} contentContainerStyle={styles.formContentContainer} showsVerticalScrollIndicator={false}>
|
|
108
|
+
<Animated.View entering={FadeIn.duration(500)} style={[styles.iconContainer, { backgroundColor: iconBackgroundColor }]}>
|
|
109
|
+
<MaterialCommunityIcons name="account-outline" size={80} color={textColor}/>
|
|
110
|
+
</Animated.View>
|
|
111
|
+
<Text style={[styles.title, { color: textColor }]}>
|
|
112
|
+
Let's Get Started
|
|
113
|
+
</Text>
|
|
114
|
+
<Text style={[styles.formDescription, { color: descriptionColor }]}>
|
|
115
|
+
Tell us a bit about yourself (optional)
|
|
116
|
+
</Text>
|
|
117
|
+
|
|
118
|
+
{formFields.map((field) => (<View key={field.key} style={styles.inputWrapper}>
|
|
119
|
+
<Text style={[styles.inputLabel, { color: textColor }]}>
|
|
120
|
+
{field.label}
|
|
121
|
+
</Text>
|
|
122
|
+
<TextInput style={[
|
|
123
|
+
styles.input,
|
|
124
|
+
{
|
|
125
|
+
backgroundColor: inputBackgroundColor,
|
|
126
|
+
borderColor: inputBorderColor,
|
|
127
|
+
color: inputTextColor,
|
|
128
|
+
},
|
|
129
|
+
]} placeholder={field.placeholder} placeholderTextColor="#999999" value={formData[field.key] || ''} onChangeText={(text) => setFormData({ ...formData, [field.key]: text })} multiline={field.multiline} numberOfLines={field.multiline ? 4 : 1} autoCapitalize={field.autoCapitalize || 'sentences'}/>
|
|
130
|
+
</View>))}
|
|
131
|
+
</ScrollView>
|
|
132
|
+
</KeyboardAvoidingView>);
|
|
133
|
+
const renderSlide = ({ item, index }) => {
|
|
134
|
+
if (item.type === 'form') {
|
|
135
|
+
return renderFormSlide();
|
|
136
|
+
}
|
|
137
|
+
return renderInfoSlide({ item });
|
|
138
|
+
};
|
|
73
139
|
const handleNext = () => {
|
|
74
|
-
if (currentIndex <
|
|
140
|
+
if (currentIndex < totalSlides - 1) {
|
|
75
141
|
flatListRef.current?.scrollToIndex({
|
|
76
142
|
index: currentIndex + 1,
|
|
77
143
|
animated: true,
|
|
@@ -79,31 +145,44 @@ export default function SimpleOnboardingScreen({ onComplete, slides = defaultSli
|
|
|
79
145
|
setCurrentIndex(currentIndex + 1);
|
|
80
146
|
}
|
|
81
147
|
else {
|
|
82
|
-
|
|
148
|
+
// Submit form data
|
|
149
|
+
onComplete(formData);
|
|
83
150
|
}
|
|
84
151
|
};
|
|
152
|
+
const handleSkip = () => {
|
|
153
|
+
onComplete();
|
|
154
|
+
};
|
|
155
|
+
const isFormDataValid = () => {
|
|
156
|
+
return true; // Form is optional, so always valid
|
|
157
|
+
};
|
|
85
158
|
return (<SafeAreaView testID={testID} style={[styles.container, { backgroundColor }]} edges={['top', 'bottom']}>
|
|
86
159
|
<StatusBar barStyle="dark-content" backgroundColor="transparent" translucent/>
|
|
87
160
|
|
|
88
|
-
<FlatList ref={flatListRef} data={
|
|
161
|
+
<FlatList ref={flatListRef} data={displaySlides} renderItem={renderSlide} horizontal pagingEnabled showsHorizontalScrollIndicator={false} onMomentumScrollEnd={(event) => {
|
|
89
162
|
const index = Math.round(event.nativeEvent.contentOffset.x / width);
|
|
90
163
|
setCurrentIndex(index);
|
|
91
|
-
}}/>
|
|
164
|
+
}} scrollEnabled={!isFormSlide}/>
|
|
92
165
|
|
|
93
166
|
<BlurView intensity={80} tint="light" style={styles.footer}>
|
|
94
|
-
<View style={styles.
|
|
95
|
-
{
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
167
|
+
<View style={styles.footerContent}>
|
|
168
|
+
{isFormSlide && allowSkipForm ? (<TouchableOpacity style={styles.skipButton} onPress={handleSkip}>
|
|
169
|
+
<Text style={[styles.skipButtonText, { color: descriptionColor }]}>
|
|
170
|
+
{buttonTextSkip}
|
|
171
|
+
</Text>
|
|
172
|
+
</TouchableOpacity>) : (<View style={styles.pagination}>
|
|
173
|
+
{displaySlides.slice(0, showForm ? totalSlides - 1 : totalSlides).map((_, index) => (<View key={index} style={[
|
|
174
|
+
styles.paginationDot,
|
|
175
|
+
index === currentIndex && styles.paginationDotActive,
|
|
176
|
+
index === currentIndex && { backgroundColor: primaryColor },
|
|
177
|
+
]}/>))}
|
|
178
|
+
</View>)}
|
|
101
179
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
180
|
+
<TouchableOpacity style={[styles.button, { backgroundColor: primaryColor }]} onPress={handleNext}>
|
|
181
|
+
<Text style={styles.buttonText}>
|
|
182
|
+
{isFormSlide ? buttonTextSubmit : isLastSlide ? buttonTextDone : buttonTextNext}
|
|
183
|
+
</Text>
|
|
184
|
+
</TouchableOpacity>
|
|
185
|
+
</View>
|
|
107
186
|
</BlurView>
|
|
108
187
|
</SafeAreaView>);
|
|
109
188
|
}
|
|
@@ -136,6 +215,38 @@ const styles = StyleSheet.create({
|
|
|
136
215
|
textAlign: 'center',
|
|
137
216
|
lineHeight: 24,
|
|
138
217
|
},
|
|
218
|
+
formContainer: {
|
|
219
|
+
flex: 1,
|
|
220
|
+
width: '100%',
|
|
221
|
+
},
|
|
222
|
+
formContentContainer: {
|
|
223
|
+
alignItems: 'center',
|
|
224
|
+
paddingBottom: 100,
|
|
225
|
+
},
|
|
226
|
+
formDescription: {
|
|
227
|
+
fontSize: 17,
|
|
228
|
+
textAlign: 'center',
|
|
229
|
+
lineHeight: 24,
|
|
230
|
+
marginBottom: 32,
|
|
231
|
+
},
|
|
232
|
+
inputWrapper: {
|
|
233
|
+
width: '100%',
|
|
234
|
+
marginBottom: 20,
|
|
235
|
+
},
|
|
236
|
+
inputLabel: {
|
|
237
|
+
fontSize: 16,
|
|
238
|
+
fontWeight: '600',
|
|
239
|
+
marginBottom: 8,
|
|
240
|
+
},
|
|
241
|
+
input: {
|
|
242
|
+
width: '100%',
|
|
243
|
+
paddingHorizontal: 16,
|
|
244
|
+
paddingVertical: 14,
|
|
245
|
+
borderRadius: 12,
|
|
246
|
+
borderWidth: 1,
|
|
247
|
+
fontSize: 16,
|
|
248
|
+
textAlignVertical: 'top',
|
|
249
|
+
},
|
|
139
250
|
footer: {
|
|
140
251
|
position: 'absolute',
|
|
141
252
|
bottom: 0,
|
|
@@ -143,6 +254,8 @@ const styles = StyleSheet.create({
|
|
|
143
254
|
right: 0,
|
|
144
255
|
paddingHorizontal: 20,
|
|
145
256
|
paddingVertical: 20,
|
|
257
|
+
},
|
|
258
|
+
footerContent: {
|
|
146
259
|
flexDirection: 'row',
|
|
147
260
|
justifyContent: 'space-between',
|
|
148
261
|
alignItems: 'center',
|
|
@@ -181,4 +294,12 @@ const styles = StyleSheet.create({
|
|
|
181
294
|
fontSize: 17,
|
|
182
295
|
fontWeight: '600',
|
|
183
296
|
},
|
|
297
|
+
skipButton: {
|
|
298
|
+
paddingHorizontal: 16,
|
|
299
|
+
paddingVertical: 8,
|
|
300
|
+
},
|
|
301
|
+
skipButtonText: {
|
|
302
|
+
fontSize: 16,
|
|
303
|
+
fontWeight: '500',
|
|
304
|
+
},
|
|
184
305
|
});
|
|
@@ -2,6 +2,6 @@ export { Pagination } from './Pagination';
|
|
|
2
2
|
export { NavigationButton, NavigationButtons } from './NavigationButtons';
|
|
3
3
|
export { Onboarding, useOnboarding } from './Onboarding';
|
|
4
4
|
export { default as SimpleOnboardingScreen } from './SimpleOnboardingScreen';
|
|
5
|
-
export type { SimpleSlide } from './SimpleOnboardingScreen';
|
|
5
|
+
export type { SimpleSlide, FormField, UserData } from './SimpleOnboardingScreen';
|
|
6
6
|
export { default } from './Onboarding';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { Onboarding, useOnboarding } from './components/Onboarding';
|
|
2
2
|
export { SimpleOnboardingScreen } from './components';
|
|
3
|
-
export type { SimpleSlide } from './components';
|
|
3
|
+
export type { SimpleSlide, FormField, UserData } from './components';
|
|
4
4
|
export { ImageSlide, IconSlide, FormSlide, VideoSlide, SlideRenderer, } from './slides';
|
|
5
5
|
export { Pagination, NavigationButton, NavigationButtons, } from './components';
|
|
6
6
|
export { onepageTheme, zaprecipeTheme, pomodoTheme, modernTheme, minimalTheme, gradientTheme, onepagePreset, zaprecipePreset, pomodoPreset, modernPreset, minimalPreset, gradientPreset, getTheme, getPreset, mergeTheme, } from './themes';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGrE,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,aAAa,GACd,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,EACd,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,UAAU,CAAC;AAGlB,YAAY,EACV,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,eAAe,EACf,SAAS,EACT,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rubixscript/react-native-onboarding",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "A comprehensive React Native onboarding library with customizable slide types, animations, and themes",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -3,25 +3,35 @@
|
|
|
3
3
|
* @description A simple, beautiful onboarding screen with customizable slides, colors, and styling
|
|
4
4
|
*
|
|
5
5
|
* @props
|
|
6
|
-
* - onComplete: () => void - Handler called when onboarding is finished
|
|
6
|
+
* - onComplete: (userData?: UserData) => void - Handler called when onboarding is finished with optional user data
|
|
7
7
|
* - slides: SimpleSlide[] - Array of slides to display (optional, has default)
|
|
8
|
+
* - showForm: boolean - Whether to show a form slide at the end (default: true)
|
|
9
|
+
* - formFields: FormField[] - Custom form fields (optional, has default)
|
|
10
|
+
* - allowSkipForm: boolean - Allow skipping the form (default: true)
|
|
8
11
|
* - primaryColor: string - Primary color for buttons and active dots (default: '#FF6B6B')
|
|
9
12
|
* - backgroundColor: string - Background color of the screen (default: '#F6F6F6')
|
|
10
13
|
* - iconBackgroundColor: string - Background color for icon container (default: 'rgba(255, 107, 107, 0.1)')
|
|
11
14
|
* - textColor: string - Color for titles (default: '#000000')
|
|
12
15
|
* - descriptionColor: string - Color for descriptions (default: '#666666')
|
|
16
|
+
* - inputBackgroundColor: string - Background color for form inputs (default: '#FFFFFF')
|
|
17
|
+
* - inputBorderColor: string - Border color for form inputs (default: '#E0E0E0')
|
|
13
18
|
* - buttonTextNext: string - Text for next button (default: 'Next')
|
|
14
19
|
* - buttonTextDone: string - Text for done button (default: 'Get Started')
|
|
20
|
+
* - buttonTextSkip: string - Text for skip button (default: 'Skip')
|
|
21
|
+
* - buttonTextSubmit: string - Text for submit button (default: 'Get Started')
|
|
15
22
|
* - testID?: string - Test identifier for testing
|
|
16
23
|
*
|
|
17
24
|
* @states
|
|
18
25
|
* - currentIndex: number - Current onboarding screen index
|
|
26
|
+
* - formData: UserData - Form data collected from user
|
|
19
27
|
*
|
|
20
28
|
* @features
|
|
21
29
|
* - Step-by-step app introduction
|
|
22
30
|
* - Interactive animations
|
|
23
31
|
* - Feature highlights
|
|
24
32
|
* - Progress indication
|
|
33
|
+
* - User data collection (name, purpose)
|
|
34
|
+
* - Skip functionality
|
|
25
35
|
* - Fully customizable styling
|
|
26
36
|
*
|
|
27
37
|
* @dependencies
|
|
@@ -40,6 +50,9 @@ import {
|
|
|
40
50
|
FlatList,
|
|
41
51
|
Platform,
|
|
42
52
|
StatusBar,
|
|
53
|
+
TextInput,
|
|
54
|
+
KeyboardAvoidingView,
|
|
55
|
+
ScrollView,
|
|
43
56
|
} from 'react-native';
|
|
44
57
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
45
58
|
import { BlurView } from 'expo-blur';
|
|
@@ -55,6 +68,20 @@ export interface SimpleSlide {
|
|
|
55
68
|
icon: keyof typeof MaterialCommunityIcons.glyphMap;
|
|
56
69
|
}
|
|
57
70
|
|
|
71
|
+
export interface FormField {
|
|
72
|
+
key: string;
|
|
73
|
+
label: string;
|
|
74
|
+
placeholder: string;
|
|
75
|
+
multiline?: boolean;
|
|
76
|
+
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface UserData {
|
|
80
|
+
name?: string;
|
|
81
|
+
purpose?: string;
|
|
82
|
+
[key: string]: string | undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
58
85
|
const defaultSlides: SimpleSlide[] = [
|
|
59
86
|
{
|
|
60
87
|
id: '1',
|
|
@@ -76,35 +103,77 @@ const defaultSlides: SimpleSlide[] = [
|
|
|
76
103
|
},
|
|
77
104
|
];
|
|
78
105
|
|
|
106
|
+
const defaultFormFields: FormField[] = [
|
|
107
|
+
{
|
|
108
|
+
key: 'name',
|
|
109
|
+
label: 'What should we call you?',
|
|
110
|
+
placeholder: 'Enter your name',
|
|
111
|
+
autoCapitalize: 'words',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
key: 'purpose',
|
|
115
|
+
label: 'What are you looking to use this app for?',
|
|
116
|
+
placeholder: 'e.g., Focus on work, Study, Track goals...',
|
|
117
|
+
multiline: true,
|
|
118
|
+
autoCapitalize: 'sentences',
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
|
|
79
122
|
interface SimpleOnboardingScreenProps {
|
|
80
|
-
onComplete: () => Promise<void>;
|
|
123
|
+
onComplete: (userData?: UserData) => Promise<void>;
|
|
81
124
|
slides?: SimpleSlide[];
|
|
125
|
+
showForm?: boolean;
|
|
126
|
+
formFields?: FormField[];
|
|
127
|
+
allowSkipForm?: boolean;
|
|
82
128
|
primaryColor?: string;
|
|
83
129
|
backgroundColor?: string;
|
|
84
130
|
iconBackgroundColor?: string;
|
|
85
131
|
textColor?: string;
|
|
86
132
|
descriptionColor?: string;
|
|
133
|
+
inputBackgroundColor?: string;
|
|
134
|
+
inputBorderColor?: string;
|
|
135
|
+
inputTextColor?: string;
|
|
87
136
|
buttonTextNext?: string;
|
|
88
137
|
buttonTextDone?: string;
|
|
138
|
+
buttonTextSkip?: string;
|
|
139
|
+
buttonTextSubmit?: string;
|
|
89
140
|
testID?: string;
|
|
90
141
|
}
|
|
91
142
|
|
|
92
143
|
export default function SimpleOnboardingScreen({
|
|
93
144
|
onComplete,
|
|
94
145
|
slides = defaultSlides,
|
|
146
|
+
showForm = true,
|
|
147
|
+
formFields = defaultFormFields,
|
|
148
|
+
allowSkipForm = true,
|
|
95
149
|
primaryColor = '#FF6B6B',
|
|
96
150
|
backgroundColor = '#F6F6F6',
|
|
97
151
|
iconBackgroundColor = 'rgba(255, 107, 107, 0.1)',
|
|
98
152
|
textColor = '#000000',
|
|
99
153
|
descriptionColor = '#666666',
|
|
154
|
+
inputBackgroundColor = '#FFFFFF',
|
|
155
|
+
inputBorderColor = '#E0E0E0',
|
|
156
|
+
inputTextColor = '#000000',
|
|
100
157
|
buttonTextNext = 'Next',
|
|
101
158
|
buttonTextDone = 'Get Started',
|
|
159
|
+
buttonTextSkip = 'Skip',
|
|
160
|
+
buttonTextSubmit = 'Get Started',
|
|
102
161
|
testID,
|
|
103
162
|
}: SimpleOnboardingScreenProps) {
|
|
104
163
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
164
|
+
const [formData, setFormData] = useState<UserData>({});
|
|
105
165
|
const flatListRef = useRef<FlatList>(null);
|
|
106
166
|
|
|
107
|
-
|
|
167
|
+
// Create display data: info slides + optional form slide
|
|
168
|
+
const displaySlides = showForm
|
|
169
|
+
? [...slides, { id: 'form', type: 'form' } as any]
|
|
170
|
+
: slides;
|
|
171
|
+
|
|
172
|
+
const totalSlides = displaySlides.length;
|
|
173
|
+
const isLastSlide = currentIndex === totalSlides - 1;
|
|
174
|
+
const isFormSlide = showForm && isLastSlide;
|
|
175
|
+
|
|
176
|
+
const renderInfoSlide = ({ item }: { item: SimpleSlide }) => (
|
|
108
177
|
<View style={styles.slide}>
|
|
109
178
|
<Animated.View
|
|
110
179
|
entering={FadeIn.duration(500)}
|
|
@@ -125,18 +194,90 @@ export default function SimpleOnboardingScreen({
|
|
|
125
194
|
</View>
|
|
126
195
|
);
|
|
127
196
|
|
|
197
|
+
const renderFormSlide = () => (
|
|
198
|
+
<KeyboardAvoidingView
|
|
199
|
+
style={styles.slide}
|
|
200
|
+
behavior="padding"
|
|
201
|
+
keyboardVerticalOffset={100}
|
|
202
|
+
>
|
|
203
|
+
<ScrollView
|
|
204
|
+
style={styles.formContainer}
|
|
205
|
+
contentContainerStyle={styles.formContentContainer}
|
|
206
|
+
showsVerticalScrollIndicator={false}
|
|
207
|
+
>
|
|
208
|
+
<Animated.View
|
|
209
|
+
entering={FadeIn.duration(500)}
|
|
210
|
+
style={[styles.iconContainer, { backgroundColor: iconBackgroundColor }]}
|
|
211
|
+
>
|
|
212
|
+
<MaterialCommunityIcons
|
|
213
|
+
name="account-outline"
|
|
214
|
+
size={80}
|
|
215
|
+
color={textColor}
|
|
216
|
+
/>
|
|
217
|
+
</Animated.View>
|
|
218
|
+
<Text style={[styles.title, { color: textColor }]}>
|
|
219
|
+
Let's Get Started
|
|
220
|
+
</Text>
|
|
221
|
+
<Text style={[styles.formDescription, { color: descriptionColor }]}>
|
|
222
|
+
Tell us a bit about yourself (optional)
|
|
223
|
+
</Text>
|
|
224
|
+
|
|
225
|
+
{formFields.map((field) => (
|
|
226
|
+
<View key={field.key} style={styles.inputWrapper}>
|
|
227
|
+
<Text style={[styles.inputLabel, { color: textColor }]}>
|
|
228
|
+
{field.label}
|
|
229
|
+
</Text>
|
|
230
|
+
<TextInput
|
|
231
|
+
style={[
|
|
232
|
+
styles.input,
|
|
233
|
+
{
|
|
234
|
+
backgroundColor: inputBackgroundColor,
|
|
235
|
+
borderColor: inputBorderColor,
|
|
236
|
+
color: inputTextColor,
|
|
237
|
+
},
|
|
238
|
+
]}
|
|
239
|
+
placeholder={field.placeholder}
|
|
240
|
+
placeholderTextColor="#999999"
|
|
241
|
+
value={formData[field.key] || ''}
|
|
242
|
+
onChangeText={(text) => setFormData({ ...formData, [field.key]: text })}
|
|
243
|
+
multiline={field.multiline}
|
|
244
|
+
numberOfLines={field.multiline ? 4 : 1}
|
|
245
|
+
autoCapitalize={field.autoCapitalize || 'sentences'}
|
|
246
|
+
/>
|
|
247
|
+
</View>
|
|
248
|
+
))}
|
|
249
|
+
</ScrollView>
|
|
250
|
+
</KeyboardAvoidingView>
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
const renderSlide = ({ item, index }: { item: any; index: number }) => {
|
|
254
|
+
if (item.type === 'form') {
|
|
255
|
+
return renderFormSlide();
|
|
256
|
+
}
|
|
257
|
+
return renderInfoSlide({ item });
|
|
258
|
+
};
|
|
259
|
+
|
|
128
260
|
const handleNext = () => {
|
|
129
|
-
if (currentIndex <
|
|
261
|
+
if (currentIndex < totalSlides - 1) {
|
|
130
262
|
flatListRef.current?.scrollToIndex({
|
|
131
263
|
index: currentIndex + 1,
|
|
132
264
|
animated: true,
|
|
133
265
|
});
|
|
134
266
|
setCurrentIndex(currentIndex + 1);
|
|
135
267
|
} else {
|
|
136
|
-
|
|
268
|
+
// Submit form data
|
|
269
|
+
onComplete(formData);
|
|
137
270
|
}
|
|
138
271
|
};
|
|
139
272
|
|
|
273
|
+
const handleSkip = () => {
|
|
274
|
+
onComplete();
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const isFormDataValid = () => {
|
|
278
|
+
return true; // Form is optional, so always valid
|
|
279
|
+
};
|
|
280
|
+
|
|
140
281
|
return (
|
|
141
282
|
<SafeAreaView testID={testID} style={[styles.container, { backgroundColor }]} edges={['top', 'bottom']}>
|
|
142
283
|
<StatusBar
|
|
@@ -147,7 +288,7 @@ export default function SimpleOnboardingScreen({
|
|
|
147
288
|
|
|
148
289
|
<FlatList
|
|
149
290
|
ref={flatListRef}
|
|
150
|
-
data={
|
|
291
|
+
data={displaySlides}
|
|
151
292
|
renderItem={renderSlide}
|
|
152
293
|
horizontal
|
|
153
294
|
pagingEnabled
|
|
@@ -156,6 +297,7 @@ export default function SimpleOnboardingScreen({
|
|
|
156
297
|
const index = Math.round(event.nativeEvent.contentOffset.x / width);
|
|
157
298
|
setCurrentIndex(index);
|
|
158
299
|
}}
|
|
300
|
+
scrollEnabled={!isFormSlide}
|
|
159
301
|
/>
|
|
160
302
|
|
|
161
303
|
<BlurView
|
|
@@ -163,27 +305,40 @@ export default function SimpleOnboardingScreen({
|
|
|
163
305
|
tint="light"
|
|
164
306
|
style={styles.footer}
|
|
165
307
|
>
|
|
166
|
-
<View style={styles.
|
|
167
|
-
{
|
|
168
|
-
<
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
)
|
|
177
|
-
|
|
308
|
+
<View style={styles.footerContent}>
|
|
309
|
+
{isFormSlide && allowSkipForm ? (
|
|
310
|
+
<TouchableOpacity
|
|
311
|
+
style={styles.skipButton}
|
|
312
|
+
onPress={handleSkip}
|
|
313
|
+
>
|
|
314
|
+
<Text style={[styles.skipButtonText, { color: descriptionColor }]}>
|
|
315
|
+
{buttonTextSkip}
|
|
316
|
+
</Text>
|
|
317
|
+
</TouchableOpacity>
|
|
318
|
+
) : (
|
|
319
|
+
<View style={styles.pagination}>
|
|
320
|
+
{displaySlides.slice(0, showForm ? totalSlides - 1 : totalSlides).map((_, index) => (
|
|
321
|
+
<View
|
|
322
|
+
key={index}
|
|
323
|
+
style={[
|
|
324
|
+
styles.paginationDot,
|
|
325
|
+
index === currentIndex && styles.paginationDotActive,
|
|
326
|
+
index === currentIndex && { backgroundColor: primaryColor },
|
|
327
|
+
]}
|
|
328
|
+
/>
|
|
329
|
+
))}
|
|
330
|
+
</View>
|
|
331
|
+
)}
|
|
178
332
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
333
|
+
<TouchableOpacity
|
|
334
|
+
style={[styles.button, { backgroundColor: primaryColor }]}
|
|
335
|
+
onPress={handleNext}
|
|
336
|
+
>
|
|
337
|
+
<Text style={styles.buttonText}>
|
|
338
|
+
{isFormSlide ? buttonTextSubmit : isLastSlide ? buttonTextDone : buttonTextNext}
|
|
339
|
+
</Text>
|
|
340
|
+
</TouchableOpacity>
|
|
341
|
+
</View>
|
|
187
342
|
</BlurView>
|
|
188
343
|
</SafeAreaView>
|
|
189
344
|
);
|
|
@@ -218,6 +373,38 @@ const styles = StyleSheet.create({
|
|
|
218
373
|
textAlign: 'center',
|
|
219
374
|
lineHeight: 24,
|
|
220
375
|
},
|
|
376
|
+
formContainer: {
|
|
377
|
+
flex: 1,
|
|
378
|
+
width: '100%',
|
|
379
|
+
},
|
|
380
|
+
formContentContainer: {
|
|
381
|
+
alignItems: 'center',
|
|
382
|
+
paddingBottom: 100,
|
|
383
|
+
},
|
|
384
|
+
formDescription: {
|
|
385
|
+
fontSize: 17,
|
|
386
|
+
textAlign: 'center',
|
|
387
|
+
lineHeight: 24,
|
|
388
|
+
marginBottom: 32,
|
|
389
|
+
},
|
|
390
|
+
inputWrapper: {
|
|
391
|
+
width: '100%',
|
|
392
|
+
marginBottom: 20,
|
|
393
|
+
},
|
|
394
|
+
inputLabel: {
|
|
395
|
+
fontSize: 16,
|
|
396
|
+
fontWeight: '600',
|
|
397
|
+
marginBottom: 8,
|
|
398
|
+
},
|
|
399
|
+
input: {
|
|
400
|
+
width: '100%',
|
|
401
|
+
paddingHorizontal: 16,
|
|
402
|
+
paddingVertical: 14,
|
|
403
|
+
borderRadius: 12,
|
|
404
|
+
borderWidth: 1,
|
|
405
|
+
fontSize: 16,
|
|
406
|
+
textAlignVertical: 'top',
|
|
407
|
+
},
|
|
221
408
|
footer: {
|
|
222
409
|
position: 'absolute',
|
|
223
410
|
bottom: 0,
|
|
@@ -225,6 +412,8 @@ const styles = StyleSheet.create({
|
|
|
225
412
|
right: 0,
|
|
226
413
|
paddingHorizontal: 20,
|
|
227
414
|
paddingVertical: 20,
|
|
415
|
+
},
|
|
416
|
+
footerContent: {
|
|
228
417
|
flexDirection: 'row',
|
|
229
418
|
justifyContent: 'space-between',
|
|
230
419
|
alignItems: 'center',
|
|
@@ -263,4 +452,12 @@ const styles = StyleSheet.create({
|
|
|
263
452
|
fontSize: 17,
|
|
264
453
|
fontWeight: '600',
|
|
265
454
|
},
|
|
455
|
+
skipButton: {
|
|
456
|
+
paddingHorizontal: 16,
|
|
457
|
+
paddingVertical: 8,
|
|
458
|
+
},
|
|
459
|
+
skipButtonText: {
|
|
460
|
+
fontSize: 16,
|
|
461
|
+
fontWeight: '500',
|
|
462
|
+
},
|
|
266
463
|
});
|
package/src/components/index.ts
CHANGED
|
@@ -2,6 +2,6 @@ export { Pagination } from './Pagination';
|
|
|
2
2
|
export { NavigationButton, NavigationButtons } from './NavigationButtons';
|
|
3
3
|
export { Onboarding, useOnboarding } from './Onboarding';
|
|
4
4
|
export { default as SimpleOnboardingScreen } from './SimpleOnboardingScreen';
|
|
5
|
-
export type { SimpleSlide } from './SimpleOnboardingScreen';
|
|
5
|
+
export type { SimpleSlide, FormField, UserData } from './SimpleOnboardingScreen';
|
|
6
6
|
|
|
7
7
|
export { default } from './Onboarding';
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { Onboarding, useOnboarding } from './components/Onboarding';
|
|
|
3
3
|
|
|
4
4
|
// Simple Onboarding Screen - A simple, customizable onboarding component
|
|
5
5
|
export { SimpleOnboardingScreen } from './components';
|
|
6
|
-
export type { SimpleSlide } from './components';
|
|
6
|
+
export type { SimpleSlide, FormField, UserData } from './components';
|
|
7
7
|
|
|
8
8
|
// Slide Components
|
|
9
9
|
export {
|