@rubixscript/react-native-onboarding 1.0.1 → 1.1.1
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/LICENSE +21 -21
- package/README.md +383 -383
- package/dist/components/NavigationButtons.js +17 -17
- package/dist/components/Onboarding.js +16 -16
- package/dist/components/Pagination.js +30 -30
- package/dist/components/SimpleOnboardingScreen.d.ts +54 -0
- package/dist/components/SimpleOnboardingScreen.d.ts.map +1 -0
- package/dist/components/SimpleOnboardingScreen.js +184 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +24 -27
- package/dist/slides/FormSlide.js +37 -37
- package/dist/slides/IconSlide.js +24 -24
- package/dist/slides/ImageSlide.js +20 -20
- package/dist/slides/VideoSlide.js +20 -20
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/index.js +9 -7
- package/package.json +71 -66
- package/src/components/NavigationButtons.tsx +198 -198
- package/src/components/Onboarding.tsx +337 -337
- package/src/components/Pagination.tsx +337 -337
- package/src/components/SimpleOnboardingScreen.tsx +266 -0
- package/src/components/index.ts +7 -5
- package/src/index.ts +69 -65
- package/src/presets/index.ts +391 -394
- package/src/slides/FormSlide.tsx +314 -314
- package/src/slides/IconSlide.tsx +166 -166
- package/src/slides/ImageSlide.tsx +132 -132
- package/src/slides/VideoSlide.tsx +146 -146
- package/src/slides/index.tsx +37 -37
- package/src/themes/index.ts +576 -574
- package/src/types/index.ts +247 -247
|
@@ -36,8 +36,8 @@ export const NavigationButton = ({ label, onPress, theme, variant = 'primary', d
|
|
|
36
36
|
};
|
|
37
37
|
return base;
|
|
38
38
|
}, [theme, variant]);
|
|
39
|
-
return (<AnimatedTouchableOpacity style={[buttonStyle, style]} onPress={onPress} disabled={disabled || loading} activeOpacity={0.8} entering={FadeIn} exiting={FadeOut}>
|
|
40
|
-
{loading ? (<ActivityIndicator color={variant === 'ghost' ? theme.colors.text.primary : theme.colors.text.inverse}/>) : (<Text style={[buttonText, textStyle]}>{label}</Text>)}
|
|
39
|
+
return (<AnimatedTouchableOpacity style={[buttonStyle, style]} onPress={onPress} disabled={disabled || loading} activeOpacity={0.8} entering={FadeIn} exiting={FadeOut}>
|
|
40
|
+
{loading ? (<ActivityIndicator color={variant === 'ghost' ? theme.colors.text.primary : theme.colors.text.inverse}/>) : (<Text style={[buttonText, textStyle]}>{label}</Text>)}
|
|
41
41
|
</AnimatedTouchableOpacity>);
|
|
42
42
|
};
|
|
43
43
|
export const NavigationButtons = ({ currentIndex, totalSlides, theme, config, onNext, onBack, onSkip, canGoNext = true, isLastSlide = false, isLoading = false, darkMode = false, }) => {
|
|
@@ -57,23 +57,23 @@ export const NavigationButtons = ({ currentIndex, totalSlides, theme, config, on
|
|
|
57
57
|
return base;
|
|
58
58
|
}, [theme, position]);
|
|
59
59
|
const isAtStart = currentIndex === 0;
|
|
60
|
-
const buttons = (<>
|
|
61
|
-
{/* Back Button */}
|
|
62
|
-
{showBack && !isAtStart && (<NavigationButton label={backLabel} onPress={onBack} theme={theme} variant="ghost"/>)}
|
|
63
|
-
|
|
64
|
-
{/* Skip Button */}
|
|
65
|
-
{showSkip && !isLastSlide && !isLoading && (<TouchableOpacity style={styles.skipButton} onPress={onSkip} activeOpacity={0.7}>
|
|
66
|
-
<Text style={[styles.skipButtonText, { color: theme.colors.text.secondary }]}>
|
|
67
|
-
{skipLabel}
|
|
68
|
-
</Text>
|
|
69
|
-
</TouchableOpacity>)}
|
|
70
|
-
|
|
71
|
-
{/* Next/Done Button */}
|
|
72
|
-
<NavigationButton label={isLastSlide ? doneLabel : nextLabel} onPress={onNext} theme={theme} variant="primary" disabled={!canGoNext} loading={isLoading}/>
|
|
60
|
+
const buttons = (<>
|
|
61
|
+
{/* Back Button */}
|
|
62
|
+
{showBack && !isAtStart && (<NavigationButton label={backLabel} onPress={onBack} theme={theme} variant="ghost"/>)}
|
|
63
|
+
|
|
64
|
+
{/* Skip Button */}
|
|
65
|
+
{showSkip && !isLastSlide && !isLoading && (<TouchableOpacity style={styles.skipButton} onPress={onSkip} activeOpacity={0.7}>
|
|
66
|
+
<Text style={[styles.skipButtonText, { color: theme.colors.text.secondary }]}>
|
|
67
|
+
{skipLabel}
|
|
68
|
+
</Text>
|
|
69
|
+
</TouchableOpacity>)}
|
|
70
|
+
|
|
71
|
+
{/* Next/Done Button */}
|
|
72
|
+
<NavigationButton label={isLastSlide ? doneLabel : nextLabel} onPress={onNext} theme={theme} variant="primary" disabled={!canGoNext} loading={isLoading}/>
|
|
73
73
|
</>);
|
|
74
74
|
if (position === 'floating') {
|
|
75
|
-
return (<BlurView intensity={80} tint={darkMode ? 'dark' : 'light'} style={containerStyle}>
|
|
76
|
-
<View style={styles.buttonRow}>{buttons}</View>
|
|
75
|
+
return (<BlurView intensity={80} tint={darkMode ? 'dark' : 'light'} style={containerStyle}>
|
|
76
|
+
<View style={styles.buttonRow}>{buttons}</View>
|
|
77
77
|
</BlurView>);
|
|
78
78
|
}
|
|
79
79
|
return <View style={containerStyle}>{buttons}</View>;
|
|
@@ -121,8 +121,8 @@ export const Onboarding = ({ visible, slides = [], theme: customTheme, navigatio
|
|
|
121
121
|
}, []);
|
|
122
122
|
// Renderers
|
|
123
123
|
const renderSlide = useCallback(({ item, index }) => {
|
|
124
|
-
return (<View style={[styles.slide, { width: '100%' }]}>
|
|
125
|
-
<SlideRenderer data={item} theme={theme} darkMode={darkMode} onSubmit={handleFormDataChange} isSubmitting={isSubmitting}/>
|
|
124
|
+
return (<View style={[styles.slide, { width: '100%' }]}>
|
|
125
|
+
<SlideRenderer data={item} theme={theme} darkMode={darkMode} onSubmit={handleFormDataChange} isSubmitting={isSubmitting}/>
|
|
126
126
|
</View>);
|
|
127
127
|
}, [theme, darkMode, isSubmitting, handleFormDataChange]);
|
|
128
128
|
const getKey = useCallback((item, index) => item.id || `slide-${index}`, []);
|
|
@@ -133,14 +133,14 @@ export const Onboarding = ({ visible, slides = [], theme: customTheme, navigatio
|
|
|
133
133
|
const showNavigation = currentSlide?.type !== 'form';
|
|
134
134
|
if (!visible)
|
|
135
135
|
return null;
|
|
136
|
-
const content = (<View style={[styles.container, containerStyle]}>
|
|
137
|
-
{/* Background Gradient if applicable */}
|
|
138
|
-
{currentSlide?.gradientColors && currentSlide.gradientColors.length > 0 && (<LinearGradient colors={currentSlide.gradientColors} style={StyleSheet.absoluteFillObject}/>)}
|
|
139
|
-
|
|
140
|
-
{/* Pagination */}
|
|
141
|
-
{showNavigation && (<Pagination currentIndex={currentIndex} totalSlides={slides.length} theme={theme} config={navigationConfig}/>)}
|
|
142
|
-
|
|
143
|
-
{/* Slides */}
|
|
136
|
+
const content = (<View style={[styles.container, containerStyle]}>
|
|
137
|
+
{/* Background Gradient if applicable */}
|
|
138
|
+
{currentSlide?.gradientColors && currentSlide.gradientColors.length > 0 && (<LinearGradient colors={currentSlide.gradientColors} style={StyleSheet.absoluteFillObject}/>)}
|
|
139
|
+
|
|
140
|
+
{/* Pagination */}
|
|
141
|
+
{showNavigation && (<Pagination currentIndex={currentIndex} totalSlides={slides.length} theme={theme} config={navigationConfig}/>)}
|
|
142
|
+
|
|
143
|
+
{/* Slides */}
|
|
144
144
|
<AnimatedFlatListImplemented ref={flatListRef} data={slides} renderItem={renderSlide} keyExtractor={getKey} horizontal pagingEnabled showsHorizontalScrollIndicator={false} scrollEventThrottle={32} onMomentumScrollEnd={handleMomentumScrollEnd} scrollEnabled={swipeEnabled} bounces={false} initialScrollIndex={initialSlide} onScrollToIndexFailed={(info) => {
|
|
145
145
|
// Retry if scroll to index fails
|
|
146
146
|
setTimeout(() => {
|
|
@@ -149,14 +149,14 @@ export const Onboarding = ({ visible, slides = [], theme: customTheme, navigatio
|
|
|
149
149
|
animated: true,
|
|
150
150
|
});
|
|
151
151
|
}, 100);
|
|
152
|
-
}}/>
|
|
153
|
-
|
|
154
|
-
{/* Navigation Buttons */}
|
|
155
|
-
{showNavigation && (<NavigationButtons currentIndex={currentIndex} totalSlides={slides.length} theme={theme} config={navigationConfig} onNext={handleNext} onBack={handleBack} onSkip={handleSkip} isLastSlide={isLastSlide} isLoading={isSubmitting} darkMode={darkMode}/>)}
|
|
152
|
+
}}/>
|
|
153
|
+
|
|
154
|
+
{/* Navigation Buttons */}
|
|
155
|
+
{showNavigation && (<NavigationButtons currentIndex={currentIndex} totalSlides={slides.length} theme={theme} config={navigationConfig} onNext={handleNext} onBack={handleBack} onSkip={handleSkip} isLastSlide={isLastSlide} isLoading={isSubmitting} darkMode={darkMode}/>)}
|
|
156
156
|
</View>);
|
|
157
157
|
if (safeAreaEnabled) {
|
|
158
|
-
return (<SafeAreaView style={styles.safeArea}>
|
|
159
|
-
<SafeAreaProvider>{content}</SafeAreaProvider>
|
|
158
|
+
return (<SafeAreaView style={styles.safeArea}>
|
|
159
|
+
<SafeAreaProvider>{content}</SafeAreaProvider>
|
|
160
160
|
</SafeAreaView>);
|
|
161
161
|
}
|
|
162
162
|
return content;
|
|
@@ -5,7 +5,7 @@ import { LinearGradient } from 'expo-linear-gradient';
|
|
|
5
5
|
// DOTS PAGINATION
|
|
6
6
|
const DotsPagination = ({ currentIndex, totalSlides, theme, style }) => {
|
|
7
7
|
const animatedIndex = useDerivedValue(() => withSpring(currentIndex, { damping: 15, stiffness: 150 }));
|
|
8
|
-
return (<View style={[styles.dotsContainer, style]}>
|
|
8
|
+
return (<View style={[styles.dotsContainer, style]}>
|
|
9
9
|
{Array.from({ length: totalSlides }).map((_, index) => {
|
|
10
10
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
11
11
|
width: index === animatedIndex.value ? 24 : 8,
|
|
@@ -18,59 +18,59 @@ const DotsPagination = ({ currentIndex, totalSlides, theme, style }) => {
|
|
|
18
18
|
},
|
|
19
19
|
animatedStyle,
|
|
20
20
|
]}/>);
|
|
21
|
-
})}
|
|
21
|
+
})}
|
|
22
22
|
</View>);
|
|
23
23
|
};
|
|
24
24
|
// PROGRESS BAR PAGINATION
|
|
25
25
|
const ProgressBarPagination = ({ currentIndex, totalSlides, theme, style }) => {
|
|
26
26
|
const progress = useMemo(() => (currentIndex + 1) / totalSlides, [currentIndex, totalSlides]);
|
|
27
|
-
return (<View style={[styles.progressContainer, style]}>
|
|
28
|
-
<View style={[styles.progressBackground, { backgroundColor: theme.colors.border }]}>
|
|
27
|
+
return (<View style={[styles.progressContainer, style]}>
|
|
28
|
+
<View style={[styles.progressBackground, { backgroundColor: theme.colors.border }]}>
|
|
29
29
|
<Animated.View style={[
|
|
30
30
|
styles.progressFill,
|
|
31
31
|
{
|
|
32
32
|
width: `${progress * 100}%`,
|
|
33
33
|
backgroundColor: theme.colors.primary,
|
|
34
34
|
},
|
|
35
|
-
]}/>
|
|
36
|
-
</View>
|
|
37
|
-
<Animated.Text style={[styles.progressText, { color: theme.colors.text.secondary }]}>
|
|
38
|
-
{currentIndex + 1} / {totalSlides}
|
|
39
|
-
</Animated.Text>
|
|
35
|
+
]}/>
|
|
36
|
+
</View>
|
|
37
|
+
<Animated.Text style={[styles.progressText, { color: theme.colors.text.secondary }]}>
|
|
38
|
+
{currentIndex + 1} / {totalSlides}
|
|
39
|
+
</Animated.Text>
|
|
40
40
|
</View>);
|
|
41
41
|
};
|
|
42
42
|
// STEPS PAGINATION
|
|
43
43
|
const StepsPagination = ({ currentIndex, totalSlides, theme, style }) => {
|
|
44
|
-
return (<View style={[styles.stepsContainer, style]}>
|
|
44
|
+
return (<View style={[styles.stepsContainer, style]}>
|
|
45
45
|
{Array.from({ length: totalSlides }).map((_, index) => {
|
|
46
46
|
const isCompleted = index < currentIndex;
|
|
47
47
|
const isCurrent = index === currentIndex;
|
|
48
|
-
return (<View key={index} style={styles.stepItem}>
|
|
48
|
+
return (<View key={index} style={styles.stepItem}>
|
|
49
49
|
<View style={[
|
|
50
50
|
styles.stepCircle,
|
|
51
51
|
{
|
|
52
52
|
backgroundColor: isCompleted ? theme.colors.primary : isCurrent ? theme.colors.primary : theme.colors.border,
|
|
53
53
|
borderColor: theme.colors.border,
|
|
54
54
|
},
|
|
55
|
-
]}>
|
|
55
|
+
]}>
|
|
56
56
|
{isCompleted ? (<View style={styles.stepCheckmark}/>) : (<Animated.Text style={[
|
|
57
57
|
styles.stepNumber,
|
|
58
58
|
{ color: isCurrent ? theme.colors.text.inverse : theme.colors.text.secondary },
|
|
59
|
-
]}>
|
|
60
|
-
{index + 1}
|
|
61
|
-
</Animated.Text>)}
|
|
62
|
-
</View>
|
|
59
|
+
]}>
|
|
60
|
+
{index + 1}
|
|
61
|
+
</Animated.Text>)}
|
|
62
|
+
</View>
|
|
63
63
|
{index < totalSlides - 1 && (<View style={[
|
|
64
64
|
styles.stepLine,
|
|
65
65
|
{ backgroundColor: isCompleted ? theme.colors.primary : theme.colors.border },
|
|
66
|
-
]}/>)}
|
|
66
|
+
]}/>)}
|
|
67
67
|
</View>);
|
|
68
|
-
})}
|
|
68
|
+
})}
|
|
69
69
|
</View>);
|
|
70
70
|
};
|
|
71
71
|
// NUMBERS PAGINATION
|
|
72
72
|
const NumbersPagination = ({ currentIndex, totalSlides, theme, style }) => {
|
|
73
|
-
return (<View style={[styles.numbersContainer, style]}>
|
|
73
|
+
return (<View style={[styles.numbersContainer, style]}>
|
|
74
74
|
{Array.from({ length: totalSlides }).map((_, index) => {
|
|
75
75
|
const isCurrent = index === currentIndex;
|
|
76
76
|
return (<Animated.View key={index} style={[
|
|
@@ -79,31 +79,31 @@ const NumbersPagination = ({ currentIndex, totalSlides, theme, style }) => {
|
|
|
79
79
|
backgroundColor: isCurrent ? theme.colors.primary : 'transparent',
|
|
80
80
|
borderColor: theme.colors.border,
|
|
81
81
|
},
|
|
82
|
-
]}>
|
|
82
|
+
]}>
|
|
83
83
|
<Animated.Text style={[
|
|
84
84
|
styles.numberText,
|
|
85
85
|
{ color: isCurrent ? theme.colors.text.inverse : theme.colors.text.secondary },
|
|
86
|
-
]}>
|
|
87
|
-
{index + 1}
|
|
88
|
-
</Animated.Text>
|
|
86
|
+
]}>
|
|
87
|
+
{index + 1}
|
|
88
|
+
</Animated.Text>
|
|
89
89
|
</Animated.View>);
|
|
90
|
-
})}
|
|
90
|
+
})}
|
|
91
91
|
</View>);
|
|
92
92
|
};
|
|
93
93
|
// FLOATING DOTS PAGINATION
|
|
94
94
|
const FloatingDotsPagination = ({ currentIndex, totalSlides, theme, style }) => {
|
|
95
|
-
return (<View style={[styles.floatingContainer, style]}>
|
|
96
|
-
<LinearGradient colors={[theme.colors.surface + 'CC', theme.colors.surface + 'CC']} style={styles.floatingBackground}>
|
|
97
|
-
<View style={styles.floatingDots}>
|
|
95
|
+
return (<View style={[styles.floatingContainer, style]}>
|
|
96
|
+
<LinearGradient colors={[theme.colors.surface + 'CC', theme.colors.surface + 'CC']} style={styles.floatingBackground}>
|
|
97
|
+
<View style={styles.floatingDots}>
|
|
98
98
|
{Array.from({ length: totalSlides }).map((_, index) => (<Animated.View key={index} style={[
|
|
99
99
|
styles.floatingDot,
|
|
100
100
|
{
|
|
101
101
|
width: index === currentIndex ? 28 : 10,
|
|
102
102
|
backgroundColor: index === currentIndex ? theme.colors.primary : theme.colors.border,
|
|
103
103
|
},
|
|
104
|
-
]}/>))}
|
|
105
|
-
</View>
|
|
106
|
-
</LinearGradient>
|
|
104
|
+
]}/>))}
|
|
105
|
+
</View>
|
|
106
|
+
</LinearGradient>
|
|
107
107
|
</View>);
|
|
108
108
|
};
|
|
109
109
|
// MAIN PAGINATION COMPONENT
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** METADATA
|
|
2
|
+
* @component SimpleOnboardingScreen
|
|
3
|
+
* @description A simple, beautiful onboarding screen with customizable slides, colors, and styling
|
|
4
|
+
*
|
|
5
|
+
* @props
|
|
6
|
+
* - onComplete: () => void - Handler called when onboarding is finished
|
|
7
|
+
* - slides: SimpleSlide[] - Array of slides to display (optional, has default)
|
|
8
|
+
* - primaryColor: string - Primary color for buttons and active dots (default: '#FF6B6B')
|
|
9
|
+
* - backgroundColor: string - Background color of the screen (default: '#F6F6F6')
|
|
10
|
+
* - iconBackgroundColor: string - Background color for icon container (default: 'rgba(255, 107, 107, 0.1)')
|
|
11
|
+
* - textColor: string - Color for titles (default: '#000000')
|
|
12
|
+
* - descriptionColor: string - Color for descriptions (default: '#666666')
|
|
13
|
+
* - buttonTextNext: string - Text for next button (default: 'Next')
|
|
14
|
+
* - buttonTextDone: string - Text for done button (default: 'Get Started')
|
|
15
|
+
* - testID?: string - Test identifier for testing
|
|
16
|
+
*
|
|
17
|
+
* @states
|
|
18
|
+
* - currentIndex: number - Current onboarding screen index
|
|
19
|
+
*
|
|
20
|
+
* @features
|
|
21
|
+
* - Step-by-step app introduction
|
|
22
|
+
* - Interactive animations
|
|
23
|
+
* - Feature highlights
|
|
24
|
+
* - Progress indication
|
|
25
|
+
* - Fully customizable styling
|
|
26
|
+
*
|
|
27
|
+
* @dependencies
|
|
28
|
+
* - react-native-reanimated: For animations
|
|
29
|
+
* - @expo/vector-icons: For UI icons
|
|
30
|
+
* - react-native components
|
|
31
|
+
*/
|
|
32
|
+
import React from 'react';
|
|
33
|
+
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
|
34
|
+
export interface SimpleSlide {
|
|
35
|
+
id: string;
|
|
36
|
+
title: string;
|
|
37
|
+
description: string;
|
|
38
|
+
icon: keyof typeof MaterialCommunityIcons.glyphMap;
|
|
39
|
+
}
|
|
40
|
+
interface SimpleOnboardingScreenProps {
|
|
41
|
+
onComplete: () => Promise<void>;
|
|
42
|
+
slides?: SimpleSlide[];
|
|
43
|
+
primaryColor?: string;
|
|
44
|
+
backgroundColor?: string;
|
|
45
|
+
iconBackgroundColor?: string;
|
|
46
|
+
textColor?: string;
|
|
47
|
+
descriptionColor?: string;
|
|
48
|
+
buttonTextNext?: string;
|
|
49
|
+
buttonTextDone?: string;
|
|
50
|
+
testID?: string;
|
|
51
|
+
}
|
|
52
|
+
export default function SimpleOnboardingScreen({ onComplete, slides, primaryColor, backgroundColor, iconBackgroundColor, textColor, descriptionColor, buttonTextNext, buttonTextDone, testID, }: SimpleOnboardingScreenProps): React.JSX.Element;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=SimpleOnboardingScreen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimpleOnboardingScreen.d.ts","sourceRoot":"","sources":["../../src/components/SimpleOnboardingScreen.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAA2B,MAAM,OAAO,CAAC;AAahD,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;AAuBD,UAAU,2BAA2B;IACnC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,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,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAC7C,UAAU,EACV,MAAsB,EACtB,YAAwB,EACxB,eAA2B,EAC3B,mBAAgD,EAChD,SAAqB,EACrB,gBAA4B,EAC5B,cAAuB,EACvB,cAA8B,EAC9B,MAAM,GACP,EAAE,2BAA2B,qBAuF7B"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/** METADATA
|
|
2
|
+
* @component SimpleOnboardingScreen
|
|
3
|
+
* @description A simple, beautiful onboarding screen with customizable slides, colors, and styling
|
|
4
|
+
*
|
|
5
|
+
* @props
|
|
6
|
+
* - onComplete: () => void - Handler called when onboarding is finished
|
|
7
|
+
* - slides: SimpleSlide[] - Array of slides to display (optional, has default)
|
|
8
|
+
* - primaryColor: string - Primary color for buttons and active dots (default: '#FF6B6B')
|
|
9
|
+
* - backgroundColor: string - Background color of the screen (default: '#F6F6F6')
|
|
10
|
+
* - iconBackgroundColor: string - Background color for icon container (default: 'rgba(255, 107, 107, 0.1)')
|
|
11
|
+
* - textColor: string - Color for titles (default: '#000000')
|
|
12
|
+
* - descriptionColor: string - Color for descriptions (default: '#666666')
|
|
13
|
+
* - buttonTextNext: string - Text for next button (default: 'Next')
|
|
14
|
+
* - buttonTextDone: string - Text for done button (default: 'Get Started')
|
|
15
|
+
* - testID?: string - Test identifier for testing
|
|
16
|
+
*
|
|
17
|
+
* @states
|
|
18
|
+
* - currentIndex: number - Current onboarding screen index
|
|
19
|
+
*
|
|
20
|
+
* @features
|
|
21
|
+
* - Step-by-step app introduction
|
|
22
|
+
* - Interactive animations
|
|
23
|
+
* - Feature highlights
|
|
24
|
+
* - Progress indication
|
|
25
|
+
* - Fully customizable styling
|
|
26
|
+
*
|
|
27
|
+
* @dependencies
|
|
28
|
+
* - react-native-reanimated: For animations
|
|
29
|
+
* - @expo/vector-icons: For UI icons
|
|
30
|
+
* - react-native components
|
|
31
|
+
*/
|
|
32
|
+
import React, { useRef, useState } from 'react';
|
|
33
|
+
import { View, Text, StyleSheet, Dimensions, TouchableOpacity, FlatList, Platform, StatusBar, } from 'react-native';
|
|
34
|
+
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
35
|
+
import { BlurView } from 'expo-blur';
|
|
36
|
+
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
|
37
|
+
import Animated, { FadeIn } from 'react-native-reanimated';
|
|
38
|
+
const { width } = Dimensions.get('window');
|
|
39
|
+
const defaultSlides = [
|
|
40
|
+
{
|
|
41
|
+
id: '1',
|
|
42
|
+
title: 'Focus Timer',
|
|
43
|
+
description: 'Stay productive with our Pomodoro timer. Work in focused intervals for better results.',
|
|
44
|
+
icon: 'timer-outline',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: '2',
|
|
48
|
+
title: 'Task Management',
|
|
49
|
+
description: 'Organize your tasks efficiently. Track progress and set priorities with ease.',
|
|
50
|
+
icon: 'checkbox-marked-circle-outline',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: '3',
|
|
54
|
+
title: 'Statistics',
|
|
55
|
+
description: 'Monitor your productivity with detailed statistics and insights.',
|
|
56
|
+
icon: 'chart-line',
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
export default function SimpleOnboardingScreen({ onComplete, slides = defaultSlides, primaryColor = '#FF6B6B', backgroundColor = '#F6F6F6', iconBackgroundColor = 'rgba(255, 107, 107, 0.1)', textColor = '#000000', descriptionColor = '#666666', buttonTextNext = 'Next', buttonTextDone = 'Get Started', testID, }) {
|
|
60
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
61
|
+
const flatListRef = useRef(null);
|
|
62
|
+
const renderSlide = ({ item }) => (<View style={styles.slide}>
|
|
63
|
+
<Animated.View entering={FadeIn.duration(500)} style={[styles.iconContainer, { backgroundColor: iconBackgroundColor }]}>
|
|
64
|
+
<MaterialCommunityIcons name={item.icon} size={80} color={textColor}/>
|
|
65
|
+
</Animated.View>
|
|
66
|
+
<Text style={[styles.title, { color: textColor }]}>
|
|
67
|
+
{item.title}
|
|
68
|
+
</Text>
|
|
69
|
+
<Text style={[styles.description, { color: descriptionColor }]}>
|
|
70
|
+
{item.description}
|
|
71
|
+
</Text>
|
|
72
|
+
</View>);
|
|
73
|
+
const handleNext = () => {
|
|
74
|
+
if (currentIndex < slides.length - 1) {
|
|
75
|
+
flatListRef.current?.scrollToIndex({
|
|
76
|
+
index: currentIndex + 1,
|
|
77
|
+
animated: true,
|
|
78
|
+
});
|
|
79
|
+
setCurrentIndex(currentIndex + 1);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
onComplete();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return (<SafeAreaView testID={testID} style={[styles.container, { backgroundColor }]} edges={['top', 'bottom']}>
|
|
86
|
+
<StatusBar barStyle="dark-content" backgroundColor="transparent" translucent/>
|
|
87
|
+
|
|
88
|
+
<FlatList ref={flatListRef} data={slides} renderItem={renderSlide} horizontal pagingEnabled showsHorizontalScrollIndicator={false} onMomentumScrollEnd={(event) => {
|
|
89
|
+
const index = Math.round(event.nativeEvent.contentOffset.x / width);
|
|
90
|
+
setCurrentIndex(index);
|
|
91
|
+
}}/>
|
|
92
|
+
|
|
93
|
+
<BlurView intensity={80} tint="light" style={styles.footer}>
|
|
94
|
+
<View style={styles.pagination}>
|
|
95
|
+
{slides.map((_, index) => (<View key={index} style={[
|
|
96
|
+
styles.paginationDot,
|
|
97
|
+
index === currentIndex && styles.paginationDotActive,
|
|
98
|
+
index === currentIndex && { backgroundColor: primaryColor },
|
|
99
|
+
]}/>))}
|
|
100
|
+
</View>
|
|
101
|
+
|
|
102
|
+
<TouchableOpacity style={[styles.button, { backgroundColor: primaryColor }]} onPress={handleNext}>
|
|
103
|
+
<Text style={styles.buttonText}>
|
|
104
|
+
{currentIndex === slides.length - 1 ? buttonTextDone : buttonTextNext}
|
|
105
|
+
</Text>
|
|
106
|
+
</TouchableOpacity>
|
|
107
|
+
</BlurView>
|
|
108
|
+
</SafeAreaView>);
|
|
109
|
+
}
|
|
110
|
+
const styles = StyleSheet.create({
|
|
111
|
+
container: {
|
|
112
|
+
flex: 1,
|
|
113
|
+
},
|
|
114
|
+
slide: {
|
|
115
|
+
width,
|
|
116
|
+
alignItems: 'center',
|
|
117
|
+
justifyContent: 'center',
|
|
118
|
+
paddingHorizontal: 40,
|
|
119
|
+
},
|
|
120
|
+
iconContainer: {
|
|
121
|
+
width: 160,
|
|
122
|
+
height: 160,
|
|
123
|
+
borderRadius: 80,
|
|
124
|
+
alignItems: 'center',
|
|
125
|
+
justifyContent: 'center',
|
|
126
|
+
marginBottom: 40,
|
|
127
|
+
},
|
|
128
|
+
title: {
|
|
129
|
+
fontSize: 28,
|
|
130
|
+
fontWeight: '700',
|
|
131
|
+
marginBottom: 16,
|
|
132
|
+
textAlign: 'center',
|
|
133
|
+
},
|
|
134
|
+
description: {
|
|
135
|
+
fontSize: 17,
|
|
136
|
+
textAlign: 'center',
|
|
137
|
+
lineHeight: 24,
|
|
138
|
+
},
|
|
139
|
+
footer: {
|
|
140
|
+
position: 'absolute',
|
|
141
|
+
bottom: 0,
|
|
142
|
+
left: 0,
|
|
143
|
+
right: 0,
|
|
144
|
+
paddingHorizontal: 20,
|
|
145
|
+
paddingVertical: 20,
|
|
146
|
+
flexDirection: 'row',
|
|
147
|
+
justifyContent: 'space-between',
|
|
148
|
+
alignItems: 'center',
|
|
149
|
+
},
|
|
150
|
+
pagination: {
|
|
151
|
+
flexDirection: 'row',
|
|
152
|
+
gap: 8,
|
|
153
|
+
},
|
|
154
|
+
paginationDot: {
|
|
155
|
+
width: 8,
|
|
156
|
+
height: 8,
|
|
157
|
+
borderRadius: 4,
|
|
158
|
+
backgroundColor: 'rgba(0, 0, 0, 0.2)',
|
|
159
|
+
},
|
|
160
|
+
paginationDotActive: {
|
|
161
|
+
width: 20,
|
|
162
|
+
},
|
|
163
|
+
button: {
|
|
164
|
+
paddingHorizontal: 32,
|
|
165
|
+
paddingVertical: 16,
|
|
166
|
+
borderRadius: 24,
|
|
167
|
+
...Platform.select({
|
|
168
|
+
ios: {
|
|
169
|
+
shadowColor: '#000',
|
|
170
|
+
shadowOffset: { width: 0, height: 8 },
|
|
171
|
+
shadowOpacity: 0.15,
|
|
172
|
+
shadowRadius: 12,
|
|
173
|
+
},
|
|
174
|
+
android: {
|
|
175
|
+
elevation: 8,
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
178
|
+
},
|
|
179
|
+
buttonText: {
|
|
180
|
+
color: '#FFFFFF',
|
|
181
|
+
fontSize: 17,
|
|
182
|
+
fontWeight: '600',
|
|
183
|
+
},
|
|
184
|
+
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { Pagination } from './Pagination';
|
|
2
2
|
export { NavigationButton, NavigationButtons } from './NavigationButtons';
|
|
3
3
|
export { Onboarding, useOnboarding } from './Onboarding';
|
|
4
|
+
export { default as SimpleOnboardingScreen } from './SimpleOnboardingScreen';
|
|
5
|
+
export type { SimpleSlide } from './SimpleOnboardingScreen';
|
|
4
6
|
export { default } from './Onboarding';
|
|
5
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;
|
|
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;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { Pagination } from './Pagination';
|
|
2
2
|
export { NavigationButton, NavigationButtons } from './NavigationButtons';
|
|
3
3
|
export { Onboarding, useOnboarding } from './Onboarding';
|
|
4
|
+
export { default as SimpleOnboardingScreen } from './SimpleOnboardingScreen';
|
|
4
5
|
export { default } from './Onboarding';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { Onboarding, useOnboarding } from './components/Onboarding';
|
|
2
|
+
export { SimpleOnboardingScreen } from './components';
|
|
3
|
+
export type { SimpleSlide } from './components';
|
|
2
4
|
export { ImageSlide, IconSlide, FormSlide, VideoSlide, SlideRenderer, } from './slides';
|
|
3
5
|
export { Pagination, NavigationButton, NavigationButtons, } from './components';
|
|
4
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,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"}
|
|
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;AAGhD,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/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Main Component
|
|
2
2
|
export { Onboarding, useOnboarding } from './components/Onboarding';
|
|
3
|
+
// Simple Onboarding Screen - A simple, customizable onboarding component
|
|
4
|
+
export { SimpleOnboardingScreen } from './components';
|
|
3
5
|
// Slide Components
|
|
4
6
|
export { ImageSlide, IconSlide, FormSlide, VideoSlide, SlideRenderer, } from './slides';
|
|
5
7
|
// UI Components
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAMvD,eAAO,MAAM,aAAa,EAAE,SAAS,EAuEpC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,SAAS,EAqEtC,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAMvD,eAAO,MAAM,aAAa,EAAE,SAAS,EAuEpC,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,SAAS,EAqEtC,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,SAAS,EA8CnC,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,SAAS,EA2CnC,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,SAAS,EA2CpC,CAAC;AAMF,eAAO,MAAM,cAAc,EAAE,SAAS,EAyBrC,CAAC;AAMF,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,KAAG,SAAS,EAUzD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAKxE,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,gBAG3B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,gBAG7B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,gBAI1B,CAAC;;;;;;;;8BArCsC,MAAM,KAAG,SAAS,EAAE;8BAYpB,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAAC;;;;;AA2B1E,wBAYE"}
|
package/dist/presets/index.js
CHANGED
|
@@ -151,49 +151,46 @@ export const zaprecipeSlides = [
|
|
|
151
151
|
// ============================================================================
|
|
152
152
|
export const pomodoSlides = [
|
|
153
153
|
{
|
|
154
|
-
id: '
|
|
154
|
+
id: '1',
|
|
155
155
|
type: 'icon',
|
|
156
|
-
title: '
|
|
157
|
-
|
|
158
|
-
description: 'Boost your productivity with our customizable Pomodoro timer. Work in focused intervals and take meaningful breaks.',
|
|
156
|
+
title: 'Focus Timer',
|
|
157
|
+
description: 'Stay productive with our Pomodoro timer. Work in focused intervals for better results.',
|
|
159
158
|
icon: {
|
|
160
|
-
name: 'timer',
|
|
161
|
-
type: '
|
|
162
|
-
size:
|
|
163
|
-
color: '#
|
|
164
|
-
backgroundColor: '
|
|
159
|
+
name: 'timer-outline',
|
|
160
|
+
type: 'material-community',
|
|
161
|
+
size: 80,
|
|
162
|
+
color: '#000000',
|
|
163
|
+
backgroundColor: 'rgba(255, 107, 107, 0.1)',
|
|
165
164
|
backgroundSize: 160,
|
|
166
165
|
},
|
|
167
166
|
backgroundColor: '#F6F6F6',
|
|
168
167
|
},
|
|
169
168
|
{
|
|
170
|
-
id: '
|
|
169
|
+
id: '2',
|
|
171
170
|
type: 'icon',
|
|
172
|
-
title: '
|
|
173
|
-
|
|
174
|
-
description: 'Keep track of all your tasks with priorities, tags, and subtasks. Never lose track of what needs to be done.',
|
|
171
|
+
title: 'Task Management',
|
|
172
|
+
description: 'Organize your tasks efficiently. Track progress and set priorities with ease.',
|
|
175
173
|
icon: {
|
|
176
|
-
name: '
|
|
177
|
-
type: '
|
|
178
|
-
size:
|
|
179
|
-
color: '#
|
|
180
|
-
backgroundColor: '
|
|
174
|
+
name: 'checkbox-marked-circle-outline',
|
|
175
|
+
type: 'material-community',
|
|
176
|
+
size: 80,
|
|
177
|
+
color: '#000000',
|
|
178
|
+
backgroundColor: 'rgba(255, 107, 107, 0.1)',
|
|
181
179
|
backgroundSize: 160,
|
|
182
180
|
},
|
|
183
181
|
backgroundColor: '#F6F6F6',
|
|
184
182
|
},
|
|
185
183
|
{
|
|
186
|
-
id: '
|
|
184
|
+
id: '3',
|
|
187
185
|
type: 'icon',
|
|
188
|
-
title: '
|
|
189
|
-
|
|
190
|
-
description: 'Monitor your productivity with detailed statistics. See your focus time, completed tasks, and patterns.',
|
|
186
|
+
title: 'Statistics',
|
|
187
|
+
description: 'Monitor your productivity with detailed statistics and insights.',
|
|
191
188
|
icon: {
|
|
192
|
-
name: '
|
|
193
|
-
type: '
|
|
194
|
-
size:
|
|
195
|
-
color: '#
|
|
196
|
-
backgroundColor: '
|
|
189
|
+
name: 'chart-line',
|
|
190
|
+
type: 'material-community',
|
|
191
|
+
size: 80,
|
|
192
|
+
color: '#000000',
|
|
193
|
+
backgroundColor: 'rgba(255, 107, 107, 0.1)',
|
|
197
194
|
backgroundSize: 160,
|
|
198
195
|
},
|
|
199
196
|
backgroundColor: '#F6F6F6',
|