@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.cjs CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AnimationAdapterProvider: () => AnimationAdapterProvider,
24
+ DialogRegistryProvider: () => DialogRegistryProvider,
24
25
  OverlayBackdrop: () => OverlayBackdrop,
25
26
  TourFocusManager: () => TourFocusManager,
26
27
  TourPopoverPortal: () => TourPopoverPortal,
@@ -37,6 +38,8 @@ __export(index_exports, {
37
38
  useAnimationAdapter: () => useAnimationAdapter,
38
39
  useBodyScrollLock: () => useBodyScrollLock,
39
40
  useDelayAdvance: () => useDelayAdvance,
41
+ useDialogRegistry: () => useDialogRegistry,
42
+ useDialogRegistryOptional: () => useDialogRegistryOptional,
40
43
  useHiddenTargetFallback: () => useHiddenTargetFallback,
41
44
  useHudDescription: () => useHudDescription,
42
45
  useHudMotion: () => useHudMotion,
@@ -45,6 +48,7 @@ __export(index_exports, {
45
48
  useHudTargetIssue: () => useHudTargetIssue,
46
49
  usePreferredAnimationAdapter: () => usePreferredAnimationAdapter,
47
50
  useRadixDialogAdapter: () => useRadixDialogAdapter,
51
+ useRadixTourDialog: () => useRadixTourDialog,
48
52
  useTour: () => useTour,
49
53
  useTourControls: () => useTourControls,
50
54
  useTourEvents: () => useTourEvents,
@@ -53,13 +57,14 @@ __export(index_exports, {
53
57
  useTourLabels: () => useTourLabels,
54
58
  useTourOverlay: () => useTourOverlay,
55
59
  useTourTarget: () => useTourTarget,
56
- useViewportRect: () => useViewportRect
60
+ useViewportRect: () => useViewportRect,
61
+ waitForDom: () => waitForDom
57
62
  });
58
63
  module.exports = __toCommonJS(index_exports);
59
64
 
60
65
  // src/context.tsx
61
66
  var import_core = require("@flowsterix/core");
62
- var import_react4 = require("react");
67
+ var import_react6 = require("react");
63
68
 
64
69
  // src/labels.ts
65
70
  var import_react = require("react");
@@ -90,20 +95,166 @@ function useTourLabels() {
90
95
  return (0, import_react.useContext)(LabelsContext);
91
96
  }
92
97
 
93
- // src/motion/animationAdapter.tsx
94
- var import_react2 = require("motion/react");
95
- var import_react3 = require("react");
98
+ // src/dialog/DialogRegistryContext.tsx
99
+ var import_react2 = require("react");
96
100
  var import_jsx_runtime = require("react/jsx-runtime");
101
+ var DialogRegistryContext = (0, import_react2.createContext)(void 0);
102
+ var DialogRegistryProvider = ({ children }) => {
103
+ const controllersRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
104
+ const register = (0, import_react2.useCallback)(
105
+ (dialogId, controller) => {
106
+ controllersRef.current.set(dialogId, controller);
107
+ },
108
+ []
109
+ );
110
+ const unregister = (0, import_react2.useCallback)((dialogId) => {
111
+ controllersRef.current.delete(dialogId);
112
+ }, []);
113
+ const getController = (0, import_react2.useCallback)((dialogId) => {
114
+ return controllersRef.current.get(dialogId);
115
+ }, []);
116
+ const isRegistered = (0, import_react2.useCallback)((dialogId) => {
117
+ return controllersRef.current.has(dialogId);
118
+ }, []);
119
+ const value = (0, import_react2.useMemo)(
120
+ () => ({
121
+ register,
122
+ unregister,
123
+ getController,
124
+ isRegistered
125
+ }),
126
+ [register, unregister, getController, isRegistered]
127
+ );
128
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogRegistryContext.Provider, { value, children });
129
+ };
130
+ var useDialogRegistry = () => {
131
+ const context = (0, import_react2.useContext)(DialogRegistryContext);
132
+ if (!context) {
133
+ throw new Error(
134
+ "useDialogRegistry must be used within a DialogRegistryProvider"
135
+ );
136
+ }
137
+ return context;
138
+ };
139
+ var useDialogRegistryOptional = () => {
140
+ return (0, import_react2.useContext)(DialogRegistryContext);
141
+ };
142
+
143
+ // src/hooks/useDialogAutomation.ts
144
+ var import_react3 = require("react");
145
+ var resolveAutoOpen = (config) => {
146
+ if (!config) return { onEnter: true, onResume: true };
147
+ const { autoOpen } = config;
148
+ if (autoOpen === false) return { onEnter: false, onResume: false };
149
+ if (autoOpen === true || autoOpen === void 0) {
150
+ return { onEnter: true, onResume: true };
151
+ }
152
+ return {
153
+ onEnter: autoOpen.onEnter ?? true,
154
+ onResume: autoOpen.onResume ?? true
155
+ };
156
+ };
157
+ var useDialogAutomation = (params) => {
158
+ const { flow, state, events, registry, onDialogNotMounted } = params;
159
+ const previousDialogIdRef = (0, import_react3.useRef)(void 0);
160
+ (0, import_react3.useEffect)(() => {
161
+ if (!events || !flow || !registry) return;
162
+ const unsubscribeEnter = events.on("stepEnter", (payload) => {
163
+ const step = payload.currentStep;
164
+ const dialogId = step.dialogId;
165
+ const previousDialogId = previousDialogIdRef.current;
166
+ if (previousDialogId && previousDialogId !== dialogId && flow.dialogs?.[previousDialogId]) {
167
+ const config = flow.dialogs[previousDialogId];
168
+ const autoClose = config.autoClose ?? "differentDialog";
169
+ if (autoClose === "always" || autoClose === "differentDialog") {
170
+ const controller = registry.getController(previousDialogId);
171
+ if (controller) {
172
+ requestAnimationFrame(() => {
173
+ controller.close();
174
+ });
175
+ }
176
+ }
177
+ }
178
+ if (dialogId && flow.dialogs?.[dialogId]) {
179
+ const config = flow.dialogs[dialogId];
180
+ const autoOpenConfig = resolveAutoOpen(config);
181
+ const isResume = payload.reason === "resume";
182
+ const shouldAutoOpen = isResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
183
+ if (shouldAutoOpen) {
184
+ const controller = registry.getController(dialogId);
185
+ if (controller) {
186
+ requestAnimationFrame(() => {
187
+ controller.open();
188
+ });
189
+ } else if (onDialogNotMounted) {
190
+ onDialogNotMounted(dialogId, step.id);
191
+ }
192
+ }
193
+ }
194
+ previousDialogIdRef.current = dialogId;
195
+ });
196
+ const unsubscribeExit = events.on("stepExit", (payload) => {
197
+ const step = payload.previousStep;
198
+ const dialogId = step.dialogId;
199
+ const nextStep = payload.currentStep;
200
+ if (nextStep?.dialogId === dialogId) return;
201
+ if (dialogId && flow.dialogs?.[dialogId]) {
202
+ const config = flow.dialogs[dialogId];
203
+ const autoClose = config.autoClose ?? "differentDialog";
204
+ if (autoClose === "never") return;
205
+ const controller = registry.getController(dialogId);
206
+ if (controller) {
207
+ requestAnimationFrame(() => {
208
+ controller.close();
209
+ });
210
+ }
211
+ }
212
+ });
213
+ const handleFlowEnd = () => {
214
+ const dialogId = previousDialogIdRef.current;
215
+ if (dialogId && flow.dialogs?.[dialogId]) {
216
+ const config = flow.dialogs[dialogId];
217
+ const autoClose = config.autoClose ?? "differentDialog";
218
+ if (autoClose !== "never") {
219
+ const controller = registry.getController(dialogId);
220
+ controller?.close();
221
+ }
222
+ }
223
+ previousDialogIdRef.current = void 0;
224
+ };
225
+ const unsubscribePause = events.on("flowPause", handleFlowEnd);
226
+ const unsubscribeCancel = events.on("flowCancel", handleFlowEnd);
227
+ const unsubscribeComplete = events.on("flowComplete", handleFlowEnd);
228
+ return () => {
229
+ unsubscribeEnter();
230
+ unsubscribeExit();
231
+ unsubscribePause();
232
+ unsubscribeCancel();
233
+ unsubscribeComplete();
234
+ };
235
+ }, [events, flow, registry, onDialogNotMounted]);
236
+ (0, import_react3.useEffect)(() => {
237
+ if (!flow || !state || state.status !== "running") return;
238
+ if (state.stepIndex < 0 || state.stepIndex >= flow.steps.length) return;
239
+ const currentStep = flow.steps[state.stepIndex];
240
+ previousDialogIdRef.current = currentStep.dialogId;
241
+ }, [flow, state]);
242
+ };
243
+
244
+ // src/motion/animationAdapter.tsx
245
+ var import_react4 = require("motion/react");
246
+ var import_react5 = require("react");
247
+ var import_jsx_runtime2 = require("react/jsx-runtime");
97
248
  var defaultAdapter = {
98
249
  components: {
99
- MotionDiv: import_react2.motion.div,
100
- MotionSection: import_react2.motion.section,
101
- MotionSvg: import_react2.motion.svg,
102
- MotionDefs: import_react2.motion.defs,
103
- MotionMask: import_react2.motion.mask,
104
- MotionRect: import_react2.motion.rect,
105
- MotionSpan: import_react2.motion.span,
106
- MotionButton: import_react2.motion.button
250
+ MotionDiv: import_react4.motion.div,
251
+ MotionSection: import_react4.motion.section,
252
+ MotionSvg: import_react4.motion.svg,
253
+ MotionDefs: import_react4.motion.defs,
254
+ MotionMask: import_react4.motion.mask,
255
+ MotionRect: import_react4.motion.rect,
256
+ MotionSpan: import_react4.motion.span,
257
+ MotionButton: import_react4.motion.button
107
258
  },
108
259
  transitions: {
109
260
  overlayHighlight: {
@@ -136,16 +287,16 @@ var defaultAdapter = {
136
287
  }
137
288
  }
138
289
  };
139
- var AnimationAdapterContext = (0, import_react3.createContext)(defaultAdapter);
290
+ var AnimationAdapterContext = (0, import_react5.createContext)(defaultAdapter);
140
291
  var AnimationAdapterProvider = ({
141
292
  adapter,
142
293
  children
143
294
  }) => {
144
- const value = (0, import_react3.useMemo)(() => adapter ?? defaultAdapter, [adapter]);
145
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AnimationAdapterContext.Provider, { value, children });
295
+ const value = (0, import_react5.useMemo)(() => adapter ?? defaultAdapter, [adapter]);
296
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AnimationAdapterContext.Provider, { value, children });
146
297
  };
147
298
  var useAnimationAdapter = () => {
148
- return (0, import_react3.useContext)(AnimationAdapterContext);
299
+ return (0, import_react5.useContext)(AnimationAdapterContext);
149
300
  };
150
301
  var defaultAnimationAdapter = defaultAdapter;
151
302
  var reducedMotionAnimationAdapter = {
@@ -185,11 +336,11 @@ var usePreferredAnimationAdapter = (options) => {
185
336
  reducedMotionAdapter: reducedOption = reducedMotionAnimationAdapter,
186
337
  enabled = true
187
338
  } = options ?? {};
188
- const [prefersReduced, setPrefersReduced] = (0, import_react3.useState)(() => {
339
+ const [prefersReduced, setPrefersReduced] = (0, import_react5.useState)(() => {
189
340
  if (!enabled || typeof window === "undefined") return false;
190
341
  return window.matchMedia(REDUCED_MOTION_QUERY).matches;
191
342
  });
192
- (0, import_react3.useEffect)(() => {
343
+ (0, import_react5.useEffect)(() => {
193
344
  if (!enabled || typeof window === "undefined") return;
194
345
  const mediaQuery = window.matchMedia(REDUCED_MOTION_QUERY);
195
346
  const handleChange = (event) => {
@@ -437,11 +588,11 @@ var matchRoute = (params) => {
437
588
  };
438
589
 
439
590
  // src/context.tsx
440
- var import_jsx_runtime2 = require("react/jsx-runtime");
441
- var TourContext = (0, import_react4.createContext)(void 0);
591
+ var import_jsx_runtime3 = require("react/jsx-runtime");
592
+ var TourContext = (0, import_react6.createContext)(void 0);
442
593
  var DEFAULT_STORAGE_PREFIX = "tour";
443
594
  var useFlowMap = (flows) => {
444
- return (0, import_react4.useMemo)(() => {
595
+ return (0, import_react6.useMemo)(() => {
445
596
  const map = /* @__PURE__ */ new Map();
446
597
  for (const flow of flows) {
447
598
  map.set(flow.id, flow);
@@ -465,25 +616,25 @@ var TourProvider = ({
465
616
  labels: labelsProp,
466
617
  onVersionMismatch
467
618
  }) => {
468
- const mergedLabels = (0, import_react4.useMemo)(
619
+ const mergedLabels = (0, import_react6.useMemo)(
469
620
  () => ({ ...defaultLabels, ...labelsProp }),
470
621
  [labelsProp]
471
622
  );
472
623
  const flowMap = useFlowMap(flows);
473
- const storeRef = (0, import_react4.useRef)(null);
474
- const unsubscribeRef = (0, import_react4.useRef)(null);
475
- const stepHooksUnsubscribeRef = (0, import_react4.useRef)(null);
476
- const fallbackStorageRef = (0, import_react4.useRef)(void 0);
477
- const pendingResumeRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
478
- const autoStartRequestedRef = (0, import_react4.useRef)(null);
479
- const [activeFlowId, setActiveFlowId] = (0, import_react4.useState)(null);
480
- const [state, setState] = (0, import_react4.useState)(null);
481
- const [events, setEvents] = (0, import_react4.useState)(
624
+ const storeRef = (0, import_react6.useRef)(null);
625
+ const unsubscribeRef = (0, import_react6.useRef)(null);
626
+ const stepHooksUnsubscribeRef = (0, import_react6.useRef)(null);
627
+ const fallbackStorageRef = (0, import_react6.useRef)(void 0);
628
+ const pendingResumeRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
629
+ const autoStartRequestedRef = (0, import_react6.useRef)(null);
630
+ const [activeFlowId, setActiveFlowId] = (0, import_react6.useState)(null);
631
+ const [state, setState] = (0, import_react6.useState)(null);
632
+ const [events, setEvents] = (0, import_react6.useState)(
482
633
  null
483
634
  );
484
- const [debugEnabled, setDebugEnabled] = (0, import_react4.useState)(defaultDebug);
485
- const [delayInfo, setDelayInfo] = (0, import_react4.useState)(null);
486
- const teardownStore = (0, import_react4.useCallback)(() => {
635
+ const [debugEnabled, setDebugEnabled] = (0, import_react6.useState)(defaultDebug);
636
+ const [delayInfo, setDelayInfo] = (0, import_react6.useState)(null);
637
+ const teardownStore = (0, import_react6.useCallback)(() => {
487
638
  unsubscribeRef.current?.();
488
639
  unsubscribeRef.current = null;
489
640
  stepHooksUnsubscribeRef.current?.();
@@ -493,7 +644,7 @@ var TourProvider = ({
493
644
  setDelayInfo(null);
494
645
  pendingResumeRef.current.clear();
495
646
  }, []);
496
- (0, import_react4.useEffect)(() => {
647
+ (0, import_react6.useEffect)(() => {
497
648
  return () => {
498
649
  teardownStore();
499
650
  setState(null);
@@ -501,7 +652,7 @@ var TourProvider = ({
501
652
  setActiveFlowId(null);
502
653
  };
503
654
  }, [teardownStore]);
504
- (0, import_react4.useEffect)(() => {
655
+ (0, import_react6.useEffect)(() => {
505
656
  if (!activeFlowId) return;
506
657
  const definition = flowMap.get(activeFlowId);
507
658
  if (!definition) {
@@ -524,7 +675,7 @@ var TourProvider = ({
524
675
  console.warn(`[tour][step] ${phase} hook failed`, error);
525
676
  }
526
677
  };
527
- const ensureStore = (0, import_react4.useCallback)(
678
+ const ensureStore = (0, import_react6.useCallback)(
528
679
  (flowId) => {
529
680
  const existing = storeRef.current;
530
681
  if (existing && existing.definition.id === flowId) {
@@ -583,7 +734,7 @@ var TourProvider = ({
583
734
  teardownStore
584
735
  ]
585
736
  );
586
- const getActiveStore = (0, import_react4.useCallback)(() => {
737
+ const getActiveStore = (0, import_react6.useCallback)(() => {
587
738
  const store = storeRef.current;
588
739
  if (!store) {
589
740
  throw new Error(
@@ -595,7 +746,7 @@ var TourProvider = ({
595
746
  const isPromiseLike2 = (value) => {
596
747
  return typeof value === "object" && value !== null && typeof value.then === "function";
597
748
  };
598
- const invokeStepHook = (0, import_react4.useCallback)(
749
+ const invokeStepHook = (0, import_react6.useCallback)(
599
750
  async (hook, context, phase) => {
600
751
  if (!hook) return;
601
752
  try {
@@ -609,7 +760,7 @@ var TourProvider = ({
609
760
  },
610
761
  []
611
762
  );
612
- const runResumeHooks = (0, import_react4.useCallback)(
763
+ const runResumeHooks = (0, import_react6.useCallback)(
613
764
  async (definition, flowState, strategy) => {
614
765
  if (flowState.status !== "running") return;
615
766
  if (strategy === "current") {
@@ -649,13 +800,13 @@ var TourProvider = ({
649
800
  },
650
801
  [invokeStepHook]
651
802
  );
652
- const resolveResumeStrategy = (0, import_react4.useCallback)(
803
+ const resolveResumeStrategy = (0, import_react6.useCallback)(
653
804
  (definition, options) => {
654
805
  return options?.resumeStrategy ?? definition.resumeStrategy ?? "chain";
655
806
  },
656
807
  []
657
808
  );
658
- const startFlow = (0, import_react4.useCallback)(
809
+ const startFlow = (0, import_react6.useCallback)(
659
810
  (flowId, options) => {
660
811
  const store = ensureStore(flowId);
661
812
  const previousState = store.getState();
@@ -684,8 +835,8 @@ var TourProvider = ({
684
835
  },
685
836
  [ensureStore, resolveResumeStrategy, runResumeHooks]
686
837
  );
687
- const [eligibleFlows, setEligibleFlows] = (0, import_react4.useState)([]);
688
- (0, import_react4.useEffect)(() => {
838
+ const [eligibleFlows, setEligibleFlows] = (0, import_react6.useState)([]);
839
+ (0, import_react6.useEffect)(() => {
689
840
  const autoStartFlows = flows.filter((f) => f.autoStart);
690
841
  if (autoStartFlows.length === 0) {
691
842
  setEligibleFlows([]);
@@ -749,7 +900,7 @@ var TourProvider = ({
749
900
  cancelled = true;
750
901
  };
751
902
  }, [flows, storageAdapter, storageNamespace]);
752
- (0, import_react4.useEffect)(() => {
903
+ (0, import_react6.useEffect)(() => {
753
904
  if (eligibleFlows.length === 0) {
754
905
  autoStartRequestedRef.current = null;
755
906
  return;
@@ -784,14 +935,14 @@ var TourProvider = ({
784
935
  }
785
936
  };
786
937
  }, [activeFlowId, eligibleFlows, startFlow]);
787
- const next = (0, import_react4.useCallback)(() => getActiveStore().next(), [getActiveStore]);
788
- const back = (0, import_react4.useCallback)(() => getActiveStore().back(), [getActiveStore]);
789
- const goToStep = (0, import_react4.useCallback)(
938
+ const next = (0, import_react6.useCallback)(() => getActiveStore().next(), [getActiveStore]);
939
+ const back = (0, import_react6.useCallback)(() => getActiveStore().back(), [getActiveStore]);
940
+ const goToStep = (0, import_react6.useCallback)(
790
941
  (step) => getActiveStore().goToStep(step),
791
942
  [getActiveStore]
792
943
  );
793
- const pause = (0, import_react4.useCallback)(() => getActiveStore().pause(), [getActiveStore]);
794
- const resume = (0, import_react4.useCallback)(() => {
944
+ const pause = (0, import_react6.useCallback)(() => getActiveStore().pause(), [getActiveStore]);
945
+ const resume = (0, import_react6.useCallback)(() => {
795
946
  const store = getActiveStore();
796
947
  const previousState = store.getState();
797
948
  if (previousState.status === "paused") {
@@ -809,27 +960,31 @@ var TourProvider = ({
809
960
  }
810
961
  return result;
811
962
  }, [getActiveStore, resolveResumeStrategy, runResumeHooks]);
812
- const cancel = (0, import_react4.useCallback)(
963
+ const cancel = (0, import_react6.useCallback)(
813
964
  (reason) => getActiveStore().cancel(reason),
814
965
  [getActiveStore]
815
966
  );
816
- const complete = (0, import_react4.useCallback)(
967
+ const complete = (0, import_react6.useCallback)(
817
968
  () => getActiveStore().complete(),
818
969
  [getActiveStore]
819
970
  );
820
- const advanceStep = (0, import_react4.useCallback)(
971
+ const advanceStep = (0, import_react6.useCallback)(
821
972
  (stepId) => getActiveStore().advanceStep(stepId),
822
973
  [getActiveStore]
823
974
  );
824
- const toggleDebug = (0, import_react4.useCallback)(() => {
975
+ const toggleDebug = (0, import_react6.useCallback)(() => {
825
976
  setDebugEnabled((previous) => !previous);
826
977
  }, []);
827
- const activeStep = (0, import_react4.useMemo)(() => {
978
+ const activeStep = (0, import_react6.useMemo)(() => {
828
979
  if (!state || !storeRef.current) return null;
829
980
  if (state.stepIndex < 0) return null;
830
981
  return storeRef.current.definition.steps[state.stepIndex] ?? null;
831
982
  }, [state]);
832
- (0, import_react4.useEffect)(() => {
983
+ const activeDialogConfig = (0, import_react6.useMemo)(() => {
984
+ if (!activeStep?.dialogId || !storeRef.current) return void 0;
985
+ return storeRef.current.definition.dialogs?.[activeStep.dialogId];
986
+ }, [activeStep]);
987
+ (0, import_react6.useEffect)(() => {
833
988
  if (!activeFlowId) return;
834
989
  if (!pendingResumeRef.current.has(activeFlowId)) return;
835
990
  if (!state || state.status !== "running") return;
@@ -844,12 +999,13 @@ var TourProvider = ({
844
999
  pendingResumeRef.current.delete(activeFlowId);
845
1000
  void runResumeHooks(definition, state, resumeStrategy);
846
1001
  }, [activeFlowId, flowMap, resolveResumeStrategy, runResumeHooks, state]);
847
- const contextValue = (0, import_react4.useMemo)(
1002
+ const contextValue = (0, import_react6.useMemo)(
848
1003
  () => ({
849
1004
  flows: flowMap,
850
1005
  activeFlowId,
851
1006
  state,
852
1007
  activeStep,
1008
+ activeDialogConfig,
853
1009
  startFlow,
854
1010
  next,
855
1011
  back,
@@ -871,6 +1027,7 @@ var TourProvider = ({
871
1027
  [
872
1028
  activeFlowId,
873
1029
  activeStep,
1030
+ activeDialogConfig,
874
1031
  advanceStep,
875
1032
  back,
876
1033
  cancel,
@@ -897,10 +1054,41 @@ var TourProvider = ({
897
1054
  reducedMotionAdapter,
898
1055
  enabled: autoDetectReducedMotion
899
1056
  });
900
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AnimationAdapterProvider, { adapter: resolvedAnimationAdapter, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LabelsProvider, { value: mergedLabels, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TourContext.Provider, { value: contextValue, children }) }) });
1057
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AnimationAdapterProvider, { adapter: resolvedAnimationAdapter, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LabelsProvider, { value: mergedLabels, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DialogRegistryProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(TourContext.Provider, { value: contextValue, children: [
1058
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1059
+ DialogAutomationBridge,
1060
+ {
1061
+ flow: activeFlowId ? flowMap.get(activeFlowId) : void 0,
1062
+ state,
1063
+ events
1064
+ }
1065
+ ),
1066
+ children
1067
+ ] }) }) }) });
1068
+ };
1069
+ var DialogAutomationBridge = ({
1070
+ flow,
1071
+ state,
1072
+ events
1073
+ }) => {
1074
+ const registry = useDialogRegistryOptional();
1075
+ useDialogAutomation({
1076
+ flow,
1077
+ state,
1078
+ events,
1079
+ registry,
1080
+ onDialogNotMounted: (dialogId, stepId) => {
1081
+ if (process.env.NODE_ENV !== "production") {
1082
+ console.warn(
1083
+ `[tour] Step "${stepId}" references dialogId "${dialogId}" but no dialog is mounted with that ID. Ensure your dialog uses useTourDialog({ dialogId: "${dialogId}" }).`
1084
+ );
1085
+ }
1086
+ }
1087
+ });
1088
+ return null;
901
1089
  };
902
1090
  var useTour = () => {
903
- const context = (0, import_react4.useContext)(TourContext);
1091
+ const context = (0, import_react6.useContext)(TourContext);
904
1092
  if (!context) {
905
1093
  throw new Error("useTour must be used within a TourProvider");
906
1094
  }
@@ -908,14 +1096,14 @@ var useTour = () => {
908
1096
  };
909
1097
  var useTourEvents = (event, handler) => {
910
1098
  const { events } = useTour();
911
- (0, import_react4.useEffect)(() => {
1099
+ (0, import_react6.useEffect)(() => {
912
1100
  if (!events) return;
913
1101
  return events.on(event, handler);
914
1102
  }, [event, events, handler]);
915
1103
  };
916
1104
 
917
1105
  // src/hooks/useTourTarget.ts
918
- var import_react5 = require("react");
1106
+ var import_react7 = require("react");
919
1107
 
920
1108
  // src/hooks/scrollMargin.ts
921
1109
  var DEFAULT_SCROLL_MARGIN = 16;
@@ -1218,12 +1406,12 @@ var resolveStepTarget = (target) => {
1218
1406
  };
1219
1407
  var useTourTarget = () => {
1220
1408
  const { activeStep, state, activeFlowId, flows } = useTour();
1221
- const [targetInfo, setTargetInfo] = (0, import_react5.useState)(INITIAL_TARGET_INFO);
1222
- const autoScrollStateRef = (0, import_react5.useRef)({ stepId: null, checks: 0, stalledChecks: 0, done: false, lastRect: null });
1223
- const autoScrollRafRef = (0, import_react5.useRef)(null);
1224
- const autoScrollTimeoutRef = (0, import_react5.useRef)(null);
1225
- const lastRectRef = (0, import_react5.useRef)(null);
1226
- const initialScrollStepRef = (0, import_react5.useRef)(null);
1409
+ const [targetInfo, setTargetInfo] = (0, import_react7.useState)(INITIAL_TARGET_INFO);
1410
+ const autoScrollStateRef = (0, import_react7.useRef)({ stepId: null, checks: 0, stalledChecks: 0, done: false, lastRect: null });
1411
+ const autoScrollRafRef = (0, import_react7.useRef)(null);
1412
+ const autoScrollTimeoutRef = (0, import_react7.useRef)(null);
1413
+ const lastRectRef = (0, import_react7.useRef)(null);
1414
+ const initialScrollStepRef = (0, import_react7.useRef)(null);
1227
1415
  const cancelAutoScrollLoop = () => {
1228
1416
  if (!isBrowser) return;
1229
1417
  if (autoScrollTimeoutRef.current !== null) {
@@ -1235,7 +1423,7 @@ var useTourTarget = () => {
1235
1423
  autoScrollRafRef.current = null;
1236
1424
  }
1237
1425
  };
1238
- (0, import_react5.useEffect)(() => {
1426
+ (0, import_react7.useEffect)(() => {
1239
1427
  if (!activeStep) {
1240
1428
  initialScrollStepRef.current = null;
1241
1429
  }
@@ -1243,7 +1431,7 @@ var useTourTarget = () => {
1243
1431
  initialScrollStepRef.current = null;
1244
1432
  };
1245
1433
  }, [activeStep?.id]);
1246
- (0, import_react5.useLayoutEffect)(() => {
1434
+ (0, import_react7.useLayoutEffect)(() => {
1247
1435
  if (!isBrowser) return;
1248
1436
  if (!activeStep) return;
1249
1437
  if (targetInfo.status !== "ready") return;
@@ -1275,7 +1463,7 @@ var useTourTarget = () => {
1275
1463
  targetInfo.status,
1276
1464
  targetInfo.rectSource
1277
1465
  ]);
1278
- (0, import_react5.useEffect)(() => {
1466
+ (0, import_react7.useEffect)(() => {
1279
1467
  if (!activeStep || !state || state.status !== "running") {
1280
1468
  setTargetInfo(INITIAL_TARGET_INFO);
1281
1469
  autoScrollStateRef.current = {
@@ -1598,7 +1786,7 @@ var useTourTarget = () => {
1598
1786
  waitForPredicateController = null;
1599
1787
  };
1600
1788
  }, [activeStep, activeFlowId, flows, state]);
1601
- (0, import_react5.useEffect)(() => {
1789
+ (0, import_react7.useEffect)(() => {
1602
1790
  if (!isBrowser) return;
1603
1791
  if (!activeStep) {
1604
1792
  cancelAutoScrollLoop();
@@ -1679,10 +1867,10 @@ var useTourTarget = () => {
1679
1867
  };
1680
1868
 
1681
1869
  // src/hooks/useHudState.ts
1682
- var import_react10 = require("react");
1870
+ var import_react12 = require("react");
1683
1871
 
1684
1872
  // src/hooks/useAdvanceRules.ts
1685
- var import_react6 = require("react");
1873
+ var import_react8 = require("react");
1686
1874
  var DEFAULT_POLL_MS2 = 250;
1687
1875
  var isListenerTarget = (value) => {
1688
1876
  return !!value && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function";
@@ -1721,7 +1909,7 @@ var useAdvanceRules = (target) => {
1721
1909
  complete,
1722
1910
  setDelayInfo
1723
1911
  } = useTour();
1724
- (0, import_react6.useEffect)(() => {
1912
+ (0, import_react8.useEffect)(() => {
1725
1913
  if (!isBrowser) return;
1726
1914
  if (!state || state.status !== "running") return;
1727
1915
  if (!activeStep) return;
@@ -1892,7 +2080,7 @@ var useAdvanceRules = (target) => {
1892
2080
  };
1893
2081
 
1894
2082
  // src/hooks/useHiddenTargetFallback.ts
1895
- var import_react7 = require("react");
2083
+ var import_react9 = require("react");
1896
2084
  var DEFAULT_DELAY_MS = 900;
1897
2085
  var DEFAULT_GRACE_PERIOD_MS = 400;
1898
2086
  var useHiddenTargetFallback = ({
@@ -1901,11 +2089,11 @@ var useHiddenTargetFallback = ({
1901
2089
  viewportRect,
1902
2090
  onSkip
1903
2091
  }) => {
1904
- const [usingScreenFallback, setUsingScreenFallback] = (0, import_react7.useState)(false);
1905
- const [isInGracePeriod, setIsInGracePeriod] = (0, import_react7.useState)(false);
1906
- const timeoutRef = (0, import_react7.useRef)(null);
1907
- const graceTimeoutRef = (0, import_react7.useRef)(null);
1908
- const skipTriggeredRef = (0, import_react7.useRef)(false);
2092
+ const [usingScreenFallback, setUsingScreenFallback] = (0, import_react9.useState)(false);
2093
+ const [isInGracePeriod, setIsInGracePeriod] = (0, import_react9.useState)(false);
2094
+ const timeoutRef = (0, import_react9.useRef)(null);
2095
+ const graceTimeoutRef = (0, import_react9.useRef)(null);
2096
+ const skipTriggeredRef = (0, import_react9.useRef)(false);
1909
2097
  const hiddenMode = step?.targetBehavior?.hidden ?? "screen";
1910
2098
  const hiddenDelayMs = Math.max(
1911
2099
  0,
@@ -1923,7 +2111,7 @@ var useHiddenTargetFallback = ({
1923
2111
  graceTimeoutRef.current = null;
1924
2112
  }
1925
2113
  };
1926
- (0, import_react7.useEffect)(() => {
2114
+ (0, import_react9.useEffect)(() => {
1927
2115
  skipTriggeredRef.current = false;
1928
2116
  setUsingScreenFallback(false);
1929
2117
  setIsInGracePeriod(false);
@@ -1934,7 +2122,7 @@ var useHiddenTargetFallback = ({
1934
2122
  clearGraceTimeout();
1935
2123
  };
1936
2124
  }, [step?.id]);
1937
- (0, import_react7.useEffect)(() => {
2125
+ (0, import_react9.useEffect)(() => {
1938
2126
  if (!isBrowser) return void 0;
1939
2127
  if (!step) return void 0;
1940
2128
  clearPendingTimeout();
@@ -1980,7 +2168,7 @@ var useHiddenTargetFallback = ({
1980
2168
  hiddenDelayMs,
1981
2169
  onSkip
1982
2170
  ]);
1983
- const resolvedTarget = (0, import_react7.useMemo)(() => {
2171
+ const resolvedTarget = (0, import_react9.useMemo)(() => {
1984
2172
  if (!usingScreenFallback) {
1985
2173
  return target;
1986
2174
  }
@@ -2002,7 +2190,7 @@ var useHiddenTargetFallback = ({
2002
2190
  };
2003
2191
 
2004
2192
  // src/hooks/useRouteMismatch.ts
2005
- var import_react8 = require("react");
2193
+ var import_react10 = require("react");
2006
2194
 
2007
2195
  // src/router/utils.ts
2008
2196
  var ensurePrefix = (value, prefix) => value.startsWith(prefix) ? value : `${prefix}${value}`;
@@ -2049,8 +2237,8 @@ var createPathString = (pathname, search, hash) => {
2049
2237
 
2050
2238
  // src/hooks/useRouteMismatch.ts
2051
2239
  var useRouteMismatch = (step) => {
2052
- const [currentPath, setCurrentPath] = (0, import_react8.useState)(() => getCurrentRoutePath());
2053
- (0, import_react8.useEffect)(() => {
2240
+ const [currentPath, setCurrentPath] = (0, import_react10.useState)(() => getCurrentRoutePath());
2241
+ (0, import_react10.useEffect)(() => {
2054
2242
  return subscribeToRouteChanges((path) => {
2055
2243
  setCurrentPath(path);
2056
2244
  });
@@ -2065,13 +2253,13 @@ var useRouteMismatch = (step) => {
2065
2253
  };
2066
2254
 
2067
2255
  // src/hooks/useViewportRect.ts
2068
- var import_react9 = require("react");
2256
+ var import_react11 = require("react");
2069
2257
  var useViewportRect = () => {
2070
- const [viewport, setViewport] = (0, import_react9.useState)(
2258
+ const [viewport, setViewport] = (0, import_react11.useState)(
2071
2259
  () => getViewportRect()
2072
2260
  );
2073
- const rafRef = (0, import_react9.useRef)(null);
2074
- (0, import_react9.useEffect)(() => {
2261
+ const rafRef = (0, import_react11.useRef)(null);
2262
+ (0, import_react11.useEffect)(() => {
2075
2263
  if (!isBrowser) return;
2076
2264
  const updateViewport = () => {
2077
2265
  rafRef.current = null;
@@ -2113,12 +2301,12 @@ var normalizeFlowFilter = (value) => {
2113
2301
  };
2114
2302
  var useHudState = (options = {}) => {
2115
2303
  const { flowId } = options;
2116
- const flowFilter = (0, import_react10.useMemo)(() => normalizeFlowFilter(flowId), [flowId]);
2304
+ const flowFilter = (0, import_react12.useMemo)(() => normalizeFlowFilter(flowId), [flowId]);
2117
2305
  const { state, activeStep, activeFlowId, flows, next, complete, pause, resume } = useTour();
2118
2306
  const target = useTourTarget();
2119
2307
  const viewportRect = useViewportRect();
2120
2308
  useAdvanceRules(target);
2121
- const matchesFlowFilter = (0, import_react10.useMemo)(() => {
2309
+ const matchesFlowFilter = (0, import_react12.useMemo)(() => {
2122
2310
  if (!flowFilter || flowFilter.length === 0) return true;
2123
2311
  if (!activeFlowId) return false;
2124
2312
  return flowFilter.includes(activeFlowId);
@@ -2126,15 +2314,15 @@ var useHudState = (options = {}) => {
2126
2314
  const isRunning = state?.status === "running";
2127
2315
  const runningState = isRunning && matchesFlowFilter ? state : null;
2128
2316
  const runningStep = runningState && activeStep ? activeStep : null;
2129
- const [shouldRender, setShouldRender] = (0, import_react10.useState)(
2317
+ const [shouldRender, setShouldRender] = (0, import_react12.useState)(
2130
2318
  Boolean(runningStep)
2131
2319
  );
2132
- (0, import_react10.useEffect)(() => {
2320
+ (0, import_react12.useEffect)(() => {
2133
2321
  if (runningStep) {
2134
2322
  setShouldRender(true);
2135
2323
  }
2136
2324
  }, [runningStep?.id]);
2137
- (0, import_react10.useEffect)(() => {
2325
+ (0, import_react12.useEffect)(() => {
2138
2326
  if (!shouldRender) return;
2139
2327
  if (runningStep) return;
2140
2328
  if (target.status !== "idle") return;
@@ -2146,19 +2334,19 @@ var useHudState = (options = {}) => {
2146
2334
  };
2147
2335
  }, [runningStep, shouldRender, target.status]);
2148
2336
  const { isRouteMismatch, currentPath } = useRouteMismatch(activeStep);
2149
- const pausedForMissingTargetRef = (0, import_react10.useRef)(null);
2150
- (0, import_react10.useEffect)(() => {
2337
+ const pausedForMissingTargetRef = (0, import_react12.useRef)(null);
2338
+ (0, import_react12.useEffect)(() => {
2151
2339
  if (!isRouteMismatch) return;
2152
2340
  if (!runningState || runningState.status !== "running") return;
2153
2341
  pause();
2154
2342
  }, [isRouteMismatch, runningState, pause]);
2155
- (0, import_react10.useEffect)(() => {
2343
+ (0, import_react12.useEffect)(() => {
2156
2344
  if (isRouteMismatch) return;
2157
2345
  if (pausedForMissingTargetRef.current !== null) return;
2158
2346
  if (!state || state.status !== "paused") return;
2159
2347
  resume();
2160
2348
  }, [isRouteMismatch, state, resume]);
2161
- const skipHiddenStep = (0, import_react10.useCallback)(() => {
2349
+ const skipHiddenStep = (0, import_react12.useCallback)(() => {
2162
2350
  if (!runningState || runningState.status !== "running") return;
2163
2351
  if (!activeFlowId) return;
2164
2352
  const flow = flows.get(activeFlowId);
@@ -2176,7 +2364,7 @@ var useHudState = (options = {}) => {
2176
2364
  viewportRect,
2177
2365
  onSkip: skipHiddenStep
2178
2366
  });
2179
- (0, import_react10.useEffect)(() => {
2367
+ (0, import_react12.useEffect)(() => {
2180
2368
  if (isRouteMismatch) return;
2181
2369
  if (activeStep?.route !== void 0) return;
2182
2370
  if (isInGracePeriod) return;
@@ -2195,14 +2383,14 @@ var useHudState = (options = {}) => {
2195
2383
  currentPath,
2196
2384
  pause
2197
2385
  ]);
2198
- (0, import_react10.useEffect)(() => {
2386
+ (0, import_react12.useEffect)(() => {
2199
2387
  if (pausedForMissingTargetRef.current === null) return;
2200
2388
  if (!state || state.status !== "paused") return;
2201
2389
  if (currentPath === pausedForMissingTargetRef.current) return;
2202
2390
  pausedForMissingTargetRef.current = null;
2203
2391
  resume();
2204
2392
  }, [currentPath, state, resume]);
2205
- (0, import_react10.useEffect)(() => {
2393
+ (0, import_react12.useEffect)(() => {
2206
2394
  pausedForMissingTargetRef.current = null;
2207
2395
  }, [activeStep?.id]);
2208
2396
  const canRenderStep = Boolean(runningStep && runningState);
@@ -2227,24 +2415,24 @@ var useHudState = (options = {}) => {
2227
2415
  };
2228
2416
 
2229
2417
  // src/hooks/useHudDescription.ts
2230
- var import_react11 = require("react");
2418
+ var import_react13 = require("react");
2231
2419
  var sanitizeForId = (value) => {
2232
2420
  const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
2233
2421
  return normalized.length > 0 ? normalized : "step";
2234
2422
  };
2235
2423
  var useHudDescription = (options) => {
2236
2424
  const { step, fallbackAriaDescribedBy } = options;
2237
- const targetDescription = (0, import_react11.useMemo)(() => {
2425
+ const targetDescription = (0, import_react13.useMemo)(() => {
2238
2426
  if (!step) return null;
2239
2427
  if (typeof step.target !== "object") return null;
2240
2428
  const description = step.target.description;
2241
2429
  return typeof description === "string" ? description : null;
2242
2430
  }, [step]);
2243
- const descriptionId = (0, import_react11.useMemo)(() => {
2431
+ const descriptionId = (0, import_react13.useMemo)(() => {
2244
2432
  if (!step || !targetDescription) return void 0;
2245
2433
  return `tour-step-${sanitizeForId(step.id)}-description`;
2246
2434
  }, [step, targetDescription]);
2247
- const combinedAriaDescribedBy = (0, import_react11.useMemo)(() => {
2435
+ const combinedAriaDescribedBy = (0, import_react13.useMemo)(() => {
2248
2436
  const parts = [fallbackAriaDescribedBy, descriptionId].filter(Boolean);
2249
2437
  return parts.length > 0 ? parts.join(" ") : void 0;
2250
2438
  }, [descriptionId, fallbackAriaDescribedBy]);
@@ -2256,10 +2444,10 @@ var useHudDescription = (options) => {
2256
2444
  };
2257
2445
 
2258
2446
  // src/hooks/useHudShortcuts.ts
2259
- var import_react13 = require("react");
2447
+ var import_react15 = require("react");
2260
2448
 
2261
2449
  // src/hooks/useTourControls.ts
2262
- var import_react12 = require("react");
2450
+ var import_react14 = require("react");
2263
2451
  var hasManualAdvance = (rules) => rules.some((rule) => rule.type === "manual");
2264
2452
  var didPreviousAdvanceViaRoute = (rules) => rules.some((rule) => rule.type === "route");
2265
2453
  var useTourControls = () => {
@@ -2274,7 +2462,7 @@ var useTourControls = () => {
2274
2462
  flows,
2275
2463
  activeStep
2276
2464
  } = tour;
2277
- const computed = (0, import_react12.useMemo)(() => {
2465
+ const computed = (0, import_react14.useMemo)(() => {
2278
2466
  if (!state || state.status !== "running" || !activeStep) {
2279
2467
  return {
2280
2468
  isActive: false,
@@ -2323,11 +2511,11 @@ var useTourControls = () => {
2323
2511
  } = computed;
2324
2512
  const canGoBack = showBackButton && !backDisabled;
2325
2513
  const canGoNext = showNextButton && !nextDisabled;
2326
- const goBack = (0, import_react12.useCallback)(() => {
2514
+ const goBack = (0, import_react14.useCallback)(() => {
2327
2515
  if (!canGoBack) return;
2328
2516
  back();
2329
2517
  }, [back, canGoBack]);
2330
- const goNext = (0, import_react12.useCallback)(() => {
2518
+ const goNext = (0, import_react14.useCallback)(() => {
2331
2519
  if (!canGoNext) return;
2332
2520
  if (isLast) {
2333
2521
  complete();
@@ -2335,7 +2523,7 @@ var useTourControls = () => {
2335
2523
  next();
2336
2524
  }
2337
2525
  }, [canGoNext, complete, isLast, next]);
2338
- return (0, import_react12.useMemo)(
2526
+ return (0, import_react14.useMemo)(
2339
2527
  () => ({
2340
2528
  showBackButton,
2341
2529
  backDisabled,
@@ -2380,7 +2568,7 @@ var useHudShortcuts = (target, options) => {
2380
2568
  const escapeEnabled = options?.escape ?? true;
2381
2569
  const { state } = useTour();
2382
2570
  const { cancel, canGoBack, goBack, canGoNext, goNext, isActive } = useTourControls();
2383
- (0, import_react13.useEffect)(() => {
2571
+ (0, import_react15.useEffect)(() => {
2384
2572
  if (!isBrowser) return void 0;
2385
2573
  if (!enabled) return void 0;
2386
2574
  if (!target) return void 0;
@@ -2444,10 +2632,10 @@ var useHudShortcuts = (target, options) => {
2444
2632
  };
2445
2633
 
2446
2634
  // src/hooks/useTourHud.ts
2447
- var import_react16 = require("react");
2635
+ var import_react18 = require("react");
2448
2636
 
2449
2637
  // src/hooks/useBodyScrollLock.ts
2450
- var import_react14 = require("react");
2638
+ var import_react16 = require("react");
2451
2639
  var lockCount = 0;
2452
2640
  var previousOverflow = null;
2453
2641
  var acquireLock = () => {
@@ -2468,7 +2656,7 @@ var releaseLock = () => {
2468
2656
  }
2469
2657
  };
2470
2658
  var useBodyScrollLock = (enabled) => {
2471
- (0, import_react14.useEffect)(() => {
2659
+ (0, import_react16.useEffect)(() => {
2472
2660
  if (!enabled) return;
2473
2661
  acquireLock();
2474
2662
  return () => {
@@ -2478,7 +2666,7 @@ var useBodyScrollLock = (enabled) => {
2478
2666
  };
2479
2667
 
2480
2668
  // src/hooks/useHudTargetIssue.ts
2481
- var import_react15 = require("react");
2669
+ var import_react17 = require("react");
2482
2670
  var deriveTargetIssue = (params) => {
2483
2671
  const { target, labels } = params;
2484
2672
  if (target.isScreen) return null;
@@ -2511,12 +2699,12 @@ var deriveTargetIssue = (params) => {
2511
2699
  var useHudTargetIssue = (target, options) => {
2512
2700
  const labels = useTourLabels();
2513
2701
  const delayMs = Math.max(0, options?.delayMs ?? 500);
2514
- const [armed, setArmed] = (0, import_react15.useState)(false);
2515
- const rawIssue = (0, import_react15.useMemo)(
2702
+ const [armed, setArmed] = (0, import_react17.useState)(false);
2703
+ const rawIssue = (0, import_react17.useMemo)(
2516
2704
  () => deriveTargetIssue({ target, labels }),
2517
2705
  [target.isScreen, target.rectSource, target.status, target.visibility, labels]
2518
2706
  );
2519
- (0, import_react15.useEffect)(() => {
2707
+ (0, import_react17.useEffect)(() => {
2520
2708
  if (!rawIssue) {
2521
2709
  setArmed(false);
2522
2710
  return;
@@ -2550,7 +2738,7 @@ var useTourHud = (options = {}) => {
2550
2738
  const { backdropInteraction, lockBodyScroll } = useTour();
2551
2739
  const hudState = useHudState();
2552
2740
  const disableDefaultHud = hudState.hudRenderMode === "none";
2553
- const [popoverNode, setPopoverNode] = (0, import_react16.useState)(null);
2741
+ const [popoverNode, setPopoverNode] = (0, import_react18.useState)(null);
2554
2742
  const popoverOptions = hudState.flowHudOptions?.popover;
2555
2743
  const description = useHudDescription({
2556
2744
  step: hudState.runningStep,
@@ -2574,7 +2762,7 @@ var useTourHud = (options = {}) => {
2574
2762
  radius: overlayRadius,
2575
2763
  interactionMode: hudState.flowHudOptions?.backdrop?.interaction ?? backdropInteraction
2576
2764
  };
2577
- const popover = (0, import_react16.useMemo)(() => {
2765
+ const popover = (0, import_react18.useMemo)(() => {
2578
2766
  return {
2579
2767
  offset: popoverOptions?.offset ?? 32,
2580
2768
  role: popoverOptions?.role ?? "dialog",
@@ -2586,13 +2774,13 @@ var useTourHud = (options = {}) => {
2586
2774
  placement: hudState.runningStep?.placement
2587
2775
  };
2588
2776
  }, [hudState.runningStep?.placement, popoverOptions]);
2589
- const descriptionResult = (0, import_react16.useMemo)(() => {
2777
+ const descriptionResult = (0, import_react18.useMemo)(() => {
2590
2778
  return {
2591
2779
  ...description,
2592
2780
  text: description.targetDescription
2593
2781
  };
2594
2782
  }, [description]);
2595
- const focusManager = (0, import_react16.useMemo)(
2783
+ const focusManager = (0, import_react18.useMemo)(
2596
2784
  () => ({
2597
2785
  active: hudState.focusTrapActive,
2598
2786
  target: hudState.hudTarget,
@@ -2622,7 +2810,7 @@ var useTourHud = (options = {}) => {
2622
2810
  };
2623
2811
 
2624
2812
  // src/hooks/useTourOverlay.ts
2625
- var import_react17 = require("react");
2813
+ var import_react19 = require("react");
2626
2814
  var DEFAULT_PADDING = 12;
2627
2815
  var DEFAULT_RADIUS = 12;
2628
2816
  var DEFAULT_EDGE_BUFFER = 0;
@@ -2635,9 +2823,9 @@ var useTourOverlay = (options) => {
2635
2823
  interactionMode = "passthrough",
2636
2824
  isInGracePeriod = false
2637
2825
  } = options;
2638
- const hasShownRef = (0, import_react17.useRef)(false);
2639
- const lastReadyTargetRef = (0, import_react17.useRef)(null);
2640
- (0, import_react17.useEffect)(() => {
2826
+ const hasShownRef = (0, import_react19.useRef)(false);
2827
+ const lastReadyTargetRef = (0, import_react19.useRef)(null);
2828
+ (0, import_react19.useEffect)(() => {
2641
2829
  if (!isBrowser) return;
2642
2830
  if (target.status === "ready") {
2643
2831
  hasShownRef.current = true;
@@ -2687,15 +2875,15 @@ var useTourOverlay = (options) => {
2687
2875
  height: highlightHeight,
2688
2876
  radius: highlightRadius
2689
2877
  } : null;
2690
- const maskCapable = (0, import_react17.useMemo)(() => supportsMasking(), []);
2878
+ const maskCapable = (0, import_react19.useMemo)(() => supportsMasking(), []);
2691
2879
  const isActive = target.status === "ready" || target.status === "resolving" && cachedTarget !== null || isInGracePeriod;
2692
2880
  const shouldMask = maskCapable && isActive;
2693
- const maskId = (0, import_react17.useMemo)(
2881
+ const maskId = (0, import_react19.useMemo)(
2694
2882
  () => `tour-overlay-mask-${Math.random().toString(36).slice(2, 10)}`,
2695
2883
  []
2696
2884
  );
2697
2885
  const maskUrl = shouldMask ? `url(#${maskId})` : void 0;
2698
- const fallbackSegments = (0, import_react17.useMemo)(() => {
2886
+ const fallbackSegments = (0, import_react19.useMemo)(() => {
2699
2887
  if (!isActive || shouldMask || !hasHighlightBounds || !highlightRect) {
2700
2888
  return null;
2701
2889
  }
@@ -2748,7 +2936,7 @@ var useTourOverlay = (options) => {
2748
2936
  viewport.height,
2749
2937
  viewport.width
2750
2938
  ]);
2751
- const blockerSegments = (0, import_react17.useMemo)(() => {
2939
+ const blockerSegments = (0, import_react19.useMemo)(() => {
2752
2940
  if (interactionMode !== "block") {
2753
2941
  return null;
2754
2942
  }
@@ -2872,13 +3060,206 @@ var useRadixDialogAdapter = (options = {}) => {
2872
3060
  };
2873
3061
  };
2874
3062
 
3063
+ // src/adapters/radixDialogHelpers.ts
3064
+ var waitForDom = () => new Promise(
3065
+ (resolve) => requestAnimationFrame(() => setTimeout(resolve, 0))
3066
+ );
3067
+
3068
+ // src/hooks/useRadixTourDialog.ts
3069
+ var import_react20 = require("react");
3070
+ var resolveAutoOpen2 = (config) => {
3071
+ if (!config) return { onEnter: true, onResume: true };
3072
+ const { autoOpen } = config;
3073
+ if (autoOpen === false) return { onEnter: false, onResume: false };
3074
+ if (autoOpen === true || autoOpen === void 0) {
3075
+ return { onEnter: true, onResume: true };
3076
+ }
3077
+ return {
3078
+ onEnter: autoOpen.onEnter ?? true,
3079
+ onResume: autoOpen.onResume ?? true
3080
+ };
3081
+ };
3082
+ var useRadixTourDialog = (params) => {
3083
+ const { dialogId } = params;
3084
+ const { activeFlowId, state, flows, goToStep, events } = useTour();
3085
+ const registry = useDialogRegistryOptional();
3086
+ const { suspendExternalFocusTrap } = useTourFocusDominance();
3087
+ const [internalOpen, setInternalOpen] = (0, import_react20.useState)(false);
3088
+ const lastStepIndexRef = (0, import_react20.useRef)(-1);
3089
+ const isResumeRef = (0, import_react20.useRef)(false);
3090
+ const flow = activeFlowId ? flows.get(activeFlowId) : void 0;
3091
+ const dialogConfig = flow?.dialogs?.[dialogId];
3092
+ const currentStep = flow && state && state.stepIndex >= 0 ? flow.steps[state.stepIndex] : void 0;
3093
+ const isStepActive = currentStep?.dialogId === dialogId;
3094
+ const autoOpenConfig = resolveAutoOpen2(dialogConfig);
3095
+ const autoClose = dialogConfig?.autoClose ?? "differentDialog";
3096
+ const shouldBeOpen = (0, import_react20.useMemo)(() => {
3097
+ if (!isStepActive) return false;
3098
+ return true;
3099
+ }, [isStepActive]);
3100
+ (0, import_react20.useEffect)(() => {
3101
+ if (!events) return;
3102
+ const unsubscribe = events.on("flowResume", () => {
3103
+ isResumeRef.current = true;
3104
+ });
3105
+ return unsubscribe;
3106
+ }, [events]);
3107
+ (0, import_react20.useEffect)(() => {
3108
+ if (!state || state.status !== "running") return;
3109
+ if (!flow) return;
3110
+ const currentStepIndex = state.stepIndex;
3111
+ const previousStepIndex = lastStepIndexRef.current;
3112
+ const wasResume = isResumeRef.current;
3113
+ isResumeRef.current = false;
3114
+ if (previousStepIndex === -1 && currentStepIndex >= 0) {
3115
+ lastStepIndexRef.current = currentStepIndex;
3116
+ if (isStepActive) {
3117
+ const shouldAutoOpen = wasResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
3118
+ if (shouldAutoOpen) {
3119
+ setInternalOpen(true);
3120
+ }
3121
+ }
3122
+ return;
3123
+ }
3124
+ if (previousStepIndex === currentStepIndex) return;
3125
+ lastStepIndexRef.current = currentStepIndex;
3126
+ const previousStep = previousStepIndex >= 0 ? flow.steps[previousStepIndex] : void 0;
3127
+ const wasActive = previousStep?.dialogId === dialogId;
3128
+ if (isStepActive && !wasActive) {
3129
+ const shouldAutoOpen = wasResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
3130
+ if (shouldAutoOpen) {
3131
+ setInternalOpen(true);
3132
+ }
3133
+ }
3134
+ if (wasActive && !isStepActive) {
3135
+ if (autoClose === "always" || autoClose === "differentDialog") {
3136
+ setInternalOpen(false);
3137
+ }
3138
+ }
3139
+ }, [
3140
+ state,
3141
+ flow,
3142
+ dialogId,
3143
+ isStepActive,
3144
+ autoOpenConfig.onEnter,
3145
+ autoOpenConfig.onResume,
3146
+ autoClose
3147
+ ]);
3148
+ (0, import_react20.useEffect)(() => {
3149
+ if (!events) return;
3150
+ const unsubscribeEnter = events.on("stepEnter", (payload) => {
3151
+ const step = payload.currentStep;
3152
+ if (step.dialogId !== dialogId) return;
3153
+ const isResume = payload.reason === "resume";
3154
+ const shouldAutoOpen = isResume ? autoOpenConfig.onResume : autoOpenConfig.onEnter;
3155
+ if (shouldAutoOpen) {
3156
+ requestAnimationFrame(() => {
3157
+ setInternalOpen(true);
3158
+ });
3159
+ }
3160
+ });
3161
+ const unsubscribeExit = events.on("stepExit", (payload) => {
3162
+ const step = payload.previousStep;
3163
+ if (step.dialogId !== dialogId) return;
3164
+ const nextStep = payload.currentStep;
3165
+ if (nextStep?.dialogId === dialogId) {
3166
+ return;
3167
+ }
3168
+ if (autoClose === "always" || autoClose === "differentDialog") {
3169
+ requestAnimationFrame(() => {
3170
+ setInternalOpen(false);
3171
+ });
3172
+ }
3173
+ });
3174
+ return () => {
3175
+ unsubscribeEnter();
3176
+ unsubscribeExit();
3177
+ };
3178
+ }, [events, dialogId, autoOpenConfig, autoClose]);
3179
+ const handleDismiss = (0, import_react20.useCallback)(() => {
3180
+ if (!dialogConfig) return;
3181
+ setInternalOpen(false);
3182
+ goToStep(dialogConfig.onDismissGoToStepId);
3183
+ }, [dialogConfig, goToStep]);
3184
+ const onOpenChange = (0, import_react20.useCallback)(
3185
+ (open) => {
3186
+ if (open) {
3187
+ setInternalOpen(true);
3188
+ } else {
3189
+ if (isStepActive && dialogConfig) {
3190
+ handleDismiss();
3191
+ } else {
3192
+ setInternalOpen(false);
3193
+ }
3194
+ }
3195
+ },
3196
+ [isStepActive, dialogConfig, handleDismiss]
3197
+ );
3198
+ (0, import_react20.useEffect)(() => {
3199
+ if (!registry) return;
3200
+ const controller = {
3201
+ open: () => setInternalOpen(true),
3202
+ close: () => setInternalOpen(false),
3203
+ isOpen: () => internalOpen
3204
+ };
3205
+ registry.register(dialogId, controller);
3206
+ return () => registry.unregister(dialogId);
3207
+ }, [registry, dialogId, internalOpen]);
3208
+ const preventDismiss = (0, import_react20.useCallback)(
3209
+ (event) => {
3210
+ if (suspendExternalFocusTrap) {
3211
+ event.preventDefault();
3212
+ }
3213
+ },
3214
+ [suspendExternalFocusTrap]
3215
+ );
3216
+ const handleEscapeKeyDown = (0, import_react20.useCallback)(
3217
+ (event) => {
3218
+ if (isStepActive && dialogConfig) {
3219
+ event.preventDefault();
3220
+ handleDismiss();
3221
+ }
3222
+ },
3223
+ [isStepActive, dialogConfig, handleDismiss]
3224
+ );
3225
+ const handleInteractOutside = (0, import_react20.useCallback)(
3226
+ (event) => {
3227
+ if (suspendExternalFocusTrap) {
3228
+ event.preventDefault();
3229
+ return;
3230
+ }
3231
+ if (isStepActive && dialogConfig) {
3232
+ event.preventDefault();
3233
+ handleDismiss();
3234
+ }
3235
+ },
3236
+ [suspendExternalFocusTrap, isStepActive, dialogConfig, handleDismiss]
3237
+ );
3238
+ return {
3239
+ isStepActive,
3240
+ shouldBeOpen,
3241
+ onOpenChange,
3242
+ dialogProps: {
3243
+ open: internalOpen,
3244
+ onOpenChange,
3245
+ modal: !suspendExternalFocusTrap
3246
+ },
3247
+ contentProps: {
3248
+ trapFocus: !suspendExternalFocusTrap,
3249
+ onInteractOutside: handleInteractOutside,
3250
+ onFocusOutside: preventDismiss,
3251
+ onEscapeKeyDown: handleEscapeKeyDown
3252
+ }
3253
+ };
3254
+ };
3255
+
2875
3256
  // src/hooks/useDelayAdvance.ts
2876
- var import_react18 = require("react");
3257
+ var import_react21 = require("react");
2877
3258
  var getTimestamp = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
2878
3259
  var useDelayAdvance = () => {
2879
3260
  const { delayInfo, activeStep, state } = useTour();
2880
- const [now, setNow] = (0, import_react18.useState)(() => getTimestamp());
2881
- (0, import_react18.useEffect)(() => {
3261
+ const [now, setNow] = (0, import_react21.useState)(() => getTimestamp());
3262
+ (0, import_react21.useEffect)(() => {
2882
3263
  if (!delayInfo) return;
2883
3264
  if (!activeStep || activeStep.id !== delayInfo.stepId) return;
2884
3265
  if (!state || state.status !== "running") return;
@@ -2895,12 +3276,12 @@ var useDelayAdvance = () => {
2895
3276
  }
2896
3277
  };
2897
3278
  }, [delayInfo, activeStep, state]);
2898
- (0, import_react18.useEffect)(() => {
3279
+ (0, import_react21.useEffect)(() => {
2899
3280
  if (!delayInfo) {
2900
3281
  setNow(getTimestamp());
2901
3282
  }
2902
3283
  }, [delayInfo]);
2903
- return (0, import_react18.useMemo)(() => {
3284
+ return (0, import_react21.useMemo)(() => {
2904
3285
  const matchingStep = !!delayInfo && !!activeStep && activeStep.id === delayInfo.stepId;
2905
3286
  const isRunning = matchingStep && state?.status === "running";
2906
3287
  if (!delayInfo) {
@@ -2953,10 +3334,10 @@ var useDelayAdvance = () => {
2953
3334
  };
2954
3335
 
2955
3336
  // src/components/OverlayBackdrop.tsx
2956
- var import_react19 = require("react");
3337
+ var import_react22 = require("react");
2957
3338
  var import_react_dom = require("react-dom");
2958
- var import_react20 = require("motion/react");
2959
- var import_jsx_runtime3 = require("react/jsx-runtime");
3339
+ var import_react23 = require("motion/react");
3340
+ var import_jsx_runtime4 = require("react/jsx-runtime");
2960
3341
  var styles = {
2961
3342
  root: {
2962
3343
  position: "fixed",
@@ -3042,9 +3423,9 @@ var OverlayBackdrop = ({
3042
3423
  viewport
3043
3424
  } = overlay;
3044
3425
  const hasHighlightBounds = Boolean(highlight.rect);
3045
- const prevScreenTargetRef = (0, import_react19.useRef)(null);
3426
+ const prevScreenTargetRef = (0, import_react22.useRef)(null);
3046
3427
  const shouldSnapHighlight = prevScreenTargetRef.current === true && !highlight.isScreen && hasHighlightBounds;
3047
- (0, import_react19.useEffect)(() => {
3428
+ (0, import_react22.useEffect)(() => {
3048
3429
  prevScreenTargetRef.current = highlight.isScreen;
3049
3430
  }, [highlight.isScreen]);
3050
3431
  const resolvedBlur = typeof blurAmount === "number" ? `${blurAmount}px` : "0px";
@@ -3104,7 +3485,7 @@ var OverlayBackdrop = ({
3104
3485
  overlayStyle.backgroundColor = color;
3105
3486
  }
3106
3487
  return (0, import_react_dom.createPortal)(
3107
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3488
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3108
3489
  MotionDiv,
3109
3490
  {
3110
3491
  className: rootClassName,
@@ -3112,7 +3493,7 @@ var OverlayBackdrop = ({
3112
3493
  "aria-hidden": ariaHidden,
3113
3494
  "data-tour-overlay": "",
3114
3495
  children: [
3115
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3496
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react23.AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3116
3497
  MotionSvg,
3117
3498
  {
3118
3499
  width: "0",
@@ -3124,7 +3505,7 @@ var OverlayBackdrop = ({
3124
3505
  animate: { opacity: 1 },
3125
3506
  exit: { opacity: 0 },
3126
3507
  transition: overlayTransition,
3127
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MotionDefs, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3508
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MotionDefs, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3128
3509
  MotionMask,
3129
3510
  {
3130
3511
  id: maskId ?? void 0,
@@ -3136,7 +3517,7 @@ var OverlayBackdrop = ({
3136
3517
  animate: { width: viewport.width, height: viewport.height },
3137
3518
  transition: highlightTransition,
3138
3519
  children: [
3139
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3520
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3140
3521
  MotionRect,
3141
3522
  {
3142
3523
  x: "0",
@@ -3152,7 +3533,7 @@ var OverlayBackdrop = ({
3152
3533
  exit: { opacity: 0 }
3153
3534
  }
3154
3535
  ),
3155
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3536
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3156
3537
  MotionRect,
3157
3538
  {
3158
3539
  initial: false,
@@ -3171,7 +3552,7 @@ var OverlayBackdrop = ({
3171
3552
  },
3172
3553
  "tour-mask"
3173
3554
  ) : null }),
3174
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3555
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react23.AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3175
3556
  MotionDiv,
3176
3557
  {
3177
3558
  className: overlayClassName,
@@ -3199,7 +3580,7 @@ var OverlayBackdrop = ({
3199
3580
  },
3200
3581
  "tour-overlay"
3201
3582
  ) : null }),
3202
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3583
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react23.AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3203
3584
  MotionDiv,
3204
3585
  {
3205
3586
  className: segmentClassName,
@@ -3229,13 +3610,13 @@ var OverlayBackdrop = ({
3229
3610
  },
3230
3611
  `tour-overlay-fallback-${segment.key}`
3231
3612
  )) : null }),
3232
- showInteractionBlocker && blockerSegments ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3613
+ showInteractionBlocker && blockerSegments ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3233
3614
  "div",
3234
3615
  {
3235
3616
  style: { ...styles.blockerContainer, zIndex },
3236
3617
  "data-tour-overlay-layer": "interaction-blocker",
3237
3618
  "aria-hidden": true,
3238
- children: blockerSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3619
+ children: blockerSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3239
3620
  "div",
3240
3621
  {
3241
3622
  style: {
@@ -3250,7 +3631,7 @@ var OverlayBackdrop = ({
3250
3631
  ))
3251
3632
  }
3252
3633
  ) : null,
3253
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3634
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react23.AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3254
3635
  MotionDiv,
3255
3636
  {
3256
3637
  className: ringClassName,
@@ -3281,7 +3662,7 @@ var OverlayBackdrop = ({
3281
3662
  };
3282
3663
 
3283
3664
  // src/components/TourPopoverPortal.tsx
3284
- var import_react21 = require("react");
3665
+ var import_react24 = require("react");
3285
3666
  var import_react_dom2 = require("react-dom");
3286
3667
  var import_dom13 = require("@floating-ui/dom");
3287
3668
  var FLOATING_OFFSET = 8;
@@ -3342,12 +3723,12 @@ var TourPopoverPortal = ({
3342
3723
  const popoverContentTransition = transitionsOverride?.popoverContent ?? adapter.transitions.popoverContent ?? DEFAULT_POPOVER_CONTENT_TRANSITION;
3343
3724
  const viewport = useViewportRect();
3344
3725
  const prefersMobileLayout = viewport.width <= MOBILE_BREAKPOINT || viewport.height <= MOBILE_HEIGHT_BREAKPOINT;
3345
- const prefersMobileRef = (0, import_react21.useRef)(prefersMobileLayout);
3346
- (0, import_react21.useEffect)(() => {
3726
+ const prefersMobileRef = (0, import_react24.useRef)(prefersMobileLayout);
3727
+ (0, import_react24.useEffect)(() => {
3347
3728
  prefersMobileRef.current = prefersMobileLayout;
3348
3729
  }, [prefersMobileLayout]);
3349
- const lastReadyTargetRef = (0, import_react21.useRef)(null);
3350
- (0, import_react21.useEffect)(() => {
3730
+ const lastReadyTargetRef = (0, import_react24.useRef)(null);
3731
+ (0, import_react24.useEffect)(() => {
3351
3732
  if (target.status === "ready" && target.rect) {
3352
3733
  lastReadyTargetRef.current = {
3353
3734
  rect: { ...target.rect },
@@ -3363,7 +3744,7 @@ var TourPopoverPortal = ({
3363
3744
  const shouldHidePopover = !resolvedRect && !target.isScreen;
3364
3745
  const fallbackRect = resolvedRect ?? viewport;
3365
3746
  const fallbackIsScreen = resolvedIsScreen;
3366
- const [floatingSize, setFloatingSize] = (0, import_react21.useState)(null);
3747
+ const [floatingSize, setFloatingSize] = (0, import_react24.useState)(null);
3367
3748
  const clampVertical = (value) => Math.min(viewport.height - 24, Math.max(24, value));
3368
3749
  const clampHorizontal = (value) => Math.min(viewport.width - 24, Math.max(24, value));
3369
3750
  const screenCenteredTop = viewport.height / 2 - (floatingSize?.height ?? 0) / 2;
@@ -3374,7 +3755,7 @@ var TourPopoverPortal = ({
3374
3755
  const leftBase = fallbackIsScreen ? screenCenteredLeft : fallbackRect.left + fallbackRect.width / 2 - floatingWidth / 2;
3375
3756
  const left = clampHorizontal(leftBase);
3376
3757
  const fallbackTransform = "translate3d(0px, 0px, 0px)";
3377
- const fallbackPosition = (0, import_react21.useMemo)(
3758
+ const fallbackPosition = (0, import_react24.useMemo)(
3378
3759
  () => ({
3379
3760
  top,
3380
3761
  left,
@@ -3382,7 +3763,7 @@ var TourPopoverPortal = ({
3382
3763
  }),
3383
3764
  [fallbackTransform, left, top]
3384
3765
  );
3385
- const centerInitialPosition = (0, import_react21.useMemo)(
3766
+ const centerInitialPosition = (0, import_react24.useMemo)(
3386
3767
  () => ({
3387
3768
  top: viewport.height / 2,
3388
3769
  left: viewport.width / 2,
@@ -3390,23 +3771,23 @@ var TourPopoverPortal = ({
3390
3771
  }),
3391
3772
  [viewport.height, viewport.width]
3392
3773
  );
3393
- const floatingRef = (0, import_react21.useRef)(null);
3394
- const cachedFloatingPositionRef = (0, import_react21.useRef)(null);
3395
- const appliedFloatingCacheRef = (0, import_react21.useRef)(null);
3396
- const deferredScreenSnapRef = (0, import_react21.useRef)(null);
3397
- const [layoutMode, setLayoutMode] = (0, import_react21.useState)(
3774
+ const floatingRef = (0, import_react24.useRef)(null);
3775
+ const cachedFloatingPositionRef = (0, import_react24.useRef)(null);
3776
+ const appliedFloatingCacheRef = (0, import_react24.useRef)(null);
3777
+ const deferredScreenSnapRef = (0, import_react24.useRef)(null);
3778
+ const [layoutMode, setLayoutMode] = (0, import_react24.useState)(
3398
3779
  () => prefersMobileLayout ? "mobile" : "floating"
3399
3780
  );
3400
- const [floatingPosition, setFloatingPosition] = (0, import_react21.useState)(fallbackPosition);
3401
- const [dragPosition, setDragPosition] = (0, import_react21.useState)(null);
3402
- const [isDragging, setIsDragging] = (0, import_react21.useState)(false);
3403
- const dragStateRef = (0, import_react21.useRef)(null);
3404
- const overflowRetryRef = (0, import_react21.useRef)({
3781
+ const [floatingPosition, setFloatingPosition] = (0, import_react24.useState)(fallbackPosition);
3782
+ const [dragPosition, setDragPosition] = (0, import_react24.useState)(null);
3783
+ const [isDragging, setIsDragging] = (0, import_react24.useState)(false);
3784
+ const dragStateRef = (0, import_react24.useRef)(null);
3785
+ const overflowRetryRef = (0, import_react24.useRef)({
3405
3786
  stepId: null,
3406
3787
  attempts: 0
3407
3788
  });
3408
- const overflowRetryTimeoutRef = (0, import_react21.useRef)(null);
3409
- (0, import_react21.useLayoutEffect)(() => {
3789
+ const overflowRetryTimeoutRef = (0, import_react24.useRef)(null);
3790
+ (0, import_react24.useLayoutEffect)(() => {
3410
3791
  if (!isBrowser) return;
3411
3792
  const node = floatingRef.current;
3412
3793
  if (!node) return;
@@ -3425,25 +3806,25 @@ var TourPopoverPortal = ({
3425
3806
  const autoAlignment = resolvedPlacement.endsWith(
3426
3807
  "-start"
3427
3808
  ) ? "start" : resolvedPlacement.endsWith("-end") ? "end" : void 0;
3428
- (0, import_react21.useEffect)(() => {
3809
+ (0, import_react24.useEffect)(() => {
3429
3810
  setDragPosition(null);
3430
3811
  setLayoutMode(prefersMobileRef.current ? "mobile" : "floating");
3431
3812
  cachedFloatingPositionRef.current = null;
3432
3813
  appliedFloatingCacheRef.current = null;
3433
3814
  }, [target.stepId]);
3434
- (0, import_react21.useEffect)(() => {
3815
+ (0, import_react24.useEffect)(() => {
3435
3816
  if (layoutMode !== "manual") {
3436
3817
  setDragPosition(null);
3437
3818
  }
3438
3819
  }, [layoutMode]);
3439
- (0, import_react21.useEffect)(() => {
3820
+ (0, import_react24.useEffect)(() => {
3440
3821
  cachedFloatingPositionRef.current = floatingPosition;
3441
3822
  const cacheKey = getFloatingCacheKey(target);
3442
3823
  if (cacheKey) {
3443
3824
  floatingPositionCache.set(cacheKey, floatingPosition);
3444
3825
  }
3445
3826
  }, [floatingPosition, target.isScreen, target.stepId]);
3446
- const dockedPosition = (0, import_react21.useMemo)(
3827
+ const dockedPosition = (0, import_react24.useMemo)(
3447
3828
  () => ({
3448
3829
  top: viewport.height - DOCKED_MARGIN,
3449
3830
  left: viewport.width - DOCKED_MARGIN,
@@ -3451,7 +3832,7 @@ var TourPopoverPortal = ({
3451
3832
  }),
3452
3833
  [viewport.height, viewport.width]
3453
3834
  );
3454
- const mobilePosition = (0, import_react21.useMemo)(
3835
+ const mobilePosition = (0, import_react24.useMemo)(
3455
3836
  () => ({
3456
3837
  top: viewport.height - MOBILE_HORIZONTAL_GUTTER,
3457
3838
  left: viewport.width / 2,
@@ -3459,17 +3840,17 @@ var TourPopoverPortal = ({
3459
3840
  }),
3460
3841
  [viewport.height, viewport.width]
3461
3842
  );
3462
- (0, import_react21.useEffect)(() => {
3843
+ (0, import_react24.useEffect)(() => {
3463
3844
  if (layoutMode === "docked") {
3464
3845
  setFloatingPosition(dockedPosition);
3465
3846
  }
3466
3847
  }, [dockedPosition, layoutMode]);
3467
- (0, import_react21.useEffect)(() => {
3848
+ (0, import_react24.useEffect)(() => {
3468
3849
  if (layoutMode === "mobile") {
3469
3850
  setFloatingPosition(mobilePosition);
3470
3851
  }
3471
3852
  }, [layoutMode, mobilePosition]);
3472
- (0, import_react21.useEffect)(() => {
3853
+ (0, import_react24.useEffect)(() => {
3473
3854
  if (prefersMobileLayout) {
3474
3855
  if (layoutMode !== "mobile") {
3475
3856
  setLayoutMode("mobile");
@@ -3482,7 +3863,7 @@ var TourPopoverPortal = ({
3482
3863
  setFloatingPosition(fallbackPosition);
3483
3864
  }
3484
3865
  }, [fallbackPosition, layoutMode, prefersMobileLayout]);
3485
- (0, import_react21.useEffect)(() => {
3866
+ (0, import_react24.useEffect)(() => {
3486
3867
  if (layoutMode !== "floating") return;
3487
3868
  const stepId = target.stepId;
3488
3869
  if (!stepId) return;
@@ -3506,7 +3887,7 @@ var TourPopoverPortal = ({
3506
3887
  target.stepId
3507
3888
  ]);
3508
3889
  const shouldDeferScreenSnap = layoutMode === "floating" && target.isScreen && Boolean(layoutId);
3509
- (0, import_react21.useEffect)(() => {
3890
+ (0, import_react24.useEffect)(() => {
3510
3891
  return () => {
3511
3892
  if (deferredScreenSnapRef.current !== null) {
3512
3893
  cancelAnimationFrame(deferredScreenSnapRef.current);
@@ -3514,7 +3895,7 @@ var TourPopoverPortal = ({
3514
3895
  }
3515
3896
  };
3516
3897
  }, []);
3517
- (0, import_react21.useLayoutEffect)(() => {
3898
+ (0, import_react24.useLayoutEffect)(() => {
3518
3899
  if (layoutMode !== "floating") return;
3519
3900
  if (target.status === "ready" && !target.isScreen) return;
3520
3901
  if (shouldDeferScreenSnap) return;
@@ -3526,7 +3907,7 @@ var TourPopoverPortal = ({
3526
3907
  target.isScreen,
3527
3908
  target.status
3528
3909
  ]);
3529
- (0, import_react21.useEffect)(() => {
3910
+ (0, import_react24.useEffect)(() => {
3530
3911
  if (!shouldDeferScreenSnap) return;
3531
3912
  if (deferredScreenSnapRef.current !== null) {
3532
3913
  cancelAnimationFrame(deferredScreenSnapRef.current);
@@ -3553,14 +3934,14 @@ var TourPopoverPortal = ({
3553
3934
  }
3554
3935
  };
3555
3936
  }, [fallbackPosition, shouldDeferScreenSnap]);
3556
- (0, import_react21.useEffect)(() => {
3937
+ (0, import_react24.useEffect)(() => {
3557
3938
  return () => {
3558
3939
  if (overflowRetryTimeoutRef.current !== null) {
3559
3940
  window.clearTimeout(overflowRetryTimeoutRef.current);
3560
3941
  }
3561
3942
  };
3562
3943
  }, []);
3563
- (0, import_react21.useLayoutEffect)(() => {
3944
+ (0, import_react24.useLayoutEffect)(() => {
3564
3945
  if (!isBrowser) return;
3565
3946
  const floatingEl = floatingRef.current;
3566
3947
  const rectInfo = target.rect;
@@ -3694,7 +4075,7 @@ var TourPopoverPortal = ({
3694
4075
  target.status,
3695
4076
  target.stepId
3696
4077
  ]);
3697
- (0, import_react21.useLayoutEffect)(() => {
4078
+ (0, import_react24.useLayoutEffect)(() => {
3698
4079
  if (layoutMode !== "manual" || !dragPosition) return;
3699
4080
  setFloatingPosition({
3700
4081
  top: dragPosition.top,
@@ -3779,7 +4160,7 @@ var TourPopoverPortal = ({
3779
4160
  }
3780
4161
  event.preventDefault();
3781
4162
  };
3782
- (0, import_react21.useEffect)(() => endDrag, []);
4163
+ (0, import_react24.useEffect)(() => endDrag, []);
3783
4164
  const shouldUseFallbackInitial = layoutMode !== "mobile" && (Boolean(target.lastResolvedRect) || Boolean(cachedTarget));
3784
4165
  const floatingCacheKey = layoutMode === "mobile" ? null : getFloatingCacheKey(target);
3785
4166
  const persistedFloatingInitial = floatingCacheKey && floatingPositionCache.has(floatingCacheKey) ? floatingPositionCache.get(floatingCacheKey) ?? null : null;
@@ -3871,7 +4252,7 @@ var TourPopoverPortal = ({
3871
4252
  };
3872
4253
 
3873
4254
  // src/components/TourFocusManager.tsx
3874
- var import_react22 = require("react");
4255
+ var import_react25 = require("react");
3875
4256
  var import_react_dom3 = require("react-dom");
3876
4257
 
3877
4258
  // src/utils/focus.ts
@@ -3932,7 +4313,7 @@ var focusElement = (element, options) => {
3932
4313
  };
3933
4314
 
3934
4315
  // src/components/TourFocusManager.tsx
3935
- var import_jsx_runtime4 = require("react/jsx-runtime");
4316
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3936
4317
  var runMicrotask = (callback) => {
3937
4318
  if (typeof queueMicrotask === "function") {
3938
4319
  queueMicrotask(callback);
@@ -3948,18 +4329,18 @@ var TourFocusManager = ({
3948
4329
  highlightRect,
3949
4330
  guardElementFocusRing
3950
4331
  }) => {
3951
- const previousFocusRef = (0, import_react22.useRef)(null);
3952
- const guardNodesRef = (0, import_react22.useRef)({
4332
+ const previousFocusRef = (0, import_react25.useRef)(null);
4333
+ const guardNodesRef = (0, import_react25.useRef)({
3953
4334
  "target-start": null,
3954
4335
  "target-end": null,
3955
4336
  "popover-start": null,
3956
4337
  "popover-end": null
3957
4338
  });
3958
- const lastTabDirectionRef = (0, import_react22.useRef)("forward");
3959
- const suppressGuardHopRef = (0, import_react22.useRef)(null);
3960
- const [targetRingActive, setTargetRingActive] = (0, import_react22.useState)(false);
3961
- const [popoverRingActive, setPopoverRingActive] = (0, import_react22.useState)(false);
3962
- const [popoverRect, setPopoverRect] = (0, import_react22.useState)(null);
4339
+ const lastTabDirectionRef = (0, import_react25.useRef)("forward");
4340
+ const suppressGuardHopRef = (0, import_react25.useRef)(null);
4341
+ const [targetRingActive, setTargetRingActive] = (0, import_react25.useState)(false);
4342
+ const [popoverRingActive, setPopoverRingActive] = (0, import_react25.useState)(false);
4343
+ const [popoverRect, setPopoverRect] = (0, import_react25.useState)(null);
3963
4344
  const restoreFocus = () => {
3964
4345
  const previous = previousFocusRef.current;
3965
4346
  previousFocusRef.current = null;
@@ -3969,7 +4350,7 @@ var TourFocusManager = ({
3969
4350
  });
3970
4351
  }
3971
4352
  };
3972
- (0, import_react22.useLayoutEffect)(() => {
4353
+ (0, import_react25.useLayoutEffect)(() => {
3973
4354
  if (!isBrowser) return;
3974
4355
  if (!active) {
3975
4356
  restoreFocus();
@@ -3985,7 +4366,7 @@ var TourFocusManager = ({
3985
4366
  restoreFocus();
3986
4367
  };
3987
4368
  }, [active, popoverNode, target.element]);
3988
- (0, import_react22.useEffect)(() => {
4369
+ (0, import_react25.useEffect)(() => {
3989
4370
  if (!isBrowser) return;
3990
4371
  if (!active) return;
3991
4372
  const doc = popoverNode?.ownerDocument ?? target.element?.ownerDocument ?? document;
@@ -4179,7 +4560,7 @@ var TourFocusManager = ({
4179
4560
  target.stepId,
4180
4561
  target.visibility
4181
4562
  ]);
4182
- (0, import_react22.useLayoutEffect)(() => {
4563
+ (0, import_react25.useLayoutEffect)(() => {
4183
4564
  if (popoverRingActive && popoverNode) {
4184
4565
  setPopoverRect(popoverNode.getBoundingClientRect());
4185
4566
  } else {
@@ -4194,8 +4575,8 @@ var TourFocusManager = ({
4194
4575
  const showPopoverRing = popoverRingActive && popoverRect;
4195
4576
  if (!showTargetRing && !showPopoverRing) return null;
4196
4577
  return (0, import_react_dom3.createPortal)(
4197
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
4198
- showTargetRing && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4578
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
4579
+ showTargetRing && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4199
4580
  "div",
4200
4581
  {
4201
4582
  style: {
@@ -4212,7 +4593,7 @@ var TourFocusManager = ({
4212
4593
  "aria-hidden": true
4213
4594
  }
4214
4595
  ),
4215
- showPopoverRing && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4596
+ showPopoverRing && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4216
4597
  "div",
4217
4598
  {
4218
4599
  style: {
@@ -4235,7 +4616,7 @@ var TourFocusManager = ({
4235
4616
  };
4236
4617
 
4237
4618
  // src/motion/useHudMotion.ts
4238
- var import_react23 = require("react");
4619
+ var import_react26 = require("react");
4239
4620
  var DEFAULT_HIGHLIGHT_TRANSITION2 = {
4240
4621
  duration: 0.35,
4241
4622
  ease: "easeOut",
@@ -4262,7 +4643,7 @@ var DEFAULT_POPOVER_CONTENT_TRANSITION2 = {
4262
4643
  };
4263
4644
  var useHudMotion = () => {
4264
4645
  const adapter = useAnimationAdapter();
4265
- return (0, import_react23.useMemo)(() => {
4646
+ return (0, import_react26.useMemo)(() => {
4266
4647
  const components = {
4267
4648
  ...adapter.components
4268
4649
  };
@@ -4281,6 +4662,7 @@ var useHudMotion = () => {
4281
4662
  // Annotate the CommonJS export names for ESM import in node:
4282
4663
  0 && (module.exports = {
4283
4664
  AnimationAdapterProvider,
4665
+ DialogRegistryProvider,
4284
4666
  OverlayBackdrop,
4285
4667
  TourFocusManager,
4286
4668
  TourPopoverPortal,
@@ -4297,6 +4679,8 @@ var useHudMotion = () => {
4297
4679
  useAnimationAdapter,
4298
4680
  useBodyScrollLock,
4299
4681
  useDelayAdvance,
4682
+ useDialogRegistry,
4683
+ useDialogRegistryOptional,
4300
4684
  useHiddenTargetFallback,
4301
4685
  useHudDescription,
4302
4686
  useHudMotion,
@@ -4305,6 +4689,7 @@ var useHudMotion = () => {
4305
4689
  useHudTargetIssue,
4306
4690
  usePreferredAnimationAdapter,
4307
4691
  useRadixDialogAdapter,
4692
+ useRadixTourDialog,
4308
4693
  useTour,
4309
4694
  useTourControls,
4310
4695
  useTourEvents,
@@ -4313,5 +4698,6 @@ var useHudMotion = () => {
4313
4698
  useTourLabels,
4314
4699
  useTourOverlay,
4315
4700
  useTourTarget,
4316
- useViewportRect
4701
+ useViewportRect,
4702
+ waitForDom
4317
4703
  });