@korsolutions/guidon 1.0.0 → 1.0.2
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 +11 -11
- package/dist/commonjs/babel.config.js +15 -0
- package/dist/commonjs/babel.config.js.map +1 -0
- package/dist/commonjs/bob.config.js +11 -0
- package/dist/commonjs/bob.config.js.map +1 -0
- package/dist/commonjs/components/GuidonOverlay.js +206 -0
- package/dist/commonjs/components/GuidonOverlay.js.map +1 -0
- package/dist/commonjs/components/GuidonProvider.js +157 -0
- package/dist/commonjs/components/GuidonProvider.js.map +1 -0
- package/dist/commonjs/components/GuidonTarget.js +108 -0
- package/dist/commonjs/components/GuidonTarget.js.map +1 -0
- package/dist/commonjs/components/GuidonTooltip.js +422 -0
- package/dist/commonjs/components/GuidonTooltip.js.map +1 -0
- package/dist/commonjs/components/index.js +40 -0
- package/dist/commonjs/components/index.js.map +1 -0
- package/dist/commonjs/hooks/index.js +13 -0
- package/dist/commonjs/hooks/index.js.map +1 -0
- package/dist/commonjs/hooks/useGuidonRef.js +132 -0
- package/dist/commonjs/hooks/useGuidonRef.js.map +1 -0
- package/dist/commonjs/index.js +143 -0
- package/dist/commonjs/index.js.map +1 -0
- package/dist/commonjs/package.json +1 -0
- package/dist/commonjs/persistence/adapters.js +213 -0
- package/dist/commonjs/persistence/adapters.js.map +1 -0
- package/dist/commonjs/persistence/hooks.js +153 -0
- package/dist/commonjs/persistence/hooks.js.map +1 -0
- package/dist/commonjs/persistence/index.js +28 -0
- package/dist/commonjs/persistence/index.js.map +1 -0
- package/dist/commonjs/store.js +305 -0
- package/dist/commonjs/store.js.map +1 -0
- package/dist/commonjs/tsconfig.json +32 -0
- package/dist/commonjs/types.js +6 -0
- package/dist/commonjs/types.js.map +1 -0
- package/dist/module/babel.config.js +15 -0
- package/dist/module/babel.config.js.map +1 -0
- package/dist/module/bob.config.js +11 -0
- package/dist/module/bob.config.js.map +1 -0
- package/dist/module/components/GuidonOverlay.js +201 -0
- package/dist/module/components/GuidonOverlay.js.map +1 -0
- package/dist/module/components/GuidonProvider.js +152 -0
- package/dist/module/components/GuidonProvider.js.map +1 -0
- package/dist/module/components/GuidonTarget.js +104 -0
- package/dist/module/components/GuidonTarget.js.map +1 -0
- package/dist/module/components/GuidonTooltip.js +417 -0
- package/dist/module/components/GuidonTooltip.js.map +1 -0
- package/dist/module/components/index.js +7 -0
- package/dist/module/components/index.js.map +1 -0
- package/dist/module/hooks/index.js +4 -0
- package/dist/module/hooks/index.js.map +1 -0
- package/dist/module/hooks/useGuidonRef.js +129 -0
- package/dist/module/hooks/useGuidonRef.js.map +1 -0
- package/dist/module/index.js +17 -0
- package/dist/module/index.js.map +1 -0
- package/dist/module/package.json +1 -0
- package/dist/module/persistence/adapters.js +203 -0
- package/dist/module/persistence/adapters.js.map +1 -0
- package/dist/module/persistence/hooks.js +148 -0
- package/dist/module/persistence/hooks.js.map +1 -0
- package/dist/module/persistence/index.js +5 -0
- package/dist/module/persistence/index.js.map +1 -0
- package/dist/module/store.js +295 -0
- package/dist/module/store.js.map +1 -0
- package/dist/module/tsconfig.json +32 -0
- package/dist/module/types.js +4 -0
- package/dist/module/types.js.map +1 -0
- package/dist/typescript/commonjs/components/GuidonOverlay.d.ts +9 -0
- package/dist/typescript/commonjs/components/GuidonOverlay.d.ts.map +1 -0
- package/dist/typescript/commonjs/components/GuidonProvider.d.ts +14 -0
- package/dist/typescript/commonjs/components/GuidonProvider.d.ts.map +1 -0
- package/dist/typescript/commonjs/components/GuidonTarget.d.ts +7 -0
- package/dist/typescript/commonjs/components/GuidonTarget.d.ts.map +1 -0
- package/dist/typescript/commonjs/components/GuidonTooltip.d.ts +24 -0
- package/dist/typescript/commonjs/components/GuidonTooltip.d.ts.map +1 -0
- package/dist/typescript/commonjs/components/index.d.ts +5 -0
- package/dist/typescript/commonjs/components/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/hooks/index.d.ts +2 -0
- package/dist/typescript/commonjs/hooks/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/hooks/useGuidonRef.d.ts +35 -0
- package/dist/typescript/commonjs/hooks/useGuidonRef.d.ts.map +1 -0
- package/dist/typescript/commonjs/index.d.ts +7 -0
- package/dist/typescript/commonjs/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/package.json +1 -0
- package/dist/typescript/commonjs/persistence/adapters.d.ts +57 -0
- package/dist/typescript/commonjs/persistence/adapters.d.ts.map +1 -0
- package/dist/typescript/commonjs/persistence/hooks.d.ts +29 -0
- package/dist/typescript/commonjs/persistence/hooks.d.ts.map +1 -0
- package/dist/typescript/commonjs/persistence/index.d.ts +3 -0
- package/dist/typescript/commonjs/persistence/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/store.d.ts +89 -0
- package/dist/typescript/commonjs/store.d.ts.map +1 -0
- package/dist/{index-D_JFvCIg.d.mts → typescript/commonjs/types.d.ts} +40 -104
- package/dist/typescript/commonjs/types.d.ts.map +1 -0
- package/dist/typescript/module/components/GuidonOverlay.d.ts +9 -0
- package/dist/typescript/module/components/GuidonOverlay.d.ts.map +1 -0
- package/dist/typescript/module/components/GuidonProvider.d.ts +14 -0
- package/dist/typescript/module/components/GuidonProvider.d.ts.map +1 -0
- package/dist/typescript/module/components/GuidonTarget.d.ts +7 -0
- package/dist/typescript/module/components/GuidonTarget.d.ts.map +1 -0
- package/dist/typescript/module/components/GuidonTooltip.d.ts +24 -0
- package/dist/typescript/module/components/GuidonTooltip.d.ts.map +1 -0
- package/dist/typescript/module/components/index.d.ts +5 -0
- package/dist/typescript/module/components/index.d.ts.map +1 -0
- package/dist/typescript/module/hooks/index.d.ts +2 -0
- package/dist/typescript/module/hooks/index.d.ts.map +1 -0
- package/dist/typescript/module/hooks/useGuidonRef.d.ts +35 -0
- package/dist/typescript/module/hooks/useGuidonRef.d.ts.map +1 -0
- package/dist/typescript/module/index.d.ts +7 -0
- package/dist/typescript/module/index.d.ts.map +1 -0
- package/dist/typescript/module/package.json +1 -0
- package/dist/typescript/module/persistence/adapters.d.ts +57 -0
- package/dist/typescript/module/persistence/adapters.d.ts.map +1 -0
- package/dist/typescript/module/persistence/hooks.d.ts +29 -0
- package/dist/typescript/module/persistence/hooks.d.ts.map +1 -0
- package/dist/typescript/module/persistence/index.d.ts +3 -0
- package/dist/typescript/module/persistence/index.d.ts.map +1 -0
- package/dist/typescript/module/store.d.ts +89 -0
- package/dist/typescript/module/store.d.ts.map +1 -0
- package/dist/{index-D_JFvCIg.d.ts → typescript/module/types.d.ts} +40 -104
- package/dist/typescript/module/types.d.ts.map +1 -0
- package/package.json +25 -13
- package/src/babel.config.js +18 -0
- package/src/bob.config.js +14 -0
- package/src/components/GuidonOverlay.tsx +60 -4
- package/src/components/GuidonProvider.tsx +29 -1
- package/src/components/GuidonTarget.tsx +26 -16
- package/src/components/GuidonTooltip.tsx +143 -9
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useGuidonRef.ts +154 -0
- package/src/index.ts +6 -0
- package/src/store.ts +40 -0
- package/src/tsconfig.json +32 -0
- package/src/types.ts +32 -2
- package/dist/index.d.mts +0 -128
- package/dist/index.d.ts +0 -128
- package/dist/index.js +0 -1098
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -1073
- package/dist/index.mjs.map +0 -1
- package/dist/persistence/index.d.mts +0 -2
- package/dist/persistence/index.d.ts +0 -2
- package/dist/persistence/index.js +0 -300
- package/dist/persistence/index.js.map +0 -1
- package/dist/persistence/index.mjs +0 -291
- package/dist/persistence/index.mjs.map +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { GuidonConfig, GuidonStore, TargetMeasurements } from "./types";
|
|
2
|
+
export declare const useGuidonStore: import("zustand").UseBoundStore<import("zustand").StoreApi<GuidonStore>>;
|
|
3
|
+
/**
|
|
4
|
+
* Guidon API for external control
|
|
5
|
+
* Can be used outside of React components
|
|
6
|
+
*/
|
|
7
|
+
export declare const Guidon: {
|
|
8
|
+
/**
|
|
9
|
+
* Configure the walkthrough with steps and options
|
|
10
|
+
*/
|
|
11
|
+
configure: (config: GuidonConfig) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Start the walkthrough
|
|
14
|
+
*/
|
|
15
|
+
start: () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Go to the next step
|
|
18
|
+
*/
|
|
19
|
+
next: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Go to the previous step
|
|
22
|
+
*/
|
|
23
|
+
previous: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* Go to a specific step by index
|
|
26
|
+
*/
|
|
27
|
+
goToStep: (index: number) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Skip the walkthrough
|
|
30
|
+
*/
|
|
31
|
+
skip: () => void;
|
|
32
|
+
/**
|
|
33
|
+
* Complete the walkthrough
|
|
34
|
+
*/
|
|
35
|
+
complete: () => void;
|
|
36
|
+
/**
|
|
37
|
+
* Reset the walkthrough to initial state
|
|
38
|
+
*/
|
|
39
|
+
reset: () => void;
|
|
40
|
+
/**
|
|
41
|
+
* Check if the walkthrough is currently active
|
|
42
|
+
*/
|
|
43
|
+
isActive: () => boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Check if the walkthrough has been completed
|
|
46
|
+
*/
|
|
47
|
+
isCompleted: () => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Get the current step index
|
|
50
|
+
*/
|
|
51
|
+
getCurrentStepIndex: () => number;
|
|
52
|
+
/**
|
|
53
|
+
* Get the current step
|
|
54
|
+
*/
|
|
55
|
+
getCurrentStep: () => import("./types").GuidonStep | null;
|
|
56
|
+
/**
|
|
57
|
+
* Get all steps
|
|
58
|
+
*/
|
|
59
|
+
getSteps: () => import("./types").GuidonStep[];
|
|
60
|
+
/**
|
|
61
|
+
* Subscribe to store changes
|
|
62
|
+
*/
|
|
63
|
+
subscribe: (listener: (state: GuidonStore, prevState: GuidonStore) => void) => () => void;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Hook selectors for common use cases
|
|
67
|
+
*/
|
|
68
|
+
export declare const useGuidonActive: () => boolean;
|
|
69
|
+
export declare const useGuidonStep: () => import("./types").GuidonStep | null;
|
|
70
|
+
export declare const useGuidonProgress: () => {
|
|
71
|
+
currentStep: number;
|
|
72
|
+
totalSteps: number;
|
|
73
|
+
percentage: number;
|
|
74
|
+
};
|
|
75
|
+
export declare const useTargetMeasurements: (targetId: string) => TargetMeasurements;
|
|
76
|
+
/**
|
|
77
|
+
* Hook to check if the guidon is waiting for a target element to mount
|
|
78
|
+
* Returns null if not active, not waiting, or if it's a floating step
|
|
79
|
+
*/
|
|
80
|
+
export declare const useWaitingState: () => {
|
|
81
|
+
isWaiting: boolean;
|
|
82
|
+
targetId: string | null;
|
|
83
|
+
message: string | null;
|
|
84
|
+
} | null;
|
|
85
|
+
/**
|
|
86
|
+
* Hook to check if the current step is a floating step (no target element)
|
|
87
|
+
*/
|
|
88
|
+
export declare const useIsFloatingStep: () => boolean;
|
|
89
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAcjB,eAAO,MAAM,cAAc,0EA+HxB,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB;;OAEG;wBACiB,YAAY;IAIhC;;OAEG;;IAKH;;OAEG;;IAKH;;OAEG;;IAKH;;OAEG;sBACe,MAAM;IAIxB;;OAEG;;IAKH;;OAEG;;IAKH;;OAEG;;IAKH;;OAEG;;IAKH;;OAEG;;IAKH;;OAEG;;IAKH;;OAEG;;IAMH;;OAEG;;IAKH;;OAEG;;CAEJ,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,eAC4B,CAAC;AAEzD,eAAO,MAAM,aAAa,2CAItB,CAAC;AAEL,eAAO,MAAM,iBAAiB;;;;CAOzB,CAAC;AAEN,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,uBAGnD,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;QAiBxB,CAAC;AAEL;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAI1B,CAAC"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
3
2
|
/**
|
|
4
3
|
* Position of tooltip relative to the highlighted element
|
|
5
4
|
*/
|
|
6
|
-
type TooltipPosition = 'top' | 'bottom' | 'left' | 'right' | 'auto';
|
|
5
|
+
export type TooltipPosition = 'top' | 'bottom' | 'left' | 'right' | 'auto';
|
|
6
|
+
/**
|
|
7
|
+
* Position for floating tooltips (steps without a target element)
|
|
8
|
+
*/
|
|
9
|
+
export type FloatingPosition = 'center' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
7
10
|
/**
|
|
8
11
|
* Defines the measurements of a target element
|
|
9
12
|
*/
|
|
10
|
-
interface TargetMeasurements {
|
|
13
|
+
export interface TargetMeasurements {
|
|
11
14
|
x: number;
|
|
12
15
|
y: number;
|
|
13
16
|
width: number;
|
|
@@ -16,28 +19,40 @@ interface TargetMeasurements {
|
|
|
16
19
|
/**
|
|
17
20
|
* A single step in the guidon
|
|
18
21
|
*/
|
|
19
|
-
interface GuidonStep {
|
|
22
|
+
export interface GuidonStep {
|
|
20
23
|
/** Unique identifier for this step */
|
|
21
24
|
id: string;
|
|
22
|
-
/**
|
|
23
|
-
|
|
25
|
+
/**
|
|
26
|
+
* ID of the target element to highlight.
|
|
27
|
+
* If omitted, this becomes a floating tooltip step.
|
|
28
|
+
*/
|
|
29
|
+
targetId?: string;
|
|
24
30
|
/** Title displayed in the tooltip */
|
|
25
31
|
title: string;
|
|
26
32
|
/** Description/content displayed in the tooltip */
|
|
27
33
|
description: string;
|
|
28
34
|
/** Preferred position of the tooltip */
|
|
29
35
|
tooltipPosition?: TooltipPosition;
|
|
36
|
+
/**
|
|
37
|
+
* Position for floating tooltips (only used when targetId is not provided)
|
|
38
|
+
* @default 'center'
|
|
39
|
+
*/
|
|
40
|
+
floatingPosition?: FloatingPosition;
|
|
30
41
|
/** Custom content to render in the tooltip */
|
|
31
42
|
customContent?: ReactNode;
|
|
32
43
|
/** Called when this step becomes active */
|
|
33
44
|
onStepEnter?: () => void;
|
|
34
45
|
/** Called when leaving this step */
|
|
35
46
|
onStepExit?: () => void;
|
|
47
|
+
/** Optional message to display while waiting for target to mount */
|
|
48
|
+
waitingMessage?: string;
|
|
49
|
+
/** Timeout in ms before auto-skipping this step (0 = no timeout) */
|
|
50
|
+
waitTimeout?: number;
|
|
36
51
|
}
|
|
37
52
|
/**
|
|
38
53
|
* Theme configuration for guidon styling
|
|
39
54
|
*/
|
|
40
|
-
interface GuidonTheme {
|
|
55
|
+
export interface GuidonTheme {
|
|
41
56
|
/** Color of the backdrop overlay */
|
|
42
57
|
backdropColor?: string;
|
|
43
58
|
/** Opacity of the backdrop (0-1) */
|
|
@@ -64,7 +79,7 @@ interface GuidonTheme {
|
|
|
64
79
|
/**
|
|
65
80
|
* State of a specific guidon tour
|
|
66
81
|
*/
|
|
67
|
-
interface GuidonProgress {
|
|
82
|
+
export interface GuidonProgress {
|
|
68
83
|
/** Unique identifier for the guidon */
|
|
69
84
|
guidonId: string;
|
|
70
85
|
/** Whether this guidon has been completed */
|
|
@@ -80,7 +95,7 @@ interface GuidonProgress {
|
|
|
80
95
|
* Persistence adapter interface for saving/loading guidon progress
|
|
81
96
|
* Implement this interface to connect the guidon to your backend
|
|
82
97
|
*/
|
|
83
|
-
interface GuidonPersistenceAdapter {
|
|
98
|
+
export interface GuidonPersistenceAdapter {
|
|
84
99
|
/**
|
|
85
100
|
* Load the progress for a specific guidon
|
|
86
101
|
* @param guidonId - Unique identifier for the guidon
|
|
@@ -106,7 +121,7 @@ interface GuidonPersistenceAdapter {
|
|
|
106
121
|
/**
|
|
107
122
|
* Configuration for a guidon
|
|
108
123
|
*/
|
|
109
|
-
interface GuidonConfig {
|
|
124
|
+
export interface GuidonConfig {
|
|
110
125
|
/** Unique identifier for this guidon */
|
|
111
126
|
id: string;
|
|
112
127
|
/** Steps in the guidon */
|
|
@@ -125,17 +140,19 @@ interface GuidonConfig {
|
|
|
125
140
|
/**
|
|
126
141
|
* Labels for tooltip buttons
|
|
127
142
|
*/
|
|
128
|
-
interface GuidonTooltipLabels {
|
|
143
|
+
export interface GuidonTooltipLabels {
|
|
129
144
|
next?: string;
|
|
130
145
|
previous?: string;
|
|
131
146
|
skip?: string;
|
|
132
147
|
finish?: string;
|
|
133
148
|
stepOf?: (current: number, total: number) => string;
|
|
149
|
+
/** Default message when waiting for target to mount */
|
|
150
|
+
waitingDefault?: string;
|
|
134
151
|
}
|
|
135
152
|
/**
|
|
136
153
|
* Props for custom tooltip renderer
|
|
137
154
|
*/
|
|
138
|
-
interface GuidonTooltipRenderProps {
|
|
155
|
+
export interface GuidonTooltipRenderProps {
|
|
139
156
|
step: GuidonStep;
|
|
140
157
|
currentIndex: number;
|
|
141
158
|
totalSteps: number;
|
|
@@ -146,7 +163,7 @@ interface GuidonTooltipRenderProps {
|
|
|
146
163
|
/**
|
|
147
164
|
* Props for the GuidonProvider component
|
|
148
165
|
*/
|
|
149
|
-
interface GuidonProviderProps {
|
|
166
|
+
export interface GuidonProviderProps {
|
|
150
167
|
children: ReactNode;
|
|
151
168
|
/** Configuration for the guidon */
|
|
152
169
|
config: GuidonConfig;
|
|
@@ -170,7 +187,7 @@ interface GuidonProviderProps {
|
|
|
170
187
|
/**
|
|
171
188
|
* Props for the GuidonTarget component
|
|
172
189
|
*/
|
|
173
|
-
interface GuidonTargetProps {
|
|
190
|
+
export interface GuidonTargetProps {
|
|
174
191
|
children: ReactNode;
|
|
175
192
|
/** Target ID that matches a step's targetId */
|
|
176
193
|
targetId: string;
|
|
@@ -180,7 +197,7 @@ interface GuidonTargetProps {
|
|
|
180
197
|
/**
|
|
181
198
|
* Internal store state
|
|
182
199
|
*/
|
|
183
|
-
interface GuidonState {
|
|
200
|
+
export interface GuidonState {
|
|
184
201
|
/** Currently active guidon config */
|
|
185
202
|
config: GuidonConfig | null;
|
|
186
203
|
/** Whether the guidon is currently active */
|
|
@@ -195,11 +212,15 @@ interface GuidonState {
|
|
|
195
212
|
isLoading: boolean;
|
|
196
213
|
/** Error from persistence operations */
|
|
197
214
|
error: string | null;
|
|
215
|
+
/** Whether the guide is waiting for a target element to mount */
|
|
216
|
+
waitingForTarget: boolean;
|
|
217
|
+
/** The targetId currently being waited for */
|
|
218
|
+
waitingTargetId: string | null;
|
|
198
219
|
}
|
|
199
220
|
/**
|
|
200
221
|
* Internal store actions
|
|
201
222
|
*/
|
|
202
|
-
interface GuidonActions {
|
|
223
|
+
export interface GuidonActions {
|
|
203
224
|
/** Configure the guidon */
|
|
204
225
|
configure: (config: GuidonConfig) => void;
|
|
205
226
|
/** Start the guidon */
|
|
@@ -225,90 +246,5 @@ interface GuidonActions {
|
|
|
225
246
|
/** Set error state */
|
|
226
247
|
setError: (error: string | null) => void;
|
|
227
248
|
}
|
|
228
|
-
type GuidonStore = GuidonState & GuidonActions;
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* No-op adapter that doesn't persist anything
|
|
232
|
-
* Useful for testing or when persistence is not needed
|
|
233
|
-
*/
|
|
234
|
-
declare const createNoopAdapter: () => GuidonPersistenceAdapter;
|
|
235
|
-
/**
|
|
236
|
-
* Memory adapter that stores progress in memory
|
|
237
|
-
* Data is lost when the app is closed
|
|
238
|
-
*/
|
|
239
|
-
declare const createMemoryAdapter: () => GuidonPersistenceAdapter;
|
|
240
|
-
/**
|
|
241
|
-
* localStorage adapter for web
|
|
242
|
-
* Only works in browser environments
|
|
243
|
-
*/
|
|
244
|
-
declare const createLocalStorageAdapter: (keyPrefix?: string) => GuidonPersistenceAdapter;
|
|
245
|
-
/**
|
|
246
|
-
* AsyncStorage adapter for React Native
|
|
247
|
-
* Requires @react-native-async-storage/async-storage to be installed
|
|
248
|
-
*
|
|
249
|
-
* @example
|
|
250
|
-
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
251
|
-
* const adapter = createAsyncStorageAdapter(AsyncStorage);
|
|
252
|
-
*/
|
|
253
|
-
declare const createAsyncStorageAdapter: (asyncStorage: {
|
|
254
|
-
getItem: (key: string) => Promise<string | null>;
|
|
255
|
-
setItem: (key: string, value: string) => Promise<void>;
|
|
256
|
-
removeItem: (key: string) => Promise<void>;
|
|
257
|
-
getAllKeys: () => Promise<readonly string[]>;
|
|
258
|
-
multiGet: (keys: readonly string[]) => Promise<readonly [string, string | null][]>;
|
|
259
|
-
}, keyPrefix?: string) => GuidonPersistenceAdapter;
|
|
260
|
-
/**
|
|
261
|
-
* Create a custom API adapter for backend persistence
|
|
262
|
-
* This is a factory function that creates an adapter based on your API endpoints
|
|
263
|
-
*
|
|
264
|
-
* @example
|
|
265
|
-
* const adapter = createApiAdapter({
|
|
266
|
-
* loadProgress: async (guidonId) => {
|
|
267
|
-
* const response = await fetch(`/api/guidon/${guidonId}`);
|
|
268
|
-
* return response.json();
|
|
269
|
-
* },
|
|
270
|
-
* saveProgress: async (progress) => {
|
|
271
|
-
* await fetch(`/api/guidon/${progress.guidonId}`, {
|
|
272
|
-
* method: 'POST',
|
|
273
|
-
* body: JSON.stringify(progress),
|
|
274
|
-
* });
|
|
275
|
-
* },
|
|
276
|
-
* });
|
|
277
|
-
*/
|
|
278
|
-
declare const createApiAdapter: (handlers: Partial<GuidonPersistenceAdapter>) => GuidonPersistenceAdapter;
|
|
279
|
-
/**
|
|
280
|
-
* Combine multiple adapters (e.g., save to both local and API)
|
|
281
|
-
* Loads from the first adapter that returns data
|
|
282
|
-
* Saves to all adapters
|
|
283
|
-
*/
|
|
284
|
-
declare const createCompositeAdapter: (adapters: GuidonPersistenceAdapter[]) => GuidonPersistenceAdapter;
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Hook to manage guidon's walkthrough progress with a persistence adapter
|
|
288
|
-
*/
|
|
289
|
-
declare function useGuidonPersistence(adapter: GuidonPersistenceAdapter | undefined, guidonId: string): {
|
|
290
|
-
progress: GuidonProgress | null;
|
|
291
|
-
isLoading: boolean;
|
|
292
|
-
error: string | null;
|
|
293
|
-
isCompleted: boolean;
|
|
294
|
-
hasStarted: boolean;
|
|
295
|
-
saveProgress: (newProgress: Omit<GuidonProgress, "guidonId">) => Promise<void>;
|
|
296
|
-
clearProgress: () => Promise<void>;
|
|
297
|
-
markCompleted: () => Promise<void>;
|
|
298
|
-
markStepViewed: (stepIndex: number) => Promise<void>;
|
|
299
|
-
};
|
|
300
|
-
/**
|
|
301
|
-
* Hook to check if a guidon should be shown
|
|
302
|
-
*/
|
|
303
|
-
declare function useShouldShowGuidon(adapter: GuidonPersistenceAdapter | undefined, guidonId: string, options?: {
|
|
304
|
-
/** Show even if completed (for replay) */
|
|
305
|
-
forceShow?: boolean;
|
|
306
|
-
/** Additional condition to check */
|
|
307
|
-
additionalCondition?: () => boolean | Promise<boolean>;
|
|
308
|
-
}): {
|
|
309
|
-
shouldShow: boolean;
|
|
310
|
-
isChecking: boolean;
|
|
311
|
-
isCompleted: boolean;
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
export { type GuidonTargetProps as G, type TargetMeasurements as T, type GuidonTheme as a, type GuidonStep as b, type GuidonProviderProps as c, type GuidonStore as d, type GuidonConfig as e, type GuidonProgress as f, type GuidonPersistenceAdapter as g, type GuidonTooltipLabels as h, type GuidonTooltipRenderProps as i, type TooltipPosition as j, type GuidonState as k, type GuidonActions as l, createNoopAdapter as m, createMemoryAdapter as n, createLocalStorageAdapter as o, createAsyncStorageAdapter as p, createApiAdapter as q, createCompositeAdapter as r, useShouldShowGuidon as s, useGuidonPersistence as u };
|
|
249
|
+
export type GuidonStore = GuidonState & GuidonActions;
|
|
250
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,QAAQ,GACR,KAAK,GACL,QAAQ,GACR,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,8CAA8C;IAC9C,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kCAAkC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mCAAmC;IACnC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,8BAA8B;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAEnE;;;OAGG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IAEhE;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,mCAAmC;IACnC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CAC9D;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB,mCAAmC;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,sDAAsD;IACtD,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,oDAAoD;IACpD,eAAe,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC/D,8BAA8B;IAC9B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,SAAS,CAAC;IAC/D,+BAA+B;IAC/B,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,sCAAsC;IACtC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,WAAW,EAAE,OAAO,CAAC;IACrB,8CAA8C;IAC9C,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACvD,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iEAAiE;IACjE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,8CAA8C;IAC9C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1C,uBAAuB;IACvB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,4BAA4B;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,sBAAsB;IACtB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,uCAAuC;IACvC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC7E,0BAA0B;IAC1B,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,wBAAwB;IACxB,UAAU,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,sBAAsB;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC1C;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@korsolutions/guidon",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A cross-platform walkthrough/onboarding component library for React Native with web support. Features spotlight effects, customizable tooltips, and flexible persistence options. ",
|
|
5
5
|
"repository": "https://github.com/KorSoftwareSolutions/guidon.git",
|
|
6
6
|
"author": "Christian Jimenez <christianjimenezfael@gmail.com>",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
7
|
+
"source": "src/index.ts",
|
|
8
|
+
"main": "dist/commonjs/index.js",
|
|
9
|
+
"module": "dist/module/index.js",
|
|
10
|
+
"types": "dist/typescript/module/index.d.ts",
|
|
11
|
+
"react-native": "src/index.ts",
|
|
10
12
|
"exports": {
|
|
11
13
|
".": {
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/typescript/module/index.d.ts",
|
|
16
|
+
"default": "./dist/module/index.js"
|
|
17
|
+
},
|
|
18
|
+
"require": {
|
|
19
|
+
"types": "./dist/typescript/commonjs/index.d.ts",
|
|
20
|
+
"default": "./dist/commonjs/index.js"
|
|
21
|
+
}
|
|
15
22
|
},
|
|
16
23
|
"./persistence": {
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
"import": {
|
|
25
|
+
"types": "./dist/typescript/module/persistence/index.d.ts",
|
|
26
|
+
"default": "./dist/module/persistence/index.js"
|
|
27
|
+
},
|
|
28
|
+
"require": {
|
|
29
|
+
"types": "./dist/typescript/commonjs/persistence/index.d.ts",
|
|
30
|
+
"default": "./dist/commonjs/persistence/index.js"
|
|
31
|
+
}
|
|
20
32
|
}
|
|
21
33
|
},
|
|
22
34
|
"files": [
|
|
@@ -24,8 +36,8 @@
|
|
|
24
36
|
"src"
|
|
25
37
|
],
|
|
26
38
|
"scripts": {
|
|
27
|
-
"build": "
|
|
28
|
-
"dev": "
|
|
39
|
+
"build": "bob build",
|
|
40
|
+
"dev": "bob build --watch",
|
|
29
41
|
"typecheck": "tsc --noEmit",
|
|
30
42
|
"clean": "rm -rf dist",
|
|
31
43
|
"prepublishOnly": "yarn build"
|
|
@@ -55,10 +67,10 @@
|
|
|
55
67
|
"devDependencies": {
|
|
56
68
|
"@types/react": "^19.2.9",
|
|
57
69
|
"@types/react-native": "^0.73.0",
|
|
70
|
+
"react-native-builder-bob": "^0.40.17",
|
|
58
71
|
"react-native-reanimated": "^4.2.1",
|
|
59
72
|
"react-native-safe-area-context": "^5.6.2",
|
|
60
73
|
"react-native-svg": "^15.15.1",
|
|
61
|
-
"tsup": "^8.5.1",
|
|
62
74
|
"typescript": "^5.0.0",
|
|
63
75
|
"zustand": "^5.0.10"
|
|
64
76
|
},
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module.exports = function (api) {
|
|
2
|
+
api.cache(true);
|
|
3
|
+
|
|
4
|
+
return {
|
|
5
|
+
presets: ["module:react-native-builder-bob/babel-preset"],
|
|
6
|
+
plugins: [
|
|
7
|
+
[
|
|
8
|
+
require.resolve("babel-plugin-module-resolver"),
|
|
9
|
+
{
|
|
10
|
+
root: ["./src"],
|
|
11
|
+
alias: {
|
|
12
|
+
"@": "./src",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -11,7 +11,7 @@ import Animated, {
|
|
|
11
11
|
Easing,
|
|
12
12
|
} from 'react-native-reanimated';
|
|
13
13
|
import Svg, { Defs, Mask, Rect, G } from 'react-native-svg';
|
|
14
|
-
import { useGuidonStore } from '../store';
|
|
14
|
+
import { useGuidonStore, useWaitingState, useIsFloatingStep } from '../store';
|
|
15
15
|
import type { TargetMeasurements, GuidonTheme, GuidonStore } from '../types';
|
|
16
16
|
|
|
17
17
|
const AnimatedSvg = Animated.createAnimatedComponent(Svg);
|
|
@@ -44,6 +44,11 @@ export function GuidonOverlay({
|
|
|
44
44
|
const currentStepIndex = useGuidonStore((state: GuidonStore) => state.currentStepIndex);
|
|
45
45
|
const targetMeasurements = useGuidonStore((state: GuidonStore) => state.targetMeasurements);
|
|
46
46
|
|
|
47
|
+
// Check for floating or waiting states
|
|
48
|
+
const isFloatingStep = useIsFloatingStep();
|
|
49
|
+
const waitingState = useWaitingState();
|
|
50
|
+
const isWaiting = waitingState?.isWaiting ?? false;
|
|
51
|
+
|
|
47
52
|
const mergedTheme = { ...DEFAULT_THEME, ...theme };
|
|
48
53
|
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
|
|
49
54
|
|
|
@@ -54,6 +59,9 @@ export function GuidonOverlay({
|
|
|
54
59
|
? targetMeasurements[currentTargetId]
|
|
55
60
|
: undefined;
|
|
56
61
|
|
|
62
|
+
// Determine if we should show full backdrop (no spotlight cutout)
|
|
63
|
+
const showFullBackdrop = isFloatingStep || isWaiting;
|
|
64
|
+
|
|
57
65
|
// Calculate spotlight dimensions with padding
|
|
58
66
|
const spotlight = useMemo(() => {
|
|
59
67
|
if (!measurements) {
|
|
@@ -68,16 +76,64 @@ export function GuidonOverlay({
|
|
|
68
76
|
}, [measurements, mergedTheme.spotlightPadding]);
|
|
69
77
|
|
|
70
78
|
// Animated styles for fade in/out
|
|
79
|
+
// Show backdrop for: normal steps with measurements, floating steps, or waiting states
|
|
80
|
+
const shouldShow = isActive && (measurements || showFullBackdrop);
|
|
71
81
|
const animatedStyle = useAnimatedStyle(() => {
|
|
72
82
|
return {
|
|
73
|
-
opacity: withTiming(
|
|
83
|
+
opacity: withTiming(shouldShow ? 1 : 0, {
|
|
74
84
|
duration: animationDuration,
|
|
75
85
|
easing: Easing.inOut(Easing.ease),
|
|
76
86
|
}),
|
|
77
87
|
};
|
|
78
|
-
}, [
|
|
88
|
+
}, [shouldShow, animationDuration]);
|
|
89
|
+
|
|
90
|
+
if (!isActive) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Render full backdrop without spotlight for floating steps or waiting states
|
|
95
|
+
if (showFullBackdrop) {
|
|
96
|
+
if (Platform.OS === 'web') {
|
|
97
|
+
return (
|
|
98
|
+
<TouchableWithoutFeedback onPress={onBackdropPress}>
|
|
99
|
+
<Animated.View style={[styles.container, animatedStyle]}>
|
|
100
|
+
<div
|
|
101
|
+
style={{
|
|
102
|
+
position: 'absolute',
|
|
103
|
+
inset: 0,
|
|
104
|
+
backgroundColor: mergedTheme.backdropColor,
|
|
105
|
+
opacity: mergedTheme.backdropOpacity,
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
</Animated.View>
|
|
109
|
+
</TouchableWithoutFeedback>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Native: full backdrop without cutout
|
|
114
|
+
return (
|
|
115
|
+
<TouchableWithoutFeedback onPress={onBackdropPress}>
|
|
116
|
+
<AnimatedSvg
|
|
117
|
+
style={[styles.container, animatedStyle]}
|
|
118
|
+
width={screenWidth}
|
|
119
|
+
height={screenHeight}
|
|
120
|
+
viewBox={`0 0 ${screenWidth} ${screenHeight}`}
|
|
121
|
+
>
|
|
122
|
+
<Rect
|
|
123
|
+
x="0"
|
|
124
|
+
y="0"
|
|
125
|
+
width="100%"
|
|
126
|
+
height="100%"
|
|
127
|
+
fill={mergedTheme.backdropColor}
|
|
128
|
+
fillOpacity={mergedTheme.backdropOpacity}
|
|
129
|
+
/>
|
|
130
|
+
</AnimatedSvg>
|
|
131
|
+
</TouchableWithoutFeedback>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
79
134
|
|
|
80
|
-
|
|
135
|
+
// If we have a target but no measurements yet, don't render anything
|
|
136
|
+
if (!measurements) {
|
|
81
137
|
return null;
|
|
82
138
|
}
|
|
83
139
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useCallback, useRef, createContext, useContext } from 'react';
|
|
2
|
-
import { useGuidonStore } from '../store';
|
|
2
|
+
import { useGuidonStore, useWaitingState } from '../store';
|
|
3
3
|
import { useGuidonPersistence } from '../persistence/hooks';
|
|
4
4
|
import { GuidonOverlay } from './GuidonOverlay';
|
|
5
5
|
import { GuidonTooltip } from './GuidonTooltip';
|
|
@@ -46,9 +46,13 @@ export function GuidonProvider({
|
|
|
46
46
|
const currentStepIndex = useGuidonStore((state: GuidonStore) => state.currentStepIndex);
|
|
47
47
|
const configure = useGuidonStore((state: GuidonStore) => state.configure);
|
|
48
48
|
const start = useGuidonStore((state: GuidonStore) => state.start);
|
|
49
|
+
const next = useGuidonStore((state: GuidonStore) => state.next);
|
|
49
50
|
const skip = useGuidonStore((state: GuidonStore) => state.skip);
|
|
50
51
|
const reset = useGuidonStore((state: GuidonStore) => state.reset);
|
|
51
52
|
|
|
53
|
+
// Check for waiting state (target element not mounted)
|
|
54
|
+
const waitingState = useWaitingState();
|
|
55
|
+
|
|
52
56
|
const {
|
|
53
57
|
isLoading,
|
|
54
58
|
isCompleted: persistedCompleted,
|
|
@@ -106,6 +110,30 @@ export function GuidonProvider({
|
|
|
106
110
|
checkAndStart();
|
|
107
111
|
}, [autoStart, isLoading, persistedCompleted, shouldStart, start]);
|
|
108
112
|
|
|
113
|
+
// Handle wait timeout - auto-skip to next step if waiting too long
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
const currentStep = config.steps[currentStepIndex];
|
|
116
|
+
const waitTimeout = currentStep?.waitTimeout;
|
|
117
|
+
|
|
118
|
+
// Only set timeout if:
|
|
119
|
+
// - We have a timeout configured
|
|
120
|
+
// - The timeout is greater than 0
|
|
121
|
+
// - We are currently waiting for a target
|
|
122
|
+
if (!waitTimeout || waitTimeout <= 0 || !waitingState?.isWaiting) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const timer = setTimeout(() => {
|
|
127
|
+
// Check if we're still waiting when the timeout fires
|
|
128
|
+
const stillWaiting = useGuidonStore.getState().targetMeasurements[currentStep.targetId!] === undefined;
|
|
129
|
+
if (stillWaiting) {
|
|
130
|
+
next(); // Skip to next step
|
|
131
|
+
}
|
|
132
|
+
}, waitTimeout);
|
|
133
|
+
|
|
134
|
+
return () => clearTimeout(timer);
|
|
135
|
+
}, [currentStepIndex, config.steps, waitingState?.isWaiting, next]);
|
|
136
|
+
|
|
109
137
|
const replay = useCallback(async () => {
|
|
110
138
|
if (persistenceAdapter) {
|
|
111
139
|
await clearProgress();
|