Skip to content

umituz/react-native-onboarding

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

55 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@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-onboarding

Peer 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.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published