react-native-tuto-showcase 1.0.4 → 1.0.6

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 CHANGED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ahmed Mohamed Ali Ali Hegazy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,48 +1,82 @@
1
- # 📘 **react-native-tuto-showcase**
1
+ # 🔦 **react-native-tuto-showcase**
2
2
 
3
- ### 🔦 A fully customizable Spotlight / Tutorial / Coachmark overlay for React Native
3
+ > Fully customizable **Spotlight / Tutorial / Coachmark overlay** for React Native — perfect for onboarding, feature discovery & guided tours.
4
4
 
5
- Perfect for onboarding flows, feature tours, highlighting UI elements, and guiding users interactively.
5
+ [![npm version](https://img.shields.io/npm/v/react-native-tuto-showcase.svg)](https://www.npmjs.com/package/react-native-tuto-showcase)
6
+ [![license](https://img.shields.io/npm/l/react-native-tuto-showcase.svg)](https://github.com/ahmedhegazydev/react-native-tuto-showcase/blob/master/LICENSE)
7
+ ![platforms](https://img.shields.io/badge/platforms-ios%20%7C%20android-lightgrey.svg)
8
+ ![TypeScript](https://img.shields.io/badge/TypeScript-ready-blue.svg)
9
+ ![React Native](https://img.shields.io/badge/React%20Native-%5E0.72%2B-61dafb.svg)
10
+
11
+ A lightweight yet powerful **spotlight / walkthrough / coachmark** component for React Native that helps you:
12
+
13
+ * Guide users through **onboarding flows**
14
+ * Highlight **new features**
15
+ * Explain **complex UI**
16
+ * Drive **feature adoption & discovery**
6
17
 
7
18
  Now with **full-screen Lottie placement** + **custom offsets**.
8
19
 
9
20
  ---
10
21
 
11
- # ✨ Features
22
+ ## ✨ Features
23
+
24
+ * 🎯 **Highlight any UI element**
25
+
26
+ * Circle or rounded-rectangle **spotlight**
27
+ * Uses `measureInWindow` to auto-calc coordinates
28
+ * 📐 **Smart positioning**
29
+
30
+ * Spotlight automatically tracks the referenced `ref`
31
+ * 🧠 **Show-once logic (AsyncStorage)**
32
+
33
+ * `.showOnce(key)` / `.resetShowOnce(key)` / `.isShowOnce(key)`
34
+ * 🎞 **Lottie Animations — Full-Screen Placement**
35
+
36
+ * Place the animation relative to the **screen**, not the spotlight
37
+ * Built-in placements:
12
38
 
13
- * 🎯 Highlight any UI element with **Circle / RoundRect** spotlight
14
- * 📐 Auto-calculated spotlight position using `measureInWindow`
15
- * 🔁 Show-once logic (AsyncStorage)
16
- * 🎞 **Lottie Animations with full-screen positioning**
39
+ * `top-left`, `top-center`, `top-right`
40
+ * `bottom-left`, `bottom-center`, `bottom-right`
41
+ * `center`
42
+ * Fine-tune with `lottieOffset={{ dx, dy }}`
43
+ * 📦 **Multiple spots on one screen**
17
44
 
18
- * `top-left`, `top-right`, `top-center`
19
- * `bottom-left`, `bottom-right`, `bottom-center`
20
- * `center`
21
- * * `lottieOffset={{dx, dy}}`
22
- * 📦 Multiple spots on one screen
23
- * ✋ Gesture hints (swipe / scroll)
24
- * 🎨 Fully customizable:
45
+ * Chain calls on the same ref (circle / rect / gestures)
46
+ * **Gesture hints**
25
47
 
26
- * Colors
27
- * Button style
28
- * Fonts
29
- * Overlay background
30
- * 📱 Works on **iOS & Android**
31
- * Supports React Native 0.72+
48
+ * `.displaySwipableLeft()`
49
+ * `.displaySwipableRight()`
50
+ * `.displayScrollable()`
51
+ * 🎨 **Fully customizable UI**
52
+
53
+ * Overlay color
54
+ * Button container & text style
55
+ * Custom title & description JSX
56
+ * Works great with your design system / theming
57
+ * 📱 **Cross-platform**
58
+
59
+ * iOS & Android
60
+ * ⚡ **Modern RN stack**
61
+
62
+ * React Native **0.72+**
63
+ * TypeScript-friendly API
32
64
 
33
65
  ---
34
66
 
35
- # 📦 Installation
67
+ ## 📦 Installation
36
68
 
37
- ```sh
69
+ ```bash
38
70
  npm install react-native-tuto-showcase
39
- # or
71
+ # OR
40
72
  yarn add react-native-tuto-showcase
41
73
  ```
42
74
 
75
+ No extra native setup required beyond your standard React Native project.
76
+
43
77
  ---
44
78
 
45
- # 🚀 Basic Usage
79
+ ## 🚀 Basic Usage
46
80
 
47
81
  ```tsx
48
82
  import React, { useRef } from 'react';
@@ -65,7 +99,10 @@ export default function Home() {
65
99
  buttonText="تمام"
66
100
  />
67
101
 
68
- <View ref={boxRef} style={{ marginTop: 120, padding: 20, backgroundColor: '#eee' }}>
102
+ <View
103
+ ref={boxRef}
104
+ style={{ marginTop: 120, padding: 20, backgroundColor: '#eee' }}
105
+ >
69
106
  <Text>Drag Me</Text>
70
107
  </View>
71
108
 
@@ -87,15 +124,13 @@ export default function Home() {
87
124
 
88
125
  ---
89
126
 
90
- # 🎞 Lottie Placement (New)
91
-
92
- The Lottie animation is now positioned **relative to the full screen**, not the spotlight.
127
+ ## 🎞 Lottie Placement (New)
93
128
 
94
- ---
129
+ By default, the Lottie view is positioned **relative to the full screen**, so you can use it as a **hero pointer / hand animation** independent from the spotlight.
95
130
 
96
- ## 🔹 Available placements
131
+ ### 🔹 Available placements
97
132
 
98
- ```
133
+ ```text
99
134
  top-left
100
135
  top-center
101
136
  top-right
@@ -105,15 +140,19 @@ bottom-right
105
140
  center
106
141
  ```
107
142
 
108
- ## 🔹 Example
143
+ ### 🔹 Example
109
144
 
110
145
  ```tsx
146
+ import LottieView from 'lottie-react-native';
147
+
111
148
  <TutoShowcase
112
149
  ref={tutoRef}
113
150
  lottie={
114
151
  <LottieView
115
152
  source={require('./hand.json')}
116
153
  style={{ width: 120, height: 120 }}
154
+ autoPlay
155
+ loop
117
156
  />
118
157
  }
119
158
  lottiePlacement="top-right"
@@ -123,110 +162,185 @@ center
123
162
 
124
163
  ---
125
164
 
126
- # 🧩 Props
165
+ ## 🧩 `<TutoShowcase />` Props
127
166
 
128
- ## `<TutoShowcase />`
167
+ | Prop | Type | Default | Description |
168
+ | ------------------------ | ------------------------------ | ------------------ | ------------------------------------ |
169
+ | `title` | `ReactNode` | — | Title JSX (text, icons, etc.) |
170
+ | `description` | `string \| ReactNode` | — | Description text or custom JSX |
171
+ | `buttonText` | `string` | `"GOT IT"` | CTA button label |
172
+ | `buttonTextStyle` | `TextStyle` | — | Style for CTA text |
173
+ | `buttonContainerStyle` | `ViewStyle` | — | Style for CTA button wrapper |
174
+ | `overlayBackgroundColor` | `string` | `rgba(0,0,0,0.78)` | Dim background overlay color |
175
+ | `onGotIt` | `() => void` | — | Callback when CTA is pressed |
176
+ | `lottie` | `ReactElement` | — | Lottie animation component |
177
+ | `lottiePlacement` | `"top-left" \| ...` | `"top-center"` | Full-screen placement of the Lottie |
178
+ | `lottieOffset` | `{ dx?: number; dy?: number }` | `{}` | Extra offset applied after placement |
129
179
 
130
- | Prop | Type | Default | Description |
131
- | ------------------------ | ------------------------------ | ------------------ | ----------------------- |
132
- | `title` | `ReactNode` | — | Title JSX |
133
- | `description` | `string \| ReactNode` | — | Description text |
134
- | `buttonText` | `string` | `"GOT IT"` | CTA label |
135
- | `buttonTextStyle` | `TextStyle` | — | Style for CTA text |
136
- | `buttonContainerStyle` | `ViewStyle` | — | Style for CTA button |
137
- | `overlayBackgroundColor` | `string` | `rgba(0,0,0,0.78)` | Dim overlay color |
138
- | `onGotIt` | `() => void` | — | Called when CTA pressed |
139
- | `lottie` | `ReactElement` | — | Lottie animation |
140
- | **`lottiePlacement`** | `"top-left" \| ...` | `"top-center"` | ⭐ Full-screen placement |
141
- | **`lottieOffset`** | `{ dx?: number; dy?: number }` | `{}` | Extra offset |
180
+ > 💡 You can pass any **custom JSX** for `title` / `description` to plug into your design system (e.g. `Text`, `Heading`, `Icon + Text`, etc.)
142
181
 
143
182
  ---
144
183
 
145
- # 🎛 Ref API
184
+ ## 🎛 Ref API
146
185
 
147
186
  ```ts
187
+ import { TutoShowcaseHandle } from 'react-native-tuto-showcase';
188
+
148
189
  const tutoRef = useRef<TutoShowcaseHandle>(null);
149
190
  ```
150
191
 
151
- | Method | Description |
152
- | -------------------------------------- | ----------------------------- |
153
- | `on(ref)` | Select target element |
154
- | `addCircle(ratio?)` | Add circle spotlight |
155
- | `addRoundRect(ratio?, radius?, opts?)` | Add rounded spotlight |
156
- | `withBorder()` | Add border |
157
- | `displaySwipableLeft()` | Gesture hint |
158
- | `displaySwipableRight()` | Gesture hint |
159
- | `displayScrollable()` | Gesture hint |
160
- | `onClick(cb)` | Capture taps inside spotlight |
161
- | `show()` | Show spotlight immediately |
162
- | `showOnce(key)` | Show once (AsyncStorage) |
163
- | `resetShowOnce(key)` | Clear stored key |
164
- | `isShowOnce(key)` | Check if key shown |
192
+ | Method | Description |
193
+ | -------------------------------------- | ---------------------------------------------- |
194
+ | `on(ref)` | Attach spotlight to a target element `ref` |
195
+ | `addCircle(ratio?)` | Add **circular** spotlight |
196
+ | `addRoundRect(ratio?, radius?, opts?)` | Add **rounded-rectangle** spotlight |
197
+ | `withBorder()` | Add border around spotlight |
198
+ | `displaySwipableLeft()` | Show swipe-left gesture hint |
199
+ | `displaySwipableRight()` | Show swipe-right gesture hint |
200
+ | `displayScrollable()` | Show scroll gesture hint |
201
+ | `onClick(cb)` | Capture taps inside spotlight area |
202
+ | `show()` | Show tutorial immediately |
203
+ | `showOnce(key)` | Show only once per key (saved in AsyncStorage) |
204
+ | `resetShowOnce(key)` | Clear stored key; show again next time |
205
+ | `isShowOnce(key)` | Check if a specific key has already been shown |
165
206
 
166
207
  ---
167
208
 
168
- # 🗂 Show Once Logic
209
+ ## 🗂 Show Once Logic
210
+
211
+ Use `showOnce(key)` to avoid spamming users with the same tutorial:
169
212
 
170
213
  ```tsx
171
214
  tutoRef.current
172
215
  ?.on(boxRef)
173
216
  .addCircle()
174
- .showOnce('first-time');
217
+ .showOnce('first-time-highlight');
218
+ ```
219
+
220
+ To reset:
221
+
222
+ ```tsx
223
+ tutoRef.current?.resetShowOnce('first-time-highlight');
224
+ ```
225
+
226
+ To check:
227
+
228
+ ```tsx
229
+ const alreadyShown = await tutoRef.current?.isShowOnce('first-time-highlight');
175
230
  ```
176
231
 
177
232
  ---
178
233
 
179
- # 🎨 Button Customization
234
+ ## 🎨 Button & Overlay Customization
180
235
 
181
236
  ```tsx
182
237
  <TutoShowcase
238
+ overlayBackgroundColor="rgba(15, 23, 42, 0.85)" // slate-like
183
239
  buttonContainerStyle={{
184
240
  backgroundColor: '#FFD700',
185
- borderRadius: 10,
241
+ borderRadius: 999,
242
+ paddingHorizontal: 24,
243
+ paddingVertical: 10,
186
244
  }}
187
245
  buttonTextStyle={{
188
246
  color: '#000',
189
247
  fontWeight: 'bold',
248
+ fontSize: 16,
190
249
  }}
191
250
  />
192
251
  ```
193
252
 
194
253
  ---
195
254
 
196
- # 📐 Spotlight Options
255
+ ## 📐 Spotlight Examples
197
256
 
198
257
  ### Circle
199
258
 
200
259
  ```tsx
201
- .on(ref)
202
- .addCircle(1.3)
203
- .show()
260
+ tutoRef.current
261
+ ?.on(boxRef)
262
+ .addCircle(1.3) // 1.0 = tight, >1 expands radius
263
+ .show();
204
264
  ```
205
265
 
206
266
  ### Rounded Rectangle
207
267
 
208
268
  ```tsx
209
- .on(ref)
210
- .addRoundRect(1.1, 20, { pad: 30 })
211
- .show()
269
+ tutoRef.current
270
+ ?.on(boxRef)
271
+ .addRoundRect(1.1, 20, { pad: 30 }) // ratio, corner radius, extra padding
272
+ .show();
212
273
  ```
213
274
 
214
275
  ---
215
276
 
216
- # 🎥 Demo Videos
277
+ ## 🎥 Demo Videos
217
278
 
218
279
  ### 📱 iOS
219
280
 
220
- [https://github.com/ahmedhegazydev/react-native-tuto-showcase/blob/master/src/assets/SimulatorScreenRecording-iPhone16Pro-2025-11-24at14.14.46online-video-cutter.com-ezgif.com-video-to-gif-converter.gif](https://github.com/ahmedhegazydev/react-native-tuto-showcase/blob/master/src/assets/SimulatorScreenRecording-iPhone16Pro-2025-11-24at14.14.46online-video-cutter.com-ezgif.com-video-to-gif-converter.gif)
281
+ [View iOS demo GIF](https://github.com/ahmedhegazydev/react-native-tuto-showcase/blob/master/src/assets/SimulatorScreenRecording-iPhone16Pro-2025-11-24at14.14.46online-video-cutter.com-ezgif.com-video-to-gif-converter.gif)
221
282
 
222
283
  ### 🤖 Android
223
284
 
224
- [https://github.com/ahmedhegazydev/react-native-tuto-showcase/blob/master/src/assets/ScreenRecording2025-12-02at7.52.23PMonline-video-cutter.com-ezgif.com-video-to-gif-converter.gif](https://github.com/ahmedhegazydev/react-native-tuto-showcase/blob/master/src/assets/ScreenRecording2025-12-02at7.52.23PMonline-video-cutter.com-ezgif.com-video-to-gif-converter.gif)
285
+ [View Android demo GIF](https://github.com/ahmedhegazydev/react-native-tuto-showcase/blob/master/src/assets/ScreenRecording2025-12-02at7.52.23PMonline-video-cutter.com-ezgif.com-video-to-gif-converter.gif)
286
+
287
+ ---
288
+
289
+ ## 🧠 Typical Use Cases
290
+
291
+ * App **onboarding** & first-time user experience
292
+ * Feature discovery (“What’s new” walkthroughs)
293
+ * Highlighting **FAB buttons**, menus, tabs, drawers
294
+ * Teaching users **drag & drop** / **reorder** interactions
295
+ * Coachmarks for:
296
+
297
+ * Dashboards
298
+ * Settings screens
299
+ * Maps & complex UI
300
+ * Internal QA / UX testing sessions
301
+
302
+ ---
303
+
304
+ ## 🛠 Troubleshooting
305
+
306
+ | Issue | Hint |
307
+ | ------------------------------- | ------------------------------------------------------------ |
308
+ | Spotlight not aligned correctly | Ensure the target has a `ref` and is rendered on screen |
309
+ | Nothing shows up | Check `tutoRef.current` is not `null` before calling methods |
310
+ | `showOnce` not working | Verify AsyncStorage is properly linked & no key collisions |
311
+ | Lottie is cut or off-screen | Adjust `lottiePlacement` + `lottieOffset` |
225
312
 
226
313
  ---
227
314
 
228
- # 📝 License
315
+ ## 🗺 Roadmap
316
+
317
+ * ✅ Multiple-step walkthrough sequences
318
+ * ✅ Better gesture presets
319
+ * 🔜 RTL-aware layouts
320
+ * 🔜 Built-in themes (light / dark)
321
+ * 🔜 Auto “Next / Previous” between spots
322
+ * 🔜 Expo Snack examples
323
+
324
+ > PRs & feature requests are very welcome ✨
325
+
326
+ ---
327
+
328
+ ## 👤 Author
329
+
330
+ Built with ❤️ by **Ahmed Hegazy**
331
+
332
+ * 📧 [ahmedmhegazy.eg@gmail.com](mailto:ahmedmhegazy.eg@gmail.com)
333
+ * 🐙 GitHub: [@ahmedhegazydev](https://github.com/ahmedhegazydev)
334
+
335
+ ---
336
+
337
+ ## 📄 License
229
338
 
230
339
  MIT © **Ahmed Mohamed Ali Ali Hegazy**
231
340
 
232
- ---
341
+ ---
342
+
343
+ ## 🔍 SEO / Keywords
344
+
345
+ **Keywords:**
346
+ `react native tutorial` · `react native onboarding` · `react native coach marks` · `react native walkthrough` · `react native spotlight` · `react native highlight view` · `react native feature discovery` · `react native guided tour` · `react native tooltip overlay` · `react native help overlay` · `react native lottie overlay` · `react native interactive tutorial` · `react native drag reorder tutorial` · `react native product tour` · `react native showcase` · `react native hint` · `react native gesture hint` · `react native ux onboarding` · `react native step by step tutorial`
@@ -1,6 +1,18 @@
1
1
  import React from 'react';
2
2
  import { AnyShape } from '../types/shapes';
3
- export default function LottieAboveTarget({ shapes, lottie, }: {
3
+ export type LottiePlacement = 'top-left' | 'top-right' | 'top-center' | 'bottom-left' | 'bottom-right' | 'bottom-center' | 'center';
4
+ type Offset = {
5
+ dx?: number;
6
+ dy?: number;
7
+ };
8
+ type Props = {
4
9
  shapes: AnyShape[];
5
10
  lottie: React.ReactElement<any>;
6
- }): import("react/jsx-runtime").JSX.Element | null;
11
+ overlayWidth: number;
12
+ overlayHeight: number;
13
+ placement?: LottiePlacement;
14
+ offset?: Offset;
15
+ };
16
+ export default function LottieAboveTarget({ shapes, lottie, overlayWidth, overlayHeight, placement, // 👈 الديفولت: فوق في النص بالنسبة للشاشة كلها
17
+ offset, }: Props): import("react/jsx-runtime").JSX.Element | null;
18
+ export {};
@@ -1,17 +1,56 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { View, StyleSheet } from 'react-native';
4
- export default function LottieAboveTarget({ shapes, lottie, }) {
5
- if (!lottie || shapes.length === 0)
4
+ const PADDING_H = 24;
5
+ const PADDING_V = 32;
6
+ export default function LottieAboveTarget({ shapes, lottie, overlayWidth, overlayHeight, placement = 'top-center', // 👈 الديفولت: فوق في النص بالنسبة للشاشة كلها
7
+ offset, }) {
8
+ if (!lottie)
6
9
  return null;
7
- const focus = shapes[shapes.length - 1];
8
10
  const layout = StyleSheet.flatten(lottie.props?.style) || {};
9
11
  const lw = layout.width ?? 100;
10
12
  const lh = layout.height ?? 100;
11
- const cx = focus.cx;
12
- const topOfHole = focus.type === 'circle' ? focus.cy - focus.r : focus.y;
13
- const top = topOfHole - lh + 50;
14
- const left = cx - lw / 2;
13
+ let top = 0;
14
+ let left = 0;
15
+ switch (placement) {
16
+ case 'top-left':
17
+ top = PADDING_V;
18
+ left = PADDING_H;
19
+ break;
20
+ case 'top-right':
21
+ top = PADDING_V;
22
+ left = overlayWidth - lw - PADDING_H;
23
+ break;
24
+ case 'top-center':
25
+ top = PADDING_V;
26
+ left = (overlayWidth - lw) / 2;
27
+ break;
28
+ case 'bottom-left':
29
+ top = overlayHeight - lh - PADDING_V;
30
+ left = PADDING_H;
31
+ break;
32
+ case 'bottom-right':
33
+ top = overlayHeight - lh - PADDING_V;
34
+ left = overlayWidth - lw - PADDING_H;
35
+ break;
36
+ case 'bottom-center':
37
+ top = overlayHeight - lh - PADDING_V;
38
+ left = (overlayWidth - lw) / 2;
39
+ break;
40
+ case 'center':
41
+ top = (overlayHeight - lh) / 2;
42
+ left = (overlayWidth - lw) / 2;
43
+ break;
44
+ default:
45
+ top = PADDING_V;
46
+ left = (overlayWidth - lw) / 2;
47
+ break;
48
+ }
49
+ // ✅ اختياري: إزاحة إضافية
50
+ if (offset?.dx)
51
+ left += offset.dx;
52
+ if (offset?.dy)
53
+ top += offset.dy;
15
54
  return (_jsx(View, { pointerEvents: "none", style: [
16
55
  styles.container,
17
56
  { top, left, width: lw, height: lh },
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { LottiePlacement } from './components/LottieAboveTarget';
2
3
  export type TutoShowcaseHandle = {
3
4
  on: (r: any) => any;
4
5
  show: () => void;
@@ -7,5 +8,20 @@ export type TutoShowcaseHandle = {
7
8
  isShowOnce: (key: string) => boolean;
8
9
  resetShowOnce: (key: string) => void;
9
10
  };
10
- declare const TutoShowcase: React.ForwardRefExoticComponent<Omit<any, "ref"> & React.RefAttributes<TutoShowcaseHandle>>;
11
+ type TutoShowcaseProps = {
12
+ title?: React.ReactNode;
13
+ description?: React.ReactNode;
14
+ buttonText?: string;
15
+ buttonTextStyle?: any;
16
+ buttonContainerStyle?: any;
17
+ overlayBackgroundColor?: string;
18
+ onGotIt?: () => void;
19
+ lottie?: React.ReactElement<any> | null;
20
+ lottiePlacement?: LottiePlacement;
21
+ lottieOffset?: {
22
+ dx?: number;
23
+ dy?: number;
24
+ };
25
+ };
26
+ declare const TutoShowcase: React.ForwardRefExoticComponent<TutoShowcaseProps & React.RefAttributes<TutoShowcaseHandle>>;
11
27
  export default TutoShowcase;
package/dist/index.js CHANGED
@@ -11,7 +11,8 @@ import { usePulseAnimation } from './hooks/usePulseAnimation';
11
11
  import { buildActionsFactory } from './helpers/buildActions';
12
12
  import { useContentPosition } from './hooks/useContentPosition';
13
13
  const DEFAULT_BG = 'rgba(0,0,0,0.78)';
14
- const TutoShowcase = forwardRef(function Tuto({ title, description, buttonText = 'GOT IT', buttonTextStyle, buttonContainerStyle, overlayBackgroundColor, onGotIt, lottie, }, ref) {
14
+ const TutoShowcase = forwardRef(function Tuto({ title, description, buttonText = 'GOT IT', buttonTextStyle, buttonContainerStyle, overlayBackgroundColor, onGotIt, lottie, lottiePlacement, // 👈 خدناه من props
15
+ lottieOffset, }, ref) {
15
16
  // -------- Hooks يجب أن تكون في الأعلى وبنفس الترتيب دائماً --------
16
17
  const [visible, setVisible] = useState(false);
17
18
  const [bgColor, setBgColor] = useState(overlayBackgroundColor || DEFAULT_BG);
@@ -84,7 +85,7 @@ const TutoShowcase = forwardRef(function Tuto({ title, description, buttonText =
84
85
  // ✅ الشرط هنا بعد كل الـ hooks
85
86
  if (!visible)
86
87
  return null;
87
- return (_jsx(Modal, { visible: true, transparent: true, animationType: "fade", children: _jsx(TouchableWithoutFeedback, { onPress: onOverlayPress, children: _jsxs(View, { ref: rootRef, onLayout: onLayout, style: [StyleSheet.absoluteFill, { direction: 'ltr' }], children: [_jsx(Overlay, { width: width, height: height, shapes: shapes, bgColor: bgColor, spotScale: spotScale, spotOpacity: spotOpacity }), lottie && _jsx(LottieAboveTarget, { shapes: shapes, lottie: lottie }), (title || description) && (_jsx(ContentSection, { title: title, description: description, buttonText: buttonText, buttonTextStyle: buttonTextStyle, buttonContainerStyle: buttonContainerStyle, coords: coords, onPress: () => {
88
+ return (_jsx(Modal, { visible: true, transparent: true, animationType: "fade", children: _jsx(TouchableWithoutFeedback, { onPress: onOverlayPress, children: _jsxs(View, { ref: rootRef, onLayout: onLayout, style: [StyleSheet.absoluteFill, { direction: 'ltr' }], children: [_jsx(Overlay, { width: width, height: height, shapes: shapes, bgColor: bgColor, spotScale: spotScale, spotOpacity: spotOpacity }), lottie && (_jsx(LottieAboveTarget, { shapes: shapes, lottie: lottie, overlayWidth: width, overlayHeight: height, placement: lottiePlacement, offset: lottieOffset })), (title || description) && (_jsx(ContentSection, { title: title, description: description, buttonText: buttonText, buttonTextStyle: buttonTextStyle, buttonContainerStyle: buttonContainerStyle, coords: coords, onPress: () => {
88
89
  onGotIt?.();
89
90
  dismiss();
90
91
  } })), _jsx(GestureHints, { hints: hints })] }) }) }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-tuto-showcase",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Customizable tutorial / spotlight overlay for React Native (onboarding, feature tours, coachmarks).",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,18 +26,18 @@
26
26
  ],
27
27
  "author": "Ahmed Mohamed Ali Ali Hegazy",
28
28
  "license": "MIT",
29
+ "packageManager": "yarn@3.6.4+sha512.e70835d4d6d62c07be76b3c1529cb640c7443f0fe434ef4b6478a5a399218cbaf1511b396b3c56eb03bc86424cff2320f6167ad2fde273aa0df6e60b7754029f",
29
30
  "peerDependencies": {
31
+ "@react-native-async-storage/async-storage": ">=1.17.0",
30
32
  "react": ">=18.0.0",
31
- "react-native": ">=0.72.0"
32
- },
33
- "dependencies": {
34
- "@react-native-async-storage/async-storage": "^1.23.0",
35
- "react-native-svg": "^13.14.0"
33
+ "react-native": ">=0.72.0",
34
+ "react-native-svg": ">=13.0.0"
36
35
  },
37
- "packageManager": "yarn@3.6.4+sha512.e70835d4d6d62c07be76b3c1529cb640c7443f0fe434ef4b6478a5a399218cbaf1511b396b3c56eb03bc86424cff2320f6167ad2fde273aa0df6e60b7754029f",
38
36
  "devDependencies": {
37
+ "@react-native-async-storage/async-storage": "^1.23.0",
39
38
  "@types/react": "^19.2.7",
40
39
  "@types/react-native": "^0.72.8",
40
+ "react-native-svg": "^13.14.0",
41
41
  "typescript": "^5.9.3"
42
42
  }
43
43
  }