@korsolutions/guidon 1.0.15 → 1.0.17

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 (59) hide show
  1. package/README.md +72 -167
  2. package/dist/commonjs/components/GuidonOverlay.js +9 -20
  3. package/dist/commonjs/components/GuidonOverlay.js.map +1 -1
  4. package/dist/commonjs/components/GuidonProvider.js +11 -77
  5. package/dist/commonjs/components/GuidonProvider.js.map +1 -1
  6. package/dist/commonjs/components/GuidonTooltip.js +48 -55
  7. package/dist/commonjs/components/GuidonTooltip.js.map +1 -1
  8. package/dist/commonjs/components/index.js +2 -2
  9. package/dist/commonjs/components/index.js.map +1 -1
  10. package/dist/commonjs/hooks/useGuidonRef.js +7 -7
  11. package/dist/commonjs/hooks/useGuidonRef.js.map +1 -1
  12. package/dist/commonjs/store.js +34 -66
  13. package/dist/commonjs/store.js.map +1 -1
  14. package/dist/module/components/GuidonOverlay.js +14 -25
  15. package/dist/module/components/GuidonOverlay.js.map +1 -1
  16. package/dist/module/components/GuidonProvider.js +12 -78
  17. package/dist/module/components/GuidonProvider.js.map +1 -1
  18. package/dist/module/components/GuidonTooltip.js +53 -60
  19. package/dist/module/components/GuidonTooltip.js.map +1 -1
  20. package/dist/module/components/index.js +2 -2
  21. package/dist/module/components/index.js.map +1 -1
  22. package/dist/module/hooks/useGuidonRef.js +7 -7
  23. package/dist/module/hooks/useGuidonRef.js.map +1 -1
  24. package/dist/module/store.js +34 -66
  25. package/dist/module/store.js.map +1 -1
  26. package/dist/typescript/commonjs/components/GuidonOverlay.d.ts +1 -1
  27. package/dist/typescript/commonjs/components/GuidonOverlay.d.ts.map +1 -1
  28. package/dist/typescript/commonjs/components/GuidonProvider.d.ts +4 -4
  29. package/dist/typescript/commonjs/components/GuidonProvider.d.ts.map +1 -1
  30. package/dist/typescript/commonjs/components/GuidonTooltip.d.ts +1 -1
  31. package/dist/typescript/commonjs/components/GuidonTooltip.d.ts.map +1 -1
  32. package/dist/typescript/commonjs/components/index.d.ts +4 -4
  33. package/dist/typescript/commonjs/components/index.d.ts.map +1 -1
  34. package/dist/typescript/commonjs/hooks/useGuidonRef.d.ts.map +1 -1
  35. package/dist/typescript/commonjs/store.d.ts +14 -15
  36. package/dist/typescript/commonjs/store.d.ts.map +1 -1
  37. package/dist/typescript/commonjs/types.d.ts +10 -69
  38. package/dist/typescript/commonjs/types.d.ts.map +1 -1
  39. package/dist/typescript/module/components/GuidonOverlay.d.ts +1 -1
  40. package/dist/typescript/module/components/GuidonOverlay.d.ts.map +1 -1
  41. package/dist/typescript/module/components/GuidonProvider.d.ts +4 -4
  42. package/dist/typescript/module/components/GuidonProvider.d.ts.map +1 -1
  43. package/dist/typescript/module/components/GuidonTooltip.d.ts +1 -1
  44. package/dist/typescript/module/components/GuidonTooltip.d.ts.map +1 -1
  45. package/dist/typescript/module/components/index.d.ts +4 -4
  46. package/dist/typescript/module/components/index.d.ts.map +1 -1
  47. package/dist/typescript/module/hooks/useGuidonRef.d.ts.map +1 -1
  48. package/dist/typescript/module/store.d.ts +14 -15
  49. package/dist/typescript/module/store.d.ts.map +1 -1
  50. package/dist/typescript/module/types.d.ts +10 -69
  51. package/dist/typescript/module/types.d.ts.map +1 -1
  52. package/package.json +1 -1
  53. package/src/components/GuidonOverlay.tsx +28 -29
  54. package/src/components/GuidonProvider.tsx +46 -111
  55. package/src/components/GuidonTooltip.tsx +125 -91
  56. package/src/components/index.ts +4 -4
  57. package/src/hooks/useGuidonRef.ts +23 -8
  58. package/src/store.ts +50 -70
  59. package/src/types.ts +10 -69
