@korsolutions/guidon 1.0.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.
@@ -0,0 +1,314 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ /**
4
+ * Position of tooltip relative to the highlighted element
5
+ */
6
+ type TooltipPosition = 'top' | 'bottom' | 'left' | 'right' | 'auto';
7
+ /**
8
+ * Defines the measurements of a target element
9
+ */
10
+ interface TargetMeasurements {
11
+ x: number;
12
+ y: number;
13
+ width: number;
14
+ height: number;
15
+ }
16
+ /**
17
+ * A single step in the guidon
18
+ */
19
+ interface GuidonStep {
20
+ /** Unique identifier for this step */
21
+ id: string;
22
+ /** ID of the target element to highlight */
23
+ targetId: string;
24
+ /** Title displayed in the tooltip */
25
+ title: string;
26
+ /** Description/content displayed in the tooltip */
27
+ description: string;
28
+ /** Preferred position of the tooltip */
29
+ tooltipPosition?: TooltipPosition;
30
+ /** Custom content to render in the tooltip */
31
+ customContent?: ReactNode;
32
+ /** Called when this step becomes active */
33
+ onStepEnter?: () => void;
34
+ /** Called when leaving this step */
35
+ onStepExit?: () => void;
36
+ }
37
+ /**
38
+ * Theme configuration for guidon styling
39
+ */
40
+ interface GuidonTheme {
41
+ /** Color of the backdrop overlay */
42
+ backdropColor?: string;
43
+ /** Opacity of the backdrop (0-1) */
44
+ backdropOpacity?: number;
45
+ /** Background color of the tooltip */
46
+ tooltipBackgroundColor?: string;
47
+ /** Border color of the tooltip */
48
+ tooltipBorderColor?: string;
49
+ /** Border radius of the tooltip */
50
+ tooltipBorderRadius?: number;
51
+ /** Color of the title text */
52
+ titleColor?: string;
53
+ /** Color of the description text */
54
+ descriptionColor?: string;
55
+ /** Primary/accent color (buttons, progress) */
56
+ primaryColor?: string;
57
+ /** Muted/secondary color */
58
+ mutedColor?: string;
59
+ /** Border radius of the spotlight cutout */
60
+ spotlightBorderRadius?: number;
61
+ /** Padding around the highlighted element */
62
+ spotlightPadding?: number;
63
+ }
64
+ /**
65
+ * State of a specific guidon tour
66
+ */
67
+ interface GuidonProgress {
68
+ /** Unique identifier for the guidon */
69
+ guidonId: string;
70
+ /** Whether this guidon has been completed */
71
+ completed: boolean;
72
+ /** Index of the last viewed step (for resuming) */
73
+ lastStepIndex?: number;
74
+ /** Timestamp of completion */
75
+ completedAt?: string;
76
+ /** Number of times this guidon has been completed */
77
+ completionCount?: number;
78
+ }
79
+ /**
80
+ * Persistence adapter interface for saving/loading guidon progress
81
+ * Implement this interface to connect the guidon to your backend
82
+ */
83
+ interface GuidonPersistenceAdapter {
84
+ /**
85
+ * Load the progress for a specific guidon
86
+ * @param guidonId - Unique identifier for the guidon
87
+ * @returns The progress data or null if not found
88
+ */
89
+ loadProgress: (guidonId: string) => Promise<GuidonProgress | null>;
90
+ /**
91
+ * Save the progress for a specific guidon
92
+ * @param progress - The progress data to save
93
+ */
94
+ saveProgress: (progress: GuidonProgress) => Promise<void>;
95
+ /**
96
+ * Load all guidon progress (optional, for bulk operations)
97
+ * @returns Map of guidon IDs to progress data
98
+ */
99
+ loadAllProgress?: () => Promise<Record<string, GuidonProgress>>;
100
+ /**
101
+ * Clear progress for a specific guidon (for replay functionality)
102
+ * @param guidonId - Unique identifier for the guidon
103
+ */
104
+ clearProgress?: (guidonId: string) => Promise<void>;
105
+ }
106
+ /**
107
+ * Configuration for a guidon
108
+ */
109
+ interface GuidonConfig {
110
+ /** Unique identifier for this guidon */
111
+ id: string;
112
+ /** Steps in the guidon */
113
+ steps: GuidonStep[];
114
+ /** Theme customization */
115
+ theme?: GuidonTheme;
116
+ /** Animation duration in milliseconds */
117
+ animationDuration?: number;
118
+ /** Called when the guidon is completed */
119
+ onComplete?: () => void;
120
+ /** Called when the guidon is skipped */
121
+ onSkip?: () => void;
122
+ /** Called when the step changes */
123
+ onStepChange?: (stepIndex: number, step: GuidonStep) => void;
124
+ }
125
+ /**
126
+ * Labels for tooltip buttons
127
+ */
128
+ interface GuidonTooltipLabels {
129
+ next?: string;
130
+ previous?: string;
131
+ skip?: string;
132
+ finish?: string;
133
+ stepOf?: (current: number, total: number) => string;
134
+ }
135
+ /**
136
+ * Props for custom tooltip renderer
137
+ */
138
+ interface GuidonTooltipRenderProps {
139
+ step: GuidonStep;
140
+ currentIndex: number;
141
+ totalSteps: number;
142
+ onNext: () => void;
143
+ onPrevious: () => void;
144
+ onSkip: () => void;
145
+ }
146
+ /**
147
+ * Props for the GuidonProvider component
148
+ */
149
+ interface GuidonProviderProps {
150
+ children: ReactNode;
151
+ /** Configuration for the guidon */
152
+ config: GuidonConfig;
153
+ /** Whether to auto-start when the component mounts */
154
+ autoStart?: boolean;
155
+ /** Condition function to determine if guidon should start */
156
+ shouldStart?: () => boolean | Promise<boolean>;
157
+ /** Persistence adapter for saving/loading progress */
158
+ persistenceAdapter?: GuidonPersistenceAdapter;
159
+ /** Custom portal component for rendering overlay */
160
+ portalComponent?: React.ComponentType<{
161
+ children: ReactNode;
162
+ }>;
163
+ /** Custom tooltip renderer */
164
+ renderTooltip?: (props: GuidonTooltipRenderProps) => ReactNode;
165
+ /** Customize tooltip labels */
166
+ tooltipLabels?: GuidonTooltipLabels;
167
+ /** Called when backdrop is pressed */
168
+ onBackdropPress?: () => void;
169
+ }
170
+ /**
171
+ * Props for the GuidonTarget component
172
+ */
173
+ interface GuidonTargetProps {
174
+ children: ReactNode;
175
+ /** Target ID that matches a step's targetId */
176
+ targetId: string;
177
+ /** Whether this target is currently active (for conditional rendering) */
178
+ active?: boolean;
179
+ }
180
+ /**
181
+ * Internal store state
182
+ */
183
+ interface GuidonState {
184
+ /** Currently active guidon config */
185
+ config: GuidonConfig | null;
186
+ /** Whether the guidon is currently active */
187
+ isActive: boolean;
188
+ /** Current step index */
189
+ currentStepIndex: number;
190
+ /** Whether the guidon has been completed */
191
+ isCompleted: boolean;
192
+ /** Map of target IDs to their measurements */
193
+ targetMeasurements: Record<string, TargetMeasurements>;
194
+ /** Loading state for persistence operations */
195
+ isLoading: boolean;
196
+ /** Error from persistence operations */
197
+ error: string | null;
198
+ }
199
+ /**
200
+ * Internal store actions
201
+ */
202
+ interface GuidonActions {
203
+ /** Configure the guidon */
204
+ configure: (config: GuidonConfig) => void;
205
+ /** Start the guidon */
206
+ start: () => void;
207
+ /** Go to the next step */
208
+ next: () => void;
209
+ /** Go to the previous step */
210
+ previous: () => void;
211
+ /** Go to a specific step */
212
+ goToStep: (index: number) => void;
213
+ /** Skip the guidon */
214
+ skip: () => void;
215
+ /** Complete the guidon */
216
+ complete: () => void;
217
+ /** Reset the guidon state */
218
+ reset: () => void;
219
+ /** Register a target's measurements */
220
+ registerTarget: (targetId: string, measurements: TargetMeasurements) => void;
221
+ /** Unregister a target */
222
+ unregisterTarget: (targetId: string) => void;
223
+ /** Set loading state */
224
+ setLoading: (isLoading: boolean) => void;
225
+ /** Set error state */
226
+ setError: (error: string | null) => void;
227
+ }
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 };
@@ -0,0 +1,128 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { G as GuidonTargetProps, a as GuidonTheme, b as GuidonStep, c as GuidonProviderProps, d as GuidonStore, e as GuidonConfig, T as TargetMeasurements } from './index-D_JFvCIg.mjs';
3
+ export { l as GuidonActions, g as GuidonPersistenceAdapter, f as GuidonProgress, k as GuidonState, h as GuidonTooltipLabels, i as GuidonTooltipRenderProps, j as TooltipPosition, q as createApiAdapter, p as createAsyncStorageAdapter, r as createCompositeAdapter, o as createLocalStorageAdapter, n as createMemoryAdapter, m as createNoopAdapter, u as useGuidonPersistence, s as useShouldShowGuidon } from './index-D_JFvCIg.mjs';
4
+ import * as zustand from 'zustand';
5
+ import 'react';
6
+
7
+ /**
8
+ * Wrapper component that marks an element as a walkthrough target
9
+ * Automatically measures and reports its position to the walkthrough store
10
+ */
11
+ declare function GuidonTarget({ children, targetId, active, }: GuidonTargetProps): react_jsx_runtime.JSX.Element;
12
+
13
+ interface GuidonOverlayProps {
14
+ theme?: GuidonTheme;
15
+ animationDuration?: number;
16
+ onBackdropPress?: () => void;
17
+ }
18
+ declare function GuidonOverlay({ theme, animationDuration, onBackdropPress, }: GuidonOverlayProps): react_jsx_runtime.JSX.Element | null;
19
+
20
+ interface GuidonTooltipProps {
21
+ theme?: GuidonTheme;
22
+ animationDuration?: number;
23
+ renderCustomTooltip?: (props: {
24
+ step: GuidonStep;
25
+ currentIndex: number;
26
+ totalSteps: number;
27
+ onNext: () => void;
28
+ onPrevious: () => void;
29
+ onSkip: () => void;
30
+ }) => React.ReactNode;
31
+ labels?: {
32
+ next?: string;
33
+ previous?: string;
34
+ skip?: string;
35
+ finish?: string;
36
+ stepOf?: (current: number, total: number) => string;
37
+ };
38
+ }
39
+ declare function GuidonTooltip({ theme, animationDuration, renderCustomTooltip, labels, }: GuidonTooltipProps): react_jsx_runtime.JSX.Element | null;
40
+
41
+ interface GuidonContextValue {
42
+ start: () => void;
43
+ skip: () => void;
44
+ reset: () => void;
45
+ replay: () => Promise<void>;
46
+ isActive: boolean;
47
+ isCompleted: boolean;
48
+ isLoading: boolean;
49
+ }
50
+ declare function useGuidonContext(): GuidonContextValue;
51
+ declare function GuidonProvider({ children, config, autoStart, shouldStart, persistenceAdapter, portalComponent: Portal, renderTooltip, tooltipLabels, onBackdropPress, }: GuidonProviderProps): react_jsx_runtime.JSX.Element;
52
+
53
+ declare const useGuidonStore: zustand.UseBoundStore<zustand.StoreApi<GuidonStore>>;
54
+ /**
55
+ * Guidon API for external control
56
+ * Can be used outside of React components
57
+ */
58
+ declare const Guidon: {
59
+ /**
60
+ * Configure the walkthrough with steps and options
61
+ */
62
+ configure: (config: GuidonConfig) => void;
63
+ /**
64
+ * Start the walkthrough
65
+ */
66
+ start: () => void;
67
+ /**
68
+ * Go to the next step
69
+ */
70
+ next: () => void;
71
+ /**
72
+ * Go to the previous step
73
+ */
74
+ previous: () => void;
75
+ /**
76
+ * Go to a specific step by index
77
+ */
78
+ goToStep: (index: number) => void;
79
+ /**
80
+ * Skip the walkthrough
81
+ */
82
+ skip: () => void;
83
+ /**
84
+ * Complete the walkthrough
85
+ */
86
+ complete: () => void;
87
+ /**
88
+ * Reset the walkthrough to initial state
89
+ */
90
+ reset: () => void;
91
+ /**
92
+ * Check if the walkthrough is currently active
93
+ */
94
+ isActive: () => boolean;
95
+ /**
96
+ * Check if the walkthrough has been completed
97
+ */
98
+ isCompleted: () => boolean;
99
+ /**
100
+ * Get the current step index
101
+ */
102
+ getCurrentStepIndex: () => number;
103
+ /**
104
+ * Get the current step
105
+ */
106
+ getCurrentStep: () => GuidonStep | null;
107
+ /**
108
+ * Get all steps
109
+ */
110
+ getSteps: () => GuidonStep[];
111
+ /**
112
+ * Subscribe to store changes
113
+ */
114
+ subscribe: (listener: (state: GuidonStore, prevState: GuidonStore) => void) => () => void;
115
+ };
116
+ /**
117
+ * Hook selectors for common use cases
118
+ */
119
+ declare const useGuidonActive: () => boolean;
120
+ declare const useGuidonStep: () => GuidonStep | null;
121
+ declare const useGuidonProgress: () => {
122
+ currentStep: number;
123
+ totalSteps: number;
124
+ percentage: number;
125
+ };
126
+ declare const useTargetMeasurements: (targetId: string) => TargetMeasurements;
127
+
128
+ export { Guidon, GuidonConfig, GuidonOverlay, GuidonProvider, GuidonProviderProps, GuidonStep, GuidonStore, GuidonTarget, GuidonTargetProps, GuidonTheme, GuidonTooltip, TargetMeasurements, useGuidonActive, useGuidonContext, useGuidonProgress, useGuidonStep, useGuidonStore, useTargetMeasurements };
@@ -0,0 +1,128 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { G as GuidonTargetProps, a as GuidonTheme, b as GuidonStep, c as GuidonProviderProps, d as GuidonStore, e as GuidonConfig, T as TargetMeasurements } from './index-D_JFvCIg.js';
3
+ export { l as GuidonActions, g as GuidonPersistenceAdapter, f as GuidonProgress, k as GuidonState, h as GuidonTooltipLabels, i as GuidonTooltipRenderProps, j as TooltipPosition, q as createApiAdapter, p as createAsyncStorageAdapter, r as createCompositeAdapter, o as createLocalStorageAdapter, n as createMemoryAdapter, m as createNoopAdapter, u as useGuidonPersistence, s as useShouldShowGuidon } from './index-D_JFvCIg.js';
4
+ import * as zustand from 'zustand';
5
+ import 'react';
6
+
7
+ /**
8
+ * Wrapper component that marks an element as a walkthrough target
9
+ * Automatically measures and reports its position to the walkthrough store
10
+ */
11
+ declare function GuidonTarget({ children, targetId, active, }: GuidonTargetProps): react_jsx_runtime.JSX.Element;
12
+
13
+ interface GuidonOverlayProps {
14
+ theme?: GuidonTheme;
15
+ animationDuration?: number;
16
+ onBackdropPress?: () => void;
17
+ }
18
+ declare function GuidonOverlay({ theme, animationDuration, onBackdropPress, }: GuidonOverlayProps): react_jsx_runtime.JSX.Element | null;
19
+
20
+ interface GuidonTooltipProps {
21
+ theme?: GuidonTheme;
22
+ animationDuration?: number;
23
+ renderCustomTooltip?: (props: {
24
+ step: GuidonStep;
25
+ currentIndex: number;
26
+ totalSteps: number;
27
+ onNext: () => void;
28
+ onPrevious: () => void;
29
+ onSkip: () => void;
30
+ }) => React.ReactNode;
31
+ labels?: {
32
+ next?: string;
33
+ previous?: string;
34
+ skip?: string;
35
+ finish?: string;
36
+ stepOf?: (current: number, total: number) => string;
37
+ };
38
+ }
39
+ declare function GuidonTooltip({ theme, animationDuration, renderCustomTooltip, labels, }: GuidonTooltipProps): react_jsx_runtime.JSX.Element | null;
40
+
41
+ interface GuidonContextValue {
42
+ start: () => void;
43
+ skip: () => void;
44
+ reset: () => void;
45
+ replay: () => Promise<void>;
46
+ isActive: boolean;
47
+ isCompleted: boolean;
48
+ isLoading: boolean;
49
+ }
50
+ declare function useGuidonContext(): GuidonContextValue;
51
+ declare function GuidonProvider({ children, config, autoStart, shouldStart, persistenceAdapter, portalComponent: Portal, renderTooltip, tooltipLabels, onBackdropPress, }: GuidonProviderProps): react_jsx_runtime.JSX.Element;
52
+
53
+ declare const useGuidonStore: zustand.UseBoundStore<zustand.StoreApi<GuidonStore>>;
54
+ /**
55
+ * Guidon API for external control
56
+ * Can be used outside of React components
57
+ */
58
+ declare const Guidon: {
59
+ /**
60
+ * Configure the walkthrough with steps and options
61
+ */
62
+ configure: (config: GuidonConfig) => void;
63
+ /**
64
+ * Start the walkthrough
65
+ */
66
+ start: () => void;
67
+ /**
68
+ * Go to the next step
69
+ */
70
+ next: () => void;
71
+ /**
72
+ * Go to the previous step
73
+ */
74
+ previous: () => void;
75
+ /**
76
+ * Go to a specific step by index
77
+ */
78
+ goToStep: (index: number) => void;
79
+ /**
80
+ * Skip the walkthrough
81
+ */
82
+ skip: () => void;
83
+ /**
84
+ * Complete the walkthrough
85
+ */
86
+ complete: () => void;
87
+ /**
88
+ * Reset the walkthrough to initial state
89
+ */
90
+ reset: () => void;
91
+ /**
92
+ * Check if the walkthrough is currently active
93
+ */
94
+ isActive: () => boolean;
95
+ /**
96
+ * Check if the walkthrough has been completed
97
+ */
98
+ isCompleted: () => boolean;
99
+ /**
100
+ * Get the current step index
101
+ */
102
+ getCurrentStepIndex: () => number;
103
+ /**
104
+ * Get the current step
105
+ */
106
+ getCurrentStep: () => GuidonStep | null;
107
+ /**
108
+ * Get all steps
109
+ */
110
+ getSteps: () => GuidonStep[];
111
+ /**
112
+ * Subscribe to store changes
113
+ */
114
+ subscribe: (listener: (state: GuidonStore, prevState: GuidonStore) => void) => () => void;
115
+ };
116
+ /**
117
+ * Hook selectors for common use cases
118
+ */
119
+ declare const useGuidonActive: () => boolean;
120
+ declare const useGuidonStep: () => GuidonStep | null;
121
+ declare const useGuidonProgress: () => {
122
+ currentStep: number;
123
+ totalSteps: number;
124
+ percentage: number;
125
+ };
126
+ declare const useTargetMeasurements: (targetId: string) => TargetMeasurements;
127
+
128
+ export { Guidon, GuidonConfig, GuidonOverlay, GuidonProvider, GuidonProviderProps, GuidonStep, GuidonStore, GuidonTarget, GuidonTargetProps, GuidonTheme, GuidonTooltip, TargetMeasurements, useGuidonActive, useGuidonContext, useGuidonProgress, useGuidonStep, useGuidonStore, useTargetMeasurements };