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.
- package/LICENSE +22 -0
- package/README.md +752 -0
- package/lib/module/index.js +26 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/spill-onboarding/adapters/expo-image.js +13 -0
- package/lib/module/spill-onboarding/adapters/expo-image.js.map +1 -0
- package/lib/module/spill-onboarding/adapters/react-native-svg.js +16 -0
- package/lib/module/spill-onboarding/adapters/react-native-svg.js.map +1 -0
- package/lib/module/spill-onboarding/analytics.js +56 -0
- package/lib/module/spill-onboarding/analytics.js.map +1 -0
- package/lib/module/spill-onboarding/buttons/PrimaryButton.js +50 -0
- package/lib/module/spill-onboarding/buttons/PrimaryButton.js.map +1 -0
- package/lib/module/spill-onboarding/buttons/SecondaryButton.js +51 -0
- package/lib/module/spill-onboarding/buttons/SecondaryButton.js.map +1 -0
- package/lib/module/spill-onboarding/buttons/SkipButton.js +35 -0
- package/lib/module/spill-onboarding/buttons/SkipButton.js.map +1 -0
- package/lib/module/spill-onboarding/components/OnboardingImageContainer.js +128 -0
- package/lib/module/spill-onboarding/components/OnboardingImageContainer.js.map +1 -0
- package/lib/module/spill-onboarding/components/OnboardingIntroPanel.js +97 -0
- package/lib/module/spill-onboarding/components/OnboardingIntroPanel.js.map +1 -0
- package/lib/module/spill-onboarding/components/OnboardingModal.js +69 -0
- package/lib/module/spill-onboarding/components/OnboardingModal.js.map +1 -0
- package/lib/module/spill-onboarding/components/OnboardingStepContainer.js +60 -0
- package/lib/module/spill-onboarding/components/OnboardingStepContainer.js.map +1 -0
- package/lib/module/spill-onboarding/components/OnboardingStepPanel.js +122 -0
- package/lib/module/spill-onboarding/components/OnboardingStepPanel.js.map +1 -0
- package/lib/module/spill-onboarding/hooks/useMeasureHeight.js +18 -0
- package/lib/module/spill-onboarding/hooks/useMeasureHeight.js.map +1 -0
- package/lib/module/spill-onboarding/icons/ArrowLeftIcon.js +57 -0
- package/lib/module/spill-onboarding/icons/ArrowLeftIcon.js.map +1 -0
- package/lib/module/spill-onboarding/icons/CloseIcon.js +49 -0
- package/lib/module/spill-onboarding/icons/CloseIcon.js.map +1 -0
- package/lib/module/spill-onboarding/index.js +206 -0
- package/lib/module/spill-onboarding/index.js.map +1 -0
- package/lib/module/spill-onboarding/types.js +4 -0
- package/lib/module/spill-onboarding/types.js.map +1 -0
- package/lib/module/utils/ThemeContext.js +78 -0
- package/lib/module/utils/ThemeContext.js.map +1 -0
- package/lib/module/utils/fontStyles.js +21 -0
- package/lib/module/utils/fontStyles.js.map +1 -0
- package/lib/module/utils/theme.js +27 -0
- package/lib/module/utils/theme.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/adapters/expo-image.d.ts +4 -0
- package/lib/typescript/src/spill-onboarding/adapters/expo-image.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/adapters/react-native-svg.d.ts +5 -0
- package/lib/typescript/src/spill-onboarding/adapters/react-native-svg.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/analytics.d.ts +2 -0
- package/lib/typescript/src/spill-onboarding/analytics.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/buttons/PrimaryButton.d.ts +13 -0
- package/lib/typescript/src/spill-onboarding/buttons/PrimaryButton.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/buttons/SecondaryButton.d.ts +13 -0
- package/lib/typescript/src/spill-onboarding/buttons/SecondaryButton.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/buttons/SkipButton.d.ts +6 -0
- package/lib/typescript/src/spill-onboarding/buttons/SkipButton.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingImageContainer.d.ts +18 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingImageContainer.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingIntroPanel.d.ts +4 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingIntroPanel.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingModal.d.ts +8 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingModal.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingStepContainer.d.ts +16 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingStepContainer.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingStepPanel.d.ts +4 -0
- package/lib/typescript/src/spill-onboarding/components/OnboardingStepPanel.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/hooks/useMeasureHeight.d.ts +9 -0
- package/lib/typescript/src/spill-onboarding/hooks/useMeasureHeight.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/icons/ArrowLeftIcon.d.ts +7 -0
- package/lib/typescript/src/spill-onboarding/icons/ArrowLeftIcon.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/icons/CloseIcon.d.ts +7 -0
- package/lib/typescript/src/spill-onboarding/icons/CloseIcon.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/index.d.ts +4 -0
- package/lib/typescript/src/spill-onboarding/index.d.ts.map +1 -0
- package/lib/typescript/src/spill-onboarding/types.d.ts +192 -0
- package/lib/typescript/src/spill-onboarding/types.d.ts.map +1 -0
- package/lib/typescript/src/utils/ThemeContext.d.ts +14 -0
- package/lib/typescript/src/utils/ThemeContext.d.ts.map +1 -0
- package/lib/typescript/src/utils/fontStyles.d.ts +19 -0
- package/lib/typescript/src/utils/fontStyles.d.ts.map +1 -0
- package/lib/typescript/src/utils/theme.d.ts +30 -0
- package/lib/typescript/src/utils/theme.d.ts.map +1 -0
- package/package.json +177 -0
- package/src/index.tsx +35 -0
- package/src/spill-onboarding/adapters/expo-image.ts +12 -0
- package/src/spill-onboarding/adapters/react-native-svg.ts +17 -0
- package/src/spill-onboarding/analytics.ts +75 -0
- package/src/spill-onboarding/buttons/PrimaryButton.tsx +70 -0
- package/src/spill-onboarding/buttons/SecondaryButton.tsx +71 -0
- package/src/spill-onboarding/buttons/SkipButton.tsx +34 -0
- package/src/spill-onboarding/components/OnboardingImageContainer.tsx +181 -0
- package/src/spill-onboarding/components/OnboardingIntroPanel.tsx +105 -0
- package/src/spill-onboarding/components/OnboardingModal.tsx +75 -0
- package/src/spill-onboarding/components/OnboardingStepContainer.tsx +85 -0
- package/src/spill-onboarding/components/OnboardingStepPanel.tsx +118 -0
- package/src/spill-onboarding/hooks/useMeasureHeight.ts +21 -0
- package/src/spill-onboarding/icons/ArrowLeftIcon.tsx +69 -0
- package/src/spill-onboarding/icons/CloseIcon.tsx +55 -0
- package/src/spill-onboarding/index.tsx +251 -0
- package/src/spill-onboarding/types.ts +243 -0
- package/src/utils/ThemeContext.tsx +87 -0
- package/src/utils/fontStyles.ts +19 -0
- package/src/utils/theme.ts +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+

|
|
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
|
+

|
|
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
|
+

|
|
165
|
+
|
|
166
|
+
#### `steps`
|
|
167
|
+
|
|
168
|
+
**Type:** `OnboardingStep[]`
|
|
169
|
+
**Required** - Array of onboarding steps to display
|
|
170
|
+
|
|
171
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

|
|
538
|
+
|
|
539
|
+
#### `steps`
|
|
540
|
+
|
|
541
|
+
**Type:** `OnboardingStep[]`
|
|
542
|
+
**Required** - Array of onboarding steps to display
|
|
543
|
+
|
|
544
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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
|
+

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