package/src/store.ts CHANGED
@@ -1,6 +1,13 @@
1
1
  import { create } from "zustand";
2
2
  import { useShallow } from "zustand/react/shallow";
3
- import type { GuidonConfig, GuidonStore, GuidonTours, GuidonToursConfig, GuidonTheme, TargetMeasurements } from "./types";
3
+ import type {
4
+ GuidonConfig,
5
+ GuidonStore,
6
+ GuidonTheme,
7
+ GuidonTours,
8
+ GuidonToursConfig,
9
+ TargetMeasurements,
10
+ } from "./types";
4
11
 
5
12
  const initialState = {
6
13
  tours: {} as GuidonTours,
@@ -21,67 +28,44 @@ const initialState = {
21
28
  export const useGuidonStore = create<GuidonStore>((set, get) => ({
22
29
  ...initialState,
23
30
 
24
- configure: (config: GuidonConfig) => {
25
- const { config: existingConfig } = get();
26
-
27
- // Skip if same config reference (prevents re-renders from resetting)
28
- if (existingConfig === config) {
29
- return;
30
- }
31
-
32
- console.log("[Guidon] configure() called - resetting to step 0");
33
- set({ config, currentStepIndex: 0, isCompleted: false });
34
- },
35
-
36
- configureTours: (config: GuidonToursConfig | GuidonTours) => {
37
- // Support both new GuidonToursConfig format and legacy GuidonTours format
38
- const isNewFormat = 'tours' in config && typeof config.tours === 'object';
39
-
40
- const tours = isNewFormat
41
- ? (config as GuidonToursConfig).tours
42
- : config as GuidonTours;
43
- const globalTheme = isNewFormat
44
- ? (config as GuidonToursConfig).theme
45
- : undefined;
46
- const globalAnimationDuration = isNewFormat
47
- ? (config as GuidonToursConfig).animationDuration
48
- : undefined;
49
-
31
+ configureTours: (config: GuidonToursConfig) => {
50
32
  const { tours: existingTours } = get();
51
33
 
52
34
  // Skip if same tours reference (prevents re-renders from resetting)
53
- if (existingTours === tours) {
35
+ if (existingTours === config.tours) {
54
36
  return;
55
37
  }
56
38
 
57
- console.log("[Guidon] configureTours() called with tours:", Object.keys(tours));
58
- set({ tours, globalTheme, globalAnimationDuration });
39
+ console.log(
40
+ "[Guidon] configureTours() called with tours:",
41
+ Object.keys(config.tours),
42
+ );
43
+ set({
44
+ tours: config.tours,
45
+ globalTheme: config.theme,
46
+ globalAnimationDuration: config.animationDuration,
47
+ });
59
48
  },
60
49
 
61
- start: (tourId?: string) => {
62
- const { tours, config: legacyConfig, globalTheme, globalAnimationDuration } = get();
50
+ start: (tourId: string) => {
51
+ const { tours, globalTheme, globalAnimationDuration } = get();
63
52
 
64
- // If tourId provided, use that tour from the tours collection
65
- let config: GuidonConfig | null = null;
66
- if (tourId) {
67
- const tourConfig = tours[tourId] ?? null;
68
- if (!tourConfig) {
69
- console.log(`[Guidon] start() - tour "${tourId}" not found`);
70
- return;
71
- }
72
- // Merge global theme/duration with tour-specific settings
73
- config = {
74
- ...tourConfig,
75
- theme: { ...globalTheme, ...tourConfig.theme },
76
- animationDuration: tourConfig.animationDuration ?? globalAnimationDuration,
77
- };
78
- } else {
79
- // Fall back to legacy single config
80
- config = legacyConfig;
53
+ const tourConfig = tours[tourId] ?? null;
54
+ if (!tourConfig) {
55
+ console.log(`[Guidon] start() - tour "${tourId}" not found`);
56
+ return;
81
57
  }
82
58
 
59
+ // Merge global theme/duration with tour-specific settings
60
+ const config: GuidonConfig = {
61
+ ...tourConfig,
62
+ theme: { ...globalTheme, ...tourConfig.theme },
63
+ animationDuration:
64
+ tourConfig.animationDuration ?? globalAnimationDuration,
65
+ };
66
+
83
67
  console.log("[Guidon] start() called", {
84
- tourId: tourId ?? "legacy",
68
+ tourId,
85
69
  hasConfig: !!config,
86
70
  stepCount: config?.steps.length ?? 0,
87
71
  });
@@ -100,7 +84,7 @@ export const useGuidonStore = create<GuidonStore>((set, get) => ({
100
84
  activeTourId: tourId ?? null,
101
85
  isActive: true,
102
86
  currentStepIndex: 0,
103
- isCompleted: false
87
+ isCompleted: false,
104
88
  });
105
89
 
106
90
  // Call onStepEnter for the first step
@@ -268,31 +252,26 @@ export const useGuidonStore = create<GuidonStore>((set, get) => ({
268
252
  */
269
253
  export const Guidon = {
270
254
  /**
271
- * Configure a single walkthrough (legacy API)
272
- */
273
- configure: (config: GuidonConfig) => {
274
- useGuidonStore.getState().configure(config);
275
- },
276
-
277
- /**
278
- * Configure multiple named tours
255
+ * Configure multiple named tours with optional global theme.
279
256
  * @example
280
257
  * Guidon.configureTours({
281
- * explore: { steps: [...], onComplete: () => {} },
282
- * profile: { steps: [...] },
258
+ * theme: { primaryColor: '#007AFF' },
259
+ * tours: {
260
+ * explore: { id: 'explore', steps: [...] },
261
+ * profile: { id: 'profile', steps: [...] },
262
+ * },
283
263
  * });
284
264
  */
285
- configureTours: (tours: GuidonTours) => {
286
- useGuidonStore.getState().configureTours(tours);
265
+ configureTours: (config: GuidonToursConfig) => {
266
+ useGuidonStore.getState().configureTours(config);
287
267
  },
288
268
 
289
269
  /**
290
- * Start a tour by ID, or the legacy single config if no ID provided
270
+ * Start a tour by ID
291
271
  * @example
292
272
  * Guidon.start('explore'); // Start the 'explore' tour
293
- * Guidon.start(); // Start legacy single config
294
273
  */
295
- start: (tourId?: string) => {
274
+ start: (tourId: string) => {
296
275
  useGuidonStore.getState().start(tourId);
297
276
  },
298
277
 
@@ -360,7 +339,7 @@ export const Guidon = {
360
339
  },
361
340
 
362
341
  /**
363
- * Get the currently active tour ID (null if using legacy single config)
342
+ * Get the currently active tour ID
364
343
  */
365
344
  getActiveTourId: () => {
366
345
  return useGuidonStore.getState().activeTourId;
@@ -428,7 +407,7 @@ export const useTargetMeasurements = (targetId: string) =>
428
407
  useGuidonStore((state: GuidonStore) => state.targetMeasurements[targetId]);
429
408
 
430
409
  /**
431
- * Hook to check if the guidon is waiting for a target element to mount
410
+ * Hook to check if the Guidon is waiting for a target element to mount
432
411
  * Returns null if not active, not waiting, or if it's a floating step
433
412
  */
434
413
  export const useWaitingState = () =>
@@ -439,7 +418,7 @@ export const useWaitingState = () =>
439
418
  const currentStep = state.config.steps[state.currentStepIndex];
440
419
  const targetId = currentStep?.targetId;
441
420
 
442
- // Floating step (no targetId) - not waiting
421
+ // Floating step therefore not waiting
443
422
  if (!targetId) return null;
444
423
 
445
424
  const hasMeasurements = !!state.targetMeasurements[targetId];
@@ -453,7 +432,8 @@ export const useWaitingState = () =>
453
432
  );
454
433
 
455
434
  /**
456
- * Hook to check if the current step is a floating step (no target element)
435
+ * Hook to check if the current step is a floating step,
436
+ * i.e. has no targetId and is centered on device
457
437
  */
458
438
  export const useIsFloatingStep = () =>
459
439
  useGuidonStore((state: GuidonStore) => {
package/src/types.ts CHANGED
@@ -186,10 +186,8 @@ export interface GuidonTooltipRenderProps {
186
186
  */
187
187
  export interface GuidonProviderProps {
188
188
  children: ReactNode;
189
- /** Configuration for the guidon (optional when using configureTours) */
190
- config?: GuidonConfig;
191
- /** Whether to auto-start when the component mounts */
192
- autoStart?: boolean;
189
+ /** Tour ID to auto-start when the provider mounts */
190
+ autoStart?: string;
193
191
  /** Condition function to determine if guidon should start */
194
192
  shouldStart?: () => boolean | Promise<boolean>;
195
193
  /** Persistence adapter for saving/loading progress */
@@ -221,62 +219,10 @@ export interface GuidonTargetProps {
221
219
  export type GuidonTours = Record<string, GuidonConfig>;
222
220
 
223
221
  /**
224
- * Single tour configuration for use within GuidonToursConfig
222
+ * Single tour configuration for use within GuidonToursConfig.
223
+ * Identical to GuidonConfig - use this alias for semantic clarity in multi-tour setups.
225
224
  */
226
- export interface GuidonTourDefinition {
227
- /** Unique identifier for this tour (should match the key) */
228
- id: string;
229
- /** Steps in the tour */
230
- steps: Array<{
231
- /** Unique identifier for this step */
232
- id: string;
233
- /**
234
- * ID of the target element to highlight.
235
- * Omit for floating tooltip (centered, no spotlight).
236
- */
237
- targetId?: string;
238
- /** Title displayed in the tooltip */
239
- title: string;
240
- /** Description/content displayed in the tooltip */
241
- description: string;
242
- /**
243
- * Preferred position of the tooltip relative to target
244
- * @default 'auto'
245
- */
246
- tooltipPosition?: TooltipPosition;
247
- /**
248
- * Position for floating tooltips (when no targetId)
249
- * @default 'center'
250
- */
251
- floatingPosition?: FloatingPosition;
252
- /** Custom React content to render in the tooltip */
253
- customContent?: ReactNode;
254
- /** Called when this step becomes active */
255
- onStepEnter?: () => void;
256
- /** Called when leaving this step */
257
- onStepExit?: () => void;
258
- /** Message shown while waiting for target element to mount */
259
- waitingMessage?: string;
260
- /**
261
- * Auto-skip timeout in ms if target doesn't mount.
262
- * Set to 0 to disable.
263
- */
264
- waitTimeout?: number;
265
- }>;
266
- /**
267
- * Theme customization for this specific tour.
268
- * Overrides the global theme if provided.
269
- */
270
- theme?: GuidonTheme;
271
- /** Animation duration in milliseconds (overrides global) */
272
- animationDuration?: number;
273
- /** Called when the tour is completed (user finishes all steps) */
274
- onComplete?: () => void;
275
- /** Called when the tour is skipped */
276
- onSkip?: () => void;
277
- /** Called when the step changes */
278
- onStepChange?: (stepIndex: number, step: GuidonStep) => void;
279
- }
225
+ export type GuidonTourDefinition = GuidonConfig;
280
226
 
281
227
  /**
282
228
  * Configuration object for defining multiple tours with shared settings.
@@ -331,7 +277,7 @@ export interface GuidonState {
331
277
  globalAnimationDuration?: number;
332
278
  /** ID of the currently active tour */
333
279
  activeTourId: string | null;
334
- /** Currently active guidon config (derived from tours + activeTourId, or legacy single config) */
280
+ /** Currently active guidon config (derived from tours + activeTourId) */
335
281
  config: GuidonConfig | null;
336
282
  /** Whether the guidon is currently active */
337
283
  isActive: boolean;
@@ -355,15 +301,10 @@ export interface GuidonState {
355
301
  * Internal store actions
356
302
  */
357
303
  export interface GuidonActions {
358
- /** Configure a single guidon (legacy API, still supported) */
359
- configure: (config: GuidonConfig) => void;
360
- /**
361
- * Configure multiple named tours.
362
- * Accepts either GuidonToursConfig (with global theme) or legacy GuidonTours format.
363
- */
364
- configureTours: (config: GuidonToursConfig | GuidonTours) => void;
365
- /** Start a tour by ID, or the legacy single config if no ID provided */
366
- start: (tourId?: string) => void;
304
+ /** Configure multiple named tours with global theme support */
305
+ configureTours: (config: GuidonToursConfig) => void;
306
+ /** Start a tour by ID */
307
+ start: (tourId: string) => void;
367
308
  /** Stop the current tour without completing it */
368
309
  stop: () => void;
369
310
  /** Go to the next step */