@flowsterix/react 0.8.1 → 0.10.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.
package/dist/index.mjs CHANGED
@@ -25,12 +25,12 @@ import {
25
25
  serializeVersion
26
26
  } from "@flowsterix/core";
27
27
  import {
28
- createContext as createContext3,
29
- useCallback,
30
- useContext as useContext3,
31
- useEffect as useEffect2,
32
- useMemo as useMemo2,
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 createContext2, useContext as useContext2, useEffect, useMemo, useState } from "react";
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 = createContext2(defaultAdapter);
264
+ var AnimationAdapterContext = createContext3(defaultAdapter);
113
265
  var AnimationAdapterProvider = ({
114
266
  adapter,
115
267
  children
116
268
  }) => {
117
- const value = useMemo(() => adapter ?? defaultAdapter, [adapter]);
118
- return /* @__PURE__ */ jsx(AnimationAdapterContext.Provider, { value, children });
269
+ const value = useMemo2(() => adapter ?? defaultAdapter, [adapter]);
270
+ return /* @__PURE__ */ jsx2(AnimationAdapterContext.Provider, { value, children });
119
271
  };
120
272
  var useAnimationAdapter = () => {
121
- return useContext2(AnimationAdapterContext);
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
- useEffect(() => {
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 jsx2 } from "react/jsx-runtime";
183
- var TourContext = createContext3(void 0);
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 useMemo2(() => {
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 = useMemo2(
362
+ const mergedLabels = useMemo3(
211
363
  () => ({ ...defaultLabels, ...labelsProp }),
212
364
  [labelsProp]
213
365
  );
214
366
  const flowMap = useFlowMap(flows);
215
- const storeRef = useRef(null);
216
- const unsubscribeRef = useRef(null);
217
- const stepHooksUnsubscribeRef = useRef(null);
218
- const fallbackStorageRef = useRef(void 0);
219
- const pendingResumeRef = useRef(/* @__PURE__ */ new Set());
220
- const autoStartRequestedRef = useRef(null);
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 = useCallback(() => {
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
- useEffect2(() => {
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
- useEffect2(() => {
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 = useCallback(
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 = useCallback(() => {
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 = useCallback(
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 = useCallback(
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 = useCallback(
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 = useCallback(
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
- useEffect2(() => {
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
- useEffect2(() => {
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 = useCallback(() => getActiveStore().next(), [getActiveStore]);
530
- const back = useCallback(() => getActiveStore().back(), [getActiveStore]);
531
- const goToStep = useCallback(
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 = useCallback(() => getActiveStore().pause(), [getActiveStore]);
536
- const resume = useCallback(() => {
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 = useCallback(
706
+ const cancel = useCallback2(
555
707
  (reason) => getActiveStore().cancel(reason),
556
708
  [getActiveStore]
557
709
  );
558
- const complete = useCallback(
710
+ const complete = useCallback2(
559
711
  () => getActiveStore().complete(),
560
712
  [getActiveStore]
561
713
  );
562
- const advanceStep = useCallback(
714
+ const advanceStep = useCallback2(
563
715
  (stepId) => getActiveStore().advanceStep(stepId),
564
716
  [getActiveStore]
565
717
  );
566
- const toggleDebug = useCallback(() => {
718
+ const toggleDebug = useCallback2(() => {
567
719
  setDebugEnabled((previous) => !previous);
568
720
  }, []);
569
- const activeStep = useMemo2(() => {
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
- useEffect2(() => {
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 = useMemo2(
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__ */ jsx2(AnimationAdapterProvider, { adapter: resolvedAnimationAdapter, children: /* @__PURE__ */ jsx2(LabelsProvider, { value: mergedLabels, children: /* @__PURE__ */ jsx2(TourContext.Provider, { value: contextValue, children }) }) });
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 = useContext3(TourContext);
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
- useEffect2(() => {
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 useEffect3, useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
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 = useRef2({ stepId: null, checks: 0, stalledChecks: 0, done: false, lastRect: null });
965
- const autoScrollRafRef = useRef2(null);
966
- const autoScrollTimeoutRef = useRef2(null);
967
- const lastRectRef = useRef2(null);
968
- const initialScrollStepRef = useRef2(null);
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
- useEffect3(() => {
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
- useEffect3(() => {
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
- useEffect3(() => {
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 useCallback2, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef5, useState as useState7 } from "react";
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 useEffect4 } from "react";
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
- useEffect4(() => {
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 useEffect5, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
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 = useRef3(null);
1649
- const graceTimeoutRef = useRef3(null);
1650
- const skipTriggeredRef = useRef3(false);
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
- useEffect5(() => {
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
- useEffect5(() => {
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 = useMemo3(() => {
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 useEffect6, useState as useState5 } from "react";
1936
+ import { useEffect as useEffect7, useState as useState5 } from "react";
1748
1937
  var useRouteMismatch = (step) => {
1749
1938
  const [currentPath, setCurrentPath] = useState5(() => getCurrentRoutePath());
1750
- useEffect6(() => {
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 useEffect7, useRef as useRef4, useState as useState6 } from "react";
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 = useRef4(null);
1771
- useEffect7(() => {
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 = useMemo4(() => normalizeFlowFilter(flowId), [flowId]);
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 = useMemo4(() => {
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
- useEffect8(() => {
2018
+ useEffect9(() => {
1830
2019
  if (runningStep) {
1831
2020
  setShouldRender(true);
1832
2021
  }
1833
2022
  }, [runningStep?.id]);
1834
- useEffect8(() => {
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 = useRef5(null);
1847
- useEffect8(() => {
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
- useEffect8(() => {
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 = useCallback2(() => {
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
- useEffect8(() => {
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
- useEffect8(() => {
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
- useEffect8(() => {
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 useMemo5 } from "react";
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 = useMemo5(() => {
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 = useMemo5(() => {
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 = useMemo5(() => {
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 useEffect9 } from "react";
2145
+ import { useEffect as useEffect10 } from "react";
1957
2146
 
1958
2147
  // src/hooks/useTourControls.ts
1959
- import { useCallback as useCallback3, useMemo as useMemo6 } from "react";
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 = useMemo6(() => {
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 = useCallback3(() => {
2212
+ const goBack = useCallback4(() => {
2024
2213
  if (!canGoBack) return;
2025
2214
  back();
2026
2215
  }, [back, canGoBack]);
2027
- const goNext = useCallback3(() => {
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 useMemo6(
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
- useEffect9(() => {
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 useMemo8, useState as useState9 } from "react";
2333
+ import { useMemo as useMemo9, useState as useState9 } from "react";
2145
2334
 
2146
2335
  // src/hooks/useBodyScrollLock.ts
2147
- import { useEffect as useEffect10 } from "react";
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
- useEffect10(() => {
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 useEffect11, useMemo as useMemo7, useState as useState8 } from "react";
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 = useMemo7(
2401
+ const rawIssue = useMemo8(
2213
2402
  () => deriveTargetIssue({ target, labels }),
2214
2403
  [target.isScreen, target.rectSource, target.status, target.visibility, labels]
2215
2404
  );
2216
- useEffect11(() => {
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 = useMemo8(() => {
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 = useMemo8(() => {
2475
+ const descriptionResult = useMemo9(() => {
2287
2476
  return {
2288
2477
  ...description,
2289
2478
  text: description.targetDescription
2290
2479
  };
2291
2480
  }, [description]);
2292
- const focusManager = useMemo8(
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 useEffect12, useMemo as useMemo9, useRef as useRef6 } from "react";
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 = useRef6(false);
2336
- const lastReadyTargetRef = useRef6(null);
2337
- useEffect12(() => {
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 = useMemo9(() => supportsMasking(), []);
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 = useMemo9(
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 = useMemo9(() => {
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 = useMemo9(() => {
2637
+ const blockerSegments = useMemo10(() => {
2449
2638
  if (interactionMode !== "block") {
2450
2639
  return null;
2451
2640
  }
@@ -2569,13 +2758,206 @@ var useRadixDialogAdapter = (options = {}) => {
2569
2758
  };
2570
2759
  };
2571
2760
 
2761
+ // src/adapters/radixDialogHelpers.ts
2762
+ var waitForDom = () => new Promise(
2763
+ (resolve) => requestAnimationFrame(() => setTimeout(resolve, 0))
2764
+ );
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
2778
+ };
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
+ }
2951
+ };
2952
+ };
2953
+
2572
2954
  // src/hooks/useDelayAdvance.ts
2573
- import { useEffect as useEffect13, useMemo as useMemo10, useState as useState10 } from "react";
2955
+ import { useEffect as useEffect15, useMemo as useMemo12, useState as useState11 } from "react";
2574
2956
  var getTimestamp = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
2575
2957
  var useDelayAdvance = () => {
2576
2958
  const { delayInfo, activeStep, state } = useTour();
2577
- const [now, setNow] = useState10(() => getTimestamp());
2578
- useEffect13(() => {
2959
+ const [now, setNow] = useState11(() => getTimestamp());
2960
+ useEffect15(() => {
2579
2961
  if (!delayInfo) return;
2580
2962
  if (!activeStep || activeStep.id !== delayInfo.stepId) return;
2581
2963
  if (!state || state.status !== "running") return;
@@ -2592,12 +2974,12 @@ var useDelayAdvance = () => {
2592
2974
  }
2593
2975
  };
2594
2976
  }, [delayInfo, activeStep, state]);
2595
- useEffect13(() => {
2977
+ useEffect15(() => {
2596
2978
  if (!delayInfo) {
2597
2979
  setNow(getTimestamp());
2598
2980
  }
2599
2981
  }, [delayInfo]);
2600
- return useMemo10(() => {
2982
+ return useMemo12(() => {
2601
2983
  const matchingStep = !!delayInfo && !!activeStep && activeStep.id === delayInfo.stepId;
2602
2984
  const isRunning = matchingStep && state?.status === "running";
2603
2985
  if (!delayInfo) {
@@ -2650,10 +3032,10 @@ var useDelayAdvance = () => {
2650
3032
  };
2651
3033
 
2652
3034
  // src/components/OverlayBackdrop.tsx
2653
- import { useEffect as useEffect14, useRef as useRef7 } from "react";
3035
+ import { useEffect as useEffect16, useRef as useRef10 } from "react";
2654
3036
  import { createPortal } from "react-dom";
2655
3037
  import { AnimatePresence } from "motion/react";
2656
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
3038
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
2657
3039
  var styles = {
2658
3040
  root: {
2659
3041
  position: "fixed",
@@ -2739,9 +3121,9 @@ var OverlayBackdrop = ({
2739
3121
  viewport
2740
3122
  } = overlay;
2741
3123
  const hasHighlightBounds = Boolean(highlight.rect);
2742
- const prevScreenTargetRef = useRef7(null);
3124
+ const prevScreenTargetRef = useRef10(null);
2743
3125
  const shouldSnapHighlight = prevScreenTargetRef.current === true && !highlight.isScreen && hasHighlightBounds;
2744
- useEffect14(() => {
3126
+ useEffect16(() => {
2745
3127
  prevScreenTargetRef.current = highlight.isScreen;
2746
3128
  }, [highlight.isScreen]);
2747
3129
  const resolvedBlur = typeof blurAmount === "number" ? `${blurAmount}px` : "0px";
@@ -2801,7 +3183,7 @@ var OverlayBackdrop = ({
2801
3183
  overlayStyle.backgroundColor = color;
2802
3184
  }
2803
3185
  return createPortal(
2804
- /* @__PURE__ */ jsxs(
3186
+ /* @__PURE__ */ jsxs2(
2805
3187
  MotionDiv,
2806
3188
  {
2807
3189
  className: rootClassName,
@@ -2809,7 +3191,7 @@ var OverlayBackdrop = ({
2809
3191
  "aria-hidden": ariaHidden,
2810
3192
  "data-tour-overlay": "",
2811
3193
  children: [
2812
- /* @__PURE__ */ jsx3(AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ jsx3(
3194
+ /* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ jsx4(
2813
3195
  MotionSvg,
2814
3196
  {
2815
3197
  width: "0",
@@ -2821,7 +3203,7 @@ var OverlayBackdrop = ({
2821
3203
  animate: { opacity: 1 },
2822
3204
  exit: { opacity: 0 },
2823
3205
  transition: overlayTransition,
2824
- children: /* @__PURE__ */ jsx3(MotionDefs, { children: /* @__PURE__ */ jsxs(
3206
+ children: /* @__PURE__ */ jsx4(MotionDefs, { children: /* @__PURE__ */ jsxs2(
2825
3207
  MotionMask,
2826
3208
  {
2827
3209
  id: maskId ?? void 0,
@@ -2833,7 +3215,7 @@ var OverlayBackdrop = ({
2833
3215
  animate: { width: viewport.width, height: viewport.height },
2834
3216
  transition: highlightTransition,
2835
3217
  children: [
2836
- /* @__PURE__ */ jsx3(
3218
+ /* @__PURE__ */ jsx4(
2837
3219
  MotionRect,
2838
3220
  {
2839
3221
  x: "0",
@@ -2849,7 +3231,7 @@ var OverlayBackdrop = ({
2849
3231
  exit: { opacity: 0 }
2850
3232
  }
2851
3233
  ),
2852
- /* @__PURE__ */ jsx3(
3234
+ /* @__PURE__ */ jsx4(
2853
3235
  MotionRect,
2854
3236
  {
2855
3237
  initial: false,
@@ -2868,7 +3250,7 @@ var OverlayBackdrop = ({
2868
3250
  },
2869
3251
  "tour-mask"
2870
3252
  ) : null }),
2871
- /* @__PURE__ */ jsx3(AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ jsx3(
3253
+ /* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ jsx4(
2872
3254
  MotionDiv,
2873
3255
  {
2874
3256
  className: overlayClassName,
@@ -2896,7 +3278,7 @@ var OverlayBackdrop = ({
2896
3278
  },
2897
3279
  "tour-overlay"
2898
3280
  ) : null }),
2899
- /* @__PURE__ */ jsx3(AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ jsx3(
3281
+ /* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ jsx4(
2900
3282
  MotionDiv,
2901
3283
  {
2902
3284
  className: segmentClassName,
@@ -2926,13 +3308,13 @@ var OverlayBackdrop = ({
2926
3308
  },
2927
3309
  `tour-overlay-fallback-${segment.key}`
2928
3310
  )) : null }),
2929
- showInteractionBlocker && blockerSegments ? /* @__PURE__ */ jsx3(
3311
+ showInteractionBlocker && blockerSegments ? /* @__PURE__ */ jsx4(
2930
3312
  "div",
2931
3313
  {
2932
3314
  style: { ...styles.blockerContainer, zIndex },
2933
3315
  "data-tour-overlay-layer": "interaction-blocker",
2934
3316
  "aria-hidden": true,
2935
- children: blockerSegments.map((segment) => /* @__PURE__ */ jsx3(
3317
+ children: blockerSegments.map((segment) => /* @__PURE__ */ jsx4(
2936
3318
  "div",
2937
3319
  {
2938
3320
  style: {
@@ -2947,7 +3329,7 @@ var OverlayBackdrop = ({
2947
3329
  ))
2948
3330
  }
2949
3331
  ) : null,
2950
- /* @__PURE__ */ jsx3(AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ jsx3(
3332
+ /* @__PURE__ */ jsx4(AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ jsx4(
2951
3333
  MotionDiv,
2952
3334
  {
2953
3335
  className: ringClassName,
@@ -2978,7 +3360,7 @@ var OverlayBackdrop = ({
2978
3360
  };
2979
3361
 
2980
3362
  // src/components/TourPopoverPortal.tsx
2981
- import { useEffect as useEffect15, useLayoutEffect as useLayoutEffect2, useMemo as useMemo11, useRef as useRef8, useState as useState11 } from "react";
3363
+ import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect2, useMemo as useMemo13, useRef as useRef11, useState as useState12 } from "react";
2982
3364
  import { createPortal as createPortal2 } from "react-dom";
2983
3365
  import {
2984
3366
  autoPlacement,
@@ -3045,12 +3427,12 @@ var TourPopoverPortal = ({
3045
3427
  const popoverContentTransition = transitionsOverride?.popoverContent ?? adapter.transitions.popoverContent ?? DEFAULT_POPOVER_CONTENT_TRANSITION;
3046
3428
  const viewport = useViewportRect();
3047
3429
  const prefersMobileLayout = viewport.width <= MOBILE_BREAKPOINT || viewport.height <= MOBILE_HEIGHT_BREAKPOINT;
3048
- const prefersMobileRef = useRef8(prefersMobileLayout);
3049
- useEffect15(() => {
3430
+ const prefersMobileRef = useRef11(prefersMobileLayout);
3431
+ useEffect17(() => {
3050
3432
  prefersMobileRef.current = prefersMobileLayout;
3051
3433
  }, [prefersMobileLayout]);
3052
- const lastReadyTargetRef = useRef8(null);
3053
- useEffect15(() => {
3434
+ const lastReadyTargetRef = useRef11(null);
3435
+ useEffect17(() => {
3054
3436
  if (target.status === "ready" && target.rect) {
3055
3437
  lastReadyTargetRef.current = {
3056
3438
  rect: { ...target.rect },
@@ -3066,7 +3448,7 @@ var TourPopoverPortal = ({
3066
3448
  const shouldHidePopover = !resolvedRect && !target.isScreen;
3067
3449
  const fallbackRect = resolvedRect ?? viewport;
3068
3450
  const fallbackIsScreen = resolvedIsScreen;
3069
- const [floatingSize, setFloatingSize] = useState11(null);
3451
+ const [floatingSize, setFloatingSize] = useState12(null);
3070
3452
  const clampVertical = (value) => Math.min(viewport.height - 24, Math.max(24, value));
3071
3453
  const clampHorizontal = (value) => Math.min(viewport.width - 24, Math.max(24, value));
3072
3454
  const screenCenteredTop = viewport.height / 2 - (floatingSize?.height ?? 0) / 2;
@@ -3077,7 +3459,7 @@ var TourPopoverPortal = ({
3077
3459
  const leftBase = fallbackIsScreen ? screenCenteredLeft : fallbackRect.left + fallbackRect.width / 2 - floatingWidth / 2;
3078
3460
  const left = clampHorizontal(leftBase);
3079
3461
  const fallbackTransform = "translate3d(0px, 0px, 0px)";
3080
- const fallbackPosition = useMemo11(
3462
+ const fallbackPosition = useMemo13(
3081
3463
  () => ({
3082
3464
  top,
3083
3465
  left,
@@ -3085,7 +3467,7 @@ var TourPopoverPortal = ({
3085
3467
  }),
3086
3468
  [fallbackTransform, left, top]
3087
3469
  );
3088
- const centerInitialPosition = useMemo11(
3470
+ const centerInitialPosition = useMemo13(
3089
3471
  () => ({
3090
3472
  top: viewport.height / 2,
3091
3473
  left: viewport.width / 2,
@@ -3093,22 +3475,22 @@ var TourPopoverPortal = ({
3093
3475
  }),
3094
3476
  [viewport.height, viewport.width]
3095
3477
  );
3096
- const floatingRef = useRef8(null);
3097
- const cachedFloatingPositionRef = useRef8(null);
3098
- const appliedFloatingCacheRef = useRef8(null);
3099
- const deferredScreenSnapRef = useRef8(null);
3100
- const [layoutMode, setLayoutMode] = useState11(
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(
3101
3483
  () => prefersMobileLayout ? "mobile" : "floating"
3102
3484
  );
3103
- const [floatingPosition, setFloatingPosition] = useState11(fallbackPosition);
3104
- const [dragPosition, setDragPosition] = useState11(null);
3105
- const [isDragging, setIsDragging] = useState11(false);
3106
- const dragStateRef = useRef8(null);
3107
- const overflowRetryRef = useRef8({
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({
3108
3490
  stepId: null,
3109
3491
  attempts: 0
3110
3492
  });
3111
- const overflowRetryTimeoutRef = useRef8(null);
3493
+ const overflowRetryTimeoutRef = useRef11(null);
3112
3494
  useLayoutEffect2(() => {
3113
3495
  if (!isBrowser) return;
3114
3496
  const node = floatingRef.current;
@@ -3128,25 +3510,25 @@ var TourPopoverPortal = ({
3128
3510
  const autoAlignment = resolvedPlacement.endsWith(
3129
3511
  "-start"
3130
3512
  ) ? "start" : resolvedPlacement.endsWith("-end") ? "end" : void 0;
3131
- useEffect15(() => {
3513
+ useEffect17(() => {
3132
3514
  setDragPosition(null);
3133
3515
  setLayoutMode(prefersMobileRef.current ? "mobile" : "floating");
3134
3516
  cachedFloatingPositionRef.current = null;
3135
3517
  appliedFloatingCacheRef.current = null;
3136
3518
  }, [target.stepId]);
3137
- useEffect15(() => {
3519
+ useEffect17(() => {
3138
3520
  if (layoutMode !== "manual") {
3139
3521
  setDragPosition(null);
3140
3522
  }
3141
3523
  }, [layoutMode]);
3142
- useEffect15(() => {
3524
+ useEffect17(() => {
3143
3525
  cachedFloatingPositionRef.current = floatingPosition;
3144
3526
  const cacheKey = getFloatingCacheKey(target);
3145
3527
  if (cacheKey) {
3146
3528
  floatingPositionCache.set(cacheKey, floatingPosition);
3147
3529
  }
3148
3530
  }, [floatingPosition, target.isScreen, target.stepId]);
3149
- const dockedPosition = useMemo11(
3531
+ const dockedPosition = useMemo13(
3150
3532
  () => ({
3151
3533
  top: viewport.height - DOCKED_MARGIN,
3152
3534
  left: viewport.width - DOCKED_MARGIN,
@@ -3154,7 +3536,7 @@ var TourPopoverPortal = ({
3154
3536
  }),
3155
3537
  [viewport.height, viewport.width]
3156
3538
  );
3157
- const mobilePosition = useMemo11(
3539
+ const mobilePosition = useMemo13(
3158
3540
  () => ({
3159
3541
  top: viewport.height - MOBILE_HORIZONTAL_GUTTER,
3160
3542
  left: viewport.width / 2,
@@ -3162,17 +3544,17 @@ var TourPopoverPortal = ({
3162
3544
  }),
3163
3545
  [viewport.height, viewport.width]
3164
3546
  );
3165
- useEffect15(() => {
3547
+ useEffect17(() => {
3166
3548
  if (layoutMode === "docked") {
3167
3549
  setFloatingPosition(dockedPosition);
3168
3550
  }
3169
3551
  }, [dockedPosition, layoutMode]);
3170
- useEffect15(() => {
3552
+ useEffect17(() => {
3171
3553
  if (layoutMode === "mobile") {
3172
3554
  setFloatingPosition(mobilePosition);
3173
3555
  }
3174
3556
  }, [layoutMode, mobilePosition]);
3175
- useEffect15(() => {
3557
+ useEffect17(() => {
3176
3558
  if (prefersMobileLayout) {
3177
3559
  if (layoutMode !== "mobile") {
3178
3560
  setLayoutMode("mobile");
@@ -3185,7 +3567,7 @@ var TourPopoverPortal = ({
3185
3567
  setFloatingPosition(fallbackPosition);
3186
3568
  }
3187
3569
  }, [fallbackPosition, layoutMode, prefersMobileLayout]);
3188
- useEffect15(() => {
3570
+ useEffect17(() => {
3189
3571
  if (layoutMode !== "floating") return;
3190
3572
  const stepId = target.stepId;
3191
3573
  if (!stepId) return;
@@ -3209,7 +3591,7 @@ var TourPopoverPortal = ({
3209
3591
  target.stepId
3210
3592
  ]);
3211
3593
  const shouldDeferScreenSnap = layoutMode === "floating" && target.isScreen && Boolean(layoutId);
3212
- useEffect15(() => {
3594
+ useEffect17(() => {
3213
3595
  return () => {
3214
3596
  if (deferredScreenSnapRef.current !== null) {
3215
3597
  cancelAnimationFrame(deferredScreenSnapRef.current);
@@ -3229,7 +3611,7 @@ var TourPopoverPortal = ({
3229
3611
  target.isScreen,
3230
3612
  target.status
3231
3613
  ]);
3232
- useEffect15(() => {
3614
+ useEffect17(() => {
3233
3615
  if (!shouldDeferScreenSnap) return;
3234
3616
  if (deferredScreenSnapRef.current !== null) {
3235
3617
  cancelAnimationFrame(deferredScreenSnapRef.current);
@@ -3256,7 +3638,7 @@ var TourPopoverPortal = ({
3256
3638
  }
3257
3639
  };
3258
3640
  }, [fallbackPosition, shouldDeferScreenSnap]);
3259
- useEffect15(() => {
3641
+ useEffect17(() => {
3260
3642
  return () => {
3261
3643
  if (overflowRetryTimeoutRef.current !== null) {
3262
3644
  window.clearTimeout(overflowRetryTimeoutRef.current);
@@ -3482,7 +3864,7 @@ var TourPopoverPortal = ({
3482
3864
  }
3483
3865
  event.preventDefault();
3484
3866
  };
3485
- useEffect15(() => endDrag, []);
3867
+ useEffect17(() => endDrag, []);
3486
3868
  const shouldUseFallbackInitial = layoutMode !== "mobile" && (Boolean(target.lastResolvedRect) || Boolean(cachedTarget));
3487
3869
  const floatingCacheKey = layoutMode === "mobile" ? null : getFloatingCacheKey(target);
3488
3870
  const persistedFloatingInitial = floatingCacheKey && floatingPositionCache.has(floatingCacheKey) ? floatingPositionCache.get(floatingCacheKey) ?? null : null;
@@ -3574,7 +3956,7 @@ var TourPopoverPortal = ({
3574
3956
  };
3575
3957
 
3576
3958
  // src/components/TourFocusManager.tsx
3577
- import { useEffect as useEffect16, useLayoutEffect as useLayoutEffect3, useRef as useRef9, useState as useState12 } from "react";
3959
+ import { useEffect as useEffect18, useLayoutEffect as useLayoutEffect3, useRef as useRef12, useState as useState13 } from "react";
3578
3960
  import { createPortal as createPortal3 } from "react-dom";
3579
3961
 
3580
3962
  // src/utils/focus.ts
@@ -3635,7 +4017,7 @@ var focusElement = (element, options) => {
3635
4017
  };
3636
4018
 
3637
4019
  // src/components/TourFocusManager.tsx
3638
- import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
4020
+ import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
3639
4021
  var runMicrotask = (callback) => {
3640
4022
  if (typeof queueMicrotask === "function") {
3641
4023
  queueMicrotask(callback);
@@ -3651,18 +4033,18 @@ var TourFocusManager = ({
3651
4033
  highlightRect,
3652
4034
  guardElementFocusRing
3653
4035
  }) => {
3654
- const previousFocusRef = useRef9(null);
3655
- const guardNodesRef = useRef9({
4036
+ const previousFocusRef = useRef12(null);
4037
+ const guardNodesRef = useRef12({
3656
4038
  "target-start": null,
3657
4039
  "target-end": null,
3658
4040
  "popover-start": null,
3659
4041
  "popover-end": null
3660
4042
  });
3661
- const lastTabDirectionRef = useRef9("forward");
3662
- const suppressGuardHopRef = useRef9(null);
3663
- const [targetRingActive, setTargetRingActive] = useState12(false);
3664
- const [popoverRingActive, setPopoverRingActive] = useState12(false);
3665
- const [popoverRect, setPopoverRect] = useState12(null);
4043
+ const lastTabDirectionRef = useRef12("forward");
4044
+ const suppressGuardHopRef = useRef12(null);
4045
+ const [targetRingActive, setTargetRingActive] = useState13(false);
4046
+ const [popoverRingActive, setPopoverRingActive] = useState13(false);
4047
+ const [popoverRect, setPopoverRect] = useState13(null);
3666
4048
  const restoreFocus = () => {
3667
4049
  const previous = previousFocusRef.current;
3668
4050
  previousFocusRef.current = null;
@@ -3688,7 +4070,7 @@ var TourFocusManager = ({
3688
4070
  restoreFocus();
3689
4071
  };
3690
4072
  }, [active, popoverNode, target.element]);
3691
- useEffect16(() => {
4073
+ useEffect18(() => {
3692
4074
  if (!isBrowser) return;
3693
4075
  if (!active) return;
3694
4076
  const doc = popoverNode?.ownerDocument ?? target.element?.ownerDocument ?? document;
@@ -3897,8 +4279,8 @@ var TourFocusManager = ({
3897
4279
  const showPopoverRing = popoverRingActive && popoverRect;
3898
4280
  if (!showTargetRing && !showPopoverRing) return null;
3899
4281
  return createPortal3(
3900
- /* @__PURE__ */ jsxs2(Fragment, { children: [
3901
- showTargetRing && /* @__PURE__ */ jsx4(
4282
+ /* @__PURE__ */ jsxs3(Fragment, { children: [
4283
+ showTargetRing && /* @__PURE__ */ jsx5(
3902
4284
  "div",
3903
4285
  {
3904
4286
  style: {
@@ -3915,7 +4297,7 @@ var TourFocusManager = ({
3915
4297
  "aria-hidden": true
3916
4298
  }
3917
4299
  ),
3918
- showPopoverRing && /* @__PURE__ */ jsx4(
4300
+ showPopoverRing && /* @__PURE__ */ jsx5(
3919
4301
  "div",
3920
4302
  {
3921
4303
  style: {
@@ -3938,7 +4320,7 @@ var TourFocusManager = ({
3938
4320
  };
3939
4321
 
3940
4322
  // src/motion/useHudMotion.ts
3941
- import { useMemo as useMemo12 } from "react";
4323
+ import { useMemo as useMemo14 } from "react";
3942
4324
  var DEFAULT_HIGHLIGHT_TRANSITION2 = {
3943
4325
  duration: 0.35,
3944
4326
  ease: "easeOut",
@@ -3965,7 +4347,7 @@ var DEFAULT_POPOVER_CONTENT_TRANSITION2 = {
3965
4347
  };
3966
4348
  var useHudMotion = () => {
3967
4349
  const adapter = useAnimationAdapter();
3968
- return useMemo12(() => {
4350
+ return useMemo14(() => {
3969
4351
  const components = {
3970
4352
  ...adapter.components
3971
4353
  };
@@ -3983,6 +4365,7 @@ var useHudMotion = () => {
3983
4365
  };
3984
4366
  export {
3985
4367
  AnimationAdapterProvider,
4368
+ DialogRegistryProvider,
3986
4369
  OverlayBackdrop,
3987
4370
  TourFocusManager,
3988
4371
  TourPopoverPortal,
@@ -3999,6 +4382,8 @@ export {
3999
4382
  useAnimationAdapter,
4000
4383
  useBodyScrollLock,
4001
4384
  useDelayAdvance,
4385
+ useDialogRegistry,
4386
+ useDialogRegistryOptional,
4002
4387
  useHiddenTargetFallback,
4003
4388
  useHudDescription,
4004
4389
  useHudMotion,
@@ -4007,6 +4392,7 @@ export {
4007
4392
  useHudTargetIssue,
4008
4393
  usePreferredAnimationAdapter,
4009
4394
  useRadixDialogAdapter,
4395
+ useRadixTourDialog,
4010
4396
  useTour,
4011
4397
  useTourControls,
4012
4398
  useTourEvents,
@@ -4015,5 +4401,6 @@ export {
4015
4401
  useTourLabels,
4016
4402
  useTourOverlay,
4017
4403
  useTourTarget,
4018
- useViewportRect
4404
+ useViewportRect,
4405
+ waitForDom
4019
4406
  };