@flowsterix/react 0.4.2 → 0.6.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/chunk-WCLT3A6G.mjs +0 -0
- package/dist/components/TourPopoverPortal.d.ts +5 -0
- package/dist/components/TourPopoverPortal.d.ts.map +1 -1
- package/dist/hooks/useHiddenTargetFallback.d.ts +5 -0
- package/dist/hooks/useHiddenTargetFallback.d.ts.map +1 -1
- package/dist/hooks/useHudState.d.ts +5 -0
- package/dist/hooks/useHudState.d.ts.map +1 -1
- package/dist/hooks/useHudTargetIssue.d.ts.map +1 -1
- package/dist/hooks/useRouteMismatch.d.ts +9 -0
- package/dist/hooks/useRouteMismatch.d.ts.map +1 -0
- package/dist/hooks/useTourOverlay.d.ts +5 -0
- package/dist/hooks/useTourOverlay.d.ts.map +1 -1
- package/dist/index.cjs +270 -166
- package/dist/index.mjs +188 -84
- package/dist/labels.d.ts +10 -0
- package/dist/labels.d.ts.map +1 -1
- package/dist/router/index.mjs +1 -0
- package/package.json +5 -2
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;
|
|
@@ -1663,7 +1673,7 @@ var useTourTarget = () => {
|
|
|
1663
1673
|
};
|
|
1664
1674
|
|
|
1665
1675
|
// src/hooks/useHudState.ts
|
|
1666
|
-
var
|
|
1676
|
+
var import_react10 = require("react");
|
|
1667
1677
|
|
|
1668
1678
|
// src/hooks/useAdvanceRules.ts
|
|
1669
1679
|
var import_react6 = require("react");
|
|
@@ -1878,6 +1888,7 @@ var useAdvanceRules = (target) => {
|
|
|
1878
1888
|
// src/hooks/useHiddenTargetFallback.ts
|
|
1879
1889
|
var import_react7 = require("react");
|
|
1880
1890
|
var DEFAULT_DELAY_MS = 900;
|
|
1891
|
+
var DEFAULT_GRACE_PERIOD_MS = 400;
|
|
1881
1892
|
var useHiddenTargetFallback = ({
|
|
1882
1893
|
step,
|
|
1883
1894
|
target,
|
|
@@ -1885,7 +1896,9 @@ var useHiddenTargetFallback = ({
|
|
|
1885
1896
|
onSkip
|
|
1886
1897
|
}) => {
|
|
1887
1898
|
const [usingScreenFallback, setUsingScreenFallback] = (0, import_react7.useState)(false);
|
|
1899
|
+
const [isInGracePeriod, setIsInGracePeriod] = (0, import_react7.useState)(false);
|
|
1888
1900
|
const timeoutRef = (0, import_react7.useRef)(null);
|
|
1901
|
+
const graceTimeoutRef = (0, import_react7.useRef)(null);
|
|
1889
1902
|
const skipTriggeredRef = (0, import_react7.useRef)(false);
|
|
1890
1903
|
const hiddenMode = step?.targetBehavior?.hidden ?? "screen";
|
|
1891
1904
|
const hiddenDelayMs = Math.max(
|
|
@@ -1898,26 +1911,44 @@ var useHiddenTargetFallback = ({
|
|
|
1898
1911
|
timeoutRef.current = null;
|
|
1899
1912
|
}
|
|
1900
1913
|
};
|
|
1914
|
+
const clearGraceTimeout = () => {
|
|
1915
|
+
if (graceTimeoutRef.current !== null) {
|
|
1916
|
+
globalThis.clearTimeout(graceTimeoutRef.current);
|
|
1917
|
+
graceTimeoutRef.current = null;
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1901
1920
|
(0, import_react7.useEffect)(() => {
|
|
1902
1921
|
skipTriggeredRef.current = false;
|
|
1903
1922
|
setUsingScreenFallback(false);
|
|
1923
|
+
setIsInGracePeriod(false);
|
|
1904
1924
|
clearPendingTimeout();
|
|
1905
|
-
|
|
1925
|
+
clearGraceTimeout();
|
|
1926
|
+
return () => {
|
|
1927
|
+
clearPendingTimeout();
|
|
1928
|
+
clearGraceTimeout();
|
|
1929
|
+
};
|
|
1906
1930
|
}, [step?.id]);
|
|
1907
1931
|
(0, import_react7.useEffect)(() => {
|
|
1908
1932
|
if (!isBrowser) return void 0;
|
|
1909
1933
|
if (!step) return void 0;
|
|
1910
1934
|
clearPendingTimeout();
|
|
1935
|
+
clearGraceTimeout();
|
|
1911
1936
|
const isHiddenOrDetached = (target.visibility === "hidden" || target.visibility === "detached") && target.status === "ready";
|
|
1912
1937
|
const isMissingWithNoRect = target.visibility === "missing" && target.status === "resolving" && target.rect === null && target.lastResolvedRect === null;
|
|
1913
|
-
const
|
|
1938
|
+
const isMissingAfterNavigation = target.visibility === "missing" && target.status === "resolving" && target.rect === null;
|
|
1939
|
+
const shouldHandleHiddenTarget = !target.isScreen && (isHiddenOrDetached || isMissingWithNoRect || isMissingAfterNavigation);
|
|
1914
1940
|
if (!shouldHandleHiddenTarget) {
|
|
1915
1941
|
setUsingScreenFallback(false);
|
|
1942
|
+
setIsInGracePeriod(false);
|
|
1916
1943
|
return void 0;
|
|
1917
1944
|
}
|
|
1945
|
+
setIsInGracePeriod(true);
|
|
1918
1946
|
if (hiddenMode !== "screen") {
|
|
1919
1947
|
setUsingScreenFallback(false);
|
|
1920
1948
|
}
|
|
1949
|
+
graceTimeoutRef.current = globalThis.setTimeout(() => {
|
|
1950
|
+
setIsInGracePeriod(false);
|
|
1951
|
+
}, DEFAULT_GRACE_PERIOD_MS);
|
|
1921
1952
|
timeoutRef.current = globalThis.setTimeout(() => {
|
|
1922
1953
|
if (hiddenMode === "screen") {
|
|
1923
1954
|
setUsingScreenFallback(true);
|
|
@@ -1928,7 +1959,10 @@ var useHiddenTargetFallback = ({
|
|
|
1928
1959
|
onSkip();
|
|
1929
1960
|
}
|
|
1930
1961
|
}, hiddenDelayMs);
|
|
1931
|
-
return
|
|
1962
|
+
return () => {
|
|
1963
|
+
clearPendingTimeout();
|
|
1964
|
+
clearGraceTimeout();
|
|
1965
|
+
};
|
|
1932
1966
|
}, [
|
|
1933
1967
|
step,
|
|
1934
1968
|
target.visibility,
|
|
@@ -1956,18 +1990,82 @@ var useHiddenTargetFallback = ({
|
|
|
1956
1990
|
}, [target, usingScreenFallback, viewportRect]);
|
|
1957
1991
|
return {
|
|
1958
1992
|
target: resolvedTarget,
|
|
1959
|
-
usingScreenFallback
|
|
1993
|
+
usingScreenFallback,
|
|
1994
|
+
isInGracePeriod
|
|
1960
1995
|
};
|
|
1961
1996
|
};
|
|
1962
1997
|
|
|
1963
|
-
// src/hooks/
|
|
1998
|
+
// src/hooks/useRouteMismatch.ts
|
|
1964
1999
|
var import_react8 = require("react");
|
|
2000
|
+
|
|
2001
|
+
// src/router/utils.ts
|
|
2002
|
+
var ensurePrefix = (value, prefix) => value.startsWith(prefix) ? value : `${prefix}${value}`;
|
|
2003
|
+
var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
2004
|
+
var toSearchString = (value) => {
|
|
2005
|
+
if (!isNonEmptyString(value)) {
|
|
2006
|
+
if (value instanceof URLSearchParams) {
|
|
2007
|
+
const serialized = value.toString();
|
|
2008
|
+
return serialized.length > 0 ? `?${serialized}` : "";
|
|
2009
|
+
}
|
|
2010
|
+
if (typeof value === "object" && value !== null) {
|
|
2011
|
+
try {
|
|
2012
|
+
const params = new URLSearchParams();
|
|
2013
|
+
for (const [key, raw] of Object.entries(
|
|
2014
|
+
value
|
|
2015
|
+
)) {
|
|
2016
|
+
if (raw === void 0 || raw === null) continue;
|
|
2017
|
+
params.set(key, String(raw));
|
|
2018
|
+
}
|
|
2019
|
+
const serialized = params.toString();
|
|
2020
|
+
return serialized.length > 0 ? `?${serialized}` : "";
|
|
2021
|
+
} catch {
|
|
2022
|
+
return "";
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
return "";
|
|
2026
|
+
}
|
|
2027
|
+
if (value === "?") return "";
|
|
2028
|
+
return value.startsWith("?") ? value : ensurePrefix(value, "?");
|
|
2029
|
+
};
|
|
2030
|
+
var toHashString = (value) => {
|
|
2031
|
+
if (!isNonEmptyString(value)) {
|
|
2032
|
+
return "";
|
|
2033
|
+
}
|
|
2034
|
+
if (value === "#") return "";
|
|
2035
|
+
return value.startsWith("#") ? value : ensurePrefix(value, "#");
|
|
2036
|
+
};
|
|
2037
|
+
var createPathString = (pathname, search, hash) => {
|
|
2038
|
+
const normalizedPath = isNonEmptyString(pathname) ? pathname.startsWith("/") ? pathname : `/${pathname}` : "/";
|
|
2039
|
+
const searchPart = toSearchString(search);
|
|
2040
|
+
const hashPart = toHashString(hash);
|
|
2041
|
+
return `${normalizedPath}${searchPart}${hashPart}`;
|
|
2042
|
+
};
|
|
2043
|
+
|
|
2044
|
+
// src/hooks/useRouteMismatch.ts
|
|
2045
|
+
var useRouteMismatch = (step) => {
|
|
2046
|
+
const [currentPath, setCurrentPath] = (0, import_react8.useState)(() => getCurrentRoutePath());
|
|
2047
|
+
(0, import_react8.useEffect)(() => {
|
|
2048
|
+
return subscribeToRouteChanges((path) => {
|
|
2049
|
+
setCurrentPath(path);
|
|
2050
|
+
});
|
|
2051
|
+
}, []);
|
|
2052
|
+
const expectedRoute = step?.route;
|
|
2053
|
+
const isRouteMismatch = step !== null && expectedRoute !== void 0 && !matchRoute({ pattern: expectedRoute, path: currentPath });
|
|
2054
|
+
return {
|
|
2055
|
+
isRouteMismatch,
|
|
2056
|
+
currentPath,
|
|
2057
|
+
expectedRoute
|
|
2058
|
+
};
|
|
2059
|
+
};
|
|
2060
|
+
|
|
2061
|
+
// src/hooks/useViewportRect.ts
|
|
2062
|
+
var import_react9 = require("react");
|
|
1965
2063
|
var useViewportRect = () => {
|
|
1966
|
-
const [viewport, setViewport] = (0,
|
|
2064
|
+
const [viewport, setViewport] = (0, import_react9.useState)(
|
|
1967
2065
|
() => getViewportRect()
|
|
1968
2066
|
);
|
|
1969
|
-
const rafRef = (0,
|
|
1970
|
-
(0,
|
|
2067
|
+
const rafRef = (0, import_react9.useRef)(null);
|
|
2068
|
+
(0, import_react9.useEffect)(() => {
|
|
1971
2069
|
if (!isBrowser) return;
|
|
1972
2070
|
const updateViewport = () => {
|
|
1973
2071
|
rafRef.current = null;
|
|
@@ -2009,12 +2107,12 @@ var normalizeFlowFilter = (value) => {
|
|
|
2009
2107
|
};
|
|
2010
2108
|
var useHudState = (options = {}) => {
|
|
2011
2109
|
const { flowId } = options;
|
|
2012
|
-
const flowFilter = (0,
|
|
2013
|
-
const { state, activeStep, activeFlowId, flows, next, complete } = useTour();
|
|
2110
|
+
const flowFilter = (0, import_react10.useMemo)(() => normalizeFlowFilter(flowId), [flowId]);
|
|
2111
|
+
const { state, activeStep, activeFlowId, flows, next, complete, pause, resume } = useTour();
|
|
2014
2112
|
const target = useTourTarget();
|
|
2015
2113
|
const viewportRect = useViewportRect();
|
|
2016
2114
|
useAdvanceRules(target);
|
|
2017
|
-
const matchesFlowFilter = (0,
|
|
2115
|
+
const matchesFlowFilter = (0, import_react10.useMemo)(() => {
|
|
2018
2116
|
if (!flowFilter || flowFilter.length === 0) return true;
|
|
2019
2117
|
if (!activeFlowId) return false;
|
|
2020
2118
|
return flowFilter.includes(activeFlowId);
|
|
@@ -2022,15 +2120,15 @@ var useHudState = (options = {}) => {
|
|
|
2022
2120
|
const isRunning = state?.status === "running";
|
|
2023
2121
|
const runningState = isRunning && matchesFlowFilter ? state : null;
|
|
2024
2122
|
const runningStep = runningState && activeStep ? activeStep : null;
|
|
2025
|
-
const [shouldRender, setShouldRender] = (0,
|
|
2123
|
+
const [shouldRender, setShouldRender] = (0, import_react10.useState)(
|
|
2026
2124
|
Boolean(runningStep)
|
|
2027
2125
|
);
|
|
2028
|
-
(0,
|
|
2126
|
+
(0, import_react10.useEffect)(() => {
|
|
2029
2127
|
if (runningStep) {
|
|
2030
2128
|
setShouldRender(true);
|
|
2031
2129
|
}
|
|
2032
2130
|
}, [runningStep?.id]);
|
|
2033
|
-
(0,
|
|
2131
|
+
(0, import_react10.useEffect)(() => {
|
|
2034
2132
|
if (!shouldRender) return;
|
|
2035
2133
|
if (runningStep) return;
|
|
2036
2134
|
if (target.status !== "idle") return;
|
|
@@ -2041,7 +2139,20 @@ var useHudState = (options = {}) => {
|
|
|
2041
2139
|
window.clearTimeout(timeoutId);
|
|
2042
2140
|
};
|
|
2043
2141
|
}, [runningStep, shouldRender, target.status]);
|
|
2044
|
-
const
|
|
2142
|
+
const { isRouteMismatch, currentPath } = useRouteMismatch(activeStep);
|
|
2143
|
+
const pausedForMissingTargetRef = (0, import_react10.useRef)(null);
|
|
2144
|
+
(0, import_react10.useEffect)(() => {
|
|
2145
|
+
if (!isRouteMismatch) return;
|
|
2146
|
+
if (!runningState || runningState.status !== "running") return;
|
|
2147
|
+
pause();
|
|
2148
|
+
}, [isRouteMismatch, runningState, pause]);
|
|
2149
|
+
(0, import_react10.useEffect)(() => {
|
|
2150
|
+
if (isRouteMismatch) return;
|
|
2151
|
+
if (pausedForMissingTargetRef.current !== null) return;
|
|
2152
|
+
if (!state || state.status !== "paused") return;
|
|
2153
|
+
resume();
|
|
2154
|
+
}, [isRouteMismatch, state, resume]);
|
|
2155
|
+
const skipHiddenStep = (0, import_react10.useCallback)(() => {
|
|
2045
2156
|
if (!runningState || runningState.status !== "running") return;
|
|
2046
2157
|
if (!activeFlowId) return;
|
|
2047
2158
|
const flow = flows.get(activeFlowId);
|
|
@@ -2053,12 +2164,41 @@ var useHudState = (options = {}) => {
|
|
|
2053
2164
|
next();
|
|
2054
2165
|
}
|
|
2055
2166
|
}, [activeFlowId, complete, flows, next, runningState]);
|
|
2056
|
-
const { target: hudTarget } = useHiddenTargetFallback({
|
|
2167
|
+
const { target: hudTarget, isInGracePeriod } = useHiddenTargetFallback({
|
|
2057
2168
|
step: runningStep,
|
|
2058
2169
|
target,
|
|
2059
2170
|
viewportRect,
|
|
2060
2171
|
onSkip: skipHiddenStep
|
|
2061
2172
|
});
|
|
2173
|
+
(0, import_react10.useEffect)(() => {
|
|
2174
|
+
if (isRouteMismatch) return;
|
|
2175
|
+
if (activeStep?.route !== void 0) return;
|
|
2176
|
+
if (isInGracePeriod) return;
|
|
2177
|
+
if (target.visibility !== "missing") return;
|
|
2178
|
+
if (target.isScreen) return;
|
|
2179
|
+
if (!runningState || runningState.status !== "running") return;
|
|
2180
|
+
pausedForMissingTargetRef.current = currentPath;
|
|
2181
|
+
pause();
|
|
2182
|
+
}, [
|
|
2183
|
+
isRouteMismatch,
|
|
2184
|
+
activeStep?.route,
|
|
2185
|
+
isInGracePeriod,
|
|
2186
|
+
target.visibility,
|
|
2187
|
+
target.isScreen,
|
|
2188
|
+
runningState,
|
|
2189
|
+
currentPath,
|
|
2190
|
+
pause
|
|
2191
|
+
]);
|
|
2192
|
+
(0, import_react10.useEffect)(() => {
|
|
2193
|
+
if (pausedForMissingTargetRef.current === null) return;
|
|
2194
|
+
if (!state || state.status !== "paused") return;
|
|
2195
|
+
if (currentPath === pausedForMissingTargetRef.current) return;
|
|
2196
|
+
pausedForMissingTargetRef.current = null;
|
|
2197
|
+
resume();
|
|
2198
|
+
}, [currentPath, state, resume]);
|
|
2199
|
+
(0, import_react10.useEffect)(() => {
|
|
2200
|
+
pausedForMissingTargetRef.current = null;
|
|
2201
|
+
}, [activeStep?.id]);
|
|
2062
2202
|
const canRenderStep = Boolean(runningStep && runningState);
|
|
2063
2203
|
const focusTrapActive = canRenderStep;
|
|
2064
2204
|
const flowHudOptions = matchesFlowFilter && activeFlowId ? flows.get(activeFlowId)?.hud ?? null : null;
|
|
@@ -2075,29 +2215,30 @@ var useHudState = (options = {}) => {
|
|
|
2075
2215
|
flowHudOptions,
|
|
2076
2216
|
hudRenderMode,
|
|
2077
2217
|
matchesFlowFilter,
|
|
2078
|
-
activeFlowId
|
|
2218
|
+
activeFlowId,
|
|
2219
|
+
isInGracePeriod
|
|
2079
2220
|
};
|
|
2080
2221
|
};
|
|
2081
2222
|
|
|
2082
2223
|
// src/hooks/useHudDescription.ts
|
|
2083
|
-
var
|
|
2224
|
+
var import_react11 = require("react");
|
|
2084
2225
|
var sanitizeForId = (value) => {
|
|
2085
2226
|
const normalized = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
2086
2227
|
return normalized.length > 0 ? normalized : "step";
|
|
2087
2228
|
};
|
|
2088
2229
|
var useHudDescription = (options) => {
|
|
2089
2230
|
const { step, fallbackAriaDescribedBy } = options;
|
|
2090
|
-
const targetDescription = (0,
|
|
2231
|
+
const targetDescription = (0, import_react11.useMemo)(() => {
|
|
2091
2232
|
if (!step) return null;
|
|
2092
2233
|
if (typeof step.target !== "object") return null;
|
|
2093
2234
|
const description = step.target.description;
|
|
2094
2235
|
return typeof description === "string" ? description : null;
|
|
2095
2236
|
}, [step]);
|
|
2096
|
-
const descriptionId = (0,
|
|
2237
|
+
const descriptionId = (0, import_react11.useMemo)(() => {
|
|
2097
2238
|
if (!step || !targetDescription) return void 0;
|
|
2098
2239
|
return `tour-step-${sanitizeForId(step.id)}-description`;
|
|
2099
2240
|
}, [step, targetDescription]);
|
|
2100
|
-
const combinedAriaDescribedBy = (0,
|
|
2241
|
+
const combinedAriaDescribedBy = (0, import_react11.useMemo)(() => {
|
|
2101
2242
|
const parts = [fallbackAriaDescribedBy, descriptionId].filter(Boolean);
|
|
2102
2243
|
return parts.length > 0 ? parts.join(" ") : void 0;
|
|
2103
2244
|
}, [descriptionId, fallbackAriaDescribedBy]);
|
|
@@ -2109,10 +2250,10 @@ var useHudDescription = (options) => {
|
|
|
2109
2250
|
};
|
|
2110
2251
|
|
|
2111
2252
|
// src/hooks/useHudShortcuts.ts
|
|
2112
|
-
var
|
|
2253
|
+
var import_react13 = require("react");
|
|
2113
2254
|
|
|
2114
2255
|
// src/hooks/useTourControls.ts
|
|
2115
|
-
var
|
|
2256
|
+
var import_react12 = require("react");
|
|
2116
2257
|
var hasManualAdvance = (rules) => rules.some((rule) => rule.type === "manual");
|
|
2117
2258
|
var didPreviousAdvanceViaRoute = (rules) => rules.some((rule) => rule.type === "route");
|
|
2118
2259
|
var didPreviousAdvanceViaTargetEvent = (rules) => rules.some((rule) => rule.type === "event" && rule.on === "target");
|
|
@@ -2128,7 +2269,7 @@ var useTourControls = () => {
|
|
|
2128
2269
|
flows,
|
|
2129
2270
|
activeStep
|
|
2130
2271
|
} = tour;
|
|
2131
|
-
const computed = (0,
|
|
2272
|
+
const computed = (0, import_react12.useMemo)(() => {
|
|
2132
2273
|
if (!state || state.status !== "running" || !activeStep) {
|
|
2133
2274
|
return {
|
|
2134
2275
|
isActive: false,
|
|
@@ -2177,11 +2318,11 @@ var useTourControls = () => {
|
|
|
2177
2318
|
} = computed;
|
|
2178
2319
|
const canGoBack = showBackButton && !backDisabled;
|
|
2179
2320
|
const canGoNext = showNextButton && !nextDisabled;
|
|
2180
|
-
const goBack = (0,
|
|
2321
|
+
const goBack = (0, import_react12.useCallback)(() => {
|
|
2181
2322
|
if (!canGoBack) return;
|
|
2182
2323
|
back();
|
|
2183
2324
|
}, [back, canGoBack]);
|
|
2184
|
-
const goNext = (0,
|
|
2325
|
+
const goNext = (0, import_react12.useCallback)(() => {
|
|
2185
2326
|
if (!canGoNext) return;
|
|
2186
2327
|
if (isLast) {
|
|
2187
2328
|
complete();
|
|
@@ -2189,7 +2330,7 @@ var useTourControls = () => {
|
|
|
2189
2330
|
next();
|
|
2190
2331
|
}
|
|
2191
2332
|
}, [canGoNext, complete, isLast, next]);
|
|
2192
|
-
return (0,
|
|
2333
|
+
return (0, import_react12.useMemo)(
|
|
2193
2334
|
() => ({
|
|
2194
2335
|
showBackButton,
|
|
2195
2336
|
backDisabled,
|
|
@@ -2234,7 +2375,7 @@ var useHudShortcuts = (target, options) => {
|
|
|
2234
2375
|
const escapeEnabled = options?.escape ?? true;
|
|
2235
2376
|
const { state } = useTour();
|
|
2236
2377
|
const { cancel, canGoBack, goBack, canGoNext, goNext, isActive } = useTourControls();
|
|
2237
|
-
(0,
|
|
2378
|
+
(0, import_react13.useEffect)(() => {
|
|
2238
2379
|
if (!isBrowser) return void 0;
|
|
2239
2380
|
if (!enabled) return void 0;
|
|
2240
2381
|
if (!target) return void 0;
|
|
@@ -2298,10 +2439,10 @@ var useHudShortcuts = (target, options) => {
|
|
|
2298
2439
|
};
|
|
2299
2440
|
|
|
2300
2441
|
// src/hooks/useTourHud.ts
|
|
2301
|
-
var
|
|
2442
|
+
var import_react16 = require("react");
|
|
2302
2443
|
|
|
2303
2444
|
// src/hooks/useBodyScrollLock.ts
|
|
2304
|
-
var
|
|
2445
|
+
var import_react14 = require("react");
|
|
2305
2446
|
var lockCount = 0;
|
|
2306
2447
|
var previousOverflow = null;
|
|
2307
2448
|
var acquireLock = () => {
|
|
@@ -2322,7 +2463,7 @@ var releaseLock = () => {
|
|
|
2322
2463
|
}
|
|
2323
2464
|
};
|
|
2324
2465
|
var useBodyScrollLock = (enabled) => {
|
|
2325
|
-
(0,
|
|
2466
|
+
(0, import_react14.useEffect)(() => {
|
|
2326
2467
|
if (!enabled) return;
|
|
2327
2468
|
acquireLock();
|
|
2328
2469
|
return () => {
|
|
@@ -2332,42 +2473,45 @@ var useBodyScrollLock = (enabled) => {
|
|
|
2332
2473
|
};
|
|
2333
2474
|
|
|
2334
2475
|
// src/hooks/useHudTargetIssue.ts
|
|
2335
|
-
var
|
|
2336
|
-
var deriveTargetIssue = (
|
|
2476
|
+
var import_react15 = require("react");
|
|
2477
|
+
var deriveTargetIssue = (params) => {
|
|
2478
|
+
const { target, labels } = params;
|
|
2337
2479
|
if (target.isScreen) return null;
|
|
2338
2480
|
if (target.status === "idle") return null;
|
|
2339
2481
|
switch (target.visibility) {
|
|
2340
2482
|
case "missing":
|
|
2341
2483
|
return {
|
|
2342
2484
|
type: "missing",
|
|
2343
|
-
title:
|
|
2344
|
-
body:
|
|
2345
|
-
hint: target.rectSource === "stored" ?
|
|
2485
|
+
title: labels.targetIssue.missingTitle,
|
|
2486
|
+
body: labels.targetIssue.missingBody,
|
|
2487
|
+
hint: target.rectSource === "stored" ? labels.targetIssue.missingHint : void 0
|
|
2346
2488
|
};
|
|
2347
2489
|
case "hidden":
|
|
2348
2490
|
return {
|
|
2349
2491
|
type: "hidden",
|
|
2350
|
-
title:
|
|
2351
|
-
body:
|
|
2492
|
+
title: labels.targetIssue.hiddenTitle,
|
|
2493
|
+
body: labels.targetIssue.hiddenBody,
|
|
2494
|
+
hint: target.rectSource === "stored" ? labels.targetIssue.hiddenHint : void 0
|
|
2352
2495
|
};
|
|
2353
2496
|
case "detached":
|
|
2354
2497
|
return {
|
|
2355
2498
|
type: "detached",
|
|
2356
|
-
title:
|
|
2357
|
-
body:
|
|
2499
|
+
title: labels.targetIssue.detachedTitle,
|
|
2500
|
+
body: labels.targetIssue.detachedBody
|
|
2358
2501
|
};
|
|
2359
2502
|
default:
|
|
2360
2503
|
return null;
|
|
2361
2504
|
}
|
|
2362
2505
|
};
|
|
2363
2506
|
var useHudTargetIssue = (target, options) => {
|
|
2507
|
+
const labels = useTourLabels();
|
|
2364
2508
|
const delayMs = Math.max(0, options?.delayMs ?? 500);
|
|
2365
|
-
const [armed, setArmed] = (0,
|
|
2366
|
-
const rawIssue = (0,
|
|
2367
|
-
() => deriveTargetIssue(target),
|
|
2368
|
-
[target.isScreen, target.rectSource, target.status, target.visibility]
|
|
2509
|
+
const [armed, setArmed] = (0, import_react15.useState)(false);
|
|
2510
|
+
const rawIssue = (0, import_react15.useMemo)(
|
|
2511
|
+
() => deriveTargetIssue({ target, labels }),
|
|
2512
|
+
[target.isScreen, target.rectSource, target.status, target.visibility, labels]
|
|
2369
2513
|
);
|
|
2370
|
-
(0,
|
|
2514
|
+
(0, import_react15.useEffect)(() => {
|
|
2371
2515
|
if (!rawIssue) {
|
|
2372
2516
|
setArmed(false);
|
|
2373
2517
|
return;
|
|
@@ -2401,7 +2545,7 @@ var useTourHud = (options = {}) => {
|
|
|
2401
2545
|
const { backdropInteraction, lockBodyScroll } = useTour();
|
|
2402
2546
|
const hudState = useHudState();
|
|
2403
2547
|
const disableDefaultHud = hudState.hudRenderMode === "none";
|
|
2404
|
-
const [popoverNode, setPopoverNode] = (0,
|
|
2548
|
+
const [popoverNode, setPopoverNode] = (0, import_react16.useState)(null);
|
|
2405
2549
|
const popoverOptions = hudState.flowHudOptions?.popover;
|
|
2406
2550
|
const description = useHudDescription({
|
|
2407
2551
|
step: hudState.runningStep,
|
|
@@ -2425,7 +2569,7 @@ var useTourHud = (options = {}) => {
|
|
|
2425
2569
|
radius: overlayRadius,
|
|
2426
2570
|
interactionMode: hudState.flowHudOptions?.backdrop?.interaction ?? backdropInteraction
|
|
2427
2571
|
};
|
|
2428
|
-
const popover = (0,
|
|
2572
|
+
const popover = (0, import_react16.useMemo)(() => {
|
|
2429
2573
|
return {
|
|
2430
2574
|
offset: popoverOptions?.offset ?? 16,
|
|
2431
2575
|
role: popoverOptions?.role ?? "dialog",
|
|
@@ -2437,13 +2581,13 @@ var useTourHud = (options = {}) => {
|
|
|
2437
2581
|
placement: hudState.runningStep?.placement
|
|
2438
2582
|
};
|
|
2439
2583
|
}, [hudState.runningStep?.placement, popoverOptions]);
|
|
2440
|
-
const descriptionResult = (0,
|
|
2584
|
+
const descriptionResult = (0, import_react16.useMemo)(() => {
|
|
2441
2585
|
return {
|
|
2442
2586
|
...description,
|
|
2443
2587
|
text: description.targetDescription
|
|
2444
2588
|
};
|
|
2445
2589
|
}, [description]);
|
|
2446
|
-
const focusManager = (0,
|
|
2590
|
+
const focusManager = (0, import_react16.useMemo)(
|
|
2447
2591
|
() => ({
|
|
2448
2592
|
active: hudState.focusTrapActive,
|
|
2449
2593
|
target: hudState.hudTarget,
|
|
@@ -2473,7 +2617,7 @@ var useTourHud = (options = {}) => {
|
|
|
2473
2617
|
};
|
|
2474
2618
|
|
|
2475
2619
|
// src/hooks/useTourOverlay.ts
|
|
2476
|
-
var
|
|
2620
|
+
var import_react17 = require("react");
|
|
2477
2621
|
var DEFAULT_PADDING = 12;
|
|
2478
2622
|
var DEFAULT_RADIUS = 12;
|
|
2479
2623
|
var DEFAULT_EDGE_BUFFER = 0;
|
|
@@ -2483,11 +2627,12 @@ var useTourOverlay = (options) => {
|
|
|
2483
2627
|
padding = DEFAULT_PADDING,
|
|
2484
2628
|
radius = DEFAULT_RADIUS,
|
|
2485
2629
|
edgeBuffer = DEFAULT_EDGE_BUFFER,
|
|
2486
|
-
interactionMode = "passthrough"
|
|
2630
|
+
interactionMode = "passthrough",
|
|
2631
|
+
isInGracePeriod = false
|
|
2487
2632
|
} = options;
|
|
2488
|
-
const hasShownRef = (0,
|
|
2489
|
-
const lastReadyTargetRef = (0,
|
|
2490
|
-
(0,
|
|
2633
|
+
const hasShownRef = (0, import_react17.useRef)(false);
|
|
2634
|
+
const lastReadyTargetRef = (0, import_react17.useRef)(null);
|
|
2635
|
+
(0, import_react17.useEffect)(() => {
|
|
2491
2636
|
if (!isBrowser) return;
|
|
2492
2637
|
if (target.status === "ready") {
|
|
2493
2638
|
hasShownRef.current = true;
|
|
@@ -2537,15 +2682,15 @@ var useTourOverlay = (options) => {
|
|
|
2537
2682
|
height: highlightHeight,
|
|
2538
2683
|
radius: highlightRadius
|
|
2539
2684
|
} : null;
|
|
2540
|
-
const maskCapable = (0,
|
|
2541
|
-
const isActive = target.status === "ready" || target.status === "resolving" && cachedTarget !== null;
|
|
2685
|
+
const maskCapable = (0, import_react17.useMemo)(() => supportsMasking(), []);
|
|
2686
|
+
const isActive = target.status === "ready" || target.status === "resolving" && cachedTarget !== null || isInGracePeriod;
|
|
2542
2687
|
const shouldMask = maskCapable && isActive;
|
|
2543
|
-
const maskId = (0,
|
|
2688
|
+
const maskId = (0, import_react17.useMemo)(
|
|
2544
2689
|
() => `tour-overlay-mask-${Math.random().toString(36).slice(2, 10)}`,
|
|
2545
2690
|
[]
|
|
2546
2691
|
);
|
|
2547
2692
|
const maskUrl = shouldMask ? `url(#${maskId})` : void 0;
|
|
2548
|
-
const fallbackSegments = (0,
|
|
2693
|
+
const fallbackSegments = (0, import_react17.useMemo)(() => {
|
|
2549
2694
|
if (!isActive || shouldMask || !hasHighlightBounds || !highlightRect) {
|
|
2550
2695
|
return null;
|
|
2551
2696
|
}
|
|
@@ -2598,7 +2743,7 @@ var useTourOverlay = (options) => {
|
|
|
2598
2743
|
viewport.height,
|
|
2599
2744
|
viewport.width
|
|
2600
2745
|
]);
|
|
2601
|
-
const blockerSegments = (0,
|
|
2746
|
+
const blockerSegments = (0, import_react17.useMemo)(() => {
|
|
2602
2747
|
if (interactionMode !== "block") {
|
|
2603
2748
|
return null;
|
|
2604
2749
|
}
|
|
@@ -2723,12 +2868,12 @@ var useRadixDialogAdapter = (options = {}) => {
|
|
|
2723
2868
|
};
|
|
2724
2869
|
|
|
2725
2870
|
// src/hooks/useDelayAdvance.ts
|
|
2726
|
-
var
|
|
2871
|
+
var import_react18 = require("react");
|
|
2727
2872
|
var getTimestamp = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
2728
2873
|
var useDelayAdvance = () => {
|
|
2729
2874
|
const { delayInfo, activeStep, state } = useTour();
|
|
2730
|
-
const [now, setNow] = (0,
|
|
2731
|
-
(0,
|
|
2875
|
+
const [now, setNow] = (0, import_react18.useState)(() => getTimestamp());
|
|
2876
|
+
(0, import_react18.useEffect)(() => {
|
|
2732
2877
|
if (!delayInfo) return;
|
|
2733
2878
|
if (!activeStep || activeStep.id !== delayInfo.stepId) return;
|
|
2734
2879
|
if (!state || state.status !== "running") return;
|
|
@@ -2745,12 +2890,12 @@ var useDelayAdvance = () => {
|
|
|
2745
2890
|
}
|
|
2746
2891
|
};
|
|
2747
2892
|
}, [delayInfo, activeStep, state]);
|
|
2748
|
-
(0,
|
|
2893
|
+
(0, import_react18.useEffect)(() => {
|
|
2749
2894
|
if (!delayInfo) {
|
|
2750
2895
|
setNow(getTimestamp());
|
|
2751
2896
|
}
|
|
2752
2897
|
}, [delayInfo]);
|
|
2753
|
-
return (0,
|
|
2898
|
+
return (0, import_react18.useMemo)(() => {
|
|
2754
2899
|
const matchingStep = !!delayInfo && !!activeStep && activeStep.id === delayInfo.stepId;
|
|
2755
2900
|
const isRunning = matchingStep && state?.status === "running";
|
|
2756
2901
|
if (!delayInfo) {
|
|
@@ -2803,9 +2948,9 @@ var useDelayAdvance = () => {
|
|
|
2803
2948
|
};
|
|
2804
2949
|
|
|
2805
2950
|
// src/components/OverlayBackdrop.tsx
|
|
2806
|
-
var
|
|
2951
|
+
var import_react19 = require("react");
|
|
2807
2952
|
var import_react_dom = require("react-dom");
|
|
2808
|
-
var
|
|
2953
|
+
var import_react20 = require("motion/react");
|
|
2809
2954
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
2810
2955
|
var styles = {
|
|
2811
2956
|
root: {
|
|
@@ -2892,9 +3037,9 @@ var OverlayBackdrop = ({
|
|
|
2892
3037
|
viewport
|
|
2893
3038
|
} = overlay;
|
|
2894
3039
|
const hasHighlightBounds = Boolean(highlight.rect);
|
|
2895
|
-
const prevScreenTargetRef = (0,
|
|
3040
|
+
const prevScreenTargetRef = (0, import_react19.useRef)(null);
|
|
2896
3041
|
const shouldSnapHighlight = prevScreenTargetRef.current === true && !highlight.isScreen && hasHighlightBounds;
|
|
2897
|
-
(0,
|
|
3042
|
+
(0, import_react19.useEffect)(() => {
|
|
2898
3043
|
prevScreenTargetRef.current = highlight.isScreen;
|
|
2899
3044
|
}, [highlight.isScreen]);
|
|
2900
3045
|
const resolvedBlur = typeof blurAmount === "number" ? `${blurAmount}px` : "0px";
|
|
@@ -2962,7 +3107,7 @@ var OverlayBackdrop = ({
|
|
|
2962
3107
|
"aria-hidden": ariaHidden,
|
|
2963
3108
|
"data-tour-overlay": "",
|
|
2964
3109
|
children: [
|
|
2965
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3110
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: shouldMask ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2966
3111
|
MotionSvg,
|
|
2967
3112
|
{
|
|
2968
3113
|
width: "0",
|
|
@@ -3021,7 +3166,7 @@ var OverlayBackdrop = ({
|
|
|
3021
3166
|
},
|
|
3022
3167
|
"tour-mask"
|
|
3023
3168
|
) : null }),
|
|
3024
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3169
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: showBaseOverlay ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3025
3170
|
MotionDiv,
|
|
3026
3171
|
{
|
|
3027
3172
|
className: overlayClassName,
|
|
@@ -3049,7 +3194,7 @@ var OverlayBackdrop = ({
|
|
|
3049
3194
|
},
|
|
3050
3195
|
"tour-overlay"
|
|
3051
3196
|
) : null }),
|
|
3052
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: fallbackSegments ? fallbackSegments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3053
3198
|
MotionDiv,
|
|
3054
3199
|
{
|
|
3055
3200
|
className: segmentClassName,
|
|
@@ -3100,7 +3245,7 @@ var OverlayBackdrop = ({
|
|
|
3100
3245
|
))
|
|
3101
3246
|
}
|
|
3102
3247
|
) : null,
|
|
3103
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3248
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react20.AnimatePresence, { mode: "popLayout", children: showHighlightRing && isActive && hasHighlightBounds ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3104
3249
|
MotionDiv,
|
|
3105
3250
|
{
|
|
3106
3251
|
className: ringClassName,
|
|
@@ -3131,7 +3276,7 @@ var OverlayBackdrop = ({
|
|
|
3131
3276
|
};
|
|
3132
3277
|
|
|
3133
3278
|
// src/components/TourPopoverPortal.tsx
|
|
3134
|
-
var
|
|
3279
|
+
var import_react21 = require("react");
|
|
3135
3280
|
var import_react_dom2 = require("react-dom");
|
|
3136
3281
|
var import_dom13 = require("@floating-ui/dom");
|
|
3137
3282
|
var FLOATING_OFFSET = 8;
|
|
@@ -3192,12 +3337,12 @@ var TourPopoverPortal = ({
|
|
|
3192
3337
|
const popoverContentTransition = transitionsOverride?.popoverContent ?? adapter.transitions.popoverContent ?? DEFAULT_POPOVER_CONTENT_TRANSITION;
|
|
3193
3338
|
const viewport = useViewportRect();
|
|
3194
3339
|
const prefersMobileLayout = viewport.width <= MOBILE_BREAKPOINT || viewport.height <= MOBILE_HEIGHT_BREAKPOINT;
|
|
3195
|
-
const prefersMobileRef = (0,
|
|
3196
|
-
(0,
|
|
3340
|
+
const prefersMobileRef = (0, import_react21.useRef)(prefersMobileLayout);
|
|
3341
|
+
(0, import_react21.useEffect)(() => {
|
|
3197
3342
|
prefersMobileRef.current = prefersMobileLayout;
|
|
3198
3343
|
}, [prefersMobileLayout]);
|
|
3199
|
-
const lastReadyTargetRef = (0,
|
|
3200
|
-
(0,
|
|
3344
|
+
const lastReadyTargetRef = (0, import_react21.useRef)(null);
|
|
3345
|
+
(0, import_react21.useEffect)(() => {
|
|
3201
3346
|
if (target.status === "ready" && target.rect) {
|
|
3202
3347
|
lastReadyTargetRef.current = {
|
|
3203
3348
|
rect: { ...target.rect },
|
|
@@ -3210,9 +3355,10 @@ var TourPopoverPortal = ({
|
|
|
3210
3355
|
const cachedTarget = lastReadyTargetRef.current;
|
|
3211
3356
|
const resolvedRect = target.rect ?? target.lastResolvedRect ?? cachedTarget?.rect ?? null;
|
|
3212
3357
|
const resolvedIsScreen = target.status === "ready" ? target.isScreen : cachedTarget?.isScreen ?? target.isScreen;
|
|
3358
|
+
const shouldHidePopover = !resolvedRect && !target.isScreen;
|
|
3213
3359
|
const fallbackRect = resolvedRect ?? viewport;
|
|
3214
3360
|
const fallbackIsScreen = resolvedIsScreen;
|
|
3215
|
-
const [floatingSize, setFloatingSize] = (0,
|
|
3361
|
+
const [floatingSize, setFloatingSize] = (0, import_react21.useState)(null);
|
|
3216
3362
|
const clampVertical = (value) => Math.min(viewport.height - 24, Math.max(24, value));
|
|
3217
3363
|
const clampHorizontal = (value) => Math.min(viewport.width - 24, Math.max(24, value));
|
|
3218
3364
|
const screenCenteredTop = viewport.height / 2 - (floatingSize?.height ?? 0) / 2;
|
|
@@ -3223,7 +3369,7 @@ var TourPopoverPortal = ({
|
|
|
3223
3369
|
const leftBase = fallbackIsScreen ? screenCenteredLeft : fallbackRect.left + fallbackRect.width / 2 - floatingWidth / 2;
|
|
3224
3370
|
const left = clampHorizontal(leftBase);
|
|
3225
3371
|
const fallbackTransform = "translate3d(0px, 0px, 0px)";
|
|
3226
|
-
const fallbackPosition = (0,
|
|
3372
|
+
const fallbackPosition = (0, import_react21.useMemo)(
|
|
3227
3373
|
() => ({
|
|
3228
3374
|
top,
|
|
3229
3375
|
left,
|
|
@@ -3231,7 +3377,7 @@ var TourPopoverPortal = ({
|
|
|
3231
3377
|
}),
|
|
3232
3378
|
[fallbackTransform, left, top]
|
|
3233
3379
|
);
|
|
3234
|
-
const centerInitialPosition = (0,
|
|
3380
|
+
const centerInitialPosition = (0, import_react21.useMemo)(
|
|
3235
3381
|
() => ({
|
|
3236
3382
|
top: viewport.height / 2,
|
|
3237
3383
|
left: viewport.width / 2,
|
|
@@ -3239,23 +3385,23 @@ var TourPopoverPortal = ({
|
|
|
3239
3385
|
}),
|
|
3240
3386
|
[viewport.height, viewport.width]
|
|
3241
3387
|
);
|
|
3242
|
-
const floatingRef = (0,
|
|
3243
|
-
const cachedFloatingPositionRef = (0,
|
|
3244
|
-
const appliedFloatingCacheRef = (0,
|
|
3245
|
-
const deferredScreenSnapRef = (0,
|
|
3246
|
-
const [layoutMode, setLayoutMode] = (0,
|
|
3388
|
+
const floatingRef = (0, import_react21.useRef)(null);
|
|
3389
|
+
const cachedFloatingPositionRef = (0, import_react21.useRef)(null);
|
|
3390
|
+
const appliedFloatingCacheRef = (0, import_react21.useRef)(null);
|
|
3391
|
+
const deferredScreenSnapRef = (0, import_react21.useRef)(null);
|
|
3392
|
+
const [layoutMode, setLayoutMode] = (0, import_react21.useState)(
|
|
3247
3393
|
() => prefersMobileLayout ? "mobile" : "floating"
|
|
3248
3394
|
);
|
|
3249
|
-
const [floatingPosition, setFloatingPosition] = (0,
|
|
3250
|
-
const [dragPosition, setDragPosition] = (0,
|
|
3251
|
-
const [isDragging, setIsDragging] = (0,
|
|
3252
|
-
const dragStateRef = (0,
|
|
3253
|
-
const overflowRetryRef = (0,
|
|
3395
|
+
const [floatingPosition, setFloatingPosition] = (0, import_react21.useState)(fallbackPosition);
|
|
3396
|
+
const [dragPosition, setDragPosition] = (0, import_react21.useState)(null);
|
|
3397
|
+
const [isDragging, setIsDragging] = (0, import_react21.useState)(false);
|
|
3398
|
+
const dragStateRef = (0, import_react21.useRef)(null);
|
|
3399
|
+
const overflowRetryRef = (0, import_react21.useRef)({
|
|
3254
3400
|
stepId: null,
|
|
3255
3401
|
attempts: 0
|
|
3256
3402
|
});
|
|
3257
|
-
const overflowRetryTimeoutRef = (0,
|
|
3258
|
-
(0,
|
|
3403
|
+
const overflowRetryTimeoutRef = (0, import_react21.useRef)(null);
|
|
3404
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
3259
3405
|
if (!isBrowser) return;
|
|
3260
3406
|
const node = floatingRef.current;
|
|
3261
3407
|
if (!node) return;
|
|
@@ -3274,25 +3420,25 @@ var TourPopoverPortal = ({
|
|
|
3274
3420
|
const autoAlignment = resolvedPlacement.endsWith(
|
|
3275
3421
|
"-start"
|
|
3276
3422
|
) ? "start" : resolvedPlacement.endsWith("-end") ? "end" : void 0;
|
|
3277
|
-
(0,
|
|
3423
|
+
(0, import_react21.useEffect)(() => {
|
|
3278
3424
|
setDragPosition(null);
|
|
3279
3425
|
setLayoutMode(prefersMobileRef.current ? "mobile" : "floating");
|
|
3280
3426
|
cachedFloatingPositionRef.current = null;
|
|
3281
3427
|
appliedFloatingCacheRef.current = null;
|
|
3282
3428
|
}, [target.stepId]);
|
|
3283
|
-
(0,
|
|
3429
|
+
(0, import_react21.useEffect)(() => {
|
|
3284
3430
|
if (layoutMode !== "manual") {
|
|
3285
3431
|
setDragPosition(null);
|
|
3286
3432
|
}
|
|
3287
3433
|
}, [layoutMode]);
|
|
3288
|
-
(0,
|
|
3434
|
+
(0, import_react21.useEffect)(() => {
|
|
3289
3435
|
cachedFloatingPositionRef.current = floatingPosition;
|
|
3290
3436
|
const cacheKey = getFloatingCacheKey(target);
|
|
3291
3437
|
if (cacheKey) {
|
|
3292
3438
|
floatingPositionCache.set(cacheKey, floatingPosition);
|
|
3293
3439
|
}
|
|
3294
3440
|
}, [floatingPosition, target.isScreen, target.stepId]);
|
|
3295
|
-
const dockedPosition = (0,
|
|
3441
|
+
const dockedPosition = (0, import_react21.useMemo)(
|
|
3296
3442
|
() => ({
|
|
3297
3443
|
top: viewport.height - DOCKED_MARGIN,
|
|
3298
3444
|
left: viewport.width - DOCKED_MARGIN,
|
|
@@ -3300,7 +3446,7 @@ var TourPopoverPortal = ({
|
|
|
3300
3446
|
}),
|
|
3301
3447
|
[viewport.height, viewport.width]
|
|
3302
3448
|
);
|
|
3303
|
-
const mobilePosition = (0,
|
|
3449
|
+
const mobilePosition = (0, import_react21.useMemo)(
|
|
3304
3450
|
() => ({
|
|
3305
3451
|
top: viewport.height - MOBILE_HORIZONTAL_GUTTER,
|
|
3306
3452
|
left: viewport.width / 2,
|
|
@@ -3308,17 +3454,17 @@ var TourPopoverPortal = ({
|
|
|
3308
3454
|
}),
|
|
3309
3455
|
[viewport.height, viewport.width]
|
|
3310
3456
|
);
|
|
3311
|
-
(0,
|
|
3457
|
+
(0, import_react21.useEffect)(() => {
|
|
3312
3458
|
if (layoutMode === "docked") {
|
|
3313
3459
|
setFloatingPosition(dockedPosition);
|
|
3314
3460
|
}
|
|
3315
3461
|
}, [dockedPosition, layoutMode]);
|
|
3316
|
-
(0,
|
|
3462
|
+
(0, import_react21.useEffect)(() => {
|
|
3317
3463
|
if (layoutMode === "mobile") {
|
|
3318
3464
|
setFloatingPosition(mobilePosition);
|
|
3319
3465
|
}
|
|
3320
3466
|
}, [layoutMode, mobilePosition]);
|
|
3321
|
-
(0,
|
|
3467
|
+
(0, import_react21.useEffect)(() => {
|
|
3322
3468
|
if (prefersMobileLayout) {
|
|
3323
3469
|
if (layoutMode !== "mobile") {
|
|
3324
3470
|
setLayoutMode("mobile");
|
|
@@ -3331,7 +3477,7 @@ var TourPopoverPortal = ({
|
|
|
3331
3477
|
setFloatingPosition(fallbackPosition);
|
|
3332
3478
|
}
|
|
3333
3479
|
}, [fallbackPosition, layoutMode, prefersMobileLayout]);
|
|
3334
|
-
(0,
|
|
3480
|
+
(0, import_react21.useEffect)(() => {
|
|
3335
3481
|
if (layoutMode !== "floating") return;
|
|
3336
3482
|
const stepId = target.stepId;
|
|
3337
3483
|
if (!stepId) return;
|
|
@@ -3355,7 +3501,7 @@ var TourPopoverPortal = ({
|
|
|
3355
3501
|
target.stepId
|
|
3356
3502
|
]);
|
|
3357
3503
|
const shouldDeferScreenSnap = layoutMode === "floating" && target.isScreen && Boolean(layoutId);
|
|
3358
|
-
(0,
|
|
3504
|
+
(0, import_react21.useEffect)(() => {
|
|
3359
3505
|
return () => {
|
|
3360
3506
|
if (deferredScreenSnapRef.current !== null) {
|
|
3361
3507
|
cancelAnimationFrame(deferredScreenSnapRef.current);
|
|
@@ -3363,7 +3509,7 @@ var TourPopoverPortal = ({
|
|
|
3363
3509
|
}
|
|
3364
3510
|
};
|
|
3365
3511
|
}, []);
|
|
3366
|
-
(0,
|
|
3512
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
3367
3513
|
if (layoutMode !== "floating") return;
|
|
3368
3514
|
if (target.status === "ready" && !target.isScreen) return;
|
|
3369
3515
|
if (shouldDeferScreenSnap) return;
|
|
@@ -3375,7 +3521,7 @@ var TourPopoverPortal = ({
|
|
|
3375
3521
|
target.isScreen,
|
|
3376
3522
|
target.status
|
|
3377
3523
|
]);
|
|
3378
|
-
(0,
|
|
3524
|
+
(0, import_react21.useEffect)(() => {
|
|
3379
3525
|
if (!shouldDeferScreenSnap) return;
|
|
3380
3526
|
if (deferredScreenSnapRef.current !== null) {
|
|
3381
3527
|
cancelAnimationFrame(deferredScreenSnapRef.current);
|
|
@@ -3402,14 +3548,14 @@ var TourPopoverPortal = ({
|
|
|
3402
3548
|
}
|
|
3403
3549
|
};
|
|
3404
3550
|
}, [fallbackPosition, shouldDeferScreenSnap]);
|
|
3405
|
-
(0,
|
|
3551
|
+
(0, import_react21.useEffect)(() => {
|
|
3406
3552
|
return () => {
|
|
3407
3553
|
if (overflowRetryTimeoutRef.current !== null) {
|
|
3408
3554
|
window.clearTimeout(overflowRetryTimeoutRef.current);
|
|
3409
3555
|
}
|
|
3410
3556
|
};
|
|
3411
3557
|
}, []);
|
|
3412
|
-
(0,
|
|
3558
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
3413
3559
|
if (!isBrowser) return;
|
|
3414
3560
|
const floatingEl = floatingRef.current;
|
|
3415
3561
|
const rectInfo = target.rect;
|
|
@@ -3543,7 +3689,7 @@ var TourPopoverPortal = ({
|
|
|
3543
3689
|
target.status,
|
|
3544
3690
|
target.stepId
|
|
3545
3691
|
]);
|
|
3546
|
-
(0,
|
|
3692
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
3547
3693
|
if (layoutMode !== "manual" || !dragPosition) return;
|
|
3548
3694
|
setFloatingPosition({
|
|
3549
3695
|
top: dragPosition.top,
|
|
@@ -3628,7 +3774,7 @@ var TourPopoverPortal = ({
|
|
|
3628
3774
|
}
|
|
3629
3775
|
event.preventDefault();
|
|
3630
3776
|
};
|
|
3631
|
-
(0,
|
|
3777
|
+
(0, import_react21.useEffect)(() => endDrag, []);
|
|
3632
3778
|
const shouldUseFallbackInitial = layoutMode !== "mobile" && (Boolean(target.lastResolvedRect) || Boolean(cachedTarget));
|
|
3633
3779
|
const floatingCacheKey = layoutMode === "mobile" ? null : getFloatingCacheKey(target);
|
|
3634
3780
|
const persistedFloatingInitial = floatingCacheKey && floatingPositionCache.has(floatingCacheKey) ? floatingPositionCache.get(floatingCacheKey) ?? null : null;
|
|
@@ -3715,11 +3861,12 @@ var TourPopoverPortal = ({
|
|
|
3715
3861
|
dragHandleProps,
|
|
3716
3862
|
descriptionProps
|
|
3717
3863
|
};
|
|
3864
|
+
if (shouldHidePopover) return null;
|
|
3718
3865
|
return (0, import_react_dom2.createPortal)(children(context), host);
|
|
3719
3866
|
};
|
|
3720
3867
|
|
|
3721
3868
|
// src/components/TourFocusManager.tsx
|
|
3722
|
-
var
|
|
3869
|
+
var import_react22 = require("react");
|
|
3723
3870
|
var import_react_dom3 = require("react-dom");
|
|
3724
3871
|
|
|
3725
3872
|
// src/utils/focus.ts
|
|
@@ -3796,18 +3943,18 @@ var TourFocusManager = ({
|
|
|
3796
3943
|
highlightRect,
|
|
3797
3944
|
guardElementFocusRing
|
|
3798
3945
|
}) => {
|
|
3799
|
-
const previousFocusRef = (0,
|
|
3800
|
-
const guardNodesRef = (0,
|
|
3946
|
+
const previousFocusRef = (0, import_react22.useRef)(null);
|
|
3947
|
+
const guardNodesRef = (0, import_react22.useRef)({
|
|
3801
3948
|
"target-start": null,
|
|
3802
3949
|
"target-end": null,
|
|
3803
3950
|
"popover-start": null,
|
|
3804
3951
|
"popover-end": null
|
|
3805
3952
|
});
|
|
3806
|
-
const lastTabDirectionRef = (0,
|
|
3807
|
-
const suppressGuardHopRef = (0,
|
|
3808
|
-
const [targetRingActive, setTargetRingActive] = (0,
|
|
3809
|
-
const [popoverRingActive, setPopoverRingActive] = (0,
|
|
3810
|
-
const [popoverRect, setPopoverRect] = (0,
|
|
3953
|
+
const lastTabDirectionRef = (0, import_react22.useRef)("forward");
|
|
3954
|
+
const suppressGuardHopRef = (0, import_react22.useRef)(null);
|
|
3955
|
+
const [targetRingActive, setTargetRingActive] = (0, import_react22.useState)(false);
|
|
3956
|
+
const [popoverRingActive, setPopoverRingActive] = (0, import_react22.useState)(false);
|
|
3957
|
+
const [popoverRect, setPopoverRect] = (0, import_react22.useState)(null);
|
|
3811
3958
|
const restoreFocus = () => {
|
|
3812
3959
|
const previous = previousFocusRef.current;
|
|
3813
3960
|
previousFocusRef.current = null;
|
|
@@ -3817,7 +3964,7 @@ var TourFocusManager = ({
|
|
|
3817
3964
|
});
|
|
3818
3965
|
}
|
|
3819
3966
|
};
|
|
3820
|
-
(0,
|
|
3967
|
+
(0, import_react22.useLayoutEffect)(() => {
|
|
3821
3968
|
if (!isBrowser) return;
|
|
3822
3969
|
if (!active) {
|
|
3823
3970
|
restoreFocus();
|
|
@@ -3833,7 +3980,7 @@ var TourFocusManager = ({
|
|
|
3833
3980
|
restoreFocus();
|
|
3834
3981
|
};
|
|
3835
3982
|
}, [active, popoverNode, target.element]);
|
|
3836
|
-
(0,
|
|
3983
|
+
(0, import_react22.useEffect)(() => {
|
|
3837
3984
|
if (!isBrowser) return;
|
|
3838
3985
|
if (!active) return;
|
|
3839
3986
|
const doc = popoverNode?.ownerDocument ?? target.element?.ownerDocument ?? document;
|
|
@@ -4027,7 +4174,7 @@ var TourFocusManager = ({
|
|
|
4027
4174
|
target.stepId,
|
|
4028
4175
|
target.visibility
|
|
4029
4176
|
]);
|
|
4030
|
-
(0,
|
|
4177
|
+
(0, import_react22.useLayoutEffect)(() => {
|
|
4031
4178
|
if (popoverRingActive && popoverNode) {
|
|
4032
4179
|
setPopoverRect(popoverNode.getBoundingClientRect());
|
|
4033
4180
|
} else {
|
|
@@ -4083,7 +4230,7 @@ var TourFocusManager = ({
|
|
|
4083
4230
|
};
|
|
4084
4231
|
|
|
4085
4232
|
// src/motion/useHudMotion.ts
|
|
4086
|
-
var
|
|
4233
|
+
var import_react23 = require("react");
|
|
4087
4234
|
var DEFAULT_HIGHLIGHT_TRANSITION2 = {
|
|
4088
4235
|
duration: 0.35,
|
|
4089
4236
|
ease: "easeOut",
|
|
@@ -4110,7 +4257,7 @@ var DEFAULT_POPOVER_CONTENT_TRANSITION2 = {
|
|
|
4110
4257
|
};
|
|
4111
4258
|
var useHudMotion = () => {
|
|
4112
4259
|
const adapter = useAnimationAdapter();
|
|
4113
|
-
return (0,
|
|
4260
|
+
return (0, import_react23.useMemo)(() => {
|
|
4114
4261
|
const components = {
|
|
4115
4262
|
...adapter.components
|
|
4116
4263
|
};
|
|
@@ -4126,49 +4273,6 @@ var useHudMotion = () => {
|
|
|
4126
4273
|
};
|
|
4127
4274
|
}, [adapter]);
|
|
4128
4275
|
};
|
|
4129
|
-
|
|
4130
|
-
// src/router/utils.ts
|
|
4131
|
-
var ensurePrefix = (value, prefix) => value.startsWith(prefix) ? value : `${prefix}${value}`;
|
|
4132
|
-
var isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
4133
|
-
var toSearchString = (value) => {
|
|
4134
|
-
if (!isNonEmptyString(value)) {
|
|
4135
|
-
if (value instanceof URLSearchParams) {
|
|
4136
|
-
const serialized = value.toString();
|
|
4137
|
-
return serialized.length > 0 ? `?${serialized}` : "";
|
|
4138
|
-
}
|
|
4139
|
-
if (typeof value === "object" && value !== null) {
|
|
4140
|
-
try {
|
|
4141
|
-
const params = new URLSearchParams();
|
|
4142
|
-
for (const [key, raw] of Object.entries(
|
|
4143
|
-
value
|
|
4144
|
-
)) {
|
|
4145
|
-
if (raw === void 0 || raw === null) continue;
|
|
4146
|
-
params.set(key, String(raw));
|
|
4147
|
-
}
|
|
4148
|
-
const serialized = params.toString();
|
|
4149
|
-
return serialized.length > 0 ? `?${serialized}` : "";
|
|
4150
|
-
} catch {
|
|
4151
|
-
return "";
|
|
4152
|
-
}
|
|
4153
|
-
}
|
|
4154
|
-
return "";
|
|
4155
|
-
}
|
|
4156
|
-
if (value === "?") return "";
|
|
4157
|
-
return value.startsWith("?") ? value : ensurePrefix(value, "?");
|
|
4158
|
-
};
|
|
4159
|
-
var toHashString = (value) => {
|
|
4160
|
-
if (!isNonEmptyString(value)) {
|
|
4161
|
-
return "";
|
|
4162
|
-
}
|
|
4163
|
-
if (value === "#") return "";
|
|
4164
|
-
return value.startsWith("#") ? value : ensurePrefix(value, "#");
|
|
4165
|
-
};
|
|
4166
|
-
var createPathString = (pathname, search, hash) => {
|
|
4167
|
-
const normalizedPath = isNonEmptyString(pathname) ? pathname.startsWith("/") ? pathname : `/${pathname}` : "/";
|
|
4168
|
-
const searchPart = toSearchString(search);
|
|
4169
|
-
const hashPart = toHashString(hash);
|
|
4170
|
-
return `${normalizedPath}${searchPart}${hashPart}`;
|
|
4171
|
-
};
|
|
4172
4276
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4173
4277
|
0 && (module.exports = {
|
|
4174
4278
|
AnimationAdapterProvider,
|