@flowsterix/react 0.9.0 → 0.10.1
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/dist/adapters/radixDialogHelpers.d.ts +0 -40
- package/dist/adapters/radixDialogHelpers.d.ts.map +1 -1
- package/dist/components/TourPopoverPortal.d.ts.map +1 -1
- package/dist/context.d.ts +2 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/dialog/DialogRegistryContext.d.ts +16 -0
- package/dist/dialog/DialogRegistryContext.d.ts.map +1 -0
- package/dist/hooks/useDialogAutomation.d.ts +16 -0
- package/dist/hooks/useDialogAutomation.d.ts.map +1 -0
- package/dist/hooks/useRadixTourDialog.d.ts +26 -0
- package/dist/hooks/useRadixTourDialog.d.ts.map +1 -0
- package/dist/index.cjs +593 -231
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +568 -203
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -25,12 +25,12 @@ import {
|
|
|
25
25
|
serializeVersion
|
|
26
26
|
} from "@flowsterix/core";
|
|
27
27
|
import {
|
|
28
|
-
createContext as
|
|
29
|
-
useCallback,
|
|
30
|
-
useContext as
|
|
31
|
-
useEffect as
|
|
32
|
-
useMemo as
|
|
33
|
-
useRef,
|
|
28
|
+
createContext as createContext4,
|
|
29
|
+
useCallback as useCallback2,
|
|
30
|
+
useContext as useContext4,
|
|
31
|
+
useEffect as useEffect3,
|
|
32
|
+
useMemo as useMemo3,
|
|
33
|
+
useRef as useRef3,
|
|
34
34
|
useState as useState2
|
|
35
35
|
} from "react";
|
|
36
36
|
|
|
@@ -63,10 +63,162 @@ function useTourLabels() {
|
|
|
63
63
|
return useContext(LabelsContext);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
// src/dialog/DialogRegistryContext.tsx
|
|
67
|
+
import {
|
|
68
|
+
createContext as createContext2,
|
|
69
|
+
useCallback,
|
|
70
|
+
useContext as useContext2,
|
|
71
|
+
useMemo,
|
|
72
|
+
useRef
|
|
73
|
+
} from "react";
|
|
74
|
+
import { jsx } from "react/jsx-runtime";
|
|
75
|
+
var DialogRegistryContext = createContext2(void 0);
|
|
76
|
+
var DialogRegistryProvider = ({ children }) => {
|
|
77
|
+
const controllersRef = useRef(/* @__PURE__ */ new Map());
|
|
78
|
+
const register = useCallback(
|
|
79
|
+
(dialogId, controller) => {
|
|
80
|
+
controllersRef.current.set(dialogId, controller);
|
|
81
|
+
},
|
|
82
|
+
[]
|
|
83
|
+
);
|
|
84
|
+
const unregister = useCallback((dialogId) => {
|
|
85
|
+
controllersRef.current.delete(dialogId);
|
|
86
|
+
}, []);
|
|
87
|
+
const getController = useCallback((dialogId) => {
|
|
88
|
+
return controllersRef.current.get(dialogId);
|
|
89
|
+
}, []);
|
|
90
|
+
const isRegistered = useCallback((dialogId) => {
|
|
91
|
+
return controllersRef.current.has(dialogId);
|
|
92
|
+
}, []);
|
|
93
|
+
const value = useMemo(
|
|
94
|
+
() => ({
|
|
95
|
+
register,
|
|
96
|
+
unregister,
|
|
97
|
+
getController,
|
|
98
|
+
isRegistered
|
|
99
|
+
}),
|
|
100
|
+
[register, unregister, getController, isRegistered]
|
|
101
|
+
);
|
|
102
|
+
return /* @__PURE__ */ jsx(DialogRegistryContext.Provider, { value, children });
|
|
103
|
+
};
|
|
104
|
+
var useDialogRegistry = () => {
|
|
105
|
+
const context = useContext2(DialogRegistryContext);
|
|
106
|
+
if (!context) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
"useDialogRegistry must be used within a DialogRegistryProvider"
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return context;
|
|
112
|
+
};
|
|
113
|
+
var useDialogRegistryOptional = () => {
|
|
114
|
+
return useContext2(DialogRegistryContext);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/hooks/useDialogAutomation.ts
|
|
118
|
+
import { useEffect, useRef as useRef2 } from "react";
|
|
119
|
+
var resolveAutoOpen = (config) => {
|
|
120
|
+
if (!config) return { onEnter: true, onResume: true };
|
|
121
|
+
const { autoOpen } = config;
|
|
122
|
+
if (autoOpen === false) return { onEnter: false, onResume: false };
|
|
123
|
+
if (autoOpen === true || autoOpen === void 0) {
|
|
124
|
+
return { onEnter: true, onResume: true };
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
onEnter: autoOpen.onEnter ?? true,
|
|
128
|
+
onResume: autoOpen.onResume ?? true
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
var useDialogAutomation = (params) => {
|
|
132
|
+
const { flow, state, events, registry, onDialogNotMounted } = params;
|
|
133
|
+
const previousDialogIdRef = useRef2(void 0);
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
if (!events || !flow || !registry) return;
|
|
136
|
+
const unsubscribeEnter = events.on("stepEnter", (payload) => {
|
|
137
|
+
const step = payload.currentStep;
|
|
138
|
+
const dialogId = step.dialogId;
|
|
139
|
+
const previousDialogId = previousDialogIdRef.current;
|
|
140
|
+
if (previousDialogId && previousDialogId !== dialogId && flow.dialogs?.[previousDialogId]) {
|
|
141
|
+
const config = flow.dialogs[previousDialogId];
|
|
142
|
+
const autoClose = config.autoClose ?? "differentDialog";
|
|
143
|
+
if (autoClose === "always" || autoClose === "differentDialog") {
|
|
144
|
+
const controller = registry.getController(previousDialogId);
|
|
145
|
+
if (controller) {
|
|
146
|
+
requestAnimationFrame(() => {
|
|
147
|
+
controller.close();
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (dialogId && flow.dialogs?.[dialogId]) {
|
|
153
|
+
const config = flow.dialogs[dialogId];
|
|
154
|
+
const autoOpenConfig = resolveAutoOpen(config);
|
|
155
|
+
const isResume = payload.reason === "resume";
|
|
156
|
+
const shouldAutoOpen = isResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
|
|
157
|
+
if (shouldAutoOpen) {
|
|
158
|
+
const controller = registry.getController(dialogId);
|
|
159
|
+
if (controller) {
|
|
160
|
+
requestAnimationFrame(() => {
|
|
161
|
+
controller.open();
|
|
162
|
+
});
|
|
163
|
+
} else if (onDialogNotMounted) {
|
|
164
|
+
onDialogNotMounted(dialogId, step.id);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
previousDialogIdRef.current = dialogId;
|
|
169
|
+
});
|
|
170
|
+
const unsubscribeExit = events.on("stepExit", (payload) => {
|
|
171
|
+
const step = payload.previousStep;
|
|
172
|
+
const dialogId = step.dialogId;
|
|
173
|
+
const nextStep = payload.currentStep;
|
|
174
|
+
if (nextStep?.dialogId === dialogId) return;
|
|
175
|
+
if (dialogId && flow.dialogs?.[dialogId]) {
|
|
176
|
+
const config = flow.dialogs[dialogId];
|
|
177
|
+
const autoClose = config.autoClose ?? "differentDialog";
|
|
178
|
+
if (autoClose === "never") return;
|
|
179
|
+
const controller = registry.getController(dialogId);
|
|
180
|
+
if (controller) {
|
|
181
|
+
requestAnimationFrame(() => {
|
|
182
|
+
controller.close();
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
const handleFlowEnd = () => {
|
|
188
|
+
const dialogId = previousDialogIdRef.current;
|
|
189
|
+
if (dialogId && flow.dialogs?.[dialogId]) {
|
|
190
|
+
const config = flow.dialogs[dialogId];
|
|
191
|
+
const autoClose = config.autoClose ?? "differentDialog";
|
|
192
|
+
if (autoClose !== "never") {
|
|
193
|
+
const controller = registry.getController(dialogId);
|
|
194
|
+
controller?.close();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
previousDialogIdRef.current = void 0;
|
|
198
|
+
};
|
|
199
|
+
const unsubscribePause = events.on("flowPause", handleFlowEnd);
|
|
200
|
+
const unsubscribeCancel = events.on("flowCancel", handleFlowEnd);
|
|
201
|
+
const unsubscribeComplete = events.on("flowComplete", handleFlowEnd);
|
|
202
|
+
return () => {
|
|
203
|
+
unsubscribeEnter();
|
|
204
|
+
unsubscribeExit();
|
|
205
|
+
unsubscribePause();
|
|
206
|
+
unsubscribeCancel();
|
|
207
|
+
unsubscribeComplete();
|
|
208
|
+
};
|
|
209
|
+
}, [events, flow, registry, onDialogNotMounted]);
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
if (!flow || !state || state.status !== "running") return;
|
|
212
|
+
if (state.stepIndex < 0 || state.stepIndex >= flow.steps.length) return;
|
|
213
|
+
const currentStep = flow.steps[state.stepIndex];
|
|
214
|
+
previousDialogIdRef.current = currentStep.dialogId;
|
|
215
|
+
}, [flow, state]);
|
|
216
|
+
};
|
|
217
|
+
|
|
66
218
|
// src/motion/animationAdapter.tsx
|
|
67
219
|
import { motion } from "motion/react";
|
|
68
|
-
import { createContext as
|
|
69
|
-
import { jsx } from "react/jsx-runtime";
|
|
220
|
+
import { createContext as createContext3, useContext as useContext3, useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
|
|
221
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
70
222
|
var defaultAdapter = {
|
|
71
223
|
components: {
|
|
72
224
|
MotionDiv: motion.div,
|
|
@@ -109,16 +261,16 @@ var defaultAdapter = {
|
|
|
109
261
|
}
|
|
110
262
|
}
|
|
111
263
|
};
|
|
112
|
-
var AnimationAdapterContext =
|
|
264
|
+
var AnimationAdapterContext = createContext3(defaultAdapter);
|
|
113
265
|
var AnimationAdapterProvider = ({
|
|
114
266
|
adapter,
|
|
115
267
|
children
|
|
116
268
|
}) => {
|
|
117
|
-
const value =
|
|
118
|
-
return /* @__PURE__ */
|
|
269
|
+
const value = useMemo2(() => adapter ?? defaultAdapter, [adapter]);
|
|
270
|
+
return /* @__PURE__ */ jsx2(AnimationAdapterContext.Provider, { value, children });
|
|
119
271
|
};
|
|
120
272
|
var useAnimationAdapter = () => {
|
|
121
|
-
return
|
|
273
|
+
return useContext3(AnimationAdapterContext);
|
|
122
274
|
};
|
|
123
275
|
var defaultAnimationAdapter = defaultAdapter;
|
|
124
276
|
var reducedMotionAnimationAdapter = {
|
|
@@ -162,7 +314,7 @@ var usePreferredAnimationAdapter = (options) => {
|
|
|
162
314
|
if (!enabled || typeof window === "undefined") return false;
|
|
163
315
|
return window.matchMedia(REDUCED_MOTION_QUERY).matches;
|
|
164
316
|
});
|
|
165
|
-
|
|
317
|
+
useEffect2(() => {
|
|
166
318
|
if (!enabled || typeof window === "undefined") return;
|
|
167
319
|
const mediaQuery = window.matchMedia(REDUCED_MOTION_QUERY);
|
|
168
320
|
const handleChange = (event) => {
|
|
@@ -179,11 +331,11 @@ var usePreferredAnimationAdapter = (options) => {
|
|
|
179
331
|
};
|
|
180
332
|
|
|
181
333
|
// src/context.tsx
|
|
182
|
-
import { jsx as
|
|
183
|
-
var TourContext =
|
|
334
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
335
|
+
var TourContext = createContext4(void 0);
|
|
184
336
|
var DEFAULT_STORAGE_PREFIX = "tour";
|
|
185
337
|
var useFlowMap = (flows) => {
|
|
186
|
-
return
|
|
338
|
+
return useMemo3(() => {
|
|
187
339
|
const map = /* @__PURE__ */ new Map();
|
|
188
340
|
for (const flow of flows) {
|
|
189
341
|
map.set(flow.id, flow);
|
|
@@ -207,17 +359,17 @@ var TourProvider = ({
|
|
|
207
359
|
labels: labelsProp,
|
|
208
360
|
onVersionMismatch
|
|
209
361
|
}) => {
|
|
210
|
-
const mergedLabels =
|
|
362
|
+
const mergedLabels = useMemo3(
|
|
211
363
|
() => ({ ...defaultLabels, ...labelsProp }),
|
|
212
364
|
[labelsProp]
|
|
213
365
|
);
|
|
214
366
|
const flowMap = useFlowMap(flows);
|
|
215
|
-
const storeRef =
|
|
216
|
-
const unsubscribeRef =
|
|
217
|
-
const stepHooksUnsubscribeRef =
|
|
218
|
-
const fallbackStorageRef =
|
|
219
|
-
const pendingResumeRef =
|
|
220
|
-
const autoStartRequestedRef =
|
|
367
|
+
const storeRef = useRef3(null);
|
|
368
|
+
const unsubscribeRef = useRef3(null);
|
|
369
|
+
const stepHooksUnsubscribeRef = useRef3(null);
|
|
370
|
+
const fallbackStorageRef = useRef3(void 0);
|
|
371
|
+
const pendingResumeRef = useRef3(/* @__PURE__ */ new Set());
|
|
372
|
+
const autoStartRequestedRef = useRef3(null);
|
|
221
373
|
const [activeFlowId, setActiveFlowId] = useState2(null);
|
|
222
374
|
const [state, setState] = useState2(null);
|
|
223
375
|
const [events, setEvents] = useState2(
|
|
@@ -225,7 +377,7 @@ var TourProvider = ({
|
|
|
225
377
|
);
|
|
226
378
|
const [debugEnabled, setDebugEnabled] = useState2(defaultDebug);
|
|
227
379
|
const [delayInfo, setDelayInfo] = useState2(null);
|
|
228
|
-
const teardownStore =
|
|
380
|
+
const teardownStore = useCallback2(() => {
|
|
229
381
|
unsubscribeRef.current?.();
|
|
230
382
|
unsubscribeRef.current = null;
|
|
231
383
|
stepHooksUnsubscribeRef.current?.();
|
|
@@ -235,7 +387,7 @@ var TourProvider = ({
|
|
|
235
387
|
setDelayInfo(null);
|
|
236
388
|
pendingResumeRef.current.clear();
|
|
237
389
|
}, []);
|
|
238
|
-
|
|
390
|
+
useEffect3(() => {
|
|
239
391
|
return () => {
|
|
240
392
|
teardownStore();
|
|
241
393
|
setState(null);
|
|
@@ -243,7 +395,7 @@ var TourProvider = ({
|
|
|
243
395
|
setActiveFlowId(null);
|
|
244
396
|
};
|
|
245
397
|
}, [teardownStore]);
|
|
246
|
-
|
|
398
|
+
useEffect3(() => {
|
|
247
399
|
if (!activeFlowId) return;
|
|
248
400
|
const definition = flowMap.get(activeFlowId);
|
|
249
401
|
if (!definition) {
|
|
@@ -266,7 +418,7 @@ var TourProvider = ({
|
|
|
266
418
|
console.warn(`[tour][step] ${phase} hook failed`, error);
|
|
267
419
|
}
|
|
268
420
|
};
|
|
269
|
-
const ensureStore =
|
|
421
|
+
const ensureStore = useCallback2(
|
|
270
422
|
(flowId) => {
|
|
271
423
|
const existing = storeRef.current;
|
|
272
424
|
if (existing && existing.definition.id === flowId) {
|
|
@@ -325,7 +477,7 @@ var TourProvider = ({
|
|
|
325
477
|
teardownStore
|
|
326
478
|
]
|
|
327
479
|
);
|
|
328
|
-
const getActiveStore =
|
|
480
|
+
const getActiveStore = useCallback2(() => {
|
|
329
481
|
const store = storeRef.current;
|
|
330
482
|
if (!store) {
|
|
331
483
|
throw new Error(
|
|
@@ -337,7 +489,7 @@ var TourProvider = ({
|
|
|
337
489
|
const isPromiseLike2 = (value) => {
|
|
338
490
|
return typeof value === "object" && value !== null && typeof value.then === "function";
|
|
339
491
|
};
|
|
340
|
-
const invokeStepHook =
|
|
492
|
+
const invokeStepHook = useCallback2(
|
|
341
493
|
async (hook, context, phase) => {
|
|
342
494
|
if (!hook) return;
|
|
343
495
|
try {
|
|
@@ -351,7 +503,7 @@ var TourProvider = ({
|
|
|
351
503
|
},
|
|
352
504
|
[]
|
|
353
505
|
);
|
|
354
|
-
const runResumeHooks =
|
|
506
|
+
const runResumeHooks = useCallback2(
|
|
355
507
|
async (definition, flowState, strategy) => {
|
|
356
508
|
if (flowState.status !== "running") return;
|
|
357
509
|
if (strategy === "current") {
|
|
@@ -391,13 +543,13 @@ var TourProvider = ({
|
|
|
391
543
|
},
|
|
392
544
|
[invokeStepHook]
|
|
393
545
|
);
|
|
394
|
-
const resolveResumeStrategy =
|
|
546
|
+
const resolveResumeStrategy = useCallback2(
|
|
395
547
|
(definition, options) => {
|
|
396
548
|
return options?.resumeStrategy ?? definition.resumeStrategy ?? "chain";
|
|
397
549
|
},
|
|
398
550
|
[]
|
|
399
551
|
);
|
|
400
|
-
const startFlow =
|
|
552
|
+
const startFlow = useCallback2(
|
|
401
553
|
(flowId, options) => {
|
|
402
554
|
const store = ensureStore(flowId);
|
|
403
555
|
const previousState = store.getState();
|
|
@@ -427,7 +579,7 @@ var TourProvider = ({
|
|
|
427
579
|
[ensureStore, resolveResumeStrategy, runResumeHooks]
|
|
428
580
|
);
|
|
429
581
|
const [eligibleFlows, setEligibleFlows] = useState2([]);
|
|
430
|
-
|
|
582
|
+
useEffect3(() => {
|
|
431
583
|
const autoStartFlows = flows.filter((f) => f.autoStart);
|
|
432
584
|
if (autoStartFlows.length === 0) {
|
|
433
585
|
setEligibleFlows([]);
|
|
@@ -491,7 +643,7 @@ var TourProvider = ({
|
|
|
491
643
|
cancelled = true;
|
|
492
644
|
};
|
|
493
645
|
}, [flows, storageAdapter, storageNamespace]);
|
|
494
|
-
|
|
646
|
+
useEffect3(() => {
|
|
495
647
|
if (eligibleFlows.length === 0) {
|
|
496
648
|
autoStartRequestedRef.current = null;
|
|
497
649
|
return;
|
|
@@ -526,14 +678,14 @@ var TourProvider = ({
|
|
|
526
678
|
}
|
|
527
679
|
};
|
|
528
680
|
}, [activeFlowId, eligibleFlows, startFlow]);
|
|
529
|
-
const next =
|
|
530
|
-
const back =
|
|
531
|
-
const goToStep =
|
|
681
|
+
const next = useCallback2(() => getActiveStore().next(), [getActiveStore]);
|
|
682
|
+
const back = useCallback2(() => getActiveStore().back(), [getActiveStore]);
|
|
683
|
+
const goToStep = useCallback2(
|
|
532
684
|
(step) => getActiveStore().goToStep(step),
|
|
533
685
|
[getActiveStore]
|
|
534
686
|
);
|
|
535
|
-
const pause =
|
|
536
|
-
const resume =
|
|
687
|
+
const pause = useCallback2(() => getActiveStore().pause(), [getActiveStore]);
|
|
688
|
+
const resume = useCallback2(() => {
|
|
537
689
|
const store = getActiveStore();
|
|
538
690
|
const previousState = store.getState();
|
|
539
691
|
if (previousState.status === "paused") {
|
|
@@ -551,27 +703,31 @@ var TourProvider = ({
|
|
|
551
703
|
}
|
|
552
704
|
return result;
|
|
553
705
|
}, [getActiveStore, resolveResumeStrategy, runResumeHooks]);
|
|
554
|
-
const cancel =
|
|
706
|
+
const cancel = useCallback2(
|
|
555
707
|
(reason) => getActiveStore().cancel(reason),
|
|
556
708
|
[getActiveStore]
|
|
557
709
|
);
|
|
558
|
-
const complete =
|
|
710
|
+
const complete = useCallback2(
|
|
559
711
|
() => getActiveStore().complete(),
|
|
560
712
|
[getActiveStore]
|
|
561
713
|
);
|
|
562
|
-
const advanceStep =
|
|
714
|
+
const advanceStep = useCallback2(
|
|
563
715
|
(stepId) => getActiveStore().advanceStep(stepId),
|
|
564
716
|
[getActiveStore]
|
|
565
717
|
);
|
|
566
|
-
const toggleDebug =
|
|
718
|
+
const toggleDebug = useCallback2(() => {
|
|
567
719
|
setDebugEnabled((previous) => !previous);
|
|
568
720
|
}, []);
|
|
569
|
-
const activeStep =
|
|
721
|
+
const activeStep = useMemo3(() => {
|
|
570
722
|
if (!state || !storeRef.current) return null;
|
|
571
723
|
if (state.stepIndex < 0) return null;
|
|
572
724
|
return storeRef.current.definition.steps[state.stepIndex] ?? null;
|
|
573
725
|
}, [state]);
|
|
574
|
-
|
|
726
|
+
const activeDialogConfig = useMemo3(() => {
|
|
727
|
+
if (!activeStep?.dialogId || !storeRef.current) return void 0;
|
|
728
|
+
return storeRef.current.definition.dialogs?.[activeStep.dialogId];
|
|
729
|
+
}, [activeStep]);
|
|
730
|
+
useEffect3(() => {
|
|
575
731
|
if (!activeFlowId) return;
|
|
576
732
|
if (!pendingResumeRef.current.has(activeFlowId)) return;
|
|
577
733
|
if (!state || state.status !== "running") return;
|
|
@@ -586,12 +742,13 @@ var TourProvider = ({
|
|
|
586
742
|
pendingResumeRef.current.delete(activeFlowId);
|
|
587
743
|
void runResumeHooks(definition, state, resumeStrategy);
|
|
588
744
|
}, [activeFlowId, flowMap, resolveResumeStrategy, runResumeHooks, state]);
|
|
589
|
-
const contextValue =
|
|
745
|
+
const contextValue = useMemo3(
|
|
590
746
|
() => ({
|
|
591
747
|
flows: flowMap,
|
|
592
748
|
activeFlowId,
|
|
593
749
|
state,
|
|
594
750
|
activeStep,
|
|
751
|
+
activeDialogConfig,
|
|
595
752
|
startFlow,
|
|
596
753
|
next,
|
|
597
754
|
back,
|
|
@@ -613,6 +770,7 @@ var TourProvider = ({
|
|
|
613
770
|
[
|
|
614
771
|
activeFlowId,
|
|
615
772
|
activeStep,
|
|
773
|
+
activeDialogConfig,
|
|
616
774
|
advanceStep,
|
|
617
775
|
back,
|
|
618
776
|
cancel,
|
|
@@ -639,10 +797,41 @@ var TourProvider = ({
|
|
|
639
797
|
reducedMotionAdapter,
|
|
640
798
|
enabled: autoDetectReducedMotion
|
|
641
799
|
});
|
|
642
|
-
return /* @__PURE__ */
|
|
800
|
+
return /* @__PURE__ */ jsx3(AnimationAdapterProvider, { adapter: resolvedAnimationAdapter, children: /* @__PURE__ */ jsx3(LabelsProvider, { value: mergedLabels, children: /* @__PURE__ */ jsx3(DialogRegistryProvider, { children: /* @__PURE__ */ jsxs(TourContext.Provider, { value: contextValue, children: [
|
|
801
|
+
/* @__PURE__ */ jsx3(
|
|
802
|
+
DialogAutomationBridge,
|
|
803
|
+
{
|
|
804
|
+
flow: activeFlowId ? flowMap.get(activeFlowId) : void 0,
|
|
805
|
+
state,
|
|
806
|
+
events
|
|
807
|
+
}
|
|
808
|
+
),
|
|
809
|
+
children
|
|
810
|
+
] }) }) }) });
|
|
811
|
+
};
|
|
812
|
+
var DialogAutomationBridge = ({
|
|
813
|
+
flow,
|
|
814
|
+
state,
|
|
815
|
+
events
|
|
816
|
+
}) => {
|
|
817
|
+
const registry = useDialogRegistryOptional();
|
|
818
|
+
useDialogAutomation({
|
|
819
|
+
flow,
|
|
820
|
+
state,
|
|
821
|
+
events,
|
|
822
|
+
registry,
|
|
823
|
+
onDialogNotMounted: (dialogId, stepId) => {
|
|
824
|
+
if (process.env.NODE_ENV !== "production") {
|
|
825
|
+
console.warn(
|
|
826
|
+
`[tour] Step "${stepId}" references dialogId "${dialogId}" but no dialog is mounted with that ID. Ensure your dialog uses useTourDialog({ dialogId: "${dialogId}" }).`
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
});
|
|
831
|
+
return null;
|
|
643
832
|
};
|
|
644
833
|
var useTour = () => {
|
|
645
|
-
const context =
|
|
834
|
+
const context = useContext4(TourContext);
|
|
646
835
|
if (!context) {
|
|
647
836
|
throw new Error("useTour must be used within a TourProvider");
|
|
648
837
|
}
|
|
@@ -650,14 +839,14 @@ var useTour = () => {
|
|
|
650
839
|
};
|
|
651
840
|
var useTourEvents = (event, handler) => {
|
|
652
841
|
const { events } = useTour();
|
|
653
|
-
|
|
842
|
+
useEffect3(() => {
|
|
654
843
|
if (!events) return;
|
|
655
844
|
return events.on(event, handler);
|
|
656
845
|
}, [event, events, handler]);
|
|
657
846
|
};
|
|
658
847
|
|
|
659
848
|
// src/hooks/useTourTarget.ts
|
|
660
|
-
import { useEffect as
|
|
849
|
+
import { useEffect as useEffect4, useLayoutEffect, useRef as useRef4, useState as useState3 } from "react";
|
|
661
850
|
|
|
662
851
|
// src/hooks/scrollMargin.ts
|
|
663
852
|
var DEFAULT_SCROLL_MARGIN = 16;
|
|
@@ -961,11 +1150,11 @@ var resolveStepTarget = (target) => {
|
|
|
961
1150
|
var useTourTarget = () => {
|
|
962
1151
|
const { activeStep, state, activeFlowId, flows } = useTour();
|
|
963
1152
|
const [targetInfo, setTargetInfo] = useState3(INITIAL_TARGET_INFO);
|
|
964
|
-
const autoScrollStateRef =
|
|
965
|
-
const autoScrollRafRef =
|
|
966
|
-
const autoScrollTimeoutRef =
|
|
967
|
-
const lastRectRef =
|
|
968
|
-
const initialScrollStepRef =
|
|
1153
|
+
const autoScrollStateRef = useRef4({ stepId: null, checks: 0, stalledChecks: 0, done: false, lastRect: null });
|
|
1154
|
+
const autoScrollRafRef = useRef4(null);
|
|
1155
|
+
const autoScrollTimeoutRef = useRef4(null);
|
|
1156
|
+
const lastRectRef = useRef4(null);
|
|
1157
|
+
const initialScrollStepRef = useRef4(null);
|
|
969
1158
|
const cancelAutoScrollLoop = () => {
|
|
970
1159
|
if (!isBrowser) return;
|
|
971
1160
|
if (autoScrollTimeoutRef.current !== null) {
|
|
@@ -977,7 +1166,7 @@ var useTourTarget = () => {
|
|
|
977
1166
|
autoScrollRafRef.current = null;
|
|
978
1167
|
}
|
|
979
1168
|
};
|
|
980
|
-
|
|
1169
|
+
useEffect4(() => {
|
|
981
1170
|
if (!activeStep) {
|
|
982
1171
|
initialScrollStepRef.current = null;
|
|
983
1172
|
}
|
|
@@ -1017,7 +1206,7 @@ var useTourTarget = () => {
|
|
|
1017
1206
|
targetInfo.status,
|
|
1018
1207
|
targetInfo.rectSource
|
|
1019
1208
|
]);
|
|
1020
|
-
|
|
1209
|
+
useEffect4(() => {
|
|
1021
1210
|
if (!activeStep || !state || state.status !== "running") {
|
|
1022
1211
|
setTargetInfo(INITIAL_TARGET_INFO);
|
|
1023
1212
|
autoScrollStateRef.current = {
|
|
@@ -1340,7 +1529,7 @@ var useTourTarget = () => {
|
|
|
1340
1529
|
waitForPredicateController = null;
|
|
1341
1530
|
};
|
|
1342
1531
|
}, [activeStep, activeFlowId, flows, state]);
|
|
1343
|
-
|
|
1532
|
+
useEffect4(() => {
|
|
1344
1533
|
if (!isBrowser) return;
|
|
1345
1534
|
if (!activeStep) {
|
|
1346
1535
|
cancelAutoScrollLoop();
|
|
@@ -1421,10 +1610,10 @@ var useTourTarget = () => {
|
|
|
1421
1610
|
};
|
|
1422
1611
|
|
|
1423
1612
|
// src/hooks/useHudState.ts
|
|
1424
|
-
import { useCallback as
|
|
1613
|
+
import { useCallback as useCallback3, useEffect as useEffect9, useMemo as useMemo5, useRef as useRef7, useState as useState7 } from "react";
|
|
1425
1614
|
|
|
1426
1615
|
// src/hooks/useAdvanceRules.ts
|
|
1427
|
-
import { useEffect as
|
|
1616
|
+
import { useEffect as useEffect5 } from "react";
|
|
1428
1617
|
var DEFAULT_POLL_MS = 250;
|
|
1429
1618
|
var isListenerTarget = (value) => {
|
|
1430
1619
|
return !!value && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function";
|
|
@@ -1463,7 +1652,7 @@ var useAdvanceRules = (target) => {
|
|
|
1463
1652
|
complete,
|
|
1464
1653
|
setDelayInfo
|
|
1465
1654
|
} = useTour();
|
|
1466
|
-
|
|
1655
|
+
useEffect5(() => {
|
|
1467
1656
|
if (!isBrowser) return;
|
|
1468
1657
|
if (!state || state.status !== "running") return;
|
|
1469
1658
|
if (!activeStep) return;
|
|
@@ -1634,7 +1823,7 @@ var useAdvanceRules = (target) => {
|
|
|
1634
1823
|
};
|
|
1635
1824
|
|
|
1636
1825
|
// src/hooks/useHiddenTargetFallback.ts
|
|
1637
|
-
import { useEffect as
|
|
1826
|
+
import { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as useState4 } from "react";
|
|
1638
1827
|
var DEFAULT_DELAY_MS = 900;
|
|
1639
1828
|
var DEFAULT_GRACE_PERIOD_MS = 400;
|
|
1640
1829
|
var useHiddenTargetFallback = ({
|
|
@@ -1645,9 +1834,9 @@ var useHiddenTargetFallback = ({
|
|
|
1645
1834
|
}) => {
|
|
1646
1835
|
const [usingScreenFallback, setUsingScreenFallback] = useState4(false);
|
|
1647
1836
|
const [isInGracePeriod, setIsInGracePeriod] = useState4(false);
|
|
1648
|
-
const timeoutRef =
|
|
1649
|
-
const graceTimeoutRef =
|
|
1650
|
-
const skipTriggeredRef =
|
|
1837
|
+
const timeoutRef = useRef5(null);
|
|
1838
|
+
const graceTimeoutRef = useRef5(null);
|
|
1839
|
+
const skipTriggeredRef = useRef5(false);
|
|
1651
1840
|
const hiddenMode = step?.targetBehavior?.hidden ?? "screen";
|
|
1652
1841
|
const hiddenDelayMs = Math.max(
|
|
1653
1842
|
0,
|
|
@@ -1665,7 +1854,7 @@ var useHiddenTargetFallback = ({
|
|
|
1665
1854
|
graceTimeoutRef.current = null;
|
|
1666
1855
|
}
|
|
1667
1856
|
};
|
|
1668
|
-
|
|
1857
|
+
useEffect6(() => {
|
|
1669
1858
|
skipTriggeredRef.current = false;
|
|
1670
1859
|
setUsingScreenFallback(false);
|
|
1671
1860
|
setIsInGracePeriod(false);
|
|
@@ -1676,7 +1865,7 @@ var useHiddenTargetFallback = ({
|
|
|
1676
1865
|
clearGraceTimeout();
|
|
1677
1866
|
};
|
|
1678
1867
|
}, [step?.id]);
|
|
1679
|
-
|
|
1868
|
+
useEffect6(() => {
|
|
1680
1869
|
if (!isBrowser) return void 0;
|
|
1681
1870
|
if (!step) return void 0;
|
|
1682
1871
|
clearPendingTimeout();
|
|
@@ -1722,7 +1911,7 @@ var useHiddenTargetFallback = ({
|
|
|
1722
1911
|
hiddenDelayMs,
|
|
1723
1912
|
onSkip
|
|
1724
1913
|
]);
|
|
1725
|
-
const resolvedTarget =
|
|
1914
|
+
const resolvedTarget = useMemo4(() => {
|
|
1726
1915
|
if (!usingScreenFallback) {
|
|
1727
1916
|
return target;
|
|
1728
1917
|
}
|
|
@@ -1744,10 +1933,10 @@ var useHiddenTargetFallback = ({
|
|
|
1744
1933
|
};
|
|
1745
1934
|
|
|
1746
1935
|
// src/hooks/useRouteMismatch.ts
|
|
1747
|
-
import { useEffect as
|
|
1936
|
+
import { useEffect as useEffect7, useState as useState5 } from "react";
|
|
1748
1937
|
var useRouteMismatch = (step) => {
|
|
1749
1938
|
const [currentPath, setCurrentPath] = useState5(() => getCurrentRoutePath());
|
|
1750
|
-
|
|
1939
|
+
useEffect7(() => {
|
|
1751
1940
|
return subscribeToRouteChanges((path) => {
|
|
1752
1941
|
setCurrentPath(path);
|
|
1753
1942
|
});
|
|
@@ -1762,13 +1951,13 @@ var useRouteMismatch = (step) => {
|
|
|
1762
1951
|
};
|
|
1763
1952
|
|
|
1764
1953
|
// src/hooks/useViewportRect.ts
|
|
1765
|
-
import { useEffect as
|
|
1954
|
+
import { useEffect as useEffect8, useRef as useRef6, useState as useState6 } from "react";
|
|
1766
1955
|
var useViewportRect = () => {
|
|
1767
1956
|
const [viewport, setViewport] = useState6(
|
|
1768
1957
|
() => getViewportRect()
|
|
1769
1958
|
);
|
|
1770
|
-
const rafRef =
|
|
1771
|
-
|
|
1959
|
+
const rafRef = useRef6(null);
|
|
1960
|
+
useEffect8(() => {
|
|
1772
1961
|
if (!isBrowser) return;
|
|
1773
1962
|
const updateViewport = () => {
|
|
1774
1963
|
rafRef.current = null;
|
|
@@ -1810,12 +1999,12 @@ var normalizeFlowFilter = (value) => {
|
|
|
1810
1999
|
};
|
|
1811
2000
|
var useHudState = (options = {}) => {
|
|
1812
2001
|
const { flowId } = options;
|
|
1813
|
-
const flowFilter =
|
|
2002
|
+
const flowFilter = useMemo5(() => normalizeFlowFilter(flowId), [flowId]);
|
|
1814
2003
|
const { state, activeStep, activeFlowId, flows, next, complete, pause, resume } = useTour();
|
|
1815
2004
|
const target = useTourTarget();
|
|
1816
2005
|
const viewportRect = useViewportRect();
|
|
1817
2006
|
useAdvanceRules(target);
|
|
1818
|
-
const matchesFlowFilter =
|
|
2007
|
+
const matchesFlowFilter = useMemo5(() => {
|
|
1819
2008
|
if (!flowFilter || flowFilter.length === 0) return true;
|
|
1820
2009
|
if (!activeFlowId) return false;
|
|
1821
2010
|
return flowFilter.includes(activeFlowId);
|
|
@@ -1826,12 +2015,12 @@ var useHudState = (options = {}) => {
|
|
|
1826
2015
|
const [shouldRender, setShouldRender] = useState7(
|
|
1827
2016
|
Boolean(runningStep)
|
|
1828
2017
|
);
|
|
1829
|
-
|
|
2018
|
+
useEffect9(() => {
|
|
1830
2019
|
if (runningStep) {
|
|
1831
2020
|
setShouldRender(true);
|
|
1832
2021
|
}
|
|
1833
2022
|
}, [runningStep?.id]);
|
|
1834
|
-
|
|
2023
|
+
useEffect9(() => {
|
|
1835
2024
|
if (!shouldRender) return;
|
|
1836
2025
|
if (runningStep) return;
|
|
1837
2026
|
if (target.status !== "idle") return;
|
|
@@ -1843,19 +2032,19 @@ var useHudState = (options = {}) => {
|
|
|
1843
2032
|
};
|
|
1844
2033
|
}, [runningStep, shouldRender, target.status]);
|
|
1845
2034
|
const { isRouteMismatch, currentPath } = useRouteMismatch(activeStep);
|
|
1846
|
-
const pausedForMissingTargetRef =
|
|
1847
|
-
|
|
2035
|
+
const pausedForMissingTargetRef = useRef7(null);
|
|
2036
|
+
useEffect9(() => {
|
|
1848
2037
|
if (!isRouteMismatch) return;
|
|
1849
2038
|
if (!runningState || runningState.status !== "running") return;
|
|
1850
2039
|
pause();
|
|
1851
2040
|
}, [isRouteMismatch, runningState, pause]);
|
|
1852
|
-
|
|
2041
|
+
useEffect9(() => {
|
|
1853
2042
|
if (isRouteMismatch) return;
|
|
1854
2043
|
if (pausedForMissingTargetRef.current !== null) return;
|
|
1855
2044
|
if (!state || state.status !== "paused") return;
|
|
1856
2045
|
resume();
|
|
1857
2046
|
}, [isRouteMismatch, state, resume]);
|
|
1858
|
-
const skipHiddenStep =
|
|
2047
|
+
const skipHiddenStep = useCallback3(() => {
|
|
1859
2048
|
if (!runningState || runningState.status !== "running") return;
|
|
1860
2049
|
if (!activeFlowId) return;
|
|
1861
2050
|
const flow = flows.get(activeFlowId);
|
|
@@ -1873,7 +2062,7 @@ var useHudState = (options = {}) => {
|
|
|
1873
2062
|
viewportRect,
|
|
1874
2063
|
onSkip: skipHiddenStep
|
|
1875
2064
|
});
|
|
1876
|
-
|
|
2065
|
+
useEffect9(() => {
|
|
1877
2066
|
if (isRouteMismatch) return;
|
|
1878
2067
|
if (activeStep?.route !== void 0) return;
|
|
1879
2068
|
if (isInGracePeriod) return;
|
|
@@ -1892,14 +2081,14 @@ var useHudState = (options = {}) => {
|
|
|
1892
2081
|
currentPath,
|
|
1893
2082
|
pause
|
|
1894
2083
|
]);
|
|
1895
|
-
|
|
2084
|
+
useEffect9(() => {
|
|
1896
2085
|
if (pausedForMissingTargetRef.current === null) return;
|
|
1897
2086
|
if (!state || state.status !== "paused") return;
|
|
1898
2087
|
if (currentPath === pausedForMissingTargetRef.current) return;
|
|
1899
2088
|
pausedForMissingTargetRef.current = null;
|
|
1900
2089
|
resume();
|
|
1901
2090
|
}, [currentPath, state, resume]);
|
|
1902
|
-
|
|
2091
|
+
useEffect9(() => {
|
|
1903
2092
|
pausedForMissingTargetRef.current = null;
|
|
1904
2093
|
}, [activeStep?.id]);
|
|
1905
2094
|
const canRenderStep = Boolean(runningStep && runningState);
|
|
@@ -1924,24 +2113,24 @@ var useHudState = (options = {}) => {
|
|
|
1924
2113
|
};
|
|
1925
2114
|
|
|
1926
2115
|
// src/hooks/useHudDescription.ts
|
|
1927
|
-
import { useMemo as
|
|
2116
|
+
import { useMemo as useMemo6 } from "react";
|
|
1928
2117
|
var sanitizeForId = (value) => {
|
|
1929
2118
|
const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1930
2119
|
return normalized.length > 0 ? normalized : "step";
|
|
1931
2120
|
};
|
|
1932
2121
|
var useHudDescription = (options) => {
|
|
1933
2122
|
const { step, fallbackAriaDescribedBy } = options;
|
|
1934
|
-
const targetDescription =
|
|
2123
|
+
const targetDescription = useMemo6(() => {
|
|
1935
2124
|
if (!step) return null;
|
|
1936
2125
|
if (typeof step.target !== "object") return null;
|
|
1937
2126
|
const description = step.target.description;
|
|
1938
2127
|
return typeof description === "string" ? description : null;
|
|
1939
2128
|
}, [step]);
|
|
1940
|
-
const descriptionId =
|
|
2129
|
+
const descriptionId = useMemo6(() => {
|
|
1941
2130
|
if (!step || !targetDescription) return void 0;
|
|
1942
2131
|
return `tour-step-${sanitizeForId(step.id)}-description`;
|
|
1943
2132
|
}, [step, targetDescription]);
|
|
1944
|
-
const combinedAriaDescribedBy =
|
|
2133
|
+
const combinedAriaDescribedBy = useMemo6(() => {
|
|
1945
2134
|
const parts = [fallbackAriaDescribedBy, descriptionId].filter(Boolean);
|
|
1946
2135
|
return parts.length > 0 ? parts.join(" ") : void 0;
|
|
1947
2136
|
}, [descriptionId, fallbackAriaDescribedBy]);
|
|
@@ -1953,10 +2142,10 @@ var useHudDescription = (options) => {
|
|
|
1953
2142
|
};
|
|
1954
2143
|
|
|
1955
2144
|
// src/hooks/useHudShortcuts.ts
|
|
1956
|
-
import { useEffect as
|
|
2145
|
+
import { useEffect as useEffect10 } from "react";
|
|
1957
2146
|
|
|
1958
2147
|
// src/hooks/useTourControls.ts
|
|
1959
|
-
import { useCallback as
|
|
2148
|
+
import { useCallback as useCallback4, useMemo as useMemo7 } from "react";
|
|
1960
2149
|
var hasManualAdvance = (rules) => rules.some((rule) => rule.type === "manual");
|
|
1961
2150
|
var didPreviousAdvanceViaRoute = (rules) => rules.some((rule) => rule.type === "route");
|
|
1962
2151
|
var useTourControls = () => {
|
|
@@ -1971,7 +2160,7 @@ var useTourControls = () => {
|
|
|
1971
2160
|
flows,
|
|
1972
2161
|
activeStep
|
|
1973
2162
|
} = tour;
|
|
1974
|
-
const computed =
|
|
2163
|
+
const computed = useMemo7(() => {
|
|
1975
2164
|
if (!state || state.status !== "running" || !activeStep) {
|
|
1976
2165
|
return {
|
|
1977
2166
|
isActive: false,
|
|
@@ -2020,11 +2209,11 @@ var useTourControls = () => {
|
|
|
2020
2209
|
} = computed;
|
|
2021
2210
|
const canGoBack = showBackButton && !backDisabled;
|
|
2022
2211
|
const canGoNext = showNextButton && !nextDisabled;
|
|
2023
|
-
const goBack =
|
|
2212
|
+
const goBack = useCallback4(() => {
|
|
2024
2213
|
if (!canGoBack) return;
|
|
2025
2214
|
back();
|
|
2026
2215
|
}, [back, canGoBack]);
|
|
2027
|
-
const goNext =
|
|
2216
|
+
const goNext = useCallback4(() => {
|
|
2028
2217
|
if (!canGoNext) return;
|
|
2029
2218
|
if (isLast) {
|
|
2030
2219
|
complete();
|
|
@@ -2032,7 +2221,7 @@ var useTourControls = () => {
|
|
|
2032
2221
|
next();
|
|
2033
2222
|
}
|
|
2034
2223
|
}, [canGoNext, complete, isLast, next]);
|
|
2035
|
-
return
|
|
2224
|
+
return useMemo7(
|
|
2036
2225
|
() => ({
|
|
2037
2226
|
showBackButton,
|
|
2038
2227
|
backDisabled,
|
|
@@ -2077,7 +2266,7 @@ var useHudShortcuts = (target, options) => {
|
|
|
2077
2266
|
const escapeEnabled = options?.escape ?? true;
|
|
2078
2267
|
const { state } = useTour();
|
|
2079
2268
|
const { cancel, canGoBack, goBack, canGoNext, goNext, isActive } = useTourControls();
|
|
2080
|
-
|
|
2269
|
+
useEffect10(() => {
|
|
2081
2270
|
if (!isBrowser) return void 0;
|
|
2082
2271
|
if (!enabled) return void 0;
|
|
2083
2272
|
if (!target) return void 0;
|
|
@@ -2141,10 +2330,10 @@ var useHudShortcuts = (target, options) => {
|
|
|
2141
2330
|
};
|
|
2142
2331
|
|
|
2143
2332
|
// src/hooks/useTourHud.ts
|
|
2144
|
-
import { useMemo as
|
|
2333
|
+
import { useMemo as useMemo9, useState as useState9 } from "react";
|
|
2145
2334
|
|
|
2146
2335
|
// src/hooks/useBodyScrollLock.ts
|
|
2147
|
-
import { useEffect as
|
|
2336
|
+
import { useEffect as useEffect11 } from "react";
|
|
2148
2337
|
var lockCount = 0;
|
|
2149
2338
|
var previousOverflow = null;
|
|
2150
2339
|
var acquireLock = () => {
|
|
@@ -2165,7 +2354,7 @@ var releaseLock = () => {
|
|
|
2165
2354
|
}
|
|
2166
2355
|
};
|
|
2167
2356
|
var useBodyScrollLock = (enabled) => {
|
|
2168
|
-
|
|
2357
|
+
useEffect11(() => {
|
|
2169
2358
|
if (!enabled) return;
|
|
2170
2359
|
acquireLock();
|
|
2171
2360
|
return () => {
|
|
@@ -2175,7 +2364,7 @@ var useBodyScrollLock = (enabled) => {
|
|
|
2175
2364
|
};
|
|
2176
2365
|
|
|
2177
2366
|
// src/hooks/useHudTargetIssue.ts
|
|
2178
|
-
import { useEffect as
|
|
2367
|
+
import { useEffect as useEffect12, useMemo as useMemo8, useState as useState8 } from "react";
|
|
2179
2368
|
var deriveTargetIssue = (params) => {
|
|
2180
2369
|
const { target, labels } = params;
|
|
2181
2370
|
if (target.isScreen) return null;
|
|
@@ -2209,11 +2398,11 @@ var useHudTargetIssue = (target, options) => {
|
|
|
2209
2398
|
const labels = useTourLabels();
|
|
2210
2399
|
const delayMs = Math.max(0, options?.delayMs ?? 500);
|
|
2211
2400
|
const [armed, setArmed] = useState8(false);
|
|
2212
|
-
const rawIssue =
|
|
2401
|
+
const rawIssue = useMemo8(
|
|
2213
2402
|
() => deriveTargetIssue({ target, labels }),
|
|
2214
2403
|
[target.isScreen, target.rectSource, target.status, target.visibility, labels]
|
|
2215
2404
|
);
|
|
2216
|
-
|
|
2405
|
+
useEffect12(() => {
|
|
2217
2406
|
if (!rawIssue) {
|
|
2218
2407
|
setArmed(false);
|
|
2219
2408
|
return;
|
|
@@ -2271,7 +2460,7 @@ var useTourHud = (options = {}) => {
|
|
|
2271
2460
|
radius: overlayRadius,
|
|
2272
2461
|
interactionMode: hudState.flowHudOptions?.backdrop?.interaction ?? backdropInteraction
|
|
2273
2462
|
};
|
|
2274
|
-
const popover =
|
|
2463
|
+
const popover = useMemo9(() => {
|
|
2275
2464
|
return {
|
|
2276
2465
|
offset: popoverOptions?.offset ?? 32,
|
|
2277
2466
|
role: popoverOptions?.role ?? "dialog",
|
|
@@ -2283,13 +2472,13 @@ var useTourHud = (options = {}) => {
|
|
|
2283
2472
|
placement: hudState.runningStep?.placement
|
|
2284
2473
|
};
|
|
2285
2474
|
}, [hudState.runningStep?.placement, popoverOptions]);
|
|
2286
|
-
const descriptionResult =
|
|
2475
|
+
const descriptionResult = useMemo9(() => {
|
|
2287
2476
|
return {
|
|
2288
2477
|
...description,
|
|
2289
2478
|
text: description.targetDescription
|
|
2290
2479
|
};
|
|
2291
2480
|
}, [description]);
|
|
2292
|
-
const focusManager =
|
|
2481
|
+
const focusManager = useMemo9(
|
|
2293
2482
|
() => ({
|
|
2294
2483
|
active: hudState.focusTrapActive,
|
|
2295
2484
|
target: hudState.hudTarget,
|
|
@@ -2319,7 +2508,7 @@ var useTourHud = (options = {}) => {
|
|
|
2319
2508
|
};
|
|
2320
2509
|
|
|
2321
2510
|
// src/hooks/useTourOverlay.ts
|
|
2322
|
-
import { useEffect as
|
|
2511
|
+
import { useEffect as useEffect13, useMemo as useMemo10, useRef as useRef8 } from "react";
|
|
2323
2512
|
var DEFAULT_PADDING = 12;
|
|
2324
2513
|
var DEFAULT_RADIUS = 12;
|
|
2325
2514
|
var DEFAULT_EDGE_BUFFER = 0;
|
|
@@ -2332,9 +2521,9 @@ var useTourOverlay = (options) => {
|
|
|
2332
2521
|
interactionMode = "passthrough",
|
|
2333
2522
|
isInGracePeriod = false
|
|
2334
2523
|
} = options;
|
|
2335
|
-
const hasShownRef =
|
|
2336
|
-
const lastReadyTargetRef =
|
|
2337
|
-
|
|
2524
|
+
const hasShownRef = useRef8(false);
|
|
2525
|
+
const lastReadyTargetRef = useRef8(null);
|
|
2526
|
+
useEffect13(() => {
|
|
2338
2527
|
if (!isBrowser) return;
|
|
2339
2528
|
if (target.status === "ready") {
|
|
2340
2529
|
hasShownRef.current = true;
|
|
@@ -2384,15 +2573,15 @@ var useTourOverlay = (options) => {
|
|
|
2384
2573
|
height: highlightHeight,
|
|
2385
2574
|
radius: highlightRadius
|
|
2386
2575
|
} : null;
|
|
2387
|
-
const maskCapable =
|
|
2576
|
+
const maskCapable = useMemo10(() => supportsMasking(), []);
|
|
2388
2577
|
const isActive = target.status === "ready" || target.status === "resolving" && cachedTarget !== null || isInGracePeriod;
|
|
2389
2578
|
const shouldMask = maskCapable && isActive;
|
|
2390
|
-
const maskId =
|
|
2579
|
+
const maskId = useMemo10(
|
|
2391
2580
|
() => `tour-overlay-mask-${Math.random().toString(36).slice(2, 10)}`,
|
|
2392
2581
|
[]
|
|
2393
2582
|
);
|
|
2394
2583
|
const maskUrl = shouldMask ? `url(#${maskId})` : void 0;
|
|
2395
|
-
const fallbackSegments =
|
|
2584
|
+
const fallbackSegments = useMemo10(() => {
|
|
2396
2585
|
if (!isActive || shouldMask || !hasHighlightBounds || !highlightRect) {
|
|
2397
2586
|
return null;
|
|
2398
2587
|
}
|
|
@@ -2445,7 +2634,7 @@ var useTourOverlay = (options) => {
|
|
|
2445
2634
|
viewport.height,
|
|
2446
2635
|
viewport.width
|
|
2447
2636
|
]);
|
|
2448
|
-
const blockerSegments =
|
|
2637
|
+
const blockerSegments = useMemo10(() => {
|
|
2449
2638
|
if (interactionMode !== "block") {
|
|
2450
2639
|
return null;
|
|
2451
2640
|
}
|
|
@@ -2573,37 +2762,202 @@ var useRadixDialogAdapter = (options = {}) => {
|
|
|
2573
2762
|
var waitForDom = () => new Promise(
|
|
2574
2763
|
(resolve) => requestAnimationFrame(() => setTimeout(resolve, 0))
|
|
2575
2764
|
);
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
};
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
await waitForDom();
|
|
2765
|
+
|
|
2766
|
+
// src/hooks/useRadixTourDialog.ts
|
|
2767
|
+
import { useCallback as useCallback5, useEffect as useEffect14, useMemo as useMemo11, useRef as useRef9, useState as useState10 } from "react";
|
|
2768
|
+
var resolveAutoOpen2 = (config) => {
|
|
2769
|
+
if (!config) return { onEnter: true, onResume: true };
|
|
2770
|
+
const { autoOpen } = config;
|
|
2771
|
+
if (autoOpen === false) return { onEnter: false, onResume: false };
|
|
2772
|
+
if (autoOpen === true || autoOpen === void 0) {
|
|
2773
|
+
return { onEnter: true, onResume: true };
|
|
2774
|
+
}
|
|
2775
|
+
return {
|
|
2776
|
+
onEnter: autoOpen.onEnter ?? true,
|
|
2777
|
+
onResume: autoOpen.onResume ?? true
|
|
2590
2778
|
};
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2779
|
+
};
|
|
2780
|
+
var useRadixTourDialog = (params) => {
|
|
2781
|
+
const { dialogId } = params;
|
|
2782
|
+
const { activeFlowId, state, flows, goToStep, events } = useTour();
|
|
2783
|
+
const registry = useDialogRegistryOptional();
|
|
2784
|
+
const { suspendExternalFocusTrap } = useTourFocusDominance();
|
|
2785
|
+
const [internalOpen, setInternalOpen] = useState10(false);
|
|
2786
|
+
const lastStepIndexRef = useRef9(-1);
|
|
2787
|
+
const isResumeRef = useRef9(false);
|
|
2788
|
+
const flow = activeFlowId ? flows.get(activeFlowId) : void 0;
|
|
2789
|
+
const dialogConfig = flow?.dialogs?.[dialogId];
|
|
2790
|
+
const currentStep = flow && state && state.stepIndex >= 0 ? flow.steps[state.stepIndex] : void 0;
|
|
2791
|
+
const isStepActive = currentStep?.dialogId === dialogId;
|
|
2792
|
+
const autoOpenConfig = resolveAutoOpen2(dialogConfig);
|
|
2793
|
+
const autoClose = dialogConfig?.autoClose ?? "differentDialog";
|
|
2794
|
+
const shouldBeOpen = useMemo11(() => {
|
|
2795
|
+
if (!isStepActive) return false;
|
|
2796
|
+
return true;
|
|
2797
|
+
}, [isStepActive]);
|
|
2798
|
+
useEffect14(() => {
|
|
2799
|
+
if (!events) return;
|
|
2800
|
+
const unsubscribe = events.on("flowResume", () => {
|
|
2801
|
+
isResumeRef.current = true;
|
|
2802
|
+
});
|
|
2803
|
+
return unsubscribe;
|
|
2804
|
+
}, [events]);
|
|
2805
|
+
useEffect14(() => {
|
|
2806
|
+
if (!state || state.status !== "running") return;
|
|
2807
|
+
if (!flow) return;
|
|
2808
|
+
const currentStepIndex = state.stepIndex;
|
|
2809
|
+
const previousStepIndex = lastStepIndexRef.current;
|
|
2810
|
+
const wasResume = isResumeRef.current;
|
|
2811
|
+
isResumeRef.current = false;
|
|
2812
|
+
if (previousStepIndex === -1 && currentStepIndex >= 0) {
|
|
2813
|
+
lastStepIndexRef.current = currentStepIndex;
|
|
2814
|
+
if (isStepActive) {
|
|
2815
|
+
const shouldAutoOpen = wasResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
|
|
2816
|
+
if (shouldAutoOpen) {
|
|
2817
|
+
setInternalOpen(true);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2822
|
+
if (previousStepIndex === currentStepIndex) return;
|
|
2823
|
+
lastStepIndexRef.current = currentStepIndex;
|
|
2824
|
+
const previousStep = previousStepIndex >= 0 ? flow.steps[previousStepIndex] : void 0;
|
|
2825
|
+
const wasActive = previousStep?.dialogId === dialogId;
|
|
2826
|
+
if (isStepActive && !wasActive) {
|
|
2827
|
+
const shouldAutoOpen = wasResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
|
|
2828
|
+
if (shouldAutoOpen) {
|
|
2829
|
+
setInternalOpen(true);
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
if (wasActive && !isStepActive) {
|
|
2833
|
+
if (autoClose === "always" || autoClose === "differentDialog") {
|
|
2834
|
+
setInternalOpen(false);
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
}, [
|
|
2838
|
+
state,
|
|
2839
|
+
flow,
|
|
2840
|
+
dialogId,
|
|
2841
|
+
isStepActive,
|
|
2842
|
+
autoOpenConfig.onEnter,
|
|
2843
|
+
autoOpenConfig.onResume,
|
|
2844
|
+
autoClose
|
|
2845
|
+
]);
|
|
2846
|
+
useEffect14(() => {
|
|
2847
|
+
if (!events) return;
|
|
2848
|
+
const unsubscribeEnter = events.on("stepEnter", (payload) => {
|
|
2849
|
+
const step = payload.currentStep;
|
|
2850
|
+
if (step.dialogId !== dialogId) return;
|
|
2851
|
+
const isResume = payload.reason === "resume";
|
|
2852
|
+
const shouldAutoOpen = isResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
|
|
2853
|
+
if (shouldAutoOpen) {
|
|
2854
|
+
requestAnimationFrame(() => {
|
|
2855
|
+
setInternalOpen(true);
|
|
2856
|
+
});
|
|
2857
|
+
}
|
|
2858
|
+
});
|
|
2859
|
+
const unsubscribeExit = events.on("stepExit", (payload) => {
|
|
2860
|
+
const step = payload.previousStep;
|
|
2861
|
+
if (step.dialogId !== dialogId) return;
|
|
2862
|
+
const nextStep = payload.currentStep;
|
|
2863
|
+
if (nextStep?.dialogId === dialogId) {
|
|
2864
|
+
return;
|
|
2865
|
+
}
|
|
2866
|
+
if (autoClose === "always" || autoClose === "differentDialog") {
|
|
2867
|
+
requestAnimationFrame(() => {
|
|
2868
|
+
setInternalOpen(false);
|
|
2869
|
+
});
|
|
2870
|
+
}
|
|
2871
|
+
});
|
|
2872
|
+
return () => {
|
|
2873
|
+
unsubscribeEnter();
|
|
2874
|
+
unsubscribeExit();
|
|
2875
|
+
};
|
|
2876
|
+
}, [events, dialogId, autoOpenConfig, autoClose]);
|
|
2877
|
+
const handleDismiss = useCallback5(() => {
|
|
2878
|
+
if (!dialogConfig) return;
|
|
2879
|
+
setInternalOpen(false);
|
|
2880
|
+
goToStep(dialogConfig.onDismissGoToStepId);
|
|
2881
|
+
}, [dialogConfig, goToStep]);
|
|
2882
|
+
const onOpenChange = useCallback5(
|
|
2883
|
+
(open) => {
|
|
2884
|
+
if (open) {
|
|
2885
|
+
setInternalOpen(true);
|
|
2886
|
+
} else {
|
|
2887
|
+
if (isStepActive && dialogConfig) {
|
|
2888
|
+
handleDismiss();
|
|
2889
|
+
} else {
|
|
2890
|
+
setInternalOpen(false);
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
},
|
|
2894
|
+
[isStepActive, dialogConfig, handleDismiss]
|
|
2895
|
+
);
|
|
2896
|
+
useEffect14(() => {
|
|
2897
|
+
if (!registry) return;
|
|
2898
|
+
const controller = {
|
|
2899
|
+
open: () => setInternalOpen(true),
|
|
2900
|
+
close: () => setInternalOpen(false),
|
|
2901
|
+
isOpen: () => internalOpen
|
|
2902
|
+
};
|
|
2903
|
+
registry.register(dialogId, controller);
|
|
2904
|
+
return () => registry.unregister(dialogId);
|
|
2905
|
+
}, [registry, dialogId, internalOpen]);
|
|
2906
|
+
const preventDismiss = useCallback5(
|
|
2907
|
+
(event) => {
|
|
2908
|
+
if (suspendExternalFocusTrap) {
|
|
2909
|
+
event.preventDefault();
|
|
2910
|
+
}
|
|
2911
|
+
},
|
|
2912
|
+
[suspendExternalFocusTrap]
|
|
2913
|
+
);
|
|
2914
|
+
const handleEscapeKeyDown = useCallback5(
|
|
2915
|
+
(event) => {
|
|
2916
|
+
if (isStepActive && dialogConfig) {
|
|
2917
|
+
event.preventDefault();
|
|
2918
|
+
handleDismiss();
|
|
2919
|
+
}
|
|
2920
|
+
},
|
|
2921
|
+
[isStepActive, dialogConfig, handleDismiss]
|
|
2922
|
+
);
|
|
2923
|
+
const handleInteractOutside = useCallback5(
|
|
2924
|
+
(event) => {
|
|
2925
|
+
if (suspendExternalFocusTrap) {
|
|
2926
|
+
event.preventDefault();
|
|
2927
|
+
return;
|
|
2928
|
+
}
|
|
2929
|
+
if (isStepActive && dialogConfig) {
|
|
2930
|
+
event.preventDefault();
|
|
2931
|
+
handleDismiss();
|
|
2932
|
+
}
|
|
2933
|
+
},
|
|
2934
|
+
[suspendExternalFocusTrap, isStepActive, dialogConfig, handleDismiss]
|
|
2935
|
+
);
|
|
2936
|
+
return {
|
|
2937
|
+
isStepActive,
|
|
2938
|
+
shouldBeOpen,
|
|
2939
|
+
onOpenChange,
|
|
2940
|
+
dialogProps: {
|
|
2941
|
+
open: internalOpen,
|
|
2942
|
+
onOpenChange,
|
|
2943
|
+
modal: !suspendExternalFocusTrap
|
|
2944
|
+
},
|
|
2945
|
+
contentProps: {
|
|
2946
|
+
trapFocus: !suspendExternalFocusTrap,
|
|
2947
|
+
onInteractOutside: handleInteractOutside,
|
|
2948
|
+
onFocusOutside: preventDismiss,
|
|
2949
|
+
onEscapeKeyDown: handleEscapeKeyDown
|
|
2950
|
+
}
|
|
2596
2951
|
};
|
|
2597
|
-
return { isOpen, open, close };
|
|
2598
2952
|
};
|
|
2599
2953
|
|
|
2600
2954
|
// src/hooks/useDelayAdvance.ts
|
|
2601
|
-
import { useEffect as
|
|
2955
|
+
import { useEffect as useEffect15, useMemo as useMemo12, useState as useState11 } from "react";
|
|
2602
2956
|
var getTimestamp = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
2603
2957
|
var useDelayAdvance = () => {
|
|
2604
2958
|
const { delayInfo, activeStep, state } = useTour();
|
|
2605
|
-
const [now, setNow] =
|
|
2606
|
-
|
|
2959
|
+
const [now, setNow] = useState11(() => getTimestamp());
|
|
2960
|
+
useEffect15(() => {
|
|
2607
2961
|
if (!delayInfo) return;
|
|
2608
2962
|
if (!activeStep || activeStep.id !== delayInfo.stepId) return;
|
|
2609
2963
|
if (!state || state.status !== "running") return;
|
|
@@ -2620,12 +2974,12 @@ var useDelayAdvance = () => {
|
|
|
2620
2974
|
}
|
|
2621
2975
|
};
|
|
2622
2976
|
}, [delayInfo, activeStep, state]);
|
|
2623
|
-
|
|
2977
|
+
useEffect15(() => {
|
|
2624
2978
|
if (!delayInfo) {
|
|
2625
2979
|
setNow(getTimestamp());
|
|
2626
2980
|
}
|
|
2627
2981
|
}, [delayInfo]);
|
|
2628
|
-
return
|
|
2982
|
+
return useMemo12(() => {
|
|
2629
2983
|
const matchingStep = !!delayInfo && !!activeStep && activeStep.id === delayInfo.stepId;
|
|
2630
2984
|
const isRunning = matchingStep && state?.status === "running";
|
|
2631
2985
|
if (!delayInfo) {
|
|
@@ -2678,10 +3032,10 @@ var useDelayAdvance = () => {
|
|
|
2678
3032
|
};
|
|
2679
3033
|
|
|
2680
3034
|
// src/components/OverlayBackdrop.tsx
|
|
2681
|
-
import { useEffect as
|
|
3035
|
+
import { useEffect as useEffect16, useRef as useRef10 } from "react";
|
|
2682
3036
|
import { createPortal } from "react-dom";
|
|
2683
3037
|
import { AnimatePresence } from "motion/react";
|
|
2684
|
-
import { jsx as
|
|
3038
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2685
3039
|
var styles = {
|
|
2686
3040
|
root: {
|
|
2687
3041
|
position: "fixed",
|
|
@@ -2767,9 +3121,9 @@ var OverlayBackdrop = ({
|
|
|
2767
3121
|
viewport
|
|
2768
3122
|
} = overlay;
|
|
2769
3123
|
const hasHighlightBounds = Boolean(highlight.rect);
|
|
2770
|
-
const prevScreenTargetRef =
|
|
3124
|
+
const prevScreenTargetRef = useRef10(null);
|
|
2771
3125
|
const shouldSnapHighlight = prevScreenTargetRef.current === true && !highlight.isScreen && hasHighlightBounds;
|
|
2772
|
-
|
|
3126
|
+
useEffect16(() => {
|
|
2773
3127
|
prevScreenTargetRef.current = highlight.isScreen;
|
|
2774
3128
|
}, [highlight.isScreen]);
|
|
2775
3129
|
const resolvedBlur = typeof blurAmount === "number" ? `${blurAmount}px` : "0px";
|
|
@@ -2829,7 +3183,7 @@ var OverlayBackdrop = ({
|
|
|
2829
3183
|
overlayStyle.backgroundColor = color;
|
|
2830
3184
|
}
|
|
2831
3185
|
return createPortal(
|
|
2832
|
-
/* @__PURE__ */
|
|
3186
|
+
/* @__PURE__ */ jsxs2(
|
|
2833
3187
|
MotionDiv,
|
|
2834
3188
|
{
|
|
2835
3189
|
className: rootClassName,
|
|
@@ -2837,7 +3191,7 @@ var OverlayBackdrop = ({
|
|
|
2837
3191
|
"aria-hidden": ariaHidden,
|
|
2838
3192
|
"data-tour-overlay": "",
|
|
2839
3193
|
children: [
|
|
2840
|
-
/* @__PURE__ */
|
|
3194
|
+
/* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ jsx4(
|
|
2841
3195
|
MotionSvg,
|
|
2842
3196
|
{
|
|
2843
3197
|
width: "0",
|
|
@@ -2849,7 +3203,7 @@ var OverlayBackdrop = ({
|
|
|
2849
3203
|
animate: { opacity: 1 },
|
|
2850
3204
|
exit: { opacity: 0 },
|
|
2851
3205
|
transition: overlayTransition,
|
|
2852
|
-
children: /* @__PURE__ */
|
|
3206
|
+
children: /* @__PURE__ */ jsx4(MotionDefs, { children: /* @__PURE__ */ jsxs2(
|
|
2853
3207
|
MotionMask,
|
|
2854
3208
|
{
|
|
2855
3209
|
id: maskId ?? void 0,
|
|
@@ -2861,7 +3215,7 @@ var OverlayBackdrop = ({
|
|
|
2861
3215
|
animate: { width: viewport.width, height: viewport.height },
|
|
2862
3216
|
transition: highlightTransition,
|
|
2863
3217
|
children: [
|
|
2864
|
-
/* @__PURE__ */
|
|
3218
|
+
/* @__PURE__ */ jsx4(
|
|
2865
3219
|
MotionRect,
|
|
2866
3220
|
{
|
|
2867
3221
|
x: "0",
|
|
@@ -2877,7 +3231,7 @@ var OverlayBackdrop = ({
|
|
|
2877
3231
|
exit: { opacity: 0 }
|
|
2878
3232
|
}
|
|
2879
3233
|
),
|
|
2880
|
-
/* @__PURE__ */
|
|
3234
|
+
/* @__PURE__ */ jsx4(
|
|
2881
3235
|
MotionRect,
|
|
2882
3236
|
{
|
|
2883
3237
|
initial: false,
|
|
@@ -2896,7 +3250,7 @@ var OverlayBackdrop = ({
|
|
|
2896
3250
|
},
|
|
2897
3251
|
"tour-mask"
|
|
2898
3252
|
) : null }),
|
|
2899
|
-
/* @__PURE__ */
|
|
3253
|
+
/* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ jsx4(
|
|
2900
3254
|
MotionDiv,
|
|
2901
3255
|
{
|
|
2902
3256
|
className: overlayClassName,
|
|
@@ -2924,7 +3278,7 @@ var OverlayBackdrop = ({
|
|
|
2924
3278
|
},
|
|
2925
3279
|
"tour-overlay"
|
|
2926
3280
|
) : null }),
|
|
2927
|
-
/* @__PURE__ */
|
|
3281
|
+
/* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ jsx4(
|
|
2928
3282
|
MotionDiv,
|
|
2929
3283
|
{
|
|
2930
3284
|
className: segmentClassName,
|
|
@@ -2954,13 +3308,13 @@ var OverlayBackdrop = ({
|
|
|
2954
3308
|
},
|
|
2955
3309
|
`tour-overlay-fallback-${segment.key}`
|
|
2956
3310
|
)) : null }),
|
|
2957
|
-
showInteractionBlocker && blockerSegments ? /* @__PURE__ */
|
|
3311
|
+
showInteractionBlocker && blockerSegments ? /* @__PURE__ */ jsx4(
|
|
2958
3312
|
"div",
|
|
2959
3313
|
{
|
|
2960
3314
|
style: { ...styles.blockerContainer, zIndex },
|
|
2961
3315
|
"data-tour-overlay-layer": "interaction-blocker",
|
|
2962
3316
|
"aria-hidden": true,
|
|
2963
|
-
children: blockerSegments.map((segment) => /* @__PURE__ */
|
|
3317
|
+
children: blockerSegments.map((segment) => /* @__PURE__ */ jsx4(
|
|
2964
3318
|
"div",
|
|
2965
3319
|
{
|
|
2966
3320
|
style: {
|
|
@@ -2975,7 +3329,7 @@ var OverlayBackdrop = ({
|
|
|
2975
3329
|
))
|
|
2976
3330
|
}
|
|
2977
3331
|
) : null,
|
|
2978
|
-
/* @__PURE__ */
|
|
3332
|
+
/* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ jsx4(
|
|
2979
3333
|
MotionDiv,
|
|
2980
3334
|
{
|
|
2981
3335
|
className: ringClassName,
|
|
@@ -3006,7 +3360,7 @@ var OverlayBackdrop = ({
|
|
|
3006
3360
|
};
|
|
3007
3361
|
|
|
3008
3362
|
// src/components/TourPopoverPortal.tsx
|
|
3009
|
-
import { useEffect as
|
|
3363
|
+
import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect2, useMemo as useMemo13, useRef as useRef11, useState as useState12 } from "react";
|
|
3010
3364
|
import { createPortal as createPortal2 } from "react-dom";
|
|
3011
3365
|
import {
|
|
3012
3366
|
autoPlacement,
|
|
@@ -3073,12 +3427,12 @@ var TourPopoverPortal = ({
|
|
|
3073
3427
|
const popoverContentTransition = transitionsOverride?.popoverContent ?? adapter.transitions.popoverContent ?? DEFAULT_POPOVER_CONTENT_TRANSITION;
|
|
3074
3428
|
const viewport = useViewportRect();
|
|
3075
3429
|
const prefersMobileLayout = viewport.width <= MOBILE_BREAKPOINT || viewport.height <= MOBILE_HEIGHT_BREAKPOINT;
|
|
3076
|
-
const prefersMobileRef =
|
|
3077
|
-
|
|
3430
|
+
const prefersMobileRef = useRef11(prefersMobileLayout);
|
|
3431
|
+
useEffect17(() => {
|
|
3078
3432
|
prefersMobileRef.current = prefersMobileLayout;
|
|
3079
3433
|
}, [prefersMobileLayout]);
|
|
3080
|
-
const lastReadyTargetRef =
|
|
3081
|
-
|
|
3434
|
+
const lastReadyTargetRef = useRef11(null);
|
|
3435
|
+
useEffect17(() => {
|
|
3082
3436
|
if (target.status === "ready" && target.rect) {
|
|
3083
3437
|
lastReadyTargetRef.current = {
|
|
3084
3438
|
rect: { ...target.rect },
|
|
@@ -3094,7 +3448,7 @@ var TourPopoverPortal = ({
|
|
|
3094
3448
|
const shouldHidePopover = !resolvedRect && !target.isScreen;
|
|
3095
3449
|
const fallbackRect = resolvedRect ?? viewport;
|
|
3096
3450
|
const fallbackIsScreen = resolvedIsScreen;
|
|
3097
|
-
const [floatingSize, setFloatingSize] =
|
|
3451
|
+
const [floatingSize, setFloatingSize] = useState12(null);
|
|
3098
3452
|
const clampVertical = (value) => Math.min(viewport.height - 24, Math.max(24, value));
|
|
3099
3453
|
const clampHorizontal = (value) => Math.min(viewport.width - 24, Math.max(24, value));
|
|
3100
3454
|
const screenCenteredTop = viewport.height / 2 - (floatingSize?.height ?? 0) / 2;
|
|
@@ -3105,7 +3459,7 @@ var TourPopoverPortal = ({
|
|
|
3105
3459
|
const leftBase = fallbackIsScreen ? screenCenteredLeft : fallbackRect.left + fallbackRect.width / 2 - floatingWidth / 2;
|
|
3106
3460
|
const left = clampHorizontal(leftBase);
|
|
3107
3461
|
const fallbackTransform = "translate3d(0px, 0px, 0px)";
|
|
3108
|
-
const fallbackPosition =
|
|
3462
|
+
const fallbackPosition = useMemo13(
|
|
3109
3463
|
() => ({
|
|
3110
3464
|
top,
|
|
3111
3465
|
left,
|
|
@@ -3113,7 +3467,7 @@ var TourPopoverPortal = ({
|
|
|
3113
3467
|
}),
|
|
3114
3468
|
[fallbackTransform, left, top]
|
|
3115
3469
|
);
|
|
3116
|
-
const centerInitialPosition =
|
|
3470
|
+
const centerInitialPosition = useMemo13(
|
|
3117
3471
|
() => ({
|
|
3118
3472
|
top: viewport.height / 2,
|
|
3119
3473
|
left: viewport.width / 2,
|
|
@@ -3121,22 +3475,22 @@ var TourPopoverPortal = ({
|
|
|
3121
3475
|
}),
|
|
3122
3476
|
[viewport.height, viewport.width]
|
|
3123
3477
|
);
|
|
3124
|
-
const floatingRef =
|
|
3125
|
-
const cachedFloatingPositionRef =
|
|
3126
|
-
const appliedFloatingCacheRef =
|
|
3127
|
-
const deferredScreenSnapRef =
|
|
3128
|
-
const [layoutMode, setLayoutMode] =
|
|
3478
|
+
const floatingRef = useRef11(null);
|
|
3479
|
+
const cachedFloatingPositionRef = useRef11(null);
|
|
3480
|
+
const appliedFloatingCacheRef = useRef11(null);
|
|
3481
|
+
const deferredScreenSnapRef = useRef11(null);
|
|
3482
|
+
const [layoutMode, setLayoutMode] = useState12(
|
|
3129
3483
|
() => prefersMobileLayout ? "mobile" : "floating"
|
|
3130
3484
|
);
|
|
3131
|
-
const [floatingPosition, setFloatingPosition] =
|
|
3132
|
-
const [dragPosition, setDragPosition] =
|
|
3133
|
-
const [isDragging, setIsDragging] =
|
|
3134
|
-
const dragStateRef =
|
|
3135
|
-
const overflowRetryRef =
|
|
3485
|
+
const [floatingPosition, setFloatingPosition] = useState12(fallbackPosition);
|
|
3486
|
+
const [dragPosition, setDragPosition] = useState12(null);
|
|
3487
|
+
const [isDragging, setIsDragging] = useState12(false);
|
|
3488
|
+
const dragStateRef = useRef11(null);
|
|
3489
|
+
const overflowRetryRef = useRef11({
|
|
3136
3490
|
stepId: null,
|
|
3137
3491
|
attempts: 0
|
|
3138
3492
|
});
|
|
3139
|
-
const overflowRetryTimeoutRef =
|
|
3493
|
+
const overflowRetryTimeoutRef = useRef11(null);
|
|
3140
3494
|
useLayoutEffect2(() => {
|
|
3141
3495
|
if (!isBrowser) return;
|
|
3142
3496
|
const node = floatingRef.current;
|
|
@@ -3156,25 +3510,25 @@ var TourPopoverPortal = ({
|
|
|
3156
3510
|
const autoAlignment = resolvedPlacement.endsWith(
|
|
3157
3511
|
"-start"
|
|
3158
3512
|
) ? "start" : resolvedPlacement.endsWith("-end") ? "end" : void 0;
|
|
3159
|
-
|
|
3513
|
+
useEffect17(() => {
|
|
3160
3514
|
setDragPosition(null);
|
|
3161
3515
|
setLayoutMode(prefersMobileRef.current ? "mobile" : "floating");
|
|
3162
3516
|
cachedFloatingPositionRef.current = null;
|
|
3163
3517
|
appliedFloatingCacheRef.current = null;
|
|
3164
3518
|
}, [target.stepId]);
|
|
3165
|
-
|
|
3519
|
+
useEffect17(() => {
|
|
3166
3520
|
if (layoutMode !== "manual") {
|
|
3167
3521
|
setDragPosition(null);
|
|
3168
3522
|
}
|
|
3169
3523
|
}, [layoutMode]);
|
|
3170
|
-
|
|
3524
|
+
useEffect17(() => {
|
|
3171
3525
|
cachedFloatingPositionRef.current = floatingPosition;
|
|
3172
3526
|
const cacheKey = getFloatingCacheKey(target);
|
|
3173
3527
|
if (cacheKey) {
|
|
3174
3528
|
floatingPositionCache.set(cacheKey, floatingPosition);
|
|
3175
3529
|
}
|
|
3176
3530
|
}, [floatingPosition, target.isScreen, target.stepId]);
|
|
3177
|
-
const dockedPosition =
|
|
3531
|
+
const dockedPosition = useMemo13(
|
|
3178
3532
|
() => ({
|
|
3179
3533
|
top: viewport.height - DOCKED_MARGIN,
|
|
3180
3534
|
left: viewport.width - DOCKED_MARGIN,
|
|
@@ -3182,7 +3536,7 @@ var TourPopoverPortal = ({
|
|
|
3182
3536
|
}),
|
|
3183
3537
|
[viewport.height, viewport.width]
|
|
3184
3538
|
);
|
|
3185
|
-
const mobilePosition =
|
|
3539
|
+
const mobilePosition = useMemo13(
|
|
3186
3540
|
() => ({
|
|
3187
3541
|
top: viewport.height - MOBILE_HORIZONTAL_GUTTER,
|
|
3188
3542
|
left: viewport.width / 2,
|
|
@@ -3190,17 +3544,17 @@ var TourPopoverPortal = ({
|
|
|
3190
3544
|
}),
|
|
3191
3545
|
[viewport.height, viewport.width]
|
|
3192
3546
|
);
|
|
3193
|
-
|
|
3547
|
+
useEffect17(() => {
|
|
3194
3548
|
if (layoutMode === "docked") {
|
|
3195
3549
|
setFloatingPosition(dockedPosition);
|
|
3196
3550
|
}
|
|
3197
3551
|
}, [dockedPosition, layoutMode]);
|
|
3198
|
-
|
|
3552
|
+
useEffect17(() => {
|
|
3199
3553
|
if (layoutMode === "mobile") {
|
|
3200
3554
|
setFloatingPosition(mobilePosition);
|
|
3201
3555
|
}
|
|
3202
3556
|
}, [layoutMode, mobilePosition]);
|
|
3203
|
-
|
|
3557
|
+
useEffect17(() => {
|
|
3204
3558
|
if (prefersMobileLayout) {
|
|
3205
3559
|
if (layoutMode !== "mobile") {
|
|
3206
3560
|
setLayoutMode("mobile");
|
|
@@ -3213,7 +3567,7 @@ var TourPopoverPortal = ({
|
|
|
3213
3567
|
setFloatingPosition(fallbackPosition);
|
|
3214
3568
|
}
|
|
3215
3569
|
}, [fallbackPosition, layoutMode, prefersMobileLayout]);
|
|
3216
|
-
|
|
3570
|
+
useEffect17(() => {
|
|
3217
3571
|
if (layoutMode !== "floating") return;
|
|
3218
3572
|
const stepId = target.stepId;
|
|
3219
3573
|
if (!stepId) return;
|
|
@@ -3237,7 +3591,7 @@ var TourPopoverPortal = ({
|
|
|
3237
3591
|
target.stepId
|
|
3238
3592
|
]);
|
|
3239
3593
|
const shouldDeferScreenSnap = layoutMode === "floating" && target.isScreen && Boolean(layoutId);
|
|
3240
|
-
|
|
3594
|
+
useEffect17(() => {
|
|
3241
3595
|
return () => {
|
|
3242
3596
|
if (deferredScreenSnapRef.current !== null) {
|
|
3243
3597
|
cancelAnimationFrame(deferredScreenSnapRef.current);
|
|
@@ -3257,7 +3611,7 @@ var TourPopoverPortal = ({
|
|
|
3257
3611
|
target.isScreen,
|
|
3258
3612
|
target.status
|
|
3259
3613
|
]);
|
|
3260
|
-
|
|
3614
|
+
useEffect17(() => {
|
|
3261
3615
|
if (!shouldDeferScreenSnap) return;
|
|
3262
3616
|
if (deferredScreenSnapRef.current !== null) {
|
|
3263
3617
|
cancelAnimationFrame(deferredScreenSnapRef.current);
|
|
@@ -3284,7 +3638,7 @@ var TourPopoverPortal = ({
|
|
|
3284
3638
|
}
|
|
3285
3639
|
};
|
|
3286
3640
|
}, [fallbackPosition, shouldDeferScreenSnap]);
|
|
3287
|
-
|
|
3641
|
+
useEffect17(() => {
|
|
3288
3642
|
return () => {
|
|
3289
3643
|
if (overflowRetryTimeoutRef.current !== null) {
|
|
3290
3644
|
window.clearTimeout(overflowRetryTimeoutRef.current);
|
|
@@ -3329,7 +3683,14 @@ var TourPopoverPortal = ({
|
|
|
3329
3683
|
padding: FLOATING_OFFSET,
|
|
3330
3684
|
alignment: autoAlignment
|
|
3331
3685
|
})
|
|
3332
|
-
] : [
|
|
3686
|
+
] : [
|
|
3687
|
+
flip({
|
|
3688
|
+
padding: FLOATING_OFFSET,
|
|
3689
|
+
fallbackStrategy: "bestFit",
|
|
3690
|
+
crossAxis: true,
|
|
3691
|
+
fallbackPlacements: ["bottom", "top", "right", "left"]
|
|
3692
|
+
})
|
|
3693
|
+
],
|
|
3333
3694
|
shift({ padding: FLOATING_OFFSET })
|
|
3334
3695
|
];
|
|
3335
3696
|
const updatePosition = async () => {
|
|
@@ -3374,9 +3735,10 @@ var TourPopoverPortal = ({
|
|
|
3374
3735
|
const spaceBelow = viewportBottom - targetRect.bottom;
|
|
3375
3736
|
const spaceLeft = targetRect.left - viewportLeft;
|
|
3376
3737
|
const spaceRight = viewportRight - targetRect.right;
|
|
3377
|
-
const
|
|
3378
|
-
const
|
|
3379
|
-
const
|
|
3738
|
+
const minVerticalSpaceNeeded = floatingBox.height + FLOATING_OFFSET * 2;
|
|
3739
|
+
const minHorizontalSpaceNeeded = floatingBox.width + FLOATING_OFFSET * 2;
|
|
3740
|
+
const hasVerticalSpace = spaceAbove >= minVerticalSpaceNeeded || spaceBelow >= minVerticalSpaceNeeded;
|
|
3741
|
+
const hasHorizontalSpace = spaceLeft >= minHorizontalSpaceNeeded || spaceRight >= minHorizontalSpaceNeeded;
|
|
3380
3742
|
const targetNearlyFillsViewport = !target.isScreen && !hasVerticalSpace && !hasHorizontalSpace;
|
|
3381
3743
|
const shouldDock = intersectsViewport && (targetNearlyFillsViewport || maxOverflow > overflowThreshold);
|
|
3382
3744
|
if (shouldDock) {
|
|
@@ -3510,7 +3872,7 @@ var TourPopoverPortal = ({
|
|
|
3510
3872
|
}
|
|
3511
3873
|
event.preventDefault();
|
|
3512
3874
|
};
|
|
3513
|
-
|
|
3875
|
+
useEffect17(() => endDrag, []);
|
|
3514
3876
|
const shouldUseFallbackInitial = layoutMode !== "mobile" && (Boolean(target.lastResolvedRect) || Boolean(cachedTarget));
|
|
3515
3877
|
const floatingCacheKey = layoutMode === "mobile" ? null : getFloatingCacheKey(target);
|
|
3516
3878
|
const persistedFloatingInitial = floatingCacheKey && floatingPositionCache.has(floatingCacheKey) ? floatingPositionCache.get(floatingCacheKey) ?? null : null;
|
|
@@ -3602,7 +3964,7 @@ var TourPopoverPortal = ({
|
|
|
3602
3964
|
};
|
|
3603
3965
|
|
|
3604
3966
|
// src/components/TourFocusManager.tsx
|
|
3605
|
-
import { useEffect as
|
|
3967
|
+
import { useEffect as useEffect18, useLayoutEffect as useLayoutEffect3, useRef as useRef12, useState as useState13 } from "react";
|
|
3606
3968
|
import { createPortal as createPortal3 } from "react-dom";
|
|
3607
3969
|
|
|
3608
3970
|
// src/utils/focus.ts
|
|
@@ -3663,7 +4025,7 @@ var focusElement = (element, options) => {
|
|
|
3663
4025
|
};
|
|
3664
4026
|
|
|
3665
4027
|
// src/components/TourFocusManager.tsx
|
|
3666
|
-
import { Fragment, jsx as
|
|
4028
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3667
4029
|
var runMicrotask = (callback) => {
|
|
3668
4030
|
if (typeof queueMicrotask === "function") {
|
|
3669
4031
|
queueMicrotask(callback);
|
|
@@ -3679,18 +4041,18 @@ var TourFocusManager = ({
|
|
|
3679
4041
|
highlightRect,
|
|
3680
4042
|
guardElementFocusRing
|
|
3681
4043
|
}) => {
|
|
3682
|
-
const previousFocusRef =
|
|
3683
|
-
const guardNodesRef =
|
|
4044
|
+
const previousFocusRef = useRef12(null);
|
|
4045
|
+
const guardNodesRef = useRef12({
|
|
3684
4046
|
"target-start": null,
|
|
3685
4047
|
"target-end": null,
|
|
3686
4048
|
"popover-start": null,
|
|
3687
4049
|
"popover-end": null
|
|
3688
4050
|
});
|
|
3689
|
-
const lastTabDirectionRef =
|
|
3690
|
-
const suppressGuardHopRef =
|
|
3691
|
-
const [targetRingActive, setTargetRingActive] =
|
|
3692
|
-
const [popoverRingActive, setPopoverRingActive] =
|
|
3693
|
-
const [popoverRect, setPopoverRect] =
|
|
4051
|
+
const lastTabDirectionRef = useRef12("forward");
|
|
4052
|
+
const suppressGuardHopRef = useRef12(null);
|
|
4053
|
+
const [targetRingActive, setTargetRingActive] = useState13(false);
|
|
4054
|
+
const [popoverRingActive, setPopoverRingActive] = useState13(false);
|
|
4055
|
+
const [popoverRect, setPopoverRect] = useState13(null);
|
|
3694
4056
|
const restoreFocus = () => {
|
|
3695
4057
|
const previous = previousFocusRef.current;
|
|
3696
4058
|
previousFocusRef.current = null;
|
|
@@ -3716,7 +4078,7 @@ var TourFocusManager = ({
|
|
|
3716
4078
|
restoreFocus();
|
|
3717
4079
|
};
|
|
3718
4080
|
}, [active, popoverNode, target.element]);
|
|
3719
|
-
|
|
4081
|
+
useEffect18(() => {
|
|
3720
4082
|
if (!isBrowser) return;
|
|
3721
4083
|
if (!active) return;
|
|
3722
4084
|
const doc = popoverNode?.ownerDocument ?? target.element?.ownerDocument ?? document;
|
|
@@ -3925,8 +4287,8 @@ var TourFocusManager = ({
|
|
|
3925
4287
|
const showPopoverRing = popoverRingActive && popoverRect;
|
|
3926
4288
|
if (!showTargetRing && !showPopoverRing) return null;
|
|
3927
4289
|
return createPortal3(
|
|
3928
|
-
/* @__PURE__ */
|
|
3929
|
-
showTargetRing && /* @__PURE__ */
|
|
4290
|
+
/* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
4291
|
+
showTargetRing && /* @__PURE__ */ jsx5(
|
|
3930
4292
|
"div",
|
|
3931
4293
|
{
|
|
3932
4294
|
style: {
|
|
@@ -3943,7 +4305,7 @@ var TourFocusManager = ({
|
|
|
3943
4305
|
"aria-hidden": true
|
|
3944
4306
|
}
|
|
3945
4307
|
),
|
|
3946
|
-
showPopoverRing && /* @__PURE__ */
|
|
4308
|
+
showPopoverRing && /* @__PURE__ */ jsx5(
|
|
3947
4309
|
"div",
|
|
3948
4310
|
{
|
|
3949
4311
|
style: {
|
|
@@ -3966,7 +4328,7 @@ var TourFocusManager = ({
|
|
|
3966
4328
|
};
|
|
3967
4329
|
|
|
3968
4330
|
// src/motion/useHudMotion.ts
|
|
3969
|
-
import { useMemo as
|
|
4331
|
+
import { useMemo as useMemo14 } from "react";
|
|
3970
4332
|
var DEFAULT_HIGHLIGHT_TRANSITION2 = {
|
|
3971
4333
|
duration: 0.35,
|
|
3972
4334
|
ease: "easeOut",
|
|
@@ -3993,7 +4355,7 @@ var DEFAULT_POPOVER_CONTENT_TRANSITION2 = {
|
|
|
3993
4355
|
};
|
|
3994
4356
|
var useHudMotion = () => {
|
|
3995
4357
|
const adapter = useAnimationAdapter();
|
|
3996
|
-
return
|
|
4358
|
+
return useMemo14(() => {
|
|
3997
4359
|
const components = {
|
|
3998
4360
|
...adapter.components
|
|
3999
4361
|
};
|
|
@@ -4011,12 +4373,12 @@ var useHudMotion = () => {
|
|
|
4011
4373
|
};
|
|
4012
4374
|
export {
|
|
4013
4375
|
AnimationAdapterProvider,
|
|
4376
|
+
DialogRegistryProvider,
|
|
4014
4377
|
OverlayBackdrop,
|
|
4015
4378
|
TourFocusManager,
|
|
4016
4379
|
TourPopoverPortal,
|
|
4017
4380
|
TourProvider,
|
|
4018
4381
|
createPathString,
|
|
4019
|
-
createRadixDialogHelpers,
|
|
4020
4382
|
createWaitForPredicateController,
|
|
4021
4383
|
defaultAnimationAdapter,
|
|
4022
4384
|
defaultLabels,
|
|
@@ -4028,6 +4390,8 @@ export {
|
|
|
4028
4390
|
useAnimationAdapter,
|
|
4029
4391
|
useBodyScrollLock,
|
|
4030
4392
|
useDelayAdvance,
|
|
4393
|
+
useDialogRegistry,
|
|
4394
|
+
useDialogRegistryOptional,
|
|
4031
4395
|
useHiddenTargetFallback,
|
|
4032
4396
|
useHudDescription,
|
|
4033
4397
|
useHudMotion,
|
|
@@ -4036,6 +4400,7 @@ export {
|
|
|
4036
4400
|
useHudTargetIssue,
|
|
4037
4401
|
usePreferredAnimationAdapter,
|
|
4038
4402
|
useRadixDialogAdapter,
|
|
4403
|
+
useRadixTourDialog,
|
|
4039
4404
|
useTour,
|
|
4040
4405
|
useTourControls,
|
|
4041
4406
|
useTourEvents,
|