@umituz/react-native-onboarding 3.3.11 → 3.5.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-onboarding",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.1",
|
|
4
4
|
"description": "Advanced onboarding flow for React Native apps with personalization questions, theme-aware colors, animations, and customizable slides. SOLID, DRY, KISS principles applied.",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -31,10 +31,9 @@
|
|
|
31
31
|
"url": "https://github.com/umituz/react-native-onboarding"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@umituz/react-native-icons": "latest",
|
|
35
34
|
"@umituz/react-native-storage": "latest",
|
|
36
35
|
"@umituz/react-native-localization": "latest",
|
|
37
|
-
"@umituz/react-native-design-system": "
|
|
36
|
+
"@umituz/react-native-design-system": "^2.1.0",
|
|
38
37
|
"@expo/vector-icons": ">=14.0.0",
|
|
39
38
|
"expo-image": ">=2.0.0",
|
|
40
39
|
"expo-linear-gradient": ">=13.0.0",
|
|
@@ -42,13 +41,12 @@
|
|
|
42
41
|
"react": ">=18.2.0",
|
|
43
42
|
"react-native": ">=0.74.0",
|
|
44
43
|
"react-native-safe-area-context": ">=4.0.0",
|
|
45
|
-
"zustand": "
|
|
44
|
+
"zustand": "^4.5.0 || ^5.0.0"
|
|
46
45
|
},
|
|
47
46
|
"devDependencies": {
|
|
48
|
-
"@umituz/react-native-icons": "latest",
|
|
49
47
|
"@umituz/react-native-storage": "latest",
|
|
50
48
|
"@umituz/react-native-localization": "latest",
|
|
51
|
-
"@umituz/react-native-design-system": "
|
|
49
|
+
"@umituz/react-native-design-system": "^2.1.0",
|
|
52
50
|
"@expo/vector-icons": "^14.0.0",
|
|
53
51
|
"expo-image": "~2.0.0",
|
|
54
52
|
"expo-linear-gradient": "^15.0.7",
|
|
@@ -68,4 +66,4 @@
|
|
|
68
66
|
"README.md",
|
|
69
67
|
"LICENSE"
|
|
70
68
|
]
|
|
71
|
-
}
|
|
69
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -68,6 +68,7 @@ export {
|
|
|
68
68
|
export { OnboardingScreen, type OnboardingScreenProps } from "./presentation/screens/OnboardingScreen";
|
|
69
69
|
export { OnboardingHeader, type OnboardingHeaderProps } from "./presentation/components/OnboardingHeader";
|
|
70
70
|
export { OnboardingFooter, type OnboardingFooterProps } from "./presentation/components/OnboardingFooter";
|
|
71
|
+
export { OnboardingThemeProvider, type OnboardingThemeProviderProps, useOnboardingTheme } from "./presentation/providers/OnboardingThemeProvider";
|
|
71
72
|
|
|
72
73
|
// Export OnboardingSlide component
|
|
73
74
|
// Note: TypeScript doesn't allow exporting both a type and a value with the same name
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Uses @umituz/react-native-storage for persistence
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { create } from "zustand";
|
|
8
|
+
import { create, StoreApi } from "zustand";
|
|
9
9
|
import type { OnboardingStoreState } from "./OnboardingStoreState";
|
|
10
10
|
import { initialOnboardingState } from "./OnboardingStoreState";
|
|
11
11
|
import { createOnboardingStoreActions } from "./OnboardingStoreActions";
|
|
@@ -27,8 +27,8 @@ interface OnboardingStore extends OnboardingStoreState {
|
|
|
27
27
|
setUserData: (data: any) => Promise<void>;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export const useOnboardingStore = create<OnboardingStore>((set, get) => {
|
|
31
|
-
const actions = createOnboardingStoreActions(set
|
|
30
|
+
export const useOnboardingStore = create<OnboardingStore>((set: StoreApi<OnboardingStore>['setState'], get: StoreApi<OnboardingStore>['getState']) => {
|
|
31
|
+
const actions = createOnboardingStoreActions(set, get);
|
|
32
32
|
|
|
33
33
|
return {
|
|
34
34
|
...initialOnboardingState,
|
|
@@ -54,7 +54,7 @@ export const useOnboardingStore = create<OnboardingStore>((set, get) => {
|
|
|
54
54
|
*/
|
|
55
55
|
export const useOnboarding = () => {
|
|
56
56
|
const store = useOnboardingStore();
|
|
57
|
-
const setState = store.setState
|
|
57
|
+
const setState = store.setState;
|
|
58
58
|
const getState = () => store;
|
|
59
59
|
const actions = createOnboardingStoreActions(setState, getState);
|
|
60
60
|
const selectors = createOnboardingStoreSelectors(getState);
|
|
@@ -14,10 +14,10 @@ import { OnboardingSlide as OnboardingSlideComponent } from "./OnboardingSlide";
|
|
|
14
14
|
import { QuestionSlide } from "./QuestionSlide";
|
|
15
15
|
import { OnboardingFooter } from "./OnboardingFooter";
|
|
16
16
|
import { BackgroundVideo } from "./BackgroundVideo";
|
|
17
|
+
import { useOnboardingTheme } from "../providers/OnboardingThemeProvider";
|
|
17
18
|
|
|
18
19
|
export interface OnboardingScreenContentProps {
|
|
19
20
|
containerStyle?: any;
|
|
20
|
-
useGradient: boolean;
|
|
21
21
|
currentSlide: OnboardingSlide | undefined;
|
|
22
22
|
isFirstSlide: boolean;
|
|
23
23
|
isLastSlide: boolean;
|
|
@@ -58,7 +58,6 @@ export interface OnboardingScreenContentProps {
|
|
|
58
58
|
|
|
59
59
|
export const OnboardingScreenContent = ({
|
|
60
60
|
containerStyle,
|
|
61
|
-
useGradient,
|
|
62
61
|
currentSlide,
|
|
63
62
|
isFirstSlide,
|
|
64
63
|
isLastSlide,
|
|
@@ -86,6 +85,7 @@ export const OnboardingScreenContent = ({
|
|
|
86
85
|
variant = "default",
|
|
87
86
|
}: OnboardingScreenContentProps) => {
|
|
88
87
|
const { themeMode } = useTheme();
|
|
88
|
+
const { useGradient } = useOnboardingTheme();
|
|
89
89
|
|
|
90
90
|
const hasMedia = !!currentSlide?.backgroundImage || !!currentSlide?.backgroundVideo;
|
|
91
91
|
const overlayOpacity = currentSlide?.overlayOpacity ?? 0.5;
|
|
@@ -157,7 +157,6 @@ export const OnboardingScreenContent = ({
|
|
|
157
157
|
showBackButton={showBackButton}
|
|
158
158
|
showSkipButton={showSkipButton}
|
|
159
159
|
skipButtonText={skipButtonText}
|
|
160
|
-
useGradient={effectivelyUseGradient}
|
|
161
160
|
/>
|
|
162
161
|
)}
|
|
163
162
|
{currentSlide &&
|
|
@@ -168,13 +167,11 @@ export const OnboardingScreenContent = ({
|
|
|
168
167
|
slide={currentSlide}
|
|
169
168
|
value={currentAnswer}
|
|
170
169
|
onChange={onAnswerChange}
|
|
171
|
-
useGradient={effectivelyUseGradient}
|
|
172
170
|
variant={variant}
|
|
173
171
|
/>
|
|
174
172
|
) : (
|
|
175
173
|
<OnboardingSlideComponent
|
|
176
174
|
slide={currentSlide}
|
|
177
|
-
useGradient={effectivelyUseGradient}
|
|
178
175
|
variant={variant}
|
|
179
176
|
/>
|
|
180
177
|
))}
|
|
@@ -199,7 +196,6 @@ export const OnboardingScreenContent = ({
|
|
|
199
196
|
nextButtonText={nextButtonText}
|
|
200
197
|
getStartedButtonText={getStartedButtonText}
|
|
201
198
|
disabled={!isAnswerValid}
|
|
202
|
-
useGradient={effectivelyUseGradient}
|
|
203
199
|
/>
|
|
204
200
|
)}
|
|
205
201
|
</View>
|
|
@@ -118,7 +118,6 @@ export const OnboardingScreen = ({
|
|
|
118
118
|
<OnboardingThemeProvider useGradient={useGradient}>
|
|
119
119
|
<OnboardingScreenContent
|
|
120
120
|
containerStyle={[styles.container, containerStyle]}
|
|
121
|
-
useGradient={useGradient}
|
|
122
121
|
currentSlide={currentSlide}
|
|
123
122
|
isFirstSlide={isFirstSlide}
|
|
124
123
|
isLastSlide={isLastSlide}
|
package/README.md
DELETED
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
# @umituz/react-native-onboarding
|
|
2
|
-
|
|
3
|
-
Advanced onboarding flow for React Native apps with **personalization questions**, gradient backgrounds, animations, and customizable slides. Built with SOLID, DRY, KISS principles.
|
|
4
|
-
|
|
5
|
-
## ✨ Features
|
|
6
|
-
|
|
7
|
-
- 🎨 **Beautiful gradient backgrounds** with smooth transitions
|
|
8
|
-
- ❓ **Personalization questions** - Get to know your users
|
|
9
|
-
- 📝 **Multiple question types** - Single choice, multiple choice, text input, slider, rating
|
|
10
|
-
- ✅ **Built-in validation** - Required fields, min/max values, custom validators
|
|
11
|
-
- 🔄 **Conditional slides** - Skip slides based on previous answers
|
|
12
|
-
- 💾 **Persistent storage** - Save user answers and onboarding state
|
|
13
|
-
- 🎯 **Type-safe** - Full TypeScript support
|
|
14
|
-
- 🎭 **Customizable** - Custom header, footer, and slide components
|
|
15
|
-
- 📱 **Universal** - Works on iOS, Android, and Web
|
|
16
|
-
- 🚀 **Production-ready** - Used in hundreds of apps
|
|
17
|
-
|
|
18
|
-
## 📦 Installation
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npm install @umituz/react-native-onboarding
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### Peer Dependencies
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npm install \
|
|
28
|
-
@umituz/react-native-storage \
|
|
29
|
-
@umituz/react-native-localization \
|
|
30
|
-
@umituz/react-native-design-system-theme \
|
|
31
|
-
@umituz/react-native-design-system \
|
|
32
|
-
@umituz/react-native-design-system-atoms \
|
|
33
|
-
@react-native-community/slider \
|
|
34
|
-
expo-linear-gradient \
|
|
35
|
-
react-native-safe-area-context \
|
|
36
|
-
zustand
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## 🚀 Quick Start
|
|
40
|
-
|
|
41
|
-
### Basic Onboarding (Info Slides Only)
|
|
42
|
-
|
|
43
|
-
```tsx
|
|
44
|
-
import { OnboardingScreen } from '@umituz/react-native-onboarding';
|
|
45
|
-
|
|
46
|
-
const slides = [
|
|
47
|
-
{
|
|
48
|
-
id: '1',
|
|
49
|
-
title: 'Welcome to Our App',
|
|
50
|
-
description: 'Discover amazing features',
|
|
51
|
-
icon: '👋',
|
|
52
|
-
gradient: ['#667eea', '#764ba2'],
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
id: '2',
|
|
56
|
-
title: 'Stay Organized',
|
|
57
|
-
description: 'Keep track of everything',
|
|
58
|
-
icon: '📋',
|
|
59
|
-
gradient: ['#f093fb', '#f5576c'],
|
|
60
|
-
},
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
<OnboardingScreen
|
|
64
|
-
slides={slides}
|
|
65
|
-
onComplete={() => console.log('Onboarding completed')}
|
|
66
|
-
/>
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Advanced Onboarding (With Personalization Questions)
|
|
70
|
-
|
|
71
|
-
```tsx
|
|
72
|
-
import { OnboardingScreen, OnboardingSlide } from '@umituz/react-native-onboarding';
|
|
73
|
-
|
|
74
|
-
const slides: OnboardingSlide[] = [
|
|
75
|
-
// Welcome slide
|
|
76
|
-
{
|
|
77
|
-
id: '1',
|
|
78
|
-
type: 'welcome',
|
|
79
|
-
title: 'Welcome to FishWise',
|
|
80
|
-
description: 'Your personal aquarium assistant',
|
|
81
|
-
icon: '🐠',
|
|
82
|
-
gradient: ['#667eea', '#764ba2'],
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
// Question: Experience level
|
|
86
|
-
{
|
|
87
|
-
id: '2',
|
|
88
|
-
type: 'question',
|
|
89
|
-
title: 'What\'s your experience level?',
|
|
90
|
-
description: 'Help us personalize your experience',
|
|
91
|
-
icon: '🎯',
|
|
92
|
-
gradient: ['#f093fb', '#f5576c'],
|
|
93
|
-
question: {
|
|
94
|
-
id: 'experience_level',
|
|
95
|
-
type: 'single_choice',
|
|
96
|
-
question: 'Select your experience level',
|
|
97
|
-
storageKey: '@user_experience_level',
|
|
98
|
-
validation: { required: true },
|
|
99
|
-
options: [
|
|
100
|
-
{ id: 'beginner', label: 'Beginner', icon: '🌱' },
|
|
101
|
-
{ id: 'intermediate', label: 'Intermediate', icon: '🌿' },
|
|
102
|
-
{ id: 'expert', label: 'Expert', icon: '🌳' },
|
|
103
|
-
],
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
// Question: Tank size
|
|
108
|
-
{
|
|
109
|
-
id: '3',
|
|
110
|
-
type: 'question',
|
|
111
|
-
title: 'What\'s your tank size?',
|
|
112
|
-
description: 'This helps us recommend suitable fish',
|
|
113
|
-
icon: '📏',
|
|
114
|
-
gradient: ['#4facfe', '#00f2fe'],
|
|
115
|
-
question: {
|
|
116
|
-
id: 'tank_size',
|
|
117
|
-
type: 'slider',
|
|
118
|
-
question: 'Select your tank size (gallons)',
|
|
119
|
-
storageKey: '@user_tank_size',
|
|
120
|
-
validation: { required: true, min: 10, max: 500 },
|
|
121
|
-
defaultValue: 50,
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
// Question: Interests
|
|
126
|
-
{
|
|
127
|
-
id: '4',
|
|
128
|
-
type: 'question',
|
|
129
|
-
title: 'What interests you most?',
|
|
130
|
-
description: 'Select all that apply',
|
|
131
|
-
icon: '❤️',
|
|
132
|
-
gradient: ['#fa709a', '#fee140'],
|
|
133
|
-
question: {
|
|
134
|
-
id: 'interests',
|
|
135
|
-
type: 'multiple_choice',
|
|
136
|
-
question: 'Choose your interests',
|
|
137
|
-
storageKey: '@user_interests',
|
|
138
|
-
validation: { required: true, minSelections: 1, maxSelections: 3 },
|
|
139
|
-
options: [
|
|
140
|
-
{ id: 'freshwater', label: 'Freshwater Fish', icon: '🐟' },
|
|
141
|
-
{ id: 'saltwater', label: 'Saltwater Fish', icon: '🐠' },
|
|
142
|
-
{ id: 'plants', label: 'Aquatic Plants', icon: '🌿' },
|
|
143
|
-
{ id: 'equipment', label: 'Equipment & Tech', icon: '⚙️' },
|
|
144
|
-
],
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
// Completion slide
|
|
149
|
-
{
|
|
150
|
-
id: '5',
|
|
151
|
-
type: 'completion',
|
|
152
|
-
title: 'You\'re All Set!',
|
|
153
|
-
description: 'Let\'s start your aquarium journey',
|
|
154
|
-
icon: '🎉',
|
|
155
|
-
gradient: ['#30cfd0', '#330867'],
|
|
156
|
-
},
|
|
157
|
-
];
|
|
158
|
-
|
|
159
|
-
import Slider from '@react-native-community/slider';
|
|
160
|
-
|
|
161
|
-
<OnboardingScreen
|
|
162
|
-
slides={slides}
|
|
163
|
-
SliderComponent={Slider}
|
|
164
|
-
onComplete={async () => {
|
|
165
|
-
const userData = onboardingStore.getUserData();
|
|
166
|
-
console.log('User answers:', userData.answers);
|
|
167
|
-
// Save to backend, navigate to home, etc.
|
|
168
|
-
}}
|
|
169
|
-
/>
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## 📖 API Reference
|
|
173
|
-
|
|
174
|
-
### OnboardingScreen Props
|
|
175
|
-
|
|
176
|
-
| Prop | Type | Default | Description |
|
|
177
|
-
|------|------|---------|-------------|
|
|
178
|
-
| `slides` | `OnboardingSlide[]` | Required | Array of slides to display |
|
|
179
|
-
| `onComplete` | `() => void \| Promise<void>` | - | Callback when onboarding is completed |
|
|
180
|
-
| `onSkip` | `() => void \| Promise<void>` | - | Callback when onboarding is skipped |
|
|
181
|
-
| `skipButtonText` | `string` | "Skip" | Custom skip button text |
|
|
182
|
-
| `nextButtonText` | `string` | "Next" | Custom next button text |
|
|
183
|
-
| `getStartedButtonText` | `string` | "Get Started" | Custom get started button text |
|
|
184
|
-
| `showSkipButton` | `boolean` | `true` | Show skip button |
|
|
185
|
-
| `showBackButton` | `boolean` | `true` | Show back button |
|
|
186
|
-
| `showProgressBar` | `boolean` | `true` | Show progress bar |
|
|
187
|
-
| `showDots` | `boolean` | `true` | Show dots indicator |
|
|
188
|
-
| `showProgressText` | `boolean` | `true` | Show progress text (1 of 5) |
|
|
189
|
-
| `storageKey` | `string` | - | Custom storage key for completion state |
|
|
190
|
-
| `autoComplete` | `boolean` | `false` | Auto-complete on last slide |
|
|
191
|
-
| `SliderComponent` | `React.ComponentType` | - | **Required if using slider questions.** Import from `@react-native-community/slider` |
|
|
192
|
-
|
|
193
|
-
### OnboardingSlide Interface
|
|
194
|
-
|
|
195
|
-
```typescript
|
|
196
|
-
interface OnboardingSlide {
|
|
197
|
-
id: string;
|
|
198
|
-
type?: 'info' | 'question' | 'welcome' | 'completion';
|
|
199
|
-
title: string;
|
|
200
|
-
description: string;
|
|
201
|
-
icon: string; // Emoji or Lucide icon name
|
|
202
|
-
gradient: string[]; // [startColor, endColor] or [color1, color2, color3]
|
|
203
|
-
image?: string;
|
|
204
|
-
features?: string[];
|
|
205
|
-
question?: OnboardingQuestion;
|
|
206
|
-
skipIf?: (answers: Record<string, any>) => boolean;
|
|
207
|
-
}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Question Types
|
|
211
|
-
|
|
212
|
-
#### Single Choice
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
{
|
|
216
|
-
type: 'single_choice',
|
|
217
|
-
question: 'What is your goal?',
|
|
218
|
-
options: [
|
|
219
|
-
{ id: 'weight_loss', label: 'Weight Loss', icon: '🏃' },
|
|
220
|
-
{ id: 'muscle_gain', label: 'Muscle Gain', icon: '💪' },
|
|
221
|
-
],
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
#### Multiple Choice
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
{
|
|
229
|
-
type: 'multiple_choice',
|
|
230
|
-
question: 'Select your interests',
|
|
231
|
-
validation: { minSelections: 1, maxSelections: 3 },
|
|
232
|
-
options: [
|
|
233
|
-
{ id: 'yoga', label: 'Yoga', icon: '🧘' },
|
|
234
|
-
{ id: 'running', label: 'Running', icon: '🏃' },
|
|
235
|
-
{ id: 'swimming', label: 'Swimming', icon: '🏊' },
|
|
236
|
-
],
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
#### Text Input
|
|
241
|
-
|
|
242
|
-
```typescript
|
|
243
|
-
{
|
|
244
|
-
type: 'text_input',
|
|
245
|
-
question: 'What is your name?',
|
|
246
|
-
placeholder: 'Enter your name',
|
|
247
|
-
validation: { required: true, minLength: 2, maxLength: 50 },
|
|
248
|
-
}
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
#### Slider
|
|
252
|
-
|
|
253
|
-
**⚠️ Important:** When using slider questions, you must provide the `SliderComponent` prop to `OnboardingScreen`:
|
|
254
|
-
|
|
255
|
-
```tsx
|
|
256
|
-
import Slider from '@react-native-community/slider';
|
|
257
|
-
|
|
258
|
-
<OnboardingScreen
|
|
259
|
-
slides={slides}
|
|
260
|
-
SliderComponent={Slider}
|
|
261
|
-
onComplete={handleComplete}
|
|
262
|
-
/>
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
{
|
|
267
|
-
type: 'slider',
|
|
268
|
-
question: 'What is your age?',
|
|
269
|
-
validation: { min: 18, max: 100 },
|
|
270
|
-
defaultValue: 25,
|
|
271
|
-
}
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
**Note:** Make sure `@react-native-community/slider` is installed and properly linked (run `pod install` for iOS).
|
|
275
|
-
|
|
276
|
-
#### Rating
|
|
277
|
-
|
|
278
|
-
```typescript
|
|
279
|
-
{
|
|
280
|
-
type: 'rating',
|
|
281
|
-
question: 'Rate your experience',
|
|
282
|
-
validation: { max: 5 },
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## 🎨 Customization
|
|
287
|
-
|
|
288
|
-
### Custom Header
|
|
289
|
-
|
|
290
|
-
```tsx
|
|
291
|
-
<OnboardingScreen
|
|
292
|
-
slides={slides}
|
|
293
|
-
renderHeader={({ isFirstSlide, onBack, onSkip }) => (
|
|
294
|
-
<View>
|
|
295
|
-
{!isFirstSlide && <Button onPress={onBack}>Back</Button>}
|
|
296
|
-
<Button onPress={onSkip}>Skip</Button>
|
|
297
|
-
</View>
|
|
298
|
-
)}
|
|
299
|
-
/>
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
### Custom Footer
|
|
303
|
-
|
|
304
|
-
```tsx
|
|
305
|
-
<OnboardingScreen
|
|
306
|
-
slides={slides}
|
|
307
|
-
renderFooter={({ currentIndex, totalSlides, isLastSlide, onNext }) => (
|
|
308
|
-
<View>
|
|
309
|
-
<Text>{currentIndex + 1} / {totalSlides}</Text>
|
|
310
|
-
<Button onPress={onNext}>
|
|
311
|
-
{isLastSlide ? 'Get Started' : 'Next'}
|
|
312
|
-
</Button>
|
|
313
|
-
</View>
|
|
314
|
-
)}
|
|
315
|
-
/>
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
### Conditional Slides
|
|
319
|
-
|
|
320
|
-
```tsx
|
|
321
|
-
{
|
|
322
|
-
id: '3',
|
|
323
|
-
title: 'Advanced Features',
|
|
324
|
-
description: 'Only for experienced users',
|
|
325
|
-
icon: '⚡',
|
|
326
|
-
gradient: ['#667eea', '#764ba2'],
|
|
327
|
-
skipIf: (answers) => answers.experience_level === 'beginner',
|
|
328
|
-
}
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
## 💾 Accessing User Data
|
|
332
|
-
|
|
333
|
-
```tsx
|
|
334
|
-
import { useOnboarding } from '@umituz/react-native-onboarding';
|
|
335
|
-
|
|
336
|
-
const { userData, getAnswer } = useOnboarding();
|
|
337
|
-
|
|
338
|
-
// Get specific answer
|
|
339
|
-
const experienceLevel = getAnswer('experience_level');
|
|
340
|
-
|
|
341
|
-
// Get all answers
|
|
342
|
-
const allAnswers = userData.answers;
|
|
343
|
-
|
|
344
|
-
// Check if onboarding was completed
|
|
345
|
-
const isComplete = userData.completedAt !== undefined;
|
|
346
|
-
|
|
347
|
-
// Check if onboarding was skipped
|
|
348
|
-
const wasSkipped = userData.skipped === true;
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
## 🔄 Resetting Onboarding
|
|
352
|
-
|
|
353
|
-
```tsx
|
|
354
|
-
import { useOnboarding } from '@umituz/react-native-onboarding';
|
|
355
|
-
|
|
356
|
-
const { reset } = useOnboarding();
|
|
357
|
-
|
|
358
|
-
// Reset onboarding (useful for testing or settings)
|
|
359
|
-
await reset();
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
## 📱 Platform Support
|
|
363
|
-
|
|
364
|
-
- ✅ iOS
|
|
365
|
-
- ✅ Android
|
|
366
|
-
- ✅ Web
|
|
367
|
-
|
|
368
|
-
## 🏗️ Architecture
|
|
369
|
-
|
|
370
|
-
Built with Domain-Driven Design (DDD):
|
|
371
|
-
|
|
372
|
-
- **Domain Layer**: Entities and interfaces (business logic)
|
|
373
|
-
- **Infrastructure Layer**: Storage and hooks (state management)
|
|
374
|
-
- **Presentation Layer**: Components and screens (UI)
|
|
375
|
-
|
|
376
|
-
## 📄 License
|
|
377
|
-
|
|
378
|
-
MIT
|
|
379
|
-
|
|
380
|
-
## 🤝 Contributing
|
|
381
|
-
|
|
382
|
-
Contributions are welcome! Please open an issue or PR.
|
|
383
|
-
|
|
384
|
-
## 📧 Support
|
|
385
|
-
|
|
386
|
-
For issues and questions, please open an issue on GitHub.
|
|
387
|
-
|