rn-smart-tour 1.0.3 → 1.0.4

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 (2) hide show
  1. package/README.md +83 -159
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,15 +1,23 @@
1
1
  # rn-smart-tour
2
2
 
3
- An enterprise-grade Digital Adoption Platform (DAP) package for React Native. Easily add product tours, guided walkthroughs, and onboarding overlays directly into your app without intrusive code changes.
3
+ <p align="center">
4
+ <b>Enterprise-grade Digital Adoption Platform (DAP) for React Native</b><br>
5
+ Easily add product tours, guided walkthroughs, and onboarding overlays without intrusive code changes.
6
+ </p>
4
7
 
5
- ## Features
6
- - **Multi-Pass Measurement**: Wraps your components and uses the native `measureInWindow` API with a self-correcting, multi-pass strategy — so highlights land correctly even during screen-transition animations.
7
- - **Rotation & Resize Aware**: Automatically re-measures targets when screen dimensions change (rotation, split-screen, foldables).
8
- - **Debounced Auto-Start Engine**: Automatically triggers tours when target elements mount, with a built-in debounce to ensure the overlay uses fully settled coordinates.
9
- - **Seen State Caching**: Connect any local storage database to ensure users only see tours once.
10
- - **Smart Overlays**: Creates highlighted holes in backdrops over completely custom UIs, with Back/Next/Skip navigation.
8
+ ---
9
+
10
+ ## Features
11
+
12
+ - 🎯 **Multi-Pass Measurement**: Native `measureInWindow` API with self-correcting strategy for animation resilience.
13
+ - 📱 **Rotation & Resize Aware**: Targets re-measure automatically on orientation change or split-screen.
14
+ - ⚡ **Auto-Start Engine**: Trigger tours instantly on mount with a smart debounce for layout stability.
15
+ - 💾 **Seen State Caching**: Persistent "only-once" logic with pluggable storage (AsyncStorage, MMKV, etc.).
16
+ - 🎨 **Smart Overlays**: Dynamic cutouts with Back/Next/Skip navigation and step indicators.
17
+
18
+ ---
11
19
 
12
- ## Installation
20
+ ## 📦 Installation
13
21
 
14
22
  ```sh
15
23
  npm install rn-smart-tour
@@ -17,202 +25,118 @@ npm install rn-smart-tour
17
25
 
18
26
  ---
19
27
 
20
- ## 🚀 Quick Start Guide
28
+ ## 🚀 Quick Start
21
29
 
22
- Adding a product tour to your app only takes 3 simple steps:
23
-
24
- ### Step 1: Wrap your App
25
- At the very top of your application (usually `App.tsx`), wrap everything in the `<DapProvider>`. Here you define the tours you want to show your users.
30
+ ### 1. Wrap your App
31
+ Wrap your root component in the `DapProvider` and define your tours.
26
32
 
27
33
  ```tsx
28
- import React from 'react';
29
34
  import { DapProvider } from 'rn-smart-tour';
30
35
 
