@umituz/react-native-onboarding
v2.8.1
Published
Advanced onboarding flow for React Native apps with personalization questions, theme-aware colors, animations, and customizable slides. SOLID, DRY, KISS principles applied.
Downloads
3,674
Maintainers
Readme
@umituz/react-native-onboarding
Advanced onboarding flow for React Native apps with personalization questions, gradient backgrounds, animations, and customizable slides. Built with SOLID, DRY, KISS principles.
✨ Features
- 🎨 Beautiful gradient backgrounds with smooth transitions
- ❓ Personalization questions - Get to know your users
- 📝 Multiple question types - Single choice, multiple choice, text input, slider, rating
- ✅ Built-in validation - Required fields, min/max values, custom validators
- 🔄 Conditional slides - Skip slides based on previous answers
- 💾 Persistent storage - Save user answers and onboarding state
- 🎯 Type-safe - Full TypeScript support
- 🎭 Customizable - Custom header, footer, and slide components
- 📱 Universal - Works on iOS, Android, and Web
- 🚀 Production-ready - Used in hundreds of apps
📦 Installation
npm install @umituz/react-native-onboardingPeer Dependencies
npm install \
@umituz/react-native-storage \
@umituz/react-native-localization \
@umituz/react-native-design-system-theme \
@umituz/react-native-design-system \
@umituz/react-native-design-system-atoms \
@react-native-community/slider \
expo-linear-gradient \
react-native-safe-area-context \
zustand🚀 Quick Start
Basic Onboarding (Info Slides Only)
import { OnboardingScreen } from '@umituz/react-native-onboarding';
const slides = [
{
id: '1',
title: 'Welcome to Our App',
description: 'Discover amazing features',
icon: '👋',
gradient: ['#667eea', '#764ba2'],
},
{
id: '2',
title: 'Stay Organized',
description: 'Keep track of everything',
icon: '📋',
gradient: ['#f093fb', '#f5576c'],
},
];
<OnboardingScreen
slides={slides}
onComplete={() => console.log('Onboarding completed')}
/>Advanced Onboarding (With Personalization Questions)
import { OnboardingScreen, OnboardingSlide } from '@umituz/react-native-onboarding';
const slides: OnboardingSlide[] = [
// Welcome slide
{
id: '1',
type: 'welcome',
title: 'Welcome to FishWise',
description: 'Your personal aquarium assistant',
icon: '🐠',
gradient: ['#667eea', '#764ba2'],
},
// Question: Experience level
{
id: '2',
type: 'question',
title: 'What\'s your experience level?',
description: 'Help us personalize your experience',
icon: '🎯',
gradient: ['#f093fb', '#f5576c'],
question: {
id: 'experience_level',
type: 'single_choice',
question: 'Select your experience level',
storageKey: '@user_experience_level',
validation: { required: true },
options: [
{ id: 'beginner', label: 'Beginner', icon: '🌱' },
{ id: 'intermediate', label: 'Intermediate', icon: '🌿' },
{ id: 'expert', label: 'Expert', icon: '🌳' },
],
},
},
// Question: Tank size
{
id: '3',
type: 'question',
title: 'What\'s your tank size?',
description: 'This helps us recommend suitable fish',
icon: '📏',
gradient: ['#4facfe', '#00f2fe'],
question: {
id: 'tank_size',
type: 'slider',
question: 'Select your tank size (gallons)',
storageKey: '@user_tank_size',
validation: { required: true, min: 10, max: 500 },
defaultValue: 50,
},
},
// Question: Interests
{
id: '4',
type: 'question',
title: 'What interests you most?',
description: 'Select all that apply',
icon: '❤️',
gradient: ['#fa709a', '#fee140'],
question: {
id: 'interests',
type: 'multiple_choice',
question: 'Choose your interests',
storageKey: '@user_interests',
validation: { required: true, minSelections: 1, maxSelections: 3 },
options: [
{ id: 'freshwater', label: 'Freshwater Fish', icon: '🐟' },
{ id: 'saltwater', label: 'Saltwater Fish', icon: '🐠' },
{ id: 'plants', label: 'Aquatic Plants', icon: '🌿' },
{ id: 'equipment', label: 'Equipment & Tech', icon: '⚙️' },
],
},
},
// Completion slide
{
id: '5',
type: 'completion',
title: 'You\'re All Set!',
description: 'Let\'s start your aquarium journey',
icon: '🎉',
gradient: ['#30cfd0', '#330867'],
},
];
import Slider from '@react-native-community/slider';
<OnboardingScreen
slides={slides}
SliderComponent={Slider}
onComplete={async () => {
const userData = onboardingStore.getUserData();
console.log('User answers:', userData.answers);
// Save to backend, navigate to home, etc.
}}
/>📖 API Reference
OnboardingScreen Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| slides | OnboardingSlide[] | Required | Array of slides to display |
| onComplete | () => void \| Promise<void> | - | Callback when onboarding is completed |
| onSkip | () => void \| Promise<void> | - | Callback when onboarding is skipped |
| skipButtonText | string | "Skip" | Custom skip button text |
| nextButtonText | string | "Next" | Custom next button text |
| getStartedButtonText | string | "Get Started" | Custom get started button text |
| showSkipButton | boolean | true | Show skip button |
| showBackButton | boolean | true | Show back button |
| showProgressBar | boolean | true | Show progress bar |
| showDots | boolean | true | Show dots indicator |
| showProgressText | boolean | true | Show progress text (1 of 5) |
| storageKey | string | - | Custom storage key for completion state |
| autoComplete | boolean | false | Auto-complete on last slide |
| SliderComponent | React.ComponentType | - | Required if using slider questions. Import from @react-native-community/slider |
OnboardingSlide Interface
interface OnboardingSlide {
id: string;
type?: 'info' | 'question' | 'welcome' | 'completion';
title: string;
description: string;
icon: string; // Emoji or Lucide icon name
gradient: string[]; // [startColor, endColor] or [color1, color2, color3]
image?: string;
features?: string[];
question?: OnboardingQuestion;
skipIf?: (answers: Record<string, any>) => boolean;
}Question Types
Single Choice
{
type: 'single_choice',
question: 'What is your goal?',
options: [
{ id: 'weight_loss', label: 'Weight Loss', icon: '🏃' },
{ id: 'muscle_gain', label: 'Muscle Gain', icon: '💪' },
],
}Multiple Choice
{
type: 'multiple_choice',
question: 'Select your interests',
validation: { minSelections: 1, maxSelections: 3 },
options: [
{ id: 'yoga', label: 'Yoga', icon: '🧘' },
{ id: 'running', label: 'Running', icon: '🏃' },
{ id: 'swimming', label: 'Swimming', icon: '🏊' },
],
}Text Input
{
type: 'text_input',
question: 'What is your name?',
placeholder: 'Enter your name',
validation: { required: true, minLength: 2, maxLength: 50 },
}Slider
⚠️ Important: When using slider questions, you must provide the SliderComponent prop to OnboardingScreen:
import Slider from '@react-native-community/slider';
<OnboardingScreen
slides={slides}
SliderComponent={Slider}
onComplete={handleComplete}
/>{
type: 'slider',
question: 'What is your age?',
validation: { min: 18, max: 100 },
defaultValue: 25,
}Note: Make sure @react-native-community/slider is installed and properly linked (run pod install for iOS).
Rating
{
type: 'rating',
question: 'Rate your experience',
validation: { max: 5 },
}🎨 Customization
Custom Header
<OnboardingScreen
slides={slides}
renderHeader={({ isFirstSlide, onBack, onSkip }) => (
<View>
{!isFirstSlide && <Button onPress={onBack}>Back</Button>}
<Button onPress={onSkip}>Skip</Button>
</View>
)}
/>Custom Footer
<OnboardingScreen
slides={slides}
renderFooter={({ currentIndex, totalSlides, isLastSlide, onNext }) => (
<View>
<Text>{currentIndex + 1} / {totalSlides}</Text>
<Button onPress={onNext}>
{isLastSlide ? 'Get Started' : 'Next'}
</Button>
</View>
)}
/>Conditional Slides
{
id: '3',
title: 'Advanced Features',
description: 'Only for experienced users',
icon: '⚡',
gradient: ['#667eea', '#764ba2'],
skipIf: (answers) => answers.experience_level === 'beginner',
}💾 Accessing User Data
import { useOnboarding } from '@umituz/react-native-onboarding';
const { userData, getAnswer } = useOnboarding();
// Get specific answer
const experienceLevel = getAnswer('experience_level');
// Get all answers
const allAnswers = userData.answers;
// Check if onboarding was completed
const isComplete = userData.completedAt !== undefined;
// Check if onboarding was skipped
const wasSkipped = userData.skipped === true;🔄 Resetting Onboarding
import { useOnboarding } from '@umituz/react-native-onboarding';
const { reset } = useOnboarding();
// Reset onboarding (useful for testing or settings)
await reset();📱 Platform Support
- ✅ iOS
- ✅ Android
- ✅ Web
🏗️ Architecture
Built with Domain-Driven Design (DDD):
- Domain Layer: Entities and interfaces (business logic)
- Infrastructure Layer: Storage and hooks (state management)
- Presentation Layer: Components and screens (UI)
📄 License
MIT
🤝 Contributing
Contributions are welcome! Please open an issue or PR.
📧 Support
For issues and questions, please open an issue on GitHub.
