rn-onboarding-analytics 1.0.0

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.
Files changed (105) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +752 -0
  3. package/lib/module/index.js +26 -0
  4. package/lib/module/index.js.map +1 -0
  5. package/lib/module/package.json +1 -0
  6. package/lib/module/spill-onboarding/adapters/expo-image.js +13 -0
  7. package/lib/module/spill-onboarding/adapters/expo-image.js.map +1 -0
  8. package/lib/module/spill-onboarding/adapters/react-native-svg.js +16 -0
  9. package/lib/module/spill-onboarding/adapters/react-native-svg.js.map +1 -0
  10. package/lib/module/spill-onboarding/analytics.js +56 -0
  11. package/lib/module/spill-onboarding/analytics.js.map +1 -0
  12. package/lib/module/spill-onboarding/buttons/PrimaryButton.js +50 -0
  13. package/lib/module/spill-onboarding/buttons/PrimaryButton.js.map +1 -0
  14. package/lib/module/spill-onboarding/buttons/SecondaryButton.js +51 -0
  15. package/lib/module/spill-onboarding/buttons/SecondaryButton.js.map +1 -0
  16. package/lib/module/spill-onboarding/buttons/SkipButton.js +35 -0
  17. package/lib/module/spill-onboarding/buttons/SkipButton.js.map +1 -0
  18. package/lib/module/spill-onboarding/components/OnboardingImageContainer.js +128 -0
  19. package/lib/module/spill-onboarding/components/OnboardingImageContainer.js.map +1 -0
  20. package/lib/module/spill-onboarding/components/OnboardingIntroPanel.js +97 -0
  21. package/lib/module/spill-onboarding/components/OnboardingIntroPanel.js.map +1 -0
  22. package/lib/module/spill-onboarding/components/OnboardingModal.js +69 -0
  23. package/lib/module/spill-onboarding/components/OnboardingModal.js.map +1 -0
  24. package/lib/module/spill-onboarding/components/OnboardingStepContainer.js +60 -0
  25. package/lib/module/spill-onboarding/components/OnboardingStepContainer.js.map +1 -0
  26. package/lib/module/spill-onboarding/components/OnboardingStepPanel.js +122 -0
  27. package/lib/module/spill-onboarding/components/OnboardingStepPanel.js.map +1 -0
  28. package/lib/module/spill-onboarding/hooks/useMeasureHeight.js +18 -0
  29. package/lib/module/spill-onboarding/hooks/useMeasureHeight.js.map +1 -0
  30. package/lib/module/spill-onboarding/icons/ArrowLeftIcon.js +57 -0
  31. package/lib/module/spill-onboarding/icons/ArrowLeftIcon.js.map +1 -0
  32. package/lib/module/spill-onboarding/icons/CloseIcon.js +49 -0
  33. package/lib/module/spill-onboarding/icons/CloseIcon.js.map +1 -0
  34. package/lib/module/spill-onboarding/index.js +206 -0
  35. package/lib/module/spill-onboarding/index.js.map +1 -0
  36. package/lib/module/spill-onboarding/types.js +4 -0
  37. package/lib/module/spill-onboarding/types.js.map +1 -0
  38. package/lib/module/utils/ThemeContext.js +78 -0
  39. package/lib/module/utils/ThemeContext.js.map +1 -0
  40. package/lib/module/utils/fontStyles.js +21 -0
  41. package/lib/module/utils/fontStyles.js.map +1 -0
  42. package/lib/module/utils/theme.js +27 -0
  43. package/lib/module/utils/theme.js.map +1 -0
  44. package/lib/typescript/package.json +1 -0
  45. package/lib/typescript/src/index.d.ts +5 -0
  46. package/lib/typescript/src/index.d.ts.map +1 -0
  47. package/lib/typescript/src/spill-onboarding/adapters/expo-image.d.ts +4 -0
  48. package/lib/typescript/src/spill-onboarding/adapters/expo-image.d.ts.map +1 -0
  49. package/lib/typescript/src/spill-onboarding/adapters/react-native-svg.d.ts +5 -0
  50. package/lib/typescript/src/spill-onboarding/adapters/react-native-svg.d.ts.map +1 -0
  51. package/lib/typescript/src/spill-onboarding/analytics.d.ts +2 -0
  52. package/lib/typescript/src/spill-onboarding/analytics.d.ts.map +1 -0
  53. package/lib/typescript/src/spill-onboarding/buttons/PrimaryButton.d.ts +13 -0
  54. package/lib/typescript/src/spill-onboarding/buttons/PrimaryButton.d.ts.map +1 -0
  55. package/lib/typescript/src/spill-onboarding/buttons/SecondaryButton.d.ts +13 -0
  56. package/lib/typescript/src/spill-onboarding/buttons/SecondaryButton.d.ts.map +1 -0
  57. package/lib/typescript/src/spill-onboarding/buttons/SkipButton.d.ts +6 -0
  58. package/lib/typescript/src/spill-onboarding/buttons/SkipButton.d.ts.map +1 -0
  59. package/lib/typescript/src/spill-onboarding/components/OnboardingImageContainer.d.ts +18 -0
  60. package/lib/typescript/src/spill-onboarding/components/OnboardingImageContainer.d.ts.map +1 -0
  61. package/lib/typescript/src/spill-onboarding/components/OnboardingIntroPanel.d.ts +4 -0
  62. package/lib/typescript/src/spill-onboarding/components/OnboardingIntroPanel.d.ts.map +1 -0
  63. package/lib/typescript/src/spill-onboarding/components/OnboardingModal.d.ts +8 -0
  64. package/lib/typescript/src/spill-onboarding/components/OnboardingModal.d.ts.map +1 -0
  65. package/lib/typescript/src/spill-onboarding/components/OnboardingStepContainer.d.ts +16 -0
  66. package/lib/typescript/src/spill-onboarding/components/OnboardingStepContainer.d.ts.map +1 -0
  67. package/lib/typescript/src/spill-onboarding/components/OnboardingStepPanel.d.ts +4 -0
  68. package/lib/typescript/src/spill-onboarding/components/OnboardingStepPanel.d.ts.map +1 -0
  69. package/lib/typescript/src/spill-onboarding/hooks/useMeasureHeight.d.ts +9 -0
  70. package/lib/typescript/src/spill-onboarding/hooks/useMeasureHeight.d.ts.map +1 -0
  71. package/lib/typescript/src/spill-onboarding/icons/ArrowLeftIcon.d.ts +7 -0
  72. package/lib/typescript/src/spill-onboarding/icons/ArrowLeftIcon.d.ts.map +1 -0
  73. package/lib/typescript/src/spill-onboarding/icons/CloseIcon.d.ts +7 -0
  74. package/lib/typescript/src/spill-onboarding/icons/CloseIcon.d.ts.map +1 -0
  75. package/lib/typescript/src/spill-onboarding/index.d.ts +4 -0
  76. package/lib/typescript/src/spill-onboarding/index.d.ts.map +1 -0
  77. package/lib/typescript/src/spill-onboarding/types.d.ts +192 -0
  78. package/lib/typescript/src/spill-onboarding/types.d.ts.map +1 -0
  79. package/lib/typescript/src/utils/ThemeContext.d.ts +14 -0
  80. package/lib/typescript/src/utils/ThemeContext.d.ts.map +1 -0
  81. package/lib/typescript/src/utils/fontStyles.d.ts +19 -0
  82. package/lib/typescript/src/utils/fontStyles.d.ts.map +1 -0
  83. package/lib/typescript/src/utils/theme.d.ts +30 -0
  84. package/lib/typescript/src/utils/theme.d.ts.map +1 -0
  85. package/package.json +177 -0
  86. package/src/index.tsx +35 -0
  87. package/src/spill-onboarding/adapters/expo-image.ts +12 -0
  88. package/src/spill-onboarding/adapters/react-native-svg.ts +17 -0
  89. package/src/spill-onboarding/analytics.ts +75 -0
  90. package/src/spill-onboarding/buttons/PrimaryButton.tsx +70 -0
  91. package/src/spill-onboarding/buttons/SecondaryButton.tsx +71 -0
  92. package/src/spill-onboarding/buttons/SkipButton.tsx +34 -0
  93. package/src/spill-onboarding/components/OnboardingImageContainer.tsx +181 -0
  94. package/src/spill-onboarding/components/OnboardingIntroPanel.tsx +105 -0
  95. package/src/spill-onboarding/components/OnboardingModal.tsx +75 -0
  96. package/src/spill-onboarding/components/OnboardingStepContainer.tsx +85 -0
  97. package/src/spill-onboarding/components/OnboardingStepPanel.tsx +118 -0
  98. package/src/spill-onboarding/hooks/useMeasureHeight.ts +21 -0
  99. package/src/spill-onboarding/icons/ArrowLeftIcon.tsx +69 -0
  100. package/src/spill-onboarding/icons/CloseIcon.tsx +55 -0
  101. package/src/spill-onboarding/index.tsx +251 -0
  102. package/src/spill-onboarding/types.ts +243 -0
  103. package/src/utils/ThemeContext.tsx +87 -0
  104. package/src/utils/fontStyles.ts +19 -0
  105. package/src/utils/theme.ts +29 -0
package/README.md ADDED
@@ -0,0 +1,752 @@
1
+ ![Banner](assets/banner.png)
2
+
3
+ # react-native-onboarding-analytics
4
+
5
+ Add analytics to your onboarding/tutorial flow with this React Native library.
6
+
7
+ ✨ **Beautiful, customizable onboarding/tutorial flows** for React Native — with smooth animations, flexible theming, and highly customizable components.
8
+
9
+ ## 🚀 Features
10
+
11
+ - **Cross-platform** – Works seamlessly on iOS, Android, and Web
12
+ - **Smooth animations** – React Native Reanimated for smooth transitions
13
+ - **Works out of the box** – Just install and use with default styles
14
+ - **Flexible theming and custom components** – Complete control over colors, fonts, and styling
15
+
16
+ ## Inspired by [Private Mind App](https://github.com/software-mansion-labs/private-mind)
17
+
18
+ A private AI app that runs entirely offline on your device, with no data sent to the cloud and no internet connection required. Private Mind represents a new era of AI! Powerful, personal, and completely private.
19
+
20
+ ![Banner](assets/private-mind.png)
21
+
22
+ ## 📦 Installation
23
+
24
+ ```sh
25
+ npm install rn-onboarding-analytics
26
+ ```
27
+
28
+ The library requires these dependencies for animations and safe area context:
29
+
30
+ ```sh
31
+ npm install react-native-reanimated react-native-safe-area-context
32
+ ```
33
+
34
+ Optionally for image support, install one of:
35
+
36
+ ```sh
37
+ npm install expo-image
38
+ ```
39
+
40
+ ```sh
41
+ npm install react-native-svg
42
+ ```
43
+
44
+ ## 🛠 Basic usage
45
+
46
+ You can use Onboarding component with default styles just by passing required props to the component:
47
+
48
+ ```tsx
49
+ import Onboarding from 'rn-onboarding-analytics';
50
+
51
+ function MyOnboarding() {
52
+ return (
53
+ <Onboarding
54
+ introPanel={{
55
+ title: 'Welcome to My App',
56
+ subtitle: "Let's get you started",
57
+ button: 'Get Started',
58
+ image: require('./assets/logo.png'),
59
+ apikey: 'your-key'
60
+ }}
61
+ steps={[
62
+ {
63
+ title: 'Step 1',
64
+ description: 'This is the first step of your journey',
65
+ buttonLabel: 'Next',
66
+ image: require('./assets/step1.png'),
67
+ position: 'top',
68
+ },
69
+ {
70
+ title: 'Step 2',
71
+ description: 'Learn about our amazing features',
72
+ buttonLabel: 'Continue',
73
+ image: require('./assets/step2.png'),
74
+ position: 'bottom',
75
+ },
76
+ ]}
77
+ onComplete={() => {
78
+ await AsyncStorage.setItem(ONBOARDING_COMPLETED_KEY, 'true');
79
+ console.log('Onboarding completed!');
80
+ }}
81
+ onSkip={() => console.log('Onboarding skipped')}
82
+ onStepChange={(step) => console.log('Current step:', step)}
83
+ />
84
+ );
85
+ }
86
+ ```
87
+
88
+ ### Custom Components
89
+
90
+ Or you can create your own custom components for the intro panel, individual steps, background, close button, etc.
91
+
92
+ ```tsx
93
+ function CustomIntro({ onPressStart }: { onPressStart: () => void }) {
94
+ return (
95
+ ... your custom intro panel ...
96
+ );
97
+ }
98
+
99
+ function CustomStep({ onNext, onBack, isLast }: { onNext: () => void, onBack: () => void, isLast: boolean }) {
100
+ return (
101
+ ... your custom step component ...
102
+ );
103
+ }
104
+
105
+ function CustomBackground() {
106
+ return (
107
+ ... your custom background component ...
108
+ );
109
+ }
110
+
111
+ function CustomCloseButton({ onPress }: { onPress: () => void }) {
112
+ return (
113
+ ... your custom close button component ...
114
+ );
115
+ }
116
+
117
+ <Onboarding
118
+ introPanel={CustomIntro}
119
+ background={CustomBackground}
120
+ skipButton={CustomCloseButton}
121
+ steps={[
122
+ {
123
+ component: CustomStep,
124
+ image: require('./assets/step1.png'),
125
+ position: 'top',
126
+ },
127
+ // ... more steps
128
+ ]}
129
+ // ... other props
130
+ />
131
+ ```
132
+
133
+ ## 📖 API
134
+
135
+ To see all the props and their types, check the [types](src/spill-onboarding/types.ts) file. Also example usages are available in the [example](example/src/screens) catalog.
136
+
137
+ ### OnboardingProps
138
+
139
+ #### `introPanel`
140
+
141
+ **Type:** `OnboardingIntroPanel`
142
+ **Required** - The welcome screen that users see at the start of the onboarding
143
+
144
+ The intro panel can be either:
145
+
146
+ - **Default panel**: Pass an object with `title`, `subtitle`, `button`, `image`
147
+ - **Custom component**: Pass a render function that receives `onPressStart` callback
148
+
149
+ ```tsx
150
+ // Default intro panel
151
+ introPanel={{
152
+ title: "Welcome to MyApp",
153
+ subtitle: "Let's get you started",
154
+ button: "Get Started",
155
+ image: require('./assets/welcome.png')
156
+ }}
157
+
158
+ // Custom intro panel
159
+ introPanel={({ onPressStart }) => (
160
+ <CustomWelcomeScreen onStart={onPressStart} />
161
+ )}
162
+ ```
163
+
164
+ ![Intro Panel](assets/intro-panel.png)
165
+
166
+ #### `steps`
167
+
168
+ **Type:** `OnboardingStep[]`
169
+ **Required** - Array of onboarding steps to display
170
+
171
+ ![Step](assets/step.png)
172
+
173
+ Each step can be either a default text-based step or a fully custom component:
174
+
175
+ ```tsx
176
+ // Default step
177
+ {
178
+ label: "Step 1",
179
+ title: "Connect Your Account",
180
+ description: "Link your account to get started",
181
+ buttonLabel: "Connect",
182
+ image: require('./assets/step1.png'),
183
+ position: 'top'
184
+ }
185
+
186
+ // Custom step component
187
+ {
188
+ component: ({ onNext, onBack, isLast }) => (
189
+ <CustomStepComponent
190
+ onNext={onNext}
191
+ onBack={onBack}
192
+ isLast={isLast}
193
+ ... other props ...
194
+ />
195
+ ),
196
+ image: require('./assets/step2.png'),
197
+ position: 'bottom'
198
+ }
199
+ ```
200
+
201
+ #### `onComplete`
202
+
203
+ **Type:** `() => void`
204
+ **Required** - Callback fired when user completes the final step, usually used to save the completion state to the local storage and navigate to the main app.
205
+
206
+ ```tsx
207
+ onComplete={() => {
208
+ // Navigate to main app
209
+ navigation.navigate('Home');
210
+ // Or save completion state
211
+ AsyncStorage.setItem('onboarding_completed', 'true');
212
+ }}
213
+ ```
214
+
215
+ #### `onSkip`
216
+
217
+ **Type:** `() => void`
218
+ **Optional** - Callback fired when user skips onboarding, usually used to track the skip event and navigate away from the onboarding.
219
+
220
+ ```tsx
221
+ onSkip={() => {
222
+ // Track skip event
223
+ analytics.track('onboarding_skipped');
224
+ // Navigate away
225
+ navigation.goBack();
226
+ }}
227
+ ```
228
+
229
+ #### `onStepChange`
230
+
231
+ **Type:** `(stepIndex: number) => void`
232
+ **Default:** `undefined` - Callback fired when the active step changes
233
+
234
+ ```tsx
235
+ onStepChange={(stepIndex) => {
236
+ // Track progress
237
+ analytics.track('onboarding_step', { step: stepIndex });
238
+ }}
239
+ ```
240
+
241
+ #### `showCloseButton`
242
+
243
+ **Type:** `boolean`
244
+ **Default:** `true` - Whether to show the close button in the header
245
+
246
+ ```tsx
247
+ showCloseButton={false} // Hide close button
248
+ ```
249
+
250
+ #### `showBackButton`
251
+
252
+ **Type:** `boolean`
253
+ **Default:** `true` - Whether to show back button on steps (except first step)
254
+
255
+ ![Back Button](assets/back-button.png)
256
+
257
+ ```tsx
258
+ showBackButton={false} // Disable back navigation
259
+ ```
260
+
261
+ #### `wrapInModalOnWeb`
262
+
263
+ **Type:** `boolean`
264
+ **Default:** `true` - Whether to wrap the onboarding in a modal on web
265
+
266
+ ![Modal](assets/modal.png)
267
+
268
+ ```tsx
269
+ wrapInModalOnWeb={false} // Disable modal wrapping
270
+ ```
271
+
272
+ #### `animationDuration`
273
+
274
+ **Type:** `number`
275
+ **Default:** `500` - Animation duration in milliseconds for step transitions
276
+
277
+ ```tsx
278
+ animationDuration={300} // Faster animations
279
+ animationDuration={800} // Slower if app is for seniors 👴🏽👵🏼
280
+ ```
281
+
282
+ #### `colors`
283
+
284
+ **Type:** `OnboardingColors`
285
+ **Default:**
286
+
287
+ ```tsx
288
+ colors={{
289
+ background: {
290
+ primary: '#FFFFFF',
291
+ secondary: '#F8F9FA',
292
+ label: '#E9ECEF',
293
+ accent: '#007AFF'
294
+ },
295
+ text: {
296
+ primary: '#1C1C1E',
297
+ secondary: '#8E8E93',
298
+ contrast: '#FFFFFF'
299
+ }
300
+ }}
301
+ ```
302
+
303
+ #### `fonts`
304
+
305
+ **Type:** `OnboardingFonts | string`
306
+ **Default:** `'System'` - Custom font configuration
307
+
308
+ ```tsx
309
+ // Single font for all text
310
+ fonts="Inter"
311
+
312
+ // Detailed font configuration
313
+ fonts={{
314
+ introTitle: 'Inter-Bold',
315
+ introSubtitle: 'Inter-Medium',
316
+ stepTitle: 'Inter-SemiBold',
317
+ stepDescription: 'Inter-Regular',
318
+ primaryButton: 'Inter-Medium'
319
+ }}
320
+ ```
321
+
322
+ #### `background`
323
+
324
+ **Type:** `() => ReactNode`
325
+ **Default:** `undefined` - Custom background element rendered behind content
326
+
327
+ ```tsx
328
+ background={() => (
329
+ <Image
330
+ source={require('./assets/background.png')}
331
+ style={StyleSheet.absoluteFillObject}
332
+ />
333
+ )}
334
+ ```
335
+
336
+ #### `skipButton`
337
+
338
+ **Type:** `({ onPress }: { onPress: () => void }) => ReactNode`
339
+ **Default:** X icon - Custom close button renderer
340
+
341
+ ![Skip Button](assets/skip-button.png)
342
+
343
+ ```tsx
344
+ skipButton={({ onPress }) => (
345
+ <TouchableOpacity onPress={onPress}>
346
+ <Text style={styles.customClose}>✕</Text>
347
+ </TouchableOpacity>
348
+ )}
349
+ ```
350
+
351
+ ## 💡 Best Practices
352
+
353
+ ### Image Consistency
354
+
355
+ Use images with the same dimensions for the best visual effect. This prevents layout shifts and creates smooth transitions between steps.
356
+
357
+ **Image creator**: Use this [Figma Community template](https://www.figma.com/community/file/1556597720381753708) to design consistent onboarding illustrations and export assets with the recommended dimensions.
358
+
359
+ ### Persistent Storage
360
+
361
+ Save onboarding completion state to persistent storage (MMKV, AsyncStorage) to prevent users from seeing the onboarding again after completion.
362
+
363
+ ### Navigation
364
+
365
+ On completion, navigate users to the main app to provide a smooth transition from onboarding to the core experience.
366
+
367
+ ## 🤝 Contributing
368
+
369
+ We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for development workflow and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for our code of conduct.
370
+
371
+ ---
372
+
373
+ Built with [create-react-native-library](https://github.com/callstack/react-native-builder-bob) 🛠
374
+ https://github.com/user-attachments/assets/bb51a0c3-15be-42b6-b20d-c33c29b84bc7
375
+
376
+ # react-native-onboarding-analytics
377
+
378
+ Add analytics to your onboarding/tutorial flow with this React Native library.
379
+
380
+ ✨ **Beautiful, customizable onboarding/tutorial flows** for React Native — with smooth animations, flexible theming, and highly customizable components.
381
+
382
+ ## 🚀 Features
383
+
384
+ - **Cross-platform** – Works seamlessly on iOS, Android, and Web
385
+ - **Smooth animations** – React Native Reanimated for smooth transitions
386
+ - **Works out of the box** – Just install and use with default styles
387
+ - **Flexible theming and custom components** – Complete control over colors, fonts, and styling
388
+
389
+ ## Inspired by [Private Mind App](https://github.com/software-mansion-labs/private-mind)
390
+
391
+ A private AI app that runs entirely offline on your device, with no data sent to the cloud and no internet connection required. Private Mind represents a new era of AI! Powerful, personal, and completely private.
392
+
393
+ ![Banner](assets/private-mind.png)
394
+
395
+ ## 📦 Installation
396
+
397
+ ```sh
398
+ npm install rn-onboarding-analytics
399
+ ```
400
+
401
+ The library requires these dependencies for animations and safe area context:
402
+
403
+ ```sh
404
+ npm install react-native-reanimated react-native-safe-area-context
405
+ ```
406
+
407
+ Optionally for image support, install one of:
408
+
409
+ ```sh
410
+ npm install expo-image
411
+ ```
412
+
413
+ ```sh
414
+ npm install react-native-svg
415
+ ```
416
+
417
+ ## 🛠 Basic usage
418
+
419
+ You can use Onboarding component with default styles just by passing required props to the component:
420
+
421
+ ```tsx
422
+ import Onboarding from 'rn-onboarding-analytics';
423
+
424
+ function MyOnboarding() {
425
+ return (
426
+ <Onboarding
427
+ introPanel={{
428
+ title: 'Welcome to My App',
429
+ subtitle: "Let's get you started",
430
+ button: 'Get Started',
431
+ image: require('./assets/logo.png'),
432
+ apikey: 'your-key'
433
+ }}
434
+ steps={[
435
+ {
436
+ title: 'Step 1',
437
+ description: 'This is the first step of your journey',
438
+ buttonLabel: 'Next',
439
+ image: require('./assets/step1.png'),
440
+ position: 'top',
441
+ },
442
+ {
443
+ title: 'Step 2',
444
+ description: 'Learn about our amazing features',
445
+ buttonLabel: 'Continue',
446
+ image: require('./assets/step2.png'),
447
+ position: 'bottom',
448
+ },
449
+ ]}
450
+ onComplete={() => {
451
+ await AsyncStorage.setItem(ONBOARDING_COMPLETED_KEY, 'true');
452
+ console.log('Onboarding completed!');
453
+ }}
454
+ onSkip={() => console.log('Onboarding skipped')}
455
+ onStepChange={(step) => console.log('Current step:', step)}
456
+ />
457
+ );
458
+ }
459
+ ```
460
+
461
+ ### Custom Components
462
+
463
+ Or you can create your own custom components for the intro panel, individual steps, background, close button, etc.
464
+
465
+ ```tsx
466
+ function CustomIntro({ onPressStart }: { onPressStart: () => void }) {
467
+ return (
468
+ ... your custom intro panel ...
469
+ );
470
+ }
471
+
472
+ function CustomStep({ onNext, onBack, isLast }: { onNext: () => void, onBack: () => void, isLast: boolean }) {
473
+ return (
474
+ ... your custom step component ...
475
+ );
476
+ }
477
+
478
+ function CustomBackground() {
479
+ return (
480
+ ... your custom background component ...
481
+ );
482
+ }
483
+
484
+ function CustomCloseButton({ onPress }: { onPress: () => void }) {
485
+ return (
486
+ ... your custom close button component ...
487
+ );
488
+ }
489
+
490
+ <Onboarding
491
+ introPanel={CustomIntro}
492
+ background={CustomBackground}
493
+ skipButton={CustomCloseButton}
494
+ steps={[
495
+ {
496
+ component: CustomStep,
497
+ image: require('./assets/step1.png'),
498
+ position: 'top',
499
+ },
500
+ // ... more steps
501
+ ]}
502
+ // ... other props
503
+ />
504
+ ```
505
+
506
+ ## 📖 API
507
+
508
+ To see all the props and their types, check the [types](src/spill-onboarding/types.ts) file. Also example usages are available in the [example](example/src/screens) catalog.
509
+
510
+ ### OnboardingProps
511
+
512
+ #### `introPanel`
513
+
514
+ **Type:** `OnboardingIntroPanel`
515
+ **Required** - The welcome screen that users see at the start of the onboarding
516
+
517
+ The intro panel can be either:
518
+
519
+ - **Default panel**: Pass an object with `title`, `subtitle`, `button`, `image`
520
+ - **Custom component**: Pass a render function that receives `onPressStart` callback
521
+
522
+ ```tsx
523
+ // Default intro panel
524
+ introPanel={{
525
+ title: "Welcome to MyApp",
526
+ subtitle: "Let's get you started",
527
+ button: "Get Started",
528
+ image: require('./assets/welcome.png')
529
+ }}
530
+
531
+ // Custom intro panel
532
+ introPanel={({ onPressStart }) => (
533
+ <CustomWelcomeScreen onStart={onPressStart} />
534
+ )}
535
+ ```
536
+
537
+ ![Intro Panel](assets/intro-panel.png)
538
+
539
+ #### `steps`
540
+
541
+ **Type:** `OnboardingStep[]`
542
+ **Required** - Array of onboarding steps to display
543
+
544
+ ![Step](assets/step.png)
545
+
546
+ Each step can be either a default text-based step or a fully custom component:
547
+
548
+ ```tsx
549
+ // Default step
550
+ {
551
+ label: "Step 1",
552
+ title: "Connect Your Account",
553
+ description: "Link your account to get started",
554
+ buttonLabel: "Connect",
555
+ image: require('./assets/step1.png'),
556
+ position: 'top'
557
+ }
558
+
559
+ // Custom step component
560
+ {
561
+ component: ({ onNext, onBack, isLast }) => (
562
+ <CustomStepComponent
563
+ onNext={onNext}
564
+ onBack={onBack}
565
+ isLast={isLast}
566
+ ... other props ...
567
+ />
568
+ ),
569
+ image: require('./assets/step2.png'),
570
+ position: 'bottom'
571
+ }
572
+ ```
573
+
574
+ #### `onComplete`
575
+
576
+ **Type:** `() => void`
577
+ **Required** - Callback fired when user completes the final step, usually used to save the completion state to the local storage and navigate to the main app.
578
+
579
+ ```tsx
580
+ onComplete={() => {
581
+ // Navigate to main app
582
+ navigation.navigate('Home');
583
+ // Or save completion state
584
+ AsyncStorage.setItem('onboarding_completed', 'true');
585
+ }}
586
+ ```
587
+
588
+ #### `onSkip`
589
+
590
+ **Type:** `() => void`
591
+ **Optional** - Callback fired when user skips onboarding, usually used to track the skip event and navigate away from the onboarding.
592
+
593
+ ```tsx
594
+ onSkip={() => {
595
+ // Track skip event
596
+ analytics.track('onboarding_skipped');
597
+ // Navigate away
598
+ navigation.goBack();
599
+ }}
600
+ ```
601
+
602
+ #### `onStepChange`
603
+
604
+ **Type:** `(stepIndex: number) => void`
605
+ **Default:** `undefined` - Callback fired when the active step changes
606
+
607
+ ```tsx
608
+ onStepChange={(stepIndex) => {
609
+ // Track progress
610
+ analytics.track('onboarding_step', { step: stepIndex });
611
+ }}
612
+ ```
613
+
614
+ #### `showCloseButton`
615
+
616
+ **Type:** `boolean`
617
+ **Default:** `true` - Whether to show the close button in the header
618
+
619
+ ```tsx
620
+ showCloseButton={false} // Hide close button
621
+ ```
622
+
623
+ #### `showBackButton`
624
+
625
+ **Type:** `boolean`
626
+ **Default:** `true` - Whether to show back button on steps (except first step)
627
+
628
+ ![Back Button](assets/back-button.png)
629
+
630
+ ```tsx
631
+ showBackButton={false} // Disable back navigation
632
+ ```
633
+
634
+ #### `wrapInModalOnWeb`
635
+
636
+ **Type:** `boolean`
637
+ **Default:** `true` - Whether to wrap the onboarding in a modal on web
638
+
639
+ ![Modal](assets/modal.png)
640
+
641
+ ```tsx
642
+ wrapInModalOnWeb={false} // Disable modal wrapping
643
+ ```
644
+
645
+ #### `animationDuration`
646
+
647
+ **Type:** `number`
648
+ **Default:** `500` - Animation duration in milliseconds for step transitions
649
+
650
+ ```tsx
651
+ animationDuration={300} // Faster animations
652
+ animationDuration={800} // Slower if app is for seniors 👴🏽👵🏼
653
+ ```
654
+
655
+ #### `colors`
656
+
657
+ **Type:** `OnboardingColors`
658
+ **Default:**
659
+
660
+ ```tsx
661
+ colors={{
662
+ background: {
663
+ primary: '#FFFFFF',
664
+ secondary: '#F8F9FA',
665
+ label: '#E9ECEF',
666
+ accent: '#007AFF'
667
+ },
668
+ text: {
669
+ primary: '#1C1C1E',
670
+ secondary: '#8E8E93',
671
+ contrast: '#FFFFFF'
672
+ }
673
+ }}
674
+ ```
675
+
676
+ #### `fonts`
677
+
678
+ **Type:** `OnboardingFonts | string`
679
+ **Default:** `'System'` - Custom font configuration
680
+
681
+ ```tsx
682
+ // Single font for all text
683
+ fonts="Inter"
684
+
685
+ // Detailed font configuration
686
+ fonts={{
687
+ introTitle: 'Inter-Bold',
688
+ introSubtitle: 'Inter-Medium',
689
+ stepTitle: 'Inter-SemiBold',
690
+ stepDescription: 'Inter-Regular',
691
+ primaryButton: 'Inter-Medium'
692
+ }}
693
+ ```
694
+
695
+ #### `background`
696
+
697
+ **Type:** `() => ReactNode`
698
+ **Default:** `undefined` - Custom background element rendered behind content
699
+
700
+ ```tsx
701
+ background={() => (
702
+ <Image
703
+ source={require('./assets/background.png')}
704
+ style={StyleSheet.absoluteFillObject}
705
+ />
706
+ )}
707
+ ```
708
+
709
+ #### `skipButton`
710
+
711
+ **Type:** `({ onPress }: { onPress: () => void }) => ReactNode`
712
+ **Default:** X icon - Custom close button renderer
713
+
714
+ ![Skip Button](assets/skip-button.png)
715
+
716
+ ```tsx
717
+ skipButton={({ onPress }) => (
718
+ <TouchableOpacity onPress={onPress}>
719
+ <Text style={styles.customClose}>✕</Text>
720
+ </TouchableOpacity>
721
+ )}
722
+ ```
723
+
724
+ ## 💡 Best Practices
725
+
726
+ ### Image Consistency
727
+
728
+ Use images with the same dimensions for the best visual effect. This prevents layout shifts and creates smooth transitions between steps.
729
+
730
+ **Image creator**: Use this [Figma Community template](https://www.figma.com/community/file/1556597720381753708) to design consistent onboarding illustrations and export assets with the recommended dimensions.
731
+
732
+ ### Persistent Storage
733
+
734
+ Save onboarding completion state to persistent storage (MMKV, AsyncStorage) to prevent users from seeing the onboarding again after completion.
735
+
736
+ ### Navigation
737
+
738
+ On completion, navigate users to the main app to provide a smooth transition from onboarding to the core experience.
739
+
740
+ ## 🤝 Contributing
741
+
742
+ We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for development workflow and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for our code of conduct.
743
+
744
+ ---
745
+
746
+ Built with [create-react-native-library](https://github.com/callstack/react-native-builder-bob) 🛠
747
+
748
+ # react-native-onboarding-w-analytics
749
+
750
+ Forked from [react-native-onboarding](https://github.com/software-mansion-labs/react-native-onboarding) by Blazej Kustra.
751
+
752
+ Added analytics features and custom adjustments specific to my project.