31
- // Define the steps of your tour here!
32
- const MY_TOURS = {
36
+ const TOURS = {
33
37
  'welcome-tour': {
34
38
  id: 'welcome-tour',
35
- steps: [
36
- {
37
- targetId: 'my-first-button',
38
- title: 'Welcome to the App!',
39
- description: 'Tapping this button saves your progress.',
40
- }
41
- ]
39
+ steps: [{
40
+ targetId: 'save-btn',
41
+ title: 'Welcome!',
42
+ description: 'Tap here to save your progress.',
43
+ }]
42
44
  }
43
45
  };
44
46
 
45
47
  export default function App() {
46
48
  return (
47
- <DapProvider tours={MY_TOURS}>
48
- <MainScreen />
49
+ <DapProvider tours={TOURS}>
50
+ <MainApp />
49
51
  </DapProvider>
50
52
  );
51
53
  }
52
54
  ```
53
55
 
54
- ### Step 2: Target an Element
55
- Go to any screen in your app and decide what button or view you want to highlight. Wrap that element with `<DapTarget>`. Make sure the `name` matches the `targetId` from Step 1!
56
+ ### 2. Mark your Target
57
+ Wrap any view or button you want to highlight with `DapTarget`.
56
58
 
57
59
  ```tsx
58
- import { View, Button } from 'react-native';
59
60
  import { DapTarget } from 'rn-smart-tour';
60
61
 
61
- export const MainScreen = () => {
62
- return (
63
- <View style={{ marginTop: 100 }}>
64
- {/* Wrap the button you want to highlight! */}
65
- <DapTarget name="my-first-button">
66
- <Button title="Save Button" onPress={() => {}} />
67
- </DapTarget>
68
- </View>
69
- );
70
- };
62
+ const MyButton = () => (
63
+ <DapTarget name="save-btn">
64
+ <Button title="Save" onPress={...} />
65
+ </DapTarget>
66
+ );
71
67
  ```
72
68
 
73
- ### Step 3: Trigger the Tour!
74
- To start the walkthrough, just call `startTour` anywhere inside your app.
69
+ ### 3. Start the Tour
70
+ Use the `useDap` hook to trigger the onboarding.
75
71
 
76
72
  ```tsx
77
- import { Button } from 'react-native';
78
73
  import { useDap } from 'rn-smart-tour';
79
74
 
80
- export const HelpMenu = () => {
81
- const { startTour } = useDap();
82
-
83
- return (
84
- <Button
85
- title="Start Walkthrough"
86
- onPress={() => startTour('welcome-tour')}
87
- />
88
- );
89
- }
75
+ const { startTour } = useDap();
76
+ // ...
77
+ <Button title="Help" onPress={() => startTour('welcome-tour')} />
90
78
  ```
91
79
 
92
80
  ---
93
81
 
94
- ## 🧠 Advanced Usage (Pro Features)
82
+ ## 🧠 Technical Architecture
95
83
 
96
- ### 1. Auto-Start & Show "Only Once"
97
- For true enterprise onboarding, you want the tour to start *automatically* when a user visits a new screen, and never show it to them again after they finish it.
84
+ <details>
85
+ <summary><b>View How Measurements Work (Click to expand)</b></summary>
98
86
 
99
- By passing a `storageAdapter` (like `AsyncStorage`) into the Provider, the package will permanently remember who has seen the tour!
87
+ To guarantee accuracy during navigation animations, `rn-smart-tour` uses a **multi-pass strategy**:
100
88
 
101
- ```tsx
102
- import AsyncStorage from '@react-native-async-storage/async-storage';
103
-
104
- const MY_TOURS = {
105
- 'welcome-tour': {
106
- id: 'welcome-tour',
107
- autoStart: true, // Automatically starts when "my-first-button" mounts!
108
- steps: [ ... ]
109
- }
110
- };
111
-
112
- // Map the Storage commands
113
- const myStorage = {
114
- getItem: async (key) => await AsyncStorage.getItem(key),
115
- setItem: async (key, value) => { await AsyncStorage.setItem(key, value); }
116
- };
117
-
118
- // Pass it to the Provider
119
- <DapProvider tours={MY_TOURS} storageAdapter={myStorage}>
120
- ```
89
+ - **Pass 1 (100ms)**: Fast first estimate.
90
+ - **Pass 2 (500ms)**: Corrects after most screen transitions finish.
91
+ - **Pass 3 (1000ms)**: Final safety net for slow async layout shifts.
121
92
 
122
- ### 2. How Measurement Works
93
+ Measurements only trigger a re-render if the position changes by more than **1pt (threshold)**.
123
94
 
124
- When a `<DapTarget>` mounts or re-layouts, it does **not** rely on a single measurement. Instead, it uses a **multi-pass strategy** to guarantee accuracy:
95
+ </details>
125
96
 
126
- | Pass | Delay | Purpose |
127
- |------|-------|---------|
128
- | 1st | 100ms | Fast first estimate — may capture mid-animation coordinates |
129
- | 2nd | 500ms | Self-corrects after most navigation transitions finish |
130
- | 3rd | 1000ms | Final safety net for slow animations or async layout shifts |
97
+ <details>
98
+ <summary><b>Auto-Start & Debounce Settings</b></summary>
131
99
 
132
- - Each new `onLayout` event **cancels** all pending timers and schedules fresh measurements.
133
- - A measurement is only sent to the Provider if the position has **actually changed** (>1pt threshold), avoiding unnecessary re-renders.
134
- - On **rotation/resize**, all targets automatically re-measure themselves.
135
- - On unmount, all timers are cleaned up and the target is unregistered.
100
+ When `autoStart: true` is enabled, the overlay waits **300ms** after registration. This allows the multi-pass system to settle on the final coordinates before the hole is cut into the backdrop.
136
101
 
137
- #### Auto-Start Debounce
102
+ </details>
138
103
 
139
- When `autoStart: true` is set on a tour, the overlay does **not** appear the instant a target registers. Instead, it waits **300ms** before starting. If a more accurate measurement arrives during that window (e.g., the 500ms pass corrects the 100ms pass), the debounce resets and the overlay uses the final, settled coordinates.
140
-
141
- This is why you may notice a brief (~300ms) delay before an auto-start tour appears — it's by design to prevent misaligned highlights.
142
-
143
- #### Tuning Constants
144
-
145
- If you need to adjust timing for your app's specific animation durations, the following constants can be modified in the source:
146
-
147
- | Constant | File | Default | Description |
148
- |----------|------|---------|-------------|
149
- | `MEASUREMENT_DELAYS` | `DapTarget.tsx` | `[100, 500, 1000]` | Multi-pass measurement intervals (ms) |
150
- | `POSITION_THRESHOLD` | `DapTarget.tsx` | `1` | Minimum position change (points) to trigger re-registration |
151
- | `AUTO_START_DEBOUNCE_MS` | `DapProvider.tsx` | `300` | Debounce delay (ms) before auto-starting a tour |
152
-
153
- ### 3. Programmatic Control
154
-
155
- The `useDap()` hook exposes full control over tours:
156
-
157
- ```tsx
158
- const { startTour, stopTour, nextStep, prevStep, activeTour, currentStepIndex } = useDap();
159
-
160
- // Start a specific tour
161
- startTour('welcome-tour');
104
+ ---
162
105
 
163
- // Stop and mark as seen (default)
164
- stopTour();
106
+ ## 🛠 API Reference
165
107
 
166
- // Stop WITHOUT marking as seen (user can see it again)
167
- stopTour(false);
108
+ ### Tour Configuration
109
+ | Property | Type | Description |
110
+ |:---|:---|:---|
111
+ | `id` | `string` | Unique identifier for caching. |
112
+ | `autoStart` | `boolean` | Trigger as soon as the first target mounts. |
113
+ | `steps` | `TourStep[]` | Sequence of highlight steps. |
168
114
 
169
- // Navigate between steps
170
- nextStep();
171
- prevStep();
172
- ```
115
+ ### TourStep
116
+ | Property | Type | Default | Description |
117
+ |:---|:---|:---|:---|
118
+ | `targetId` | `string` | — | Matches the `name` prop in `<DapTarget>`. |
119
+ | `title` | `string` | — | Tooltip header. |
120
+ | `description` | `string` | — | Tooltip body. |
121
+ | `position` | `string` | `'bottom'` | `top`, `bottom`, `left`, `right`. |
122
+
123
+ ### `useDap()` Hook
124
+ | Method | Description |
125
+ |:---|:---|
126
+ | `startTour(id)` | Start a tour by ID. |
127
+ | `stopTour(markAsSeen?)`| End tour. Pass `false` to keep it unread. |
128
+ | `nextStep()` / `prevStep()` | Manual step navigation. |
129
+ | `activeTour` | Current active tour object. |
130
+ | `currentStepIndex` | Current step number (0-indexed). |
173
131
 
174
- ## API Reference
132
+ ---
175
133
 
176
- ### Tour Object
177
- | Property | Type | Description |
178
- |-----------|------|-------------|
179
- | `id` | `string` | Unique identifier. Needed for cache tracking. |
180
- | `autoStart` | `boolean` | If true, automatically renders when the first step's target mounts on the screen. |
181
- | `steps` | `TourStep[]` | The sequence of highlighted elements and tooltips. |
134
+ ## 🤝 Contributing
182
135
 
183
- ### TourStep Object
184
- | Property | Type | Default | Description |
185
- |-----------|------|---------|-------------|
186
- | `targetId` | `string` | — | Must directly match the `name=""` prop passed to `<DapTarget>`. |
187
- | `title` | `string` | — | Large text inside the tooltip. |
188
- | `description` | `string` | — | Context explanation inside the tooltip. |
189
- | `position` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | Where the tooltip appears relative to the highlighted target. |
136
+ Contributions are welcome! Please feel free to submit a Pull Request.
190
137
 
191
- ### DapTarget Props
192
- | Property | Type | Description |
193
- |-----------|------|-------------|
194
- | `name` | `string` | Unique identifier that matches a `targetId` in a tour step. |
195
- | `children` | `ReactElement` | The UI element to wrap and highlight. |
196
- | `...props` | `ViewProps` | All standard React Native `View` props are forwarded. |
138
+ ---
197
139
 
198
- ### useDap() Hook
199
- | Property | Type | Description |
200
- |-----------|------|-------------|
201
- | `startTour(id)` | `(tourId: string) => void` | Start a tour by its ID. |
202
- | `stopTour(markAsSeen?)` | `(markAsSeen?: boolean) => void` | Stop the active tour. Pass `false` to allow the tour to show again. |
203
- | `nextStep()` | `() => void` | Advance to the next step. Finishes the tour if on the last step. |
204
- | `prevStep()` | `() => void` | Go back to the previous step. |
205
- | `activeTour` | `Tour \| null` | The currently active tour object, or `null`. |
206
- | `currentStepIndex` | `number` | Index of the current step in the active tour. |
207
- | `targets` | `Record<string, TargetMeasurement>` | All registered target measurements. |
208
- | `seenTours` | `Record<string, boolean>` | Map of tour IDs to whether they've been seen. |
209
-
210
- ### StorageAdapter Interface
211
- | Method | Type | Description |
212
- |--------|------|-------------|
213
- | `getItem` | `(key: string) => Promise<string \| null> \| string \| null` | Retrieve a stored value by key. |
214
- | `setItem` | `(key: string, value: string) => Promise<void> \| void` | Store a value by key. |
215
-
216
- Compatible with `AsyncStorage`, `MMKV`, or any key-value store that implements this interface.
217
- # rn-smart-tour
218
-
140
+ <p align="center">
141
+ <b>rn-smart-tour</b> Built with ❤️ for the React Native community.
142
+ </p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-smart-tour",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Enterprise-grade Digital Adoption Platform (DAP) package for React Native. Provides guided walkthroughs, tooltips, and app tours.",
5
5
  "author": "Vishwas Gaur",
6
6
  "license": "MIT",