logoChisa UI

Command Palette

Search for a command to run...

Componentschevron_rightOnboarding

Onboarding

A beautiful multi-screen onboarding flow with swipeable pages, smooth scroll-driven animations, mascot entrance effects, and animated pagination dots.

9:41
signal_cellular_altwifibattery_full
Onboarding Preview

Installation

$

Usage

Example.tsx
import { Onboarding } from './components/Onboarding';
export default function App() {
const handleComplete = () => {
console.log('Onboarding completed!');
// Navigate to main app
};
const handleSkip = () => {
console.log('User skipped onboarding');
// Navigate to main app
};
return (
<Onboarding
onComplete={handleComplete}
onSkip={handleSkip}
/>
);
}

Full Component Code

Onboarding.tsx
1import React, { useState } from 'react';
2import {
3 View,
4 Text,
5 StyleSheet,
6 useWindowDimensions,
7 TouchableOpacity,
8 SafeAreaView,
9 Platform,
10 StatusBar,
11 Image,
12} from 'react-native';
13import Animated, {
14 useSharedValue,
15 useAnimatedStyle,
16 withTiming,
17 withRepeat,
18 withSequence,
19 Easing,
20 runOnJS,
21 useAnimatedScrollHandler,
22 interpolate,
23 interpolateColor,
24 Extrapolation,
25 useAnimatedRef,
26} from 'react-native-reanimated';
27import Svg, { Path } from 'react-native-svg';
28import { ArrowRight, Sparkles, Star, CheckCircle, Zap, Palette, Code } from 'lucide-react-native';
29
30const PRIMARY_COLOR = '#D94F3D';
31const SECONDARY_COLOR = '#FFDBCF';
32const TEXT_COLOR = '#4A3B39';
33const BACKGROUND_LIGHT = '#FFF5F2';
34
35interface OnboardingProps {
36 onComplete?: () => void;
37 onSkip?: () => void;
38}
39
40export const Onboarding: React.FC<OnboardingProps> = ({ onComplete, onSkip }) => {
41 const { width } = useWindowDimensions();
42 const scrollX = useSharedValue(0);
43 const scrollRef = useAnimatedRef<Animated.ScrollView>();
44 const [currentIndex, setCurrentIndex] = useState(0);
45
46 // Intro & Sway Animation
47 const introProgress = useSharedValue(0);
48 const swayProgress = useSharedValue(0);
49
50 React.useEffect(() => {
51 introProgress.value = withTiming(1, { duration: 1000, easing: Easing.out(Easing.quad) }, (finished) => {
52 if (finished) {
53 swayProgress.value = withRepeat(
54 withSequence(
55 withTiming(1, { duration: 1500, easing: Easing.inOut(Easing.quad) }),
56 withTiming(-1, { duration: 1500, easing: Easing.inOut(Easing.quad) })
57 ),
58 -1,
59 true
60 );
61 }
62 });
63 }, []);
64
65 const scrollHandler = useAnimatedScrollHandler({
66 onScroll: (event) => {
67 scrollX.value = event.contentOffset.x;
68 },
69 onMomentumEnd: (event) => {
70 runOnJS(setCurrentIndex)(Math.round(event.contentOffset.x / width));
71 }
72 });
73
74 const handleNext = () => {
75 if (currentIndex < 2) {
76 scrollRef.current?.scrollTo({ x: (currentIndex + 1) * width, animated: true });
77 setCurrentIndex(currentIndex + 1);
78 } else {
79 onComplete?.();
80 }
81 };
82
83 // ... Slide rendering and styles (see full template)
84 return (
85 <SafeAreaView style={styles.container}>
86 <StatusBar barStyle="dark-content" backgroundColor={BACKGROUND_LIGHT} />
87 <Animated.ScrollView
88 ref={scrollRef}
89 horizontal
90 pagingEnabled
91 showsHorizontalScrollIndicator={false}
92 onScroll={scrollHandler}
93 scrollEventThrottle={16}
94 >
95 {/* Slides with mascot, features, and completion screen */}
96 </Animated.ScrollView>
97 {/* Footer with pagination dots and buttons */}
98 </SafeAreaView>
99 );
100};
101
102const styles = StyleSheet.create({
103 container: {
104 flex: 1,
105 backgroundColor: BACKGROUND_LIGHT,
106 },
107 // ... additional styles
108});

Props

NameTypeDefaultDescription
onComplete() => void-Callback when onboarding is completed
onSkip() => void-Callback when user skips the intro