react-native-lumen 1.0.1 → 1.1.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/README.md +763 -231
- package/lib/module/components/TourOverlay.js +43 -3
- package/lib/module/components/TourOverlay.js.map +1 -1
- package/lib/module/components/TourProvider.js +318 -61
- package/lib/module/components/TourProvider.js.map +1 -1
- package/lib/module/components/TourTooltip.js +113 -73
- package/lib/module/components/TourTooltip.js.map +1 -1
- package/lib/module/components/TourZone.js +186 -119
- package/lib/module/components/TourZone.js.map +1 -1
- package/lib/module/constants/defaults.js +43 -0
- package/lib/module/constants/defaults.js.map +1 -1
- package/lib/module/context/TourContext.js +5 -0
- package/lib/module/context/TourContext.js.map +1 -0
- package/lib/module/hooks/useTour.js +1 -1
- package/lib/module/hooks/useTour.js.map +1 -1
- package/lib/module/hooks/useTourScrollView.js +71 -0
- package/lib/module/hooks/useTourScrollView.js.map +1 -0
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/storage.js +188 -0
- package/lib/module/utils/storage.js.map +1 -0
- package/lib/typescript/src/components/TourOverlay.d.ts.map +1 -1
- package/lib/typescript/src/components/TourProvider.d.ts +21 -4
- package/lib/typescript/src/components/TourProvider.d.ts.map +1 -1
- package/lib/typescript/src/components/TourTooltip.d.ts.map +1 -1
- package/lib/typescript/src/components/TourZone.d.ts +19 -1
- package/lib/typescript/src/components/TourZone.d.ts.map +1 -1
- package/lib/typescript/src/constants/defaults.d.ts +10 -0
- package/lib/typescript/src/constants/defaults.d.ts.map +1 -1
- package/lib/typescript/src/context/TourContext.d.ts +3 -0
- package/lib/typescript/src/context/TourContext.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useTourScrollView.d.ts +65 -0
- package/lib/typescript/src/hooks/useTourScrollView.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types/index.d.ts +296 -1
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/storage.d.ts +51 -0
- package/lib/typescript/src/utils/storage.d.ts.map +1 -0
- package/package.json +173 -171
- package/src/components/TourOverlay.tsx +45 -2
- package/src/components/TourProvider.tsx +408 -56
- package/src/components/TourTooltip.tsx +144 -71
- package/src/components/TourZone.tsx +238 -140
- package/src/constants/defaults.ts +51 -0
- package/src/context/TourContext.ts +4 -0
- package/src/hooks/useTour.ts +1 -1
- package/src/hooks/useTourScrollView.ts +111 -0
- package/src/index.tsx +27 -0
- package/src/types/index.ts +306 -1
- package/src/utils/storage.ts +226 -0
|
@@ -13,11 +13,74 @@ import Animated, {
|
|
|
13
13
|
Extrapolation,
|
|
14
14
|
} from 'react-native-reanimated';
|
|
15
15
|
import { useTour } from '../hooks/useTour';
|
|
16
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
CardProps,
|
|
18
|
+
InternalTourContextType,
|
|
19
|
+
TooltipStyles,
|
|
20
|
+
} from '../types';
|
|
17
21
|
import { DEFAULT_LABELS } from '../constants/defaults';
|
|
18
22
|
|
|
19
23
|
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');
|
|
20
24
|
|
|
25
|
+
const getDynamicStyles = (tooltipStyles?: TooltipStyles) => {
|
|
26
|
+
const defaultStyles = {
|
|
27
|
+
backgroundColor: tooltipStyles?.backgroundColor || 'white',
|
|
28
|
+
borderRadius: tooltipStyles?.borderRadius || 12,
|
|
29
|
+
titleColor: tooltipStyles?.titleColor || '#000',
|
|
30
|
+
descriptionColor: tooltipStyles?.descriptionColor || '#444',
|
|
31
|
+
primaryButtonColor: tooltipStyles?.primaryButtonColor || '#007AFF',
|
|
32
|
+
primaryButtonTextColor: tooltipStyles?.primaryButtonTextColor || '#fff',
|
|
33
|
+
primaryButtonBorderRadius: tooltipStyles?.primaryButtonBorderRadius || 25,
|
|
34
|
+
skipButtonTextColor: tooltipStyles?.skipButtonTextColor || '#666',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return StyleSheet.create({
|
|
38
|
+
cardStyle: {
|
|
39
|
+
backgroundColor: defaultStyles.backgroundColor,
|
|
40
|
+
borderRadius: defaultStyles.borderRadius,
|
|
41
|
+
padding: 20,
|
|
42
|
+
minHeight: 120,
|
|
43
|
+
...(tooltipStyles?.containerStyle || {}),
|
|
44
|
+
},
|
|
45
|
+
title: {
|
|
46
|
+
fontSize: 18,
|
|
47
|
+
fontWeight: 'bold',
|
|
48
|
+
color: defaultStyles.titleColor,
|
|
49
|
+
flex: 1,
|
|
50
|
+
...(tooltipStyles?.titleStyle || {}),
|
|
51
|
+
},
|
|
52
|
+
description: {
|
|
53
|
+
fontSize: 15,
|
|
54
|
+
color: defaultStyles.descriptionColor,
|
|
55
|
+
marginBottom: 20,
|
|
56
|
+
lineHeight: 22,
|
|
57
|
+
...(tooltipStyles?.descriptionStyle || {}),
|
|
58
|
+
},
|
|
59
|
+
buttonPrimary: {
|
|
60
|
+
backgroundColor: defaultStyles.primaryButtonColor,
|
|
61
|
+
paddingVertical: 10,
|
|
62
|
+
paddingHorizontal: 20,
|
|
63
|
+
borderRadius: defaultStyles.primaryButtonBorderRadius,
|
|
64
|
+
...(tooltipStyles?.primaryButtonStyle || {}),
|
|
65
|
+
},
|
|
66
|
+
primaryButtonText: {
|
|
67
|
+
color: defaultStyles.primaryButtonTextColor,
|
|
68
|
+
fontWeight: 'bold',
|
|
69
|
+
fontSize: 14,
|
|
70
|
+
...(tooltipStyles?.primaryButtonTextStyle || {}),
|
|
71
|
+
},
|
|
72
|
+
skipText: {
|
|
73
|
+
color: defaultStyles.skipButtonTextColor,
|
|
74
|
+
fontWeight: '600',
|
|
75
|
+
...(tooltipStyles?.skipButtonTextStyle || {}),
|
|
76
|
+
},
|
|
77
|
+
buttonText: {
|
|
78
|
+
padding: 8,
|
|
79
|
+
...(tooltipStyles?.skipButtonStyle || {}),
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
|
|
21
84
|
export const TourTooltip = memo(() => {
|
|
22
85
|
const {
|
|
23
86
|
targetX,
|
|
@@ -31,6 +94,7 @@ export const TourTooltip = memo(() => {
|
|
|
31
94
|
stop,
|
|
32
95
|
opacity,
|
|
33
96
|
config,
|
|
97
|
+
orderedStepKeys,
|
|
34
98
|
} = useTour() as InternalTourContextType;
|
|
35
99
|
|
|
36
100
|
const currentStepData = currentStep ? steps[currentStep] : null;
|
|
@@ -38,15 +102,13 @@ export const TourTooltip = memo(() => {
|
|
|
38
102
|
const tooltipHeight = useSharedValue(150);
|
|
39
103
|
const [tooltipWidth] = useState(280);
|
|
40
104
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return keys;
|
|
49
|
-
}, [steps]);
|
|
105
|
+
const dynamicStyles = useMemo(
|
|
106
|
+
() => getDynamicStyles(config?.tooltipStyles),
|
|
107
|
+
[config?.tooltipStyles]
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Use orderedStepKeys from context (consistent with TourProvider's ordering)
|
|
111
|
+
const orderedSteps = orderedStepKeys;
|
|
50
112
|
|
|
51
113
|
const currentIndex = currentStep ? orderedSteps.indexOf(currentStep) : -1;
|
|
52
114
|
const totalSteps = orderedSteps.length;
|
|
@@ -93,8 +155,7 @@ export const TourTooltip = memo(() => {
|
|
|
93
155
|
width: tooltipWidth,
|
|
94
156
|
left: clampedLeft,
|
|
95
157
|
opacity: activeOpacity,
|
|
96
|
-
|
|
97
|
-
backgroundColor: 'white',
|
|
158
|
+
backgroundColor: config?.tooltipStyles?.backgroundColor || 'white',
|
|
98
159
|
transform: [{ translateY: interpolate(activeOpacity, [0, 1], [10, 0]) }],
|
|
99
160
|
};
|
|
100
161
|
|
|
@@ -120,19 +181,41 @@ export const TourTooltip = memo(() => {
|
|
|
120
181
|
}
|
|
121
182
|
};
|
|
122
183
|
|
|
123
|
-
//
|
|
184
|
+
// Build card props for custom renders
|
|
185
|
+
const cardProps: CardProps = {
|
|
186
|
+
step: currentStepData,
|
|
187
|
+
currentStepIndex: currentIndex,
|
|
188
|
+
totalSteps,
|
|
189
|
+
next,
|
|
190
|
+
prev,
|
|
191
|
+
stop,
|
|
192
|
+
isFirst,
|
|
193
|
+
isLast,
|
|
194
|
+
labels: config?.labels,
|
|
195
|
+
required: currentStepData.required,
|
|
196
|
+
completed: currentStepData.completed,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// Priority: Per-step custom card > Global custom card > Default card
|
|
200
|
+
// 1. Per-step custom render (highest priority)
|
|
201
|
+
if (currentStepData.renderCustomCard) {
|
|
202
|
+
return (
|
|
203
|
+
<AnimatedView
|
|
204
|
+
style={[
|
|
205
|
+
styles.container,
|
|
206
|
+
tooltipStyle,
|
|
207
|
+
// Reset styles for custom render so the user has full control
|
|
208
|
+
styles.resetStyle,
|
|
209
|
+
]}
|
|
210
|
+
onLayout={handleTooltipLayout}
|
|
211
|
+
>
|
|
212
|
+
{currentStepData.renderCustomCard(cardProps)}
|
|
213
|
+
</AnimatedView>
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 2. Global custom render
|
|
124
218
|
if (config?.renderCard) {
|
|
125
|
-
const cardProps: CardProps = {
|
|
126
|
-
step: currentStepData,
|
|
127
|
-
currentStepIndex: currentIndex,
|
|
128
|
-
totalSteps,
|
|
129
|
-
next,
|
|
130
|
-
prev,
|
|
131
|
-
stop,
|
|
132
|
-
isFirst,
|
|
133
|
-
isLast,
|
|
134
|
-
labels: config.labels,
|
|
135
|
-
};
|
|
136
219
|
return (
|
|
137
220
|
<AnimatedView
|
|
138
221
|
style={[
|
|
@@ -148,35 +231,55 @@ export const TourTooltip = memo(() => {
|
|
|
148
231
|
);
|
|
149
232
|
}
|
|
150
233
|
|
|
151
|
-
// Default Render
|
|
234
|
+
// 3. Default Render
|
|
152
235
|
const labels = { ...DEFAULT_LABELS, ...config?.labels };
|
|
153
236
|
const labelNext = isLast ? labels.finish : labels.next;
|
|
154
237
|
const labelSkip = labels.skip;
|
|
155
238
|
|
|
239
|
+
const isRequired = currentStepData.required === true;
|
|
240
|
+
const isNextDisabled = currentStepData.completed === false;
|
|
241
|
+
|
|
156
242
|
return (
|
|
157
243
|
<AnimatedView
|
|
158
|
-
|
|
159
|
-
style={[styles.container, styles.cardStyle, tooltipStyle]}
|
|
244
|
+
style={[styles.container, dynamicStyles.cardStyle, tooltipStyle]}
|
|
160
245
|
onLayout={handleTooltipLayout}
|
|
161
246
|
>
|
|
162
247
|
<View style={styles.header}>
|
|
163
|
-
<Text style={
|
|
248
|
+
<Text style={dynamicStyles.title}>
|
|
249
|
+
{currentStepData.name || 'Step'}
|
|
250
|
+
</Text>
|
|
164
251
|
<Text style={styles.stepIndicator}>
|
|
165
252
|
{currentIndex + 1} / {totalSteps}
|
|
166
253
|
</Text>
|
|
167
254
|
</View>
|
|
168
|
-
<Text style={
|
|
255
|
+
<Text style={dynamicStyles.description}>
|
|
256
|
+
{currentStepData.description}
|
|
257
|
+
</Text>
|
|
169
258
|
|
|
170
259
|
<View style={styles.footer}>
|
|
171
|
-
{!isLast && (
|
|
172
|
-
<TouchableOpacity onPress={stop} style={
|
|
173
|
-
<Text style={
|
|
260
|
+
{!isLast && !isRequired && (
|
|
261
|
+
<TouchableOpacity onPress={stop} style={dynamicStyles.buttonText}>
|
|
262
|
+
<Text style={dynamicStyles.skipText}>{labelSkip}</Text>
|
|
174
263
|
</TouchableOpacity>
|
|
175
264
|
)}
|
|
176
|
-
{isLast && <View style={styles.spacer} />}
|
|
265
|
+
{(isLast || isRequired) && <View style={styles.spacer} />}
|
|
177
266
|
|
|
178
|
-
<TouchableOpacity
|
|
179
|
-
|
|
267
|
+
<TouchableOpacity
|
|
268
|
+
onPress={isNextDisabled ? undefined : next}
|
|
269
|
+
disabled={isNextDisabled}
|
|
270
|
+
style={[
|
|
271
|
+
dynamicStyles.buttonPrimary,
|
|
272
|
+
isNextDisabled && styles.disabledButton,
|
|
273
|
+
]}
|
|
274
|
+
>
|
|
275
|
+
<Text
|
|
276
|
+
style={[
|
|
277
|
+
dynamicStyles.primaryButtonText,
|
|
278
|
+
isNextDisabled && styles.disabledButtonText,
|
|
279
|
+
]}
|
|
280
|
+
>
|
|
281
|
+
{labelNext}
|
|
282
|
+
</Text>
|
|
180
283
|
</TouchableOpacity>
|
|
181
284
|
</View>
|
|
182
285
|
</AnimatedView>
|
|
@@ -193,12 +296,6 @@ const styles = StyleSheet.create({
|
|
|
193
296
|
elevation: 8,
|
|
194
297
|
zIndex: 999,
|
|
195
298
|
},
|
|
196
|
-
cardStyle: {
|
|
197
|
-
backgroundColor: 'white', // Ensure this is solid white
|
|
198
|
-
borderRadius: 12,
|
|
199
|
-
padding: 20,
|
|
200
|
-
minHeight: 120,
|
|
201
|
-
},
|
|
202
299
|
header: {
|
|
203
300
|
flexDirection: 'row',
|
|
204
301
|
justifyContent: 'space-between',
|
|
@@ -208,41 +305,11 @@ const styles = StyleSheet.create({
|
|
|
208
305
|
fontSize: 12,
|
|
209
306
|
color: '#999',
|
|
210
307
|
},
|
|
211
|
-
title: {
|
|
212
|
-
fontSize: 18,
|
|
213
|
-
fontWeight: 'bold',
|
|
214
|
-
color: '#000',
|
|
215
|
-
flex: 1,
|
|
216
|
-
},
|
|
217
|
-
description: {
|
|
218
|
-
fontSize: 15,
|
|
219
|
-
color: '#444',
|
|
220
|
-
marginBottom: 20,
|
|
221
|
-
lineHeight: 22,
|
|
222
|
-
},
|
|
223
308
|
footer: {
|
|
224
309
|
flexDirection: 'row',
|
|
225
310
|
justifyContent: 'space-between',
|
|
226
311
|
alignItems: 'center',
|
|
227
312
|
},
|
|
228
|
-
buttonText: {
|
|
229
|
-
padding: 8,
|
|
230
|
-
},
|
|
231
|
-
skipText: {
|
|
232
|
-
color: '#666',
|
|
233
|
-
fontWeight: '600',
|
|
234
|
-
},
|
|
235
|
-
buttonPrimary: {
|
|
236
|
-
backgroundColor: '#007AFF',
|
|
237
|
-
paddingVertical: 10,
|
|
238
|
-
paddingHorizontal: 20,
|
|
239
|
-
borderRadius: 25,
|
|
240
|
-
},
|
|
241
|
-
primaryButtonText: {
|
|
242
|
-
color: '#fff',
|
|
243
|
-
fontWeight: 'bold',
|
|
244
|
-
fontSize: 14,
|
|
245
|
-
},
|
|
246
313
|
resetStyle: {
|
|
247
314
|
backgroundColor: 'transparent',
|
|
248
315
|
shadowOpacity: 0,
|
|
@@ -253,4 +320,10 @@ const styles = StyleSheet.create({
|
|
|
253
320
|
spacer: {
|
|
254
321
|
width: 10,
|
|
255
322
|
},
|
|
323
|
+
disabledButton: {
|
|
324
|
+
opacity: 0.4,
|
|
325
|
+
},
|
|
326
|
+
disabledButtonText: {
|
|
327
|
+
opacity: 0.7,
|
|
328
|
+
},
|
|
256
329
|
});
|