@korsolutions/guidon 1.0.1 → 1.0.3

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 (143) hide show
  1. package/dist/commonjs/babel.config.js +15 -0
  2. package/dist/commonjs/babel.config.js.map +1 -0
  3. package/dist/commonjs/bob.config.js +11 -0
  4. package/dist/commonjs/bob.config.js.map +1 -0
  5. package/dist/commonjs/components/GuidonOverlay.js +206 -0
  6. package/dist/commonjs/components/GuidonOverlay.js.map +1 -0
  7. package/dist/commonjs/components/GuidonProvider.js +157 -0
  8. package/dist/commonjs/components/GuidonProvider.js.map +1 -0
  9. package/dist/commonjs/components/GuidonTarget.js +110 -0
  10. package/dist/commonjs/components/GuidonTarget.js.map +1 -0
  11. package/dist/commonjs/components/GuidonTooltip.js +422 -0
  12. package/dist/commonjs/components/GuidonTooltip.js.map +1 -0
  13. package/dist/commonjs/components/index.js +40 -0
  14. package/dist/commonjs/components/index.js.map +1 -0
  15. package/dist/commonjs/hooks/index.js +13 -0
  16. package/dist/commonjs/hooks/index.js.map +1 -0
  17. package/dist/commonjs/hooks/useGuidonRef.js +132 -0
  18. package/dist/commonjs/hooks/useGuidonRef.js.map +1 -0
  19. package/dist/commonjs/index.js +143 -0
  20. package/dist/commonjs/index.js.map +1 -0
  21. package/dist/commonjs/package.json +1 -0
  22. package/dist/commonjs/persistence/adapters.js +213 -0
  23. package/dist/commonjs/persistence/adapters.js.map +1 -0
  24. package/dist/commonjs/persistence/hooks.js +153 -0
  25. package/dist/commonjs/persistence/hooks.js.map +1 -0
  26. package/dist/commonjs/persistence/index.js +28 -0
  27. package/dist/commonjs/persistence/index.js.map +1 -0
  28. package/dist/commonjs/store.js +314 -0
  29. package/dist/commonjs/store.js.map +1 -0
  30. package/dist/commonjs/tsconfig.json +32 -0
  31. package/dist/commonjs/types.js +6 -0
  32. package/dist/commonjs/types.js.map +1 -0
  33. package/dist/module/babel.config.js +15 -0
  34. package/dist/module/babel.config.js.map +1 -0
  35. package/dist/module/bob.config.js +11 -0
  36. package/dist/module/bob.config.js.map +1 -0
  37. package/dist/module/components/GuidonOverlay.js +201 -0
  38. package/dist/module/components/GuidonOverlay.js.map +1 -0
  39. package/dist/module/components/GuidonProvider.js +152 -0
  40. package/dist/module/components/GuidonProvider.js.map +1 -0
  41. package/dist/module/components/GuidonTarget.js +106 -0
  42. package/dist/module/components/GuidonTarget.js.map +1 -0
  43. package/dist/module/components/GuidonTooltip.js +417 -0
  44. package/dist/module/components/GuidonTooltip.js.map +1 -0
  45. package/dist/module/components/index.js +7 -0
  46. package/dist/module/components/index.js.map +1 -0
  47. package/dist/module/hooks/index.js +4 -0
  48. package/dist/module/hooks/index.js.map +1 -0
  49. package/dist/module/hooks/useGuidonRef.js +129 -0
  50. package/dist/module/hooks/useGuidonRef.js.map +1 -0
  51. package/dist/module/index.js +17 -0
  52. package/dist/module/index.js.map +1 -0
  53. package/dist/module/package.json +1 -0
  54. package/dist/module/persistence/adapters.js +203 -0
  55. package/dist/module/persistence/adapters.js.map +1 -0
  56. package/dist/module/persistence/hooks.js +148 -0
  57. package/dist/module/persistence/hooks.js.map +1 -0
  58. package/dist/module/persistence/index.js +5 -0
  59. package/dist/module/persistence/index.js.map +1 -0
  60. package/dist/module/store.js +304 -0
  61. package/dist/module/store.js.map +1 -0
  62. package/dist/module/tsconfig.json +32 -0
  63. package/dist/module/types.js +4 -0
  64. package/dist/module/types.js.map +1 -0
  65. package/dist/typescript/commonjs/components/GuidonOverlay.d.ts +9 -0
  66. package/dist/typescript/commonjs/components/GuidonOverlay.d.ts.map +1 -0
  67. package/dist/typescript/commonjs/components/GuidonProvider.d.ts +14 -0
  68. package/dist/typescript/commonjs/components/GuidonProvider.d.ts.map +1 -0
  69. package/dist/typescript/commonjs/components/GuidonTarget.d.ts +7 -0
  70. package/dist/typescript/commonjs/components/GuidonTarget.d.ts.map +1 -0
  71. package/dist/typescript/commonjs/components/GuidonTooltip.d.ts +24 -0
  72. package/dist/typescript/commonjs/components/GuidonTooltip.d.ts.map +1 -0
  73. package/dist/typescript/commonjs/components/index.d.ts +5 -0
  74. package/dist/typescript/commonjs/components/index.d.ts.map +1 -0
  75. package/dist/typescript/commonjs/hooks/index.d.ts +2 -0
  76. package/dist/typescript/commonjs/hooks/index.d.ts.map +1 -0
  77. package/dist/typescript/commonjs/hooks/useGuidonRef.d.ts +35 -0
  78. package/dist/typescript/commonjs/hooks/useGuidonRef.d.ts.map +1 -0
  79. package/dist/typescript/commonjs/index.d.ts +7 -0
  80. package/dist/typescript/commonjs/index.d.ts.map +1 -0
  81. package/dist/typescript/commonjs/package.json +1 -0
  82. package/dist/typescript/commonjs/persistence/adapters.d.ts +57 -0
  83. package/dist/typescript/commonjs/persistence/adapters.d.ts.map +1 -0
  84. package/dist/typescript/commonjs/persistence/hooks.d.ts +29 -0
  85. package/dist/typescript/commonjs/persistence/hooks.d.ts.map +1 -0
  86. package/dist/typescript/commonjs/persistence/index.d.ts +3 -0
  87. package/dist/typescript/commonjs/persistence/index.d.ts.map +1 -0
  88. package/dist/typescript/commonjs/store.d.ts +89 -0
  89. package/dist/typescript/commonjs/store.d.ts.map +1 -0
  90. package/dist/{index-D_JFvCIg.d.mts → typescript/commonjs/types.d.ts} +40 -104
  91. package/dist/typescript/commonjs/types.d.ts.map +1 -0
  92. package/dist/typescript/module/components/GuidonOverlay.d.ts +9 -0
  93. package/dist/typescript/module/components/GuidonOverlay.d.ts.map +1 -0
  94. package/dist/typescript/module/components/GuidonProvider.d.ts +14 -0
  95. package/dist/typescript/module/components/GuidonProvider.d.ts.map +1 -0
  96. package/dist/typescript/module/components/GuidonTarget.d.ts +7 -0
  97. package/dist/typescript/module/components/GuidonTarget.d.ts.map +1 -0
  98. package/dist/typescript/module/components/GuidonTooltip.d.ts +24 -0
  99. package/dist/typescript/module/components/GuidonTooltip.d.ts.map +1 -0
  100. package/dist/typescript/module/components/index.d.ts +5 -0
  101. package/dist/typescript/module/components/index.d.ts.map +1 -0
  102. package/dist/typescript/module/hooks/index.d.ts +2 -0
  103. package/dist/typescript/module/hooks/index.d.ts.map +1 -0
  104. package/dist/typescript/module/hooks/useGuidonRef.d.ts +35 -0
  105. package/dist/typescript/module/hooks/useGuidonRef.d.ts.map +1 -0
  106. package/dist/typescript/module/index.d.ts +7 -0
  107. package/dist/typescript/module/index.d.ts.map +1 -0
  108. package/dist/typescript/module/package.json +1 -0
  109. package/dist/typescript/module/persistence/adapters.d.ts +57 -0
  110. package/dist/typescript/module/persistence/adapters.d.ts.map +1 -0
  111. package/dist/typescript/module/persistence/hooks.d.ts +29 -0
  112. package/dist/typescript/module/persistence/hooks.d.ts.map +1 -0
  113. package/dist/typescript/module/persistence/index.d.ts +3 -0
  114. package/dist/typescript/module/persistence/index.d.ts.map +1 -0
  115. package/dist/typescript/module/store.d.ts +89 -0
  116. package/dist/typescript/module/store.d.ts.map +1 -0
  117. package/dist/{index-D_JFvCIg.d.ts → typescript/module/types.d.ts} +40 -104
  118. package/dist/typescript/module/types.d.ts.map +1 -0
  119. package/package.json +25 -13
  120. package/src/babel.config.js +18 -0
  121. package/src/bob.config.js +14 -0
  122. package/src/components/GuidonOverlay.tsx +60 -4
  123. package/src/components/GuidonProvider.tsx +29 -1
  124. package/src/components/GuidonTarget.tsx +41 -25
  125. package/src/components/GuidonTooltip.tsx +143 -9
  126. package/src/hooks/index.ts +1 -0
  127. package/src/hooks/useGuidonRef.ts +154 -0
  128. package/src/index.ts +6 -0
  129. package/src/store.ts +68 -15
  130. package/src/tsconfig.json +32 -0
  131. package/src/types.ts +32 -2
  132. package/dist/index.d.mts +0 -128
  133. package/dist/index.d.ts +0 -128
  134. package/dist/index.js +0 -1097
  135. package/dist/index.js.map +0 -1
  136. package/dist/index.mjs +0 -1072
  137. package/dist/index.mjs.map +0 -1
  138. package/dist/persistence/index.d.mts +0 -2
  139. package/dist/persistence/index.d.ts +0 -2
  140. package/dist/persistence/index.js +0 -300
  141. package/dist/persistence/index.js.map +0 -1
  142. package/dist/persistence/index.mjs +0 -291
  143. 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":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAcjB,eAAO,MAAM,cAAc,0EAuIxB,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;;;;CAS3B,CAAC;AAEJ,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,uBAGnD,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;QAmBzB,CAAC;AAEJ;;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
- /** ID of the target element to highlight */
23
- targetId: string;
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":"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"}
package/package.json CHANGED
@@ -1,22 +1,34 @@
1
1
  {
2
2
  "name": "@korsolutions/guidon",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
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
- "main": "dist/index.js",
8
- "module": "dist/index.mjs",
9
- "types": "dist/index.d.ts",
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
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.mjs",
14
- "require": "./dist/index.js"
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
- "types": "./dist/persistence/index.d.ts",
18
- "import": "./dist/persistence/index.mjs",
19
- "require": "./dist/persistence/index.js"
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": "tsup",
28
- "dev": "tsup --watch",
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
+ };
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ source: "src",
3
+ output: "dist",
4
+ targets: [
5
+ [
6
+ "module",
7
+ {
8
+ esm: true,
9
+ configFile: true,
10
+ },
11
+ ],
12
+ "typescript",
13
+ ],
14
+ };
@@ -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(isActive && measurements ? 1 : 0, {
83
+ opacity: withTiming(shouldShow ? 1 : 0, {
74
84
  duration: animationDuration,
75
85
  easing: Easing.inOut(Easing.ease),
76
86
  }),
77
87
  };
78
- }, [isActive, measurements, animationDuration]);
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
- if (!isActive || !measurements) {
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();