@flowsterix/react 0.5.0 → 0.7.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
@@ -72,7 +72,17 @@ var defaultLabels = {
72
72
  ariaStepProgress: ({ current, total }) => `Step ${current} of ${total}`,
73
73
  ariaTimeRemaining: ({ ms }) => `${Math.ceil(ms / 1e3)} seconds remaining`,
74
74
  ariaDelayProgress: "Auto-advance progress",
75
- formatTimeRemaining: ({ ms }) => `${Math.ceil(ms / 1e3)}s remaining`
75
+ formatTimeRemaining: ({ ms }) => `${Math.ceil(ms / 1e3)}s remaining`,
76
+ targetIssue: {
77
+ missingTitle: "Target not visible",
78
+ missingBody: "The target element is not currently visible. Make sure the UI piece is mounted and displayed.",
79
+ missingHint: "Showing the last known position until the element returns.",
80
+ hiddenTitle: "Target not visible",
81
+ hiddenBody: "The target element is not currently visible. Make sure the UI piece is mounted and displayed.",
82
+ hiddenHint: "Showing the last known position until the element returns.",
83
+ detachedTitle: "Target left the page",
84
+ detachedBody: "Navigate back to the screen that contains this element or reopen it before continuing the tour."
85
+ }
76
86
  };
77
87
  var LabelsContext = (0, import_react.createContext)(defaultLabels);
78
88
  var LabelsProvider = LabelsContext.Provider;
@@ -807,6 +817,10 @@ var TourProvider = ({
807
817
  () => getActiveStore().complete(),
808
818
  [getActiveStore]
809
819
  );
820
+ const advanceStep = (0, import_react4.useCallback)(
821
+ (stepId) => getActiveStore().advanceStep(stepId),
822
+ [getActiveStore]
823
+ );
810
824
  const toggleDebug = (0, import_react4.useCallback)(() => {
811
825
  setDebugEnabled((previous) => !previous);
812
826
  }, []);
@@ -844,6 +858,7 @@ var TourProvider = ({
844
858
  resume,
845
859
  cancel,
846
860
  complete,
861
+ advanceStep,
847
862
  events,
848
863
  debugEnabled,
849
864
  setDebugEnabled,
@@ -856,6 +871,7 @@ var TourProvider = ({
856
871
  [
857
872
  activeFlowId,
858
873
  activeStep,
874
+ advanceStep,
859
875
  back,
860
876
  cancel,
861
877
  complete,
@@ -1663,7 +1679,7 @@ var useTourTarget = () => {
1663
1679
  };
1664
1680
 
1665
1681
  // src/hooks/useHudState.ts
1666
- var import_react9 = require("react");
1682
+ var import_react10 = require("react");
1667
1683
 
1668
1684
  // src/hooks/useAdvanceRules.ts
1669
1685
  var import_react6 = require("react");
@@ -1925,7 +1941,8 @@ var useHiddenTargetFallback = ({
1925
1941
  clearGraceTimeout();
1926
1942
  const isHiddenOrDetached = (target.visibility === "hidden" || target.visibility === "detached") && target.status === "ready";
1927
1943
  const isMissingWithNoRect = target.visibility === "missing" && target.status === "resolving" && target.rect === null && target.lastResolvedRect === null;
1928
- const shouldHandleHiddenTarget = !target.isScreen && (isHiddenOrDetached || isMissingWithNoRect);
1944
+ const isMissingAfterNavigation = target.visibility === "missing" && target.status === "resolving" && target.rect === null;
1945
+ const shouldHandleHiddenTarget = !target.isScreen && (isHiddenOrDetached || isMissingWithNoRect || isMissingAfterNavigation);
1929
1946
  if (!shouldHandleHiddenTarget) {
1930
1947
  setUsingScreenFallback(false);
1931
1948
  setIsInGracePeriod(false);
@@ -1984,14 +2001,77 @@ var useHiddenTargetFallback = ({
1984
2001
  };
1985
2002
  };
1986
2003
 
1987
- // src/hooks/useViewportRect.ts
2004
+ // src/hooks/useRouteMismatch.ts
1988
2005
  var import_react8 = require("react");
2006
+
2007
+ // src/router/utils.ts
2008
+ var ensurePrefix = (value, prefix) => value.startsWith(prefix) ? value : `${prefix}${value}`;
2009
+ var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
2010
+ var toSearchString = (value) => {
2011
+ if (!isNonEmptyString(value)) {
2012
+ if (value instanceof URLSearchParams) {
2013
+ const serialized = value.toString();
2014
+ return serialized.length > 0 ? `?${serialized}` : "";
2015
+ }
2016
+ if (typeof value === "object" && value !== null) {
2017
+ try {
2018
+ const params = new URLSearchParams();
2019
+ for (const [key, raw] of Object.entries(
2020
+ value
2021
+ )) {
2022
+ if (raw === void 0 || raw === null) continue;
2023
+ params.set(key, String(raw));
2024
+ }
2025
+ const serialized = params.toString();
2026
+ return serialized.length > 0 ? `?${serialized}` : "";
2027
+ } catch {
2028
+ return "";
2029
+ }
2030
+ }
2031
+ return "";
2032
+ }
2033
+ if (value === "?") return "";
2034
+ return value.startsWith("?") ? value : ensurePrefix(value, "?");
2035
+ };
2036
+ var toHashString = (value) => {
2037
+ if (!isNonEmptyString(value)) {
2038
+ return "";
2039
+ }
2040
+ if (value === "#") return "";
2041
+ return value.startsWith("#") ? value : ensurePrefix(value, "#");
2042
+ };
2043
+ var createPathString = (pathname, search, hash) => {
2044
+ const normalizedPath = isNonEmptyString(pathname) ? pathname.startsWith("/") ? pathname : `/${pathname}` : "/";
2045
+ const searchPart = toSearchString(search);
2046
+ const hashPart = toHashString(hash);
2047
+ return `${normalizedPath}${searchPart}${hashPart}`;
2048
+ };
2049
+
2050
+ // src/hooks/useRouteMismatch.ts
2051
+ var useRouteMismatch = (step) => {
2052
+ const [currentPath, setCurrentPath] = (0, import_react8.useState)(() => getCurrentRoutePath());
2053
+ (0, import_react8.useEffect)(() => {
2054
+ return subscribeToRouteChanges((path) => {
2055
+ setCurrentPath(path);
2056
+ });
2057
+ }, []);
2058
+ const expectedRoute = step?.route;
2059
+ const isRouteMismatch = step !== null && expectedRoute !== void 0 && !matchRoute({ pattern: expectedRoute, path: currentPath });
2060
+ return {
2061
+ isRouteMismatch,
2062
+ currentPath,
2063
+ expectedRoute
2064
+ };
2065
+ };
2066
+
2067
+ // src/hooks/useViewportRect.ts
2068
+ var import_react9 = require("react");
1989
2069
  var useViewportRect = () => {
1990
- const [viewport, setViewport] = (0, import_react8.useState)(
2070
+ const [viewport, setViewport] = (0, import_react9.useState)(
1991
2071
  () => getViewportRect()
1992
2072
  );
1993
- const rafRef = (0, import_react8.useRef)(null);
1994
- (0, import_react8.useEffect)(() => {
2073
+ const rafRef = (0, import_react9.useRef)(null);
2074
+ (0, import_react9.useEffect)(() => {
1995
2075
  if (!isBrowser) return;
1996
2076
  const updateViewport = () => {
1997
2077
  rafRef.current = null;
@@ -2033,12 +2113,12 @@ var normalizeFlowFilter = (value) => {
2033
2113
  };
2034
2114
  var useHudState = (options = {}) => {
2035
2115
  const { flowId } = options;
2036
- const flowFilter = (0, import_react9.useMemo)(() => normalizeFlowFilter(flowId), [flowId]);
2037
- const { state, activeStep, activeFlowId, flows, next, complete } = useTour();
2116
+ const flowFilter = (0, import_react10.useMemo)(() => normalizeFlowFilter(flowId), [flowId]);
2117
+ const { state, activeStep, activeFlowId, flows, next, complete, pause, resume } = useTour();
2038
2118
  const target = useTourTarget();
2039
2119
  const viewportRect = useViewportRect();
2040
2120
  useAdvanceRules(target);
2041
- const matchesFlowFilter = (0, import_react9.useMemo)(() => {
2121
+ const matchesFlowFilter = (0, import_react10.useMemo)(() => {
2042
2122
  if (!flowFilter || flowFilter.length === 0) return true;
2043
2123
  if (!activeFlowId) return false;
2044
2124
  return flowFilter.includes(activeFlowId);
@@ -2046,15 +2126,15 @@ var useHudState = (options = {}) => {
2046
2126
  const isRunning = state?.status === "running";
2047
2127
  const runningState = isRunning && matchesFlowFilter ? state : null;
2048
2128
  const runningStep = runningState && activeStep ? activeStep : null;
2049
- const [shouldRender, setShouldRender] = (0, import_react9.useState)(
2129
+ const [shouldRender, setShouldRender] = (0, import_react10.useState)(
2050
2130
  Boolean(runningStep)
2051
2131
  );
2052
- (0, import_react9.useEffect)(() => {
2132
+ (0, import_react10.useEffect)(() => {
2053
2133
  if (runningStep) {
2054
2134
  setShouldRender(true);
2055
2135
  }
2056
2136
  }, [runningStep?.id]);
2057
- (0, import_react9.useEffect)(() => {
2137
+ (0, import_react10.useEffect)(() => {
2058
2138
  if (!shouldRender) return;
2059
2139
  if (runningStep) return;
2060
2140
  if (target.status !== "idle") return;
@@ -2065,7 +2145,20 @@ var useHudState = (options = {}) => {
2065
2145
  window.clearTimeout(timeoutId);
2066
2146
  };
2067
2147
  }, [runningStep, shouldRender, target.status]);
2068
- const skipHiddenStep = (0, import_react9.useCallback)(() => {
2148
+ const { isRouteMismatch, currentPath } = useRouteMismatch(activeStep);
2149
+ const pausedForMissingTargetRef = (0, import_react10.useRef)(null);
2150
+ (0, import_react10.useEffect)(() => {
2151
+ if (!isRouteMismatch) return;
2152
+ if (!runningState || runningState.status !== "running") return;
2153
+ pause();
2154
+ }, [isRouteMismatch, runningState, pause]);
2155
+ (0, import_react10.useEffect)(() => {
2156
+ if (isRouteMismatch) return;
2157
+ if (pausedForMissingTargetRef.current !== null) return;
2158
+ if (!state || state.status !== "paused") return;
2159
+ resume();
2160
+ }, [isRouteMismatch, state, resume]);
2161
+ const skipHiddenStep = (0, import_react10.useCallback)(() => {
2069
2162
  if (!runningState || runningState.status !== "running") return;
2070
2163
  if (!activeFlowId) return;
2071
2164
  const flow = flows.get(activeFlowId);
@@ -2083,6 +2176,35 @@ var useHudState = (options = {}) => {
2083
2176
  viewportRect,
2084
2177
  onSkip: skipHiddenStep
2085
2178
  });
2179
+ (0, import_react10.useEffect)(() => {
2180
+ if (isRouteMismatch) return;
2181
+ if (activeStep?.route !== void 0) return;
2182
+ if (isInGracePeriod) return;
2183
+ if (target.visibility !== "missing") return;
2184
+ if (target.isScreen) return;
2185
+ if (!runningState || runningState.status !== "running") return;
2186
+ pausedForMissingTargetRef.current = currentPath;
2187
+ pause();
2188
+ }, [
2189
+ isRouteMismatch,
2190
+ activeStep?.route,
2191
+ isInGracePeriod,
2192
+ target.visibility,
2193
+ target.isScreen,
2194
+ runningState,
2195
+ currentPath,
2196
+ pause
2197
+ ]);
2198
+ (0, import_react10.useEffect)(() => {
2199
+ if (pausedForMissingTargetRef.current === null) return;
2200
+ if (!state || state.status !== "paused") return;
2201
+ if (currentPath === pausedForMissingTargetRef.current) return;
2202
+ pausedForMissingTargetRef.current = null;
2203
+ resume();
2204
+ }, [currentPath, state, resume]);
2205
+ (0, import_react10.useEffect)(() => {
2206
+ pausedForMissingTargetRef.current = null;
2207
+ }, [activeStep?.id]);
2086
2208
  const canRenderStep = Boolean(runningStep && runningState);
2087
2209
  const focusTrapActive = canRenderStep;
2088
2210
  const flowHudOptions = matchesFlowFilter && activeFlowId ? flows.get(activeFlowId)?.hud ?? null : null;
@@ -2105,24 +2227,24 @@ var useHudState = (options = {}) => {
2105
2227
  };
2106
2228
 
2107
2229
  // src/hooks/useHudDescription.ts
2108
- var import_react10 = require("react");
2230
+ var import_react11 = require("react");
2109
2231
  var sanitizeForId = (value) => {
2110
2232
  const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
2111
2233
  return normalized.length > 0 ? normalized : "step";
2112
2234
  };
2113
2235
  var useHudDescription = (options) => {
2114
2236
  const { step, fallbackAriaDescribedBy } = options;
2115
- const targetDescription = (0, import_react10.useMemo)(() => {
2237
+ const targetDescription = (0, import_react11.useMemo)(() => {
2116
2238
  if (!step) return null;
2117
2239
  if (typeof step.target !== "object") return null;
2118
2240
  const description = step.target.description;
2119
2241
  return typeof description === "string" ? description : null;
2120
2242
  }, [step]);
2121
- const descriptionId = (0, import_react10.useMemo)(() => {
2243
+ const descriptionId = (0, import_react11.useMemo)(() => {
2122
2244
  if (!step || !targetDescription) return void 0;
2123
2245
  return `tour-step-${sanitizeForId(step.id)}-description`;
2124
2246
  }, [step, targetDescription]);
2125
- const combinedAriaDescribedBy = (0, import_react10.useMemo)(() => {
2247
+ const combinedAriaDescribedBy = (0, import_react11.useMemo)(() => {
2126
2248
  const parts = [fallbackAriaDescribedBy, descriptionId].filter(Boolean);
2127
2249
  return parts.length > 0 ? parts.join(" ") : void 0;
2128
2250
  }, [descriptionId, fallbackAriaDescribedBy]);
@@ -2134,10 +2256,10 @@ var useHudDescription = (options) => {
2134
2256
  };
2135
2257
 
2136
2258
  // src/hooks/useHudShortcuts.ts
2137
- var import_react12 = require("react");
2259
+ var import_react13 = require("react");
2138
2260
 
2139
2261
  // src/hooks/useTourControls.ts
2140
- var import_react11 = require("react");
2262
+ var import_react12 = require("react");
2141
2263
  var hasManualAdvance = (rules) => rules.some((rule) => rule.type === "manual");
2142
2264
  var didPreviousAdvanceViaRoute = (rules) => rules.some((rule) => rule.type === "route");
2143
2265
  var didPreviousAdvanceViaTargetEvent = (rules) => rules.some((rule) => rule.type === "event" && rule.on === "target");
@@ -2153,7 +2275,7 @@ var useTourControls = () => {
2153
2275
  flows,
2154
2276
  activeStep
2155
2277
  } = tour;
2156
- const computed = (0, import_react11.useMemo)(() => {
2278
+ const computed = (0, import_react12.useMemo)(() => {
2157
2279
  if (!state || state.status !== "running" || !activeStep) {
2158
2280
  return {
2159
2281
  isActive: false,
@@ -2202,11 +2324,11 @@ var useTourControls = () => {
2202
2324
  } = computed;
2203
2325
  const canGoBack = showBackButton && !backDisabled;
2204
2326
  const canGoNext = showNextButton && !nextDisabled;
2205
- const goBack = (0, import_react11.useCallback)(() => {
2327
+ const goBack = (0, import_react12.useCallback)(() => {
2206
2328
  if (!canGoBack) return;
2207
2329
  back();
2208
2330
  }, [back, canGoBack]);
2209
- const goNext = (0, import_react11.useCallback)(() => {
2331
+ const goNext = (0, import_react12.useCallback)(() => {
2210
2332
  if (!canGoNext) return;
2211
2333
  if (isLast) {
2212
2334
  complete();
@@ -2214,7 +2336,7 @@ var useTourControls = () => {
2214
2336
  next();
2215
2337
  }
2216
2338
  }, [canGoNext, complete, isLast, next]);
2217
- return (0, import_react11.useMemo)(
2339
+ return (0, import_react12.useMemo)(
2218
2340
  () => ({
2219
2341
  showBackButton,
2220
2342
  backDisabled,
@@ -2259,7 +2381,7 @@ var useHudShortcuts = (target, options) => {
2259
2381
  const escapeEnabled = options?.escape ?? true;
2260
2382
  const { state } = useTour();
2261
2383
  const { cancel, canGoBack, goBack, canGoNext, goNext, isActive } = useTourControls();
2262
- (0, import_react12.useEffect)(() => {
2384
+ (0, import_react13.useEffect)(() => {
2263
2385
  if (!isBrowser) return void 0;
2264
2386
  if (!enabled) return void 0;
2265
2387
  if (!target) return void 0;
@@ -2323,10 +2445,10 @@ var useHudShortcuts = (target, options) => {
2323
2445
  };
2324
2446
 
2325
2447
  // src/hooks/useTourHud.ts
2326
- var import_react15 = require("react");
2448
+ var import_react16 = require("react");
2327
2449
 
2328
2450
  // src/hooks/useBodyScrollLock.ts
2329
- var import_react13 = require("react");
2451
+ var import_react14 = require("react");
2330
2452
  var lockCount = 0;
2331
2453
  var previousOverflow = null;
2332
2454
  var acquireLock = () => {
@@ -2347,7 +2469,7 @@ var releaseLock = () => {
2347
2469
  }
2348
2470
  };
2349
2471
  var useBodyScrollLock = (enabled) => {
2350
- (0, import_react13.useEffect)(() => {
2472
+ (0, import_react14.useEffect)(() => {
2351
2473
  if (!enabled) return;
2352
2474
  acquireLock();
2353
2475
  return () => {
@@ -2357,37 +2479,45 @@ var useBodyScrollLock = (enabled) => {
2357
2479
  };
2358
2480
 
2359
2481
  // src/hooks/useHudTargetIssue.ts
2360
- var import_react14 = require("react");
2361
- var deriveTargetIssue = (target) => {
2482
+ var import_react15 = require("react");
2483
+ var deriveTargetIssue = (params) => {
2484
+ const { target, labels } = params;
2362
2485
  if (target.isScreen) return null;
2363
2486
  if (target.status === "idle") return null;
2364
2487
  switch (target.visibility) {
2365
2488
  case "missing":
2489
+ return {
2490
+ type: "missing",
2491
+ title: labels.targetIssue.missingTitle,
2492
+ body: labels.targetIssue.missingBody,
2493
+ hint: target.rectSource === "stored" ? labels.targetIssue.missingHint : void 0
2494
+ };
2366
2495
  case "hidden":
2367
2496
  return {
2368
- type: target.visibility,
2369
- title: "Target not visible",
2370
- body: "The target element is not currently visible. Make sure the UI piece is mounted and displayed.",
2371
- hint: target.rectSource === "stored" ? "Showing the last known position until the element returns." : void 0
2497
+ type: "hidden",
2498
+ title: labels.targetIssue.hiddenTitle,
2499
+ body: labels.targetIssue.hiddenBody,
2500
+ hint: target.rectSource === "stored" ? labels.targetIssue.hiddenHint : void 0
2372
2501
  };
2373
2502
  case "detached":
2374
2503
  return {
2375
2504
  type: "detached",
2376
- title: "Target left the page",
2377
- body: "Navigate back to the screen that contains this element or reopen it before continuing the tour."
2505
+ title: labels.targetIssue.detachedTitle,
2506
+ body: labels.targetIssue.detachedBody
2378
2507
  };
2379
2508
  default:
2380
2509
  return null;
2381
2510
  }
2382
2511
  };
2383
2512
  var useHudTargetIssue = (target, options) => {
2513
+ const labels = useTourLabels();
2384
2514
  const delayMs = Math.max(0, options?.delayMs ?? 500);
2385
- const [armed, setArmed] = (0, import_react14.useState)(false);
2386
- const rawIssue = (0, import_react14.useMemo)(
2387
- () => deriveTargetIssue(target),
2388
- [target.isScreen, target.rectSource, target.status, target.visibility]
2515
+ const [armed, setArmed] = (0, import_react15.useState)(false);
2516
+ const rawIssue = (0, import_react15.useMemo)(
2517
+ () => deriveTargetIssue({ target, labels }),
2518
+ [target.isScreen, target.rectSource, target.status, target.visibility, labels]
2389
2519
  );
2390
- (0, import_react14.useEffect)(() => {
2520
+ (0, import_react15.useEffect)(() => {
2391
2521
  if (!rawIssue) {
2392
2522
  setArmed(false);
2393
2523
  return;
@@ -2421,7 +2551,7 @@ var useTourHud = (options = {}) => {
2421
2551
  const { backdropInteraction, lockBodyScroll } = useTour();
2422
2552
  const hudState = useHudState();
2423
2553
  const disableDefaultHud = hudState.hudRenderMode === "none";
2424
- const [popoverNode, setPopoverNode] = (0, import_react15.useState)(null);
2554
+ const [popoverNode, setPopoverNode] = (0, import_react16.useState)(null);
2425
2555
  const popoverOptions = hudState.flowHudOptions?.popover;
2426
2556
  const description = useHudDescription({
2427
2557
  step: hudState.runningStep,
@@ -2445,7 +2575,7 @@ var useTourHud = (options = {}) => {
2445
2575
  radius: overlayRadius,
2446
2576
  interactionMode: hudState.flowHudOptions?.backdrop?.interaction ?? backdropInteraction
2447
2577
  };
2448
- const popover = (0, import_react15.useMemo)(() => {
2578
+ const popover = (0, import_react16.useMemo)(() => {
2449
2579
  return {
2450
2580
  offset: popoverOptions?.offset ?? 16,
2451
2581
  role: popoverOptions?.role ?? "dialog",
@@ -2457,13 +2587,13 @@ var useTourHud = (options = {}) => {
2457
2587
  placement: hudState.runningStep?.placement
2458
2588
  };
2459
2589
  }, [hudState.runningStep?.placement, popoverOptions]);
2460
- const descriptionResult = (0, import_react15.useMemo)(() => {
2590
+ const descriptionResult = (0, import_react16.useMemo)(() => {
2461
2591
  return {
2462
2592
  ...description,
2463
2593
  text: description.targetDescription
2464
2594
  };
2465
2595
  }, [description]);
2466
- const focusManager = (0, import_react15.useMemo)(
2596
+ const focusManager = (0, import_react16.useMemo)(
2467
2597
  () => ({
2468
2598
  active: hudState.focusTrapActive,
2469
2599
  target: hudState.hudTarget,
@@ -2493,7 +2623,7 @@ var useTourHud = (options = {}) => {
2493
2623
  };
2494
2624
 
2495
2625
  // src/hooks/useTourOverlay.ts
2496
- var import_react16 = require("react");
2626
+ var import_react17 = require("react");
2497
2627
  var DEFAULT_PADDING = 12;
2498
2628
  var DEFAULT_RADIUS = 12;
2499
2629
  var DEFAULT_EDGE_BUFFER = 0;
@@ -2506,9 +2636,9 @@ var useTourOverlay = (options) => {
2506
2636
  interactionMode = "passthrough",
2507
2637
  isInGracePeriod = false
2508
2638
  } = options;
2509
- const hasShownRef = (0, import_react16.useRef)(false);
2510
- const lastReadyTargetRef = (0, import_react16.useRef)(null);
2511
- (0, import_react16.useEffect)(() => {
2639
+ const hasShownRef = (0, import_react17.useRef)(false);
2640
+ const lastReadyTargetRef = (0, import_react17.useRef)(null);
2641
+ (0, import_react17.useEffect)(() => {
2512
2642
  if (!isBrowser) return;
2513
2643
  if (target.status === "ready") {
2514
2644
  hasShownRef.current = true;
@@ -2558,15 +2688,15 @@ var useTourOverlay = (options) => {
2558
2688
  height: highlightHeight,
2559
2689
  radius: highlightRadius
2560
2690
  } : null;
2561
- const maskCapable = (0, import_react16.useMemo)(() => supportsMasking(), []);
2691
+ const maskCapable = (0, import_react17.useMemo)(() => supportsMasking(), []);
2562
2692
  const isActive = target.status === "ready" || target.status === "resolving" && cachedTarget !== null || isInGracePeriod;
2563
2693
  const shouldMask = maskCapable && isActive;
2564
- const maskId = (0, import_react16.useMemo)(
2694
+ const maskId = (0, import_react17.useMemo)(
2565
2695
  () => `tour-overlay-mask-${Math.random().toString(36).slice(2, 10)}`,
2566
2696
  []
2567
2697
  );
2568
2698
  const maskUrl = shouldMask ? `url(#${maskId})` : void 0;
2569
- const fallbackSegments = (0, import_react16.useMemo)(() => {
2699
+ const fallbackSegments = (0, import_react17.useMemo)(() => {
2570
2700
  if (!isActive || shouldMask || !hasHighlightBounds || !highlightRect) {
2571
2701
  return null;
2572
2702
  }
@@ -2619,7 +2749,7 @@ var useTourOverlay = (options) => {
2619
2749
  viewport.height,
2620
2750
  viewport.width
2621
2751
  ]);
2622
- const blockerSegments = (0, import_react16.useMemo)(() => {
2752
+ const blockerSegments = (0, import_react17.useMemo)(() => {
2623
2753
  if (interactionMode !== "block") {
2624
2754
  return null;
2625
2755
  }
@@ -2744,12 +2874,12 @@ var useRadixDialogAdapter = (options = {}) => {
2744
2874
  };
2745
2875
 
2746
2876
  // src/hooks/useDelayAdvance.ts
2747
- var import_react17 = require("react");
2877
+ var import_react18 = require("react");
2748
2878
  var getTimestamp = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
2749
2879
  var useDelayAdvance = () => {
2750
2880
  const { delayInfo, activeStep, state } = useTour();
2751
- const [now, setNow] = (0, import_react17.useState)(() => getTimestamp());
2752
- (0, import_react17.useEffect)(() => {
2881
+ const [now, setNow] = (0, import_react18.useState)(() => getTimestamp());
2882
+ (0, import_react18.useEffect)(() => {
2753
2883
  if (!delayInfo) return;
2754
2884
  if (!activeStep || activeStep.id !== delayInfo.stepId) return;
2755
2885
  if (!state || state.status !== "running") return;
@@ -2766,12 +2896,12 @@ var useDelayAdvance = () => {
2766
2896
  }
2767
2897
  };
2768
2898
  }, [delayInfo, activeStep, state]);
2769
- (0, import_react17.useEffect)(() => {
2899
+ (0, import_react18.useEffect)(() => {
2770
2900
  if (!delayInfo) {
2771
2901
  setNow(getTimestamp());
2772
2902
  }
2773
2903
  }, [delayInfo]);
2774
- return (0, import_react17.useMemo)(() => {
2904
+ return (0, import_react18.useMemo)(() => {
2775
2905
  const matchingStep = !!delayInfo && !!activeStep && activeStep.id === delayInfo.stepId;
2776
2906
  const isRunning = matchingStep && state?.status === "running";
2777
2907
  if (!delayInfo) {
@@ -2824,9 +2954,9 @@ var useDelayAdvance = () => {
2824
2954
  };
2825
2955
 
2826
2956
  // src/components/OverlayBackdrop.tsx
2827
- var import_react18 = require("react");
2957
+ var import_react19 = require("react");
2828
2958
  var import_react_dom = require("react-dom");
2829
- var import_react19 = require("motion/react");
2959
+ var import_react20 = require("motion/react");
2830
2960
  var import_jsx_runtime3 = require("react/jsx-runtime");
2831
2961
  var styles = {
2832
2962
  root: {
@@ -2913,9 +3043,9 @@ var OverlayBackdrop = ({
2913
3043
  viewport
2914
3044
  } = overlay;
2915
3045
  const hasHighlightBounds = Boolean(highlight.rect);
2916
- const prevScreenTargetRef = (0, import_react18.useRef)(null);
3046
+ const prevScreenTargetRef = (0, import_react19.useRef)(null);
2917
3047
  const shouldSnapHighlight = prevScreenTargetRef.current === true && !highlight.isScreen && hasHighlightBounds;
2918
- (0, import_react18.useEffect)(() => {
3048
+ (0, import_react19.useEffect)(() => {
2919
3049
  prevScreenTargetRef.current = highlight.isScreen;
2920
3050
  }, [highlight.isScreen]);
2921
3051
  const resolvedBlur = typeof blurAmount === "number" ? `${blurAmount}px` : "0px";
@@ -2983,7 +3113,7 @@ var OverlayBackdrop = ({
2983
3113
  "aria-hidden": ariaHidden,
2984
3114
  "data-tour-overlay": "",
2985
3115
  children: [
2986
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react19.AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3116
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2987
3117
  MotionSvg,
2988
3118
  {
2989
3119
  width: "0",
@@ -3042,7 +3172,7 @@ var OverlayBackdrop = ({
3042
3172
  },
3043
3173
  "tour-mask"
3044
3174
  ) : null }),
3045
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react19.AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3175
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3046
3176
  MotionDiv,
3047
3177
  {
3048
3178
  className: overlayClassName,
@@ -3070,7 +3200,7 @@ var OverlayBackdrop = ({
3070
3200
  },
3071
3201
  "tour-overlay"
3072
3202
  ) : null }),
3073
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react19.AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3203
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3074
3204
  MotionDiv,
3075
3205
  {
3076
3206
  className: segmentClassName,
@@ -3121,7 +3251,7 @@ var OverlayBackdrop = ({
3121
3251
  ))
3122
3252
  }
3123
3253
  ) : null,
3124
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react19.AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3254
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3125
3255
  MotionDiv,
3126
3256
  {
3127
3257
  className: ringClassName,
@@ -3152,7 +3282,7 @@ var OverlayBackdrop = ({
3152
3282
  };
3153
3283
 
3154
3284
  // src/components/TourPopoverPortal.tsx
3155
- var import_react20 = require("react");
3285
+ var import_react21 = require("react");
3156
3286
  var import_react_dom2 = require("react-dom");
3157
3287
  var import_dom13 = require("@floating-ui/dom");
3158
3288
  var FLOATING_OFFSET = 8;
@@ -3200,8 +3330,7 @@ var TourPopoverPortal = ({
3200
3330
  layoutId,
3201
3331
  containerComponent,
3202
3332
  contentComponent,
3203
- transitionsOverride,
3204
- isInGracePeriod = false
3333
+ transitionsOverride
3205
3334
  }) => {
3206
3335
  if (!isBrowser) return null;
3207
3336
  const host = portalHost();
@@ -3214,12 +3343,12 @@ var TourPopoverPortal = ({
3214
3343
  const popoverContentTransition = transitionsOverride?.popoverContent ?? adapter.transitions.popoverContent ?? DEFAULT_POPOVER_CONTENT_TRANSITION;
3215
3344
  const viewport = useViewportRect();
3216
3345
  const prefersMobileLayout = viewport.width <= MOBILE_BREAKPOINT || viewport.height <= MOBILE_HEIGHT_BREAKPOINT;
3217
- const prefersMobileRef = (0, import_react20.useRef)(prefersMobileLayout);
3218
- (0, import_react20.useEffect)(() => {
3346
+ const prefersMobileRef = (0, import_react21.useRef)(prefersMobileLayout);
3347
+ (0, import_react21.useEffect)(() => {
3219
3348
  prefersMobileRef.current = prefersMobileLayout;
3220
3349
  }, [prefersMobileLayout]);
3221
- const lastReadyTargetRef = (0, import_react20.useRef)(null);
3222
- (0, import_react20.useEffect)(() => {
3350
+ const lastReadyTargetRef = (0, import_react21.useRef)(null);
3351
+ (0, import_react21.useEffect)(() => {
3223
3352
  if (target.status === "ready" && target.rect) {
3224
3353
  lastReadyTargetRef.current = {
3225
3354
  rect: { ...target.rect },
@@ -3232,10 +3361,10 @@ var TourPopoverPortal = ({
3232
3361
  const cachedTarget = lastReadyTargetRef.current;
3233
3362
  const resolvedRect = target.rect ?? target.lastResolvedRect ?? cachedTarget?.rect ?? null;
3234
3363
  const resolvedIsScreen = target.status === "ready" ? target.isScreen : cachedTarget?.isScreen ?? target.isScreen;
3235
- const shouldHideForGracePeriod = isInGracePeriod && !resolvedRect;
3364
+ const shouldHidePopover = !resolvedRect && !target.isScreen;
3236
3365
  const fallbackRect = resolvedRect ?? viewport;
3237
3366
  const fallbackIsScreen = resolvedIsScreen;
3238
- const [floatingSize, setFloatingSize] = (0, import_react20.useState)(null);
3367
+ const [floatingSize, setFloatingSize] = (0, import_react21.useState)(null);
3239
3368
  const clampVertical = (value) => Math.min(viewport.height - 24, Math.max(24, value));
3240
3369
  const clampHorizontal = (value) => Math.min(viewport.width - 24, Math.max(24, value));
3241
3370
  const screenCenteredTop = viewport.height / 2 - (floatingSize?.height ?? 0) / 2;
@@ -3246,7 +3375,7 @@ var TourPopoverPortal = ({
3246
3375
  const leftBase = fallbackIsScreen ? screenCenteredLeft : fallbackRect.left + fallbackRect.width / 2 - floatingWidth / 2;
3247
3376
  const left = clampHorizontal(leftBase);
3248
3377
  const fallbackTransform = "translate3d(0px, 0px, 0px)";
3249
- const fallbackPosition = (0, import_react20.useMemo)(
3378
+ const fallbackPosition = (0, import_react21.useMemo)(
3250
3379
  () => ({
3251
3380
  top,
3252
3381
  left,
@@ -3254,7 +3383,7 @@ var TourPopoverPortal = ({
3254
3383
  }),
3255
3384
  [fallbackTransform, left, top]
3256
3385
  );
3257
- const centerInitialPosition = (0, import_react20.useMemo)(
3386
+ const centerInitialPosition = (0, import_react21.useMemo)(
3258
3387
  () => ({
3259
3388
  top: viewport.height / 2,
3260
3389
  left: viewport.width / 2,
@@ -3262,23 +3391,23 @@ var TourPopoverPortal = ({
3262
3391
  }),
3263
3392
  [viewport.height, viewport.width]
3264
3393
  );
3265
- const floatingRef = (0, import_react20.useRef)(null);
3266
- const cachedFloatingPositionRef = (0, import_react20.useRef)(null);
3267
- const appliedFloatingCacheRef = (0, import_react20.useRef)(null);
3268
- const deferredScreenSnapRef = (0, import_react20.useRef)(null);
3269
- const [layoutMode, setLayoutMode] = (0, import_react20.useState)(
3394
+ const floatingRef = (0, import_react21.useRef)(null);
3395
+ const cachedFloatingPositionRef = (0, import_react21.useRef)(null);
3396
+ const appliedFloatingCacheRef = (0, import_react21.useRef)(null);
3397
+ const deferredScreenSnapRef = (0, import_react21.useRef)(null);
3398
+ const [layoutMode, setLayoutMode] = (0, import_react21.useState)(
3270
3399
  () => prefersMobileLayout ? "mobile" : "floating"
3271
3400
  );
3272
- const [floatingPosition, setFloatingPosition] = (0, import_react20.useState)(fallbackPosition);
3273
- const [dragPosition, setDragPosition] = (0, import_react20.useState)(null);
3274
- const [isDragging, setIsDragging] = (0, import_react20.useState)(false);
3275
- const dragStateRef = (0, import_react20.useRef)(null);
3276
- const overflowRetryRef = (0, import_react20.useRef)({
3401
+ const [floatingPosition, setFloatingPosition] = (0, import_react21.useState)(fallbackPosition);
3402
+ const [dragPosition, setDragPosition] = (0, import_react21.useState)(null);
3403
+ const [isDragging, setIsDragging] = (0, import_react21.useState)(false);
3404
+ const dragStateRef = (0, import_react21.useRef)(null);
3405
+ const overflowRetryRef = (0, import_react21.useRef)({
3277
3406
  stepId: null,
3278
3407
  attempts: 0
3279
3408
  });
3280
- const overflowRetryTimeoutRef = (0, import_react20.useRef)(null);
3281
- (0, import_react20.useLayoutEffect)(() => {
3409
+ const overflowRetryTimeoutRef = (0, import_react21.useRef)(null);
3410
+ (0, import_react21.useLayoutEffect)(() => {
3282
3411
  if (!isBrowser) return;
3283
3412
  const node = floatingRef.current;
3284
3413
  if (!node) return;
@@ -3297,25 +3426,25 @@ var TourPopoverPortal = ({
3297
3426
  const autoAlignment = resolvedPlacement.endsWith(
3298
3427
  "-start"
3299
3428
  ) ? "start" : resolvedPlacement.endsWith("-end") ? "end" : void 0;
3300
- (0, import_react20.useEffect)(() => {
3429
+ (0, import_react21.useEffect)(() => {
3301
3430
  setDragPosition(null);
3302
3431
  setLayoutMode(prefersMobileRef.current ? "mobile" : "floating");
3303
3432
  cachedFloatingPositionRef.current = null;
3304
3433
  appliedFloatingCacheRef.current = null;
3305
3434
  }, [target.stepId]);
3306
- (0, import_react20.useEffect)(() => {
3435
+ (0, import_react21.useEffect)(() => {
3307
3436
  if (layoutMode !== "manual") {
3308
3437
  setDragPosition(null);
3309
3438
  }
3310
3439
  }, [layoutMode]);
3311
- (0, import_react20.useEffect)(() => {
3440
+ (0, import_react21.useEffect)(() => {
3312
3441
  cachedFloatingPositionRef.current = floatingPosition;
3313
3442
  const cacheKey = getFloatingCacheKey(target);
3314
3443
  if (cacheKey) {
3315
3444
  floatingPositionCache.set(cacheKey, floatingPosition);
3316
3445
  }
3317
3446
  }, [floatingPosition, target.isScreen, target.stepId]);
3318
- const dockedPosition = (0, import_react20.useMemo)(
3447
+ const dockedPosition = (0, import_react21.useMemo)(
3319
3448
  () => ({
3320
3449
  top: viewport.height - DOCKED_MARGIN,
3321
3450
  left: viewport.width - DOCKED_MARGIN,
@@ -3323,7 +3452,7 @@ var TourPopoverPortal = ({
3323
3452
  }),
3324
3453
  [viewport.height, viewport.width]
3325
3454
  );
3326
- const mobilePosition = (0, import_react20.useMemo)(
3455
+ const mobilePosition = (0, import_react21.useMemo)(
3327
3456
  () => ({
3328
3457
  top: viewport.height - MOBILE_HORIZONTAL_GUTTER,
3329
3458
  left: viewport.width / 2,
@@ -3331,17 +3460,17 @@ var TourPopoverPortal = ({
3331
3460
  }),
3332
3461
  [viewport.height, viewport.width]
3333
3462
  );
3334
- (0, import_react20.useEffect)(() => {
3463
+ (0, import_react21.useEffect)(() => {
3335
3464
  if (layoutMode === "docked") {
3336
3465
  setFloatingPosition(dockedPosition);
3337
3466
  }
3338
3467
  }, [dockedPosition, layoutMode]);
3339
- (0, import_react20.useEffect)(() => {
3468
+ (0, import_react21.useEffect)(() => {
3340
3469
  if (layoutMode === "mobile") {
3341
3470
  setFloatingPosition(mobilePosition);
3342
3471
  }
3343
3472
  }, [layoutMode, mobilePosition]);
3344
- (0, import_react20.useEffect)(() => {
3473
+ (0, import_react21.useEffect)(() => {
3345
3474
  if (prefersMobileLayout) {
3346
3475
  if (layoutMode !== "mobile") {
3347
3476
  setLayoutMode("mobile");
@@ -3354,7 +3483,7 @@ var TourPopoverPortal = ({
3354
3483
  setFloatingPosition(fallbackPosition);
3355
3484
  }
3356
3485
  }, [fallbackPosition, layoutMode, prefersMobileLayout]);
3357
- (0, import_react20.useEffect)(() => {
3486
+ (0, import_react21.useEffect)(() => {
3358
3487
  if (layoutMode !== "floating") return;
3359
3488
  const stepId = target.stepId;
3360
3489
  if (!stepId) return;
@@ -3378,7 +3507,7 @@ var TourPopoverPortal = ({
3378
3507
  target.stepId
3379
3508
  ]);
3380
3509
  const shouldDeferScreenSnap = layoutMode === "floating" && target.isScreen && Boolean(layoutId);
3381
- (0, import_react20.useEffect)(() => {
3510
+ (0, import_react21.useEffect)(() => {
3382
3511
  return () => {
3383
3512
  if (deferredScreenSnapRef.current !== null) {
3384
3513
  cancelAnimationFrame(deferredScreenSnapRef.current);
@@ -3386,7 +3515,7 @@ var TourPopoverPortal = ({
3386
3515
  }
3387
3516
  };
3388
3517
  }, []);
3389
- (0, import_react20.useLayoutEffect)(() => {
3518
+ (0, import_react21.useLayoutEffect)(() => {
3390
3519
  if (layoutMode !== "floating") return;
3391
3520
  if (target.status === "ready" && !target.isScreen) return;
3392
3521
  if (shouldDeferScreenSnap) return;
@@ -3398,7 +3527,7 @@ var TourPopoverPortal = ({
3398
3527
  target.isScreen,
3399
3528
  target.status
3400
3529
  ]);
3401
- (0, import_react20.useEffect)(() => {
3530
+ (0, import_react21.useEffect)(() => {
3402
3531
  if (!shouldDeferScreenSnap) return;
3403
3532
  if (deferredScreenSnapRef.current !== null) {
3404
3533
  cancelAnimationFrame(deferredScreenSnapRef.current);
@@ -3425,14 +3554,14 @@ var TourPopoverPortal = ({
3425
3554
  }
3426
3555
  };
3427
3556
  }, [fallbackPosition, shouldDeferScreenSnap]);
3428
- (0, import_react20.useEffect)(() => {
3557
+ (0, import_react21.useEffect)(() => {
3429
3558
  return () => {
3430
3559
  if (overflowRetryTimeoutRef.current !== null) {
3431
3560
  window.clearTimeout(overflowRetryTimeoutRef.current);
3432
3561
  }
3433
3562
  };
3434
3563
  }, []);
3435
- (0, import_react20.useLayoutEffect)(() => {
3564
+ (0, import_react21.useLayoutEffect)(() => {
3436
3565
  if (!isBrowser) return;
3437
3566
  const floatingEl = floatingRef.current;
3438
3567
  const rectInfo = target.rect;
@@ -3566,7 +3695,7 @@ var TourPopoverPortal = ({
3566
3695
  target.status,
3567
3696
  target.stepId
3568
3697
  ]);
3569
- (0, import_react20.useLayoutEffect)(() => {
3698
+ (0, import_react21.useLayoutEffect)(() => {
3570
3699
  if (layoutMode !== "manual" || !dragPosition) return;
3571
3700
  setFloatingPosition({
3572
3701
  top: dragPosition.top,
@@ -3651,7 +3780,7 @@ var TourPopoverPortal = ({
3651
3780
  }
3652
3781
  event.preventDefault();
3653
3782
  };
3654
- (0, import_react20.useEffect)(() => endDrag, []);
3783
+ (0, import_react21.useEffect)(() => endDrag, []);
3655
3784
  const shouldUseFallbackInitial = layoutMode !== "mobile" && (Boolean(target.lastResolvedRect) || Boolean(cachedTarget));
3656
3785
  const floatingCacheKey = layoutMode === "mobile" ? null : getFloatingCacheKey(target);
3657
3786
  const persistedFloatingInitial = floatingCacheKey && floatingPositionCache.has(floatingCacheKey) ? floatingPositionCache.get(floatingCacheKey) ?? null : null;
@@ -3738,12 +3867,12 @@ var TourPopoverPortal = ({
3738
3867
  dragHandleProps,
3739
3868
  descriptionProps
3740
3869
  };
3741
- if (shouldHideForGracePeriod) return null;
3870
+ if (shouldHidePopover) return null;
3742
3871
  return (0, import_react_dom2.createPortal)(children(context), host);
3743
3872
  };
3744
3873
 
3745
3874
  // src/components/TourFocusManager.tsx
3746
- var import_react21 = require("react");
3875
+ var import_react22 = require("react");
3747
3876
  var import_react_dom3 = require("react-dom");
3748
3877
 
3749
3878
  // src/utils/focus.ts
@@ -3820,18 +3949,18 @@ var TourFocusManager = ({
3820
3949
  highlightRect,
3821
3950
  guardElementFocusRing
3822
3951
  }) => {
3823
- const previousFocusRef = (0, import_react21.useRef)(null);
3824
- const guardNodesRef = (0, import_react21.useRef)({
3952
+ const previousFocusRef = (0, import_react22.useRef)(null);
3953
+ const guardNodesRef = (0, import_react22.useRef)({
3825
3954
  "target-start": null,
3826
3955
  "target-end": null,
3827
3956
  "popover-start": null,
3828
3957
  "popover-end": null
3829
3958
  });
3830
- const lastTabDirectionRef = (0, import_react21.useRef)("forward");
3831
- const suppressGuardHopRef = (0, import_react21.useRef)(null);
3832
- const [targetRingActive, setTargetRingActive] = (0, import_react21.useState)(false);
3833
- const [popoverRingActive, setPopoverRingActive] = (0, import_react21.useState)(false);
3834
- const [popoverRect, setPopoverRect] = (0, import_react21.useState)(null);
3959
+ const lastTabDirectionRef = (0, import_react22.useRef)("forward");
3960
+ const suppressGuardHopRef = (0, import_react22.useRef)(null);
3961
+ const [targetRingActive, setTargetRingActive] = (0, import_react22.useState)(false);
3962
+ const [popoverRingActive, setPopoverRingActive] = (0, import_react22.useState)(false);
3963
+ const [popoverRect, setPopoverRect] = (0, import_react22.useState)(null);
3835
3964
  const restoreFocus = () => {
3836
3965
  const previous = previousFocusRef.current;
3837
3966
  previousFocusRef.current = null;
@@ -3841,7 +3970,7 @@ var TourFocusManager = ({
3841
3970
  });
3842
3971
  }
3843
3972
  };
3844
- (0, import_react21.useLayoutEffect)(() => {
3973
+ (0, import_react22.useLayoutEffect)(() => {
3845
3974
  if (!isBrowser) return;
3846
3975
  if (!active) {
3847
3976
  restoreFocus();
@@ -3857,7 +3986,7 @@ var TourFocusManager = ({
3857
3986
  restoreFocus();
3858
3987
  };
3859
3988
  }, [active, popoverNode, target.element]);
3860
- (0, import_react21.useEffect)(() => {
3989
+ (0, import_react22.useEffect)(() => {
3861
3990
  if (!isBrowser) return;
3862
3991
  if (!active) return;
3863
3992
  const doc = popoverNode?.ownerDocument ?? target.element?.ownerDocument ?? document;
@@ -4051,7 +4180,7 @@ var TourFocusManager = ({
4051
4180
  target.stepId,
4052
4181
  target.visibility
4053
4182
  ]);
4054
- (0, import_react21.useLayoutEffect)(() => {
4183
+ (0, import_react22.useLayoutEffect)(() => {
4055
4184
  if (popoverRingActive && popoverNode) {
4056
4185
  setPopoverRect(popoverNode.getBoundingClientRect());
4057
4186
  } else {
@@ -4107,7 +4236,7 @@ var TourFocusManager = ({
4107
4236
  };
4108
4237
 
4109
4238
  // src/motion/useHudMotion.ts
4110
- var import_react22 = require("react");
4239
+ var import_react23 = require("react");
4111
4240
  var DEFAULT_HIGHLIGHT_TRANSITION2 = {
4112
4241
  duration: 0.35,
4113
4242
  ease: "easeOut",
@@ -4134,7 +4263,7 @@ var DEFAULT_POPOVER_CONTENT_TRANSITION2 = {
4134
4263
  };
4135
4264
  var useHudMotion = () => {
4136
4265
  const adapter = useAnimationAdapter();
4137
- return (0, import_react22.useMemo)(() => {
4266
+ return (0, import_react23.useMemo)(() => {
4138
4267
  const components = {
4139
4268
  ...adapter.components
4140
4269
  };
@@ -4150,49 +4279,6 @@ var useHudMotion = () => {
4150
4279
  };
4151
4280
  }, [adapter]);
4152
4281
  };
4153
-
4154
- // src/router/utils.ts
4155
- var ensurePrefix = (value, prefix) => value.startsWith(prefix) ? value : `${prefix}${value}`;
4156
- var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
4157
- var toSearchString = (value) => {
4158
- if (!isNonEmptyString(value)) {
4159
- if (value instanceof URLSearchParams) {
4160
- const serialized = value.toString();
4161
- return serialized.length > 0 ? `?${serialized}` : "";
4162
- }
4163
- if (typeof value === "object" && value !== null) {
4164
- try {
4165
- const params = new URLSearchParams();
4166
- for (const [key, raw] of Object.entries(
4167
- value
4168
- )) {
4169
- if (raw === void 0 || raw === null) continue;
4170
- params.set(key, String(raw));
4171
- }
4172
- const serialized = params.toString();
4173
- return serialized.length > 0 ? `?${serialized}` : "";
4174
- } catch {
4175
- return "";
4176
- }
4177
- }
4178
- return "";
4179
- }
4180
- if (value === "?") return "";
4181
- return value.startsWith("?") ? value : ensurePrefix(value, "?");
4182
- };
4183
- var toHashString = (value) => {
4184
- if (!isNonEmptyString(value)) {
4185
- return "";
4186
- }
4187
- if (value === "#") return "";
4188
- return value.startsWith("#") ? value : ensurePrefix(value, "#");
4189
- };
4190
- var createPathString = (pathname, search, hash) => {
4191
- const normalizedPath = isNonEmptyString(pathname) ? pathname.startsWith("/") ? pathname : `/${pathname}` : "/";
4192
- const searchPart = toSearchString(search);
4193
- const hashPart = toHashString(hash);
4194
- return `${normalizedPath}${searchPart}${hashPart}`;
4195
- };
4196
4282
  // Annotate the CommonJS export names for ESM import in node:
4197
4283
  0 && (module.exports = {
4198
4284
  AnimationAdapterProvider,