react-native-lumen 1.0.0 → 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 -63
- package/lib/module/components/TourProvider.js.map +1 -1
- package/lib/module/components/TourTooltip.js +121 -79
- 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 +409 -57
- package/src/components/TourTooltip.tsx +151 -74
- package/src/components/TourZone.tsx +238 -141
- 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,32 +181,48 @@ 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={[
|
|
139
222
|
styles.container,
|
|
140
223
|
tooltipStyle,
|
|
141
224
|
// Reset styles for custom render so the user has full control
|
|
142
|
-
|
|
143
|
-
backgroundColor: 'transparent',
|
|
144
|
-
shadowOpacity: 0,
|
|
145
|
-
elevation: 0,
|
|
146
|
-
padding: 0,
|
|
147
|
-
borderRadius: 0,
|
|
148
|
-
},
|
|
225
|
+
styles.resetStyle,
|
|
149
226
|
]}
|
|
150
227
|
onLayout={handleTooltipLayout}
|
|
151
228
|
>
|
|
@@ -154,35 +231,55 @@ export const TourTooltip = memo(() => {
|
|
|
154
231
|
);
|
|
155
232
|
}
|
|
156
233
|
|
|
157
|
-
// Default Render
|
|
234
|
+
// 3. Default Render
|
|
158
235
|
const labels = { ...DEFAULT_LABELS, ...config?.labels };
|
|
159
236
|
const labelNext = isLast ? labels.finish : labels.next;
|
|
160
237
|
const labelSkip = labels.skip;
|
|
161
238
|
|
|
239
|
+
const isRequired = currentStepData.required === true;
|
|
240
|
+
const isNextDisabled = currentStepData.completed === false;
|
|
241
|
+
|
|
162
242
|
return (
|
|
163
243
|
<AnimatedView
|
|
164
|
-
|
|
165
|
-
style={[styles.container, styles.cardStyle, tooltipStyle]}
|
|
244
|
+
style={[styles.container, dynamicStyles.cardStyle, tooltipStyle]}
|
|
166
245
|
onLayout={handleTooltipLayout}
|
|
167
246
|
>
|
|
168
247
|
<View style={styles.header}>
|
|
169
|
-
<Text style={
|
|
248
|
+
<Text style={dynamicStyles.title}>
|
|
249
|
+
{currentStepData.name || 'Step'}
|
|
250
|
+
</Text>
|
|
170
251
|
<Text style={styles.stepIndicator}>
|
|
171
252
|
{currentIndex + 1} / {totalSteps}
|
|
172
253
|
</Text>
|
|
173
254
|
</View>
|
|
174
|
-
<Text style={
|
|
255
|
+
<Text style={dynamicStyles.description}>
|
|
256
|
+
{currentStepData.description}
|
|
257
|
+
</Text>
|
|
175
258
|
|
|
176
259
|
<View style={styles.footer}>
|
|
177
|
-
{!isLast && (
|
|
178
|
-
<TouchableOpacity onPress={stop} style={
|
|
179
|
-
<Text style={
|
|
260
|
+
{!isLast && !isRequired && (
|
|
261
|
+
<TouchableOpacity onPress={stop} style={dynamicStyles.buttonText}>
|
|
262
|
+
<Text style={dynamicStyles.skipText}>{labelSkip}</Text>
|
|
180
263
|
</TouchableOpacity>
|
|
181
264
|
)}
|
|
182
|
-
{isLast && <View style={
|
|
265
|
+
{(isLast || isRequired) && <View style={styles.spacer} />}
|
|
183
266
|
|
|
184
|
-
<TouchableOpacity
|
|
185
|
-
|
|
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>
|
|
186
283
|
</TouchableOpacity>
|
|
187
284
|
</View>
|
|
188
285
|
</AnimatedView>
|
|
@@ -199,12 +296,6 @@ const styles = StyleSheet.create({
|
|
|
199
296
|
elevation: 8,
|
|
200
297
|
zIndex: 999,
|
|
201
298
|
},
|
|
202
|
-
cardStyle: {
|
|
203
|
-
backgroundColor: 'white', // Ensure this is solid white
|
|
204
|
-
borderRadius: 12,
|
|
205
|
-
padding: 20,
|
|
206
|
-
minHeight: 120,
|
|
207
|
-
},
|
|
208
299
|
header: {
|
|
209
300
|
flexDirection: 'row',
|
|
210
301
|
justifyContent: 'space-between',
|
|
@@ -214,39 +305,25 @@ const styles = StyleSheet.create({
|
|
|
214
305
|
fontSize: 12,
|
|
215
306
|
color: '#999',
|
|
216
307
|
},
|
|
217
|
-
title: {
|
|
218
|
-
fontSize: 18,
|
|
219
|
-
fontWeight: 'bold',
|
|
220
|
-
color: '#000',
|
|
221
|
-
flex: 1,
|
|
222
|
-
},
|
|
223
|
-
description: {
|
|
224
|
-
fontSize: 15,
|
|
225
|
-
color: '#444',
|
|
226
|
-
marginBottom: 20,
|
|
227
|
-
lineHeight: 22,
|
|
228
|
-
},
|
|
229
308
|
footer: {
|
|
230
309
|
flexDirection: 'row',
|
|
231
310
|
justifyContent: 'space-between',
|
|
232
311
|
alignItems: 'center',
|
|
233
312
|
},
|
|
234
|
-
|
|
235
|
-
|
|
313
|
+
resetStyle: {
|
|
314
|
+
backgroundColor: 'transparent',
|
|
315
|
+
shadowOpacity: 0,
|
|
316
|
+
elevation: 0,
|
|
317
|
+
padding: 0,
|
|
318
|
+
borderRadius: 0,
|
|
236
319
|
},
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
fontWeight: '600',
|
|
320
|
+
spacer: {
|
|
321
|
+
width: 10,
|
|
240
322
|
},
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
paddingVertical: 10,
|
|
244
|
-
paddingHorizontal: 20,
|
|
245
|
-
borderRadius: 25,
|
|
323
|
+
disabledButton: {
|
|
324
|
+
opacity: 0.4,
|
|
246
325
|
},
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
fontWeight: 'bold',
|
|
250
|
-
fontSize: 14,
|
|
326
|
+
disabledButtonText: {
|
|
327
|
+
opacity: 0.7,
|
|
251
328
|
},
|
|
252
329
|
});
|