@flowsterix/react 0.14.0 → 0.14.2

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.d.ts CHANGED
@@ -35,7 +35,7 @@ export { TourPopoverPortal } from './components/TourPopoverPortal';
35
35
  export type { TourPopoverLayoutMode, TourPopoverPortalProps, TourPopoverPortalRenderProps, } from './components/TourPopoverPortal';
36
36
  export { TourFocusManager } from './components/TourFocusManager';
37
37
  export type { TourFocusManagerProps } from './components/TourFocusManager';
38
- export { AnimationAdapterProvider, defaultAnimationAdapter, reducedMotionAnimationAdapter, useAnimationAdapter, usePreferredAnimationAdapter, } from './motion/animationAdapter';
38
+ export { AnimationAdapterProvider, defaultAnimationAdapter, reducedMotionAnimationAdapter, tweenAnimationAdapter, useAnimationAdapter, usePreferredAnimationAdapter, } from './motion/animationAdapter';
39
39
  export type { AnimationAdapter, AnimationAdapterComponents, AnimationAdapterProviderProps, AnimationAdapterTransitions, UseAnimationAdapterOptions, } from './motion/animationAdapter';
40
40
  export { useHudMotion } from './motion/useHudMotion';
41
41
  export type { UseHudMotionResult } from './motion/useHudMotion';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
- DevToolsContext
3
- } from "./chunk-AJZMUYBN.mjs";
2
+ DevToolsContext,
3
+ setUseSpringAnimations
4
+ } from "./chunk-ZE3LNV4N.mjs";
4
5
  import "./chunk-Y5EAQSU3.mjs";
5
6
  import {
6
7
  createPathString,
@@ -276,6 +277,21 @@ var useAnimationAdapter = () => {
276
277
  return useContext3(AnimationAdapterContext);
277
278
  };
278
279
  var defaultAnimationAdapter = defaultAdapter;
280
+ var tweenAnimationAdapter = {
281
+ components: defaultAdapter.components,
282
+ transitions: {
283
+ overlayHighlight: {
284
+ type: "tween",
285
+ duration: 0.35,
286
+ ease: [0.25, 1, 0.5, 1]
287
+ },
288
+ overlayFade: defaultAdapter.transitions.overlayFade,
289
+ popoverEntrance: defaultAdapter.transitions.popoverEntrance,
290
+ popoverExit: defaultAdapter.transitions.popoverExit,
291
+ popoverContent: defaultAdapter.transitions.popoverContent,
292
+ delayIndicator: defaultAdapter.transitions.delayIndicator
293
+ }
294
+ };
279
295
  var reducedMotionAnimationAdapter = {
280
296
  components: defaultAdapter.components,
281
297
  transitions: {
@@ -361,6 +377,7 @@ var TourProvider = ({
361
377
  backdropInteraction: backdropInteractionProp = "passthrough",
362
378
  lockBodyScroll: lockBodyScrollProp = false,
363
379
  labels: labelsProp,
380
+ useSpringAnimations: useSpringAnimationsProp = true,
364
381
  onVersionMismatch
365
382
  }) => {
366
383
  const mergedLabels = useMemo3(
@@ -848,8 +865,12 @@ var TourProvider = ({
848
865
  updateFlowStorage
849
866
  ]
850
867
  );
868
+ useEffect3(() => {
869
+ setUseSpringAnimations(useSpringAnimationsProp);
870
+ }, [useSpringAnimationsProp]);
871
+ const effectiveDefaultAdapter = useSpringAnimationsProp ? animationAdapterProp : tweenAnimationAdapter;
851
872
  const resolvedAnimationAdapter = usePreferredAnimationAdapter({
852
- defaultAdapter: animationAdapterProp,
873
+ defaultAdapter: effectiveDefaultAdapter,
853
874
  reducedMotionAdapter,
854
875
  enabled: autoDetectReducedMotion
855
876
  });
@@ -1152,13 +1173,69 @@ var computeVisibilityState = (element, rect, isScreen) => {
1152
1173
  }
1153
1174
  return "visible";
1154
1175
  };
1155
- var scrollContainerBy = (container, topDelta, leftDelta, behavior) => {
1176
+ var clamp01 = (value) => Math.max(0, Math.min(1, value));
1177
+ var easeInOutCubic = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
1178
+ var windowScrollAnimationToken = 0;
1179
+ var getWindowScrollY = () => {
1180
+ if (!isBrowser) return 0;
1181
+ const scrollingElement = document.scrollingElement;
1182
+ return scrollingElement?.scrollTop ?? window.scrollY ?? 0;
1183
+ };
1184
+ var setWindowScrollY = (value) => {
1185
+ if (!isBrowser) return;
1186
+ const scrollingElement = document.scrollingElement;
1187
+ if (scrollingElement) {
1188
+ scrollingElement.scrollTop = value;
1189
+ return;
1190
+ }
1191
+ document.documentElement.scrollTop = value;
1192
+ document.body.scrollTop = value;
1193
+ };
1194
+ var animateWindowScrollBy = (topDelta, durationMs) => {
1195
+ if (!isBrowser) return;
1196
+ if (!Number.isFinite(topDelta) || Math.abs(topDelta) < 0.5) return;
1197
+ const startY = getWindowScrollY();
1198
+ const targetY = startY + topDelta;
1199
+ const scrollingElement = document.scrollingElement ?? document.documentElement;
1200
+ const maxScrollY = Math.max(
1201
+ 0,
1202
+ scrollingElement.scrollHeight - scrollingElement.clientHeight
1203
+ );
1204
+ const clampedTargetY = Math.max(0, Math.min(targetY, maxScrollY));
1205
+ const distance = clampedTargetY - startY;
1206
+ if (Math.abs(distance) < 0.5) return;
1207
+ const duration = Math.max(0, durationMs);
1208
+ const startTime = performance.now();
1209
+ const token = windowScrollAnimationToken += 1;
1210
+ const tick = (now) => {
1211
+ if (token !== windowScrollAnimationToken) return;
1212
+ const elapsed = now - startTime;
1213
+ const progress = duration === 0 ? 1 : clamp01(elapsed / duration);
1214
+ const eased = easeInOutCubic(progress);
1215
+ const nextY = startY + distance * eased;
1216
+ setWindowScrollY(nextY);
1217
+ if (progress < 1) {
1218
+ window.requestAnimationFrame(tick);
1219
+ }
1220
+ };
1221
+ window.requestAnimationFrame(tick);
1222
+ };
1223
+ var scrollContainerBy = (container, topDelta, leftDelta, options) => {
1156
1224
  if (!isBrowser) return;
1157
1225
  if (Math.abs(topDelta) < 0.5 && Math.abs(leftDelta) < 0.5) {
1158
1226
  return;
1159
1227
  }
1228
+ const behavior = options?.behavior;
1229
+ const durationMs = options?.durationMs;
1160
1230
  const isRootContainer = container === document.body || container === document.documentElement || container === document.scrollingElement;
1161
1231
  if (isRootContainer) {
1232
+ if (typeof durationMs === "number" && durationMs >= 0) {
1233
+ animateWindowScrollBy(topDelta, durationMs);
1234
+ if (Math.abs(leftDelta) >= 0.5) {
1235
+ window.scrollBy({ left: leftDelta, behavior: behavior ?? "auto" });
1236
+ }
1237
+ return;
1238
+ }
1162
1239
  window.scrollBy({
1163
1240
  top: topDelta,
1164
1241
  left: leftDelta,
@@ -1178,7 +1255,7 @@ var scrollContainerBy = (container, topDelta, leftDelta, behavior) => {
1178
1255
  elementContainer.scrollTop += topDelta;
1179
1256
  elementContainer.scrollLeft += leftDelta;
1180
1257
  };
1181
- var alignWithinViewport = (element, margin, behavior, mode) => {
1258
+ var alignWithinViewport = (element, margin, behavior, durationMs, mode) => {
1182
1259
  if (mode === "preserve") return;
1183
1260
  const viewportRect = getViewportRect();
1184
1261
  const finalRect = getClientRect(element);
@@ -1187,6 +1264,10 @@ var alignWithinViewport = (element, margin, behavior, mode) => {
1187
1264
  const desiredTop = mode === "center" ? margin.top + (availableHeight - finalRect.height) / 2 : margin.top;
1188
1265
  const delta = finalRect.top - desiredTop;
1189
1266
  if (Math.abs(delta) < 0.5) return;
1267
+ if (typeof durationMs === "number" && durationMs >= 0) {
1268
+ animateWindowScrollBy(delta, durationMs);
1269
+ return;
1270
+ }
1190
1271
  window.scrollBy({
1191
1272
  top: delta,
1192
1273
  behavior: behavior ?? "auto"
@@ -1194,6 +1275,7 @@ var alignWithinViewport = (element, margin, behavior, mode) => {
1194
1275
  };
1195
1276
  var ensureElementInView = (element, margin, options) => {
1196
1277
  const behavior = options?.behavior ?? "auto";
1278
+ const durationMs = options?.durationMs;
1197
1279
  const mode = options?.mode ?? "preserve";
1198
1280
  if (!isBrowser) return;
1199
1281
  const scrollParents = getScrollParents(element);
@@ -1217,7 +1299,10 @@ var ensureElementInView = (element, margin, options) => {
1217
1299
  leftDelta = targetRect.right - (containerRect.right - margin.right);
1218
1300
  }
1219
1301
  if (topDelta !== 0 || leftDelta !== 0) {
1220
- scrollContainerBy(container, topDelta, leftDelta, behavior);
1302
+ scrollContainerBy(container, topDelta, leftDelta, {
1303
+ behavior,
1304
+ durationMs
1305
+ });
1221
1306
  }
1222
1307
  }
1223
1308
  const viewportRect = getViewportRect();
@@ -1235,13 +1320,20 @@ var ensureElementInView = (element, margin, options) => {
1235
1320
  viewportLeftDelta = finalRect.right - (viewportRect.right - margin.right);
1236
1321
  }
1237
1322
  if (viewportTopDelta !== 0 || viewportLeftDelta !== 0) {
1238
- window.scrollBy({
1239
- top: viewportTopDelta,
1240
- left: viewportLeftDelta,
1241
- behavior
1242
- });
1323
+ if (typeof durationMs === "number" && durationMs >= 0) {
1324
+ animateWindowScrollBy(viewportTopDelta, durationMs);
1325
+ if (Math.abs(viewportLeftDelta) >= 0.5) {
1326
+ window.scrollBy({ left: viewportLeftDelta, behavior: behavior ?? "auto" });
1327
+ }
1328
+ } else {
1329
+ window.scrollBy({
1330
+ top: viewportTopDelta,
1331
+ left: viewportLeftDelta,
1332
+ behavior
1333
+ });
1334
+ }
1243
1335
  }
1244
- alignWithinViewport(element, margin, behavior, mode);
1336
+ alignWithinViewport(element, margin, behavior, durationMs, mode);
1245
1337
  };
1246
1338
  var resolveStepTarget = (target) => {
1247
1339
  if (!isBrowser) return null;
@@ -1269,7 +1361,13 @@ var resolveStepTarget = (target) => {
1269
1361
  var useTourTarget = () => {
1270
1362
  const { activeStep, state, activeFlowId, flows } = useTour();
1271
1363
  const [targetInfo, setTargetInfo] = useState3(INITIAL_TARGET_INFO);
1272
- const autoScrollStateRef = useRef4({ stepId: null, checks: 0, stalledChecks: 0, done: false, lastRect: null });
1364
+ const autoScrollStateRef = useRef4({
1365
+ stepId: null,
1366
+ checks: 0,
1367
+ stalledChecks: 0,
1368
+ done: false,
1369
+ lastRect: null
1370
+ });
1273
1371
  const autoScrollRafRef = useRef4(null);
1274
1372
  const autoScrollTimeoutRef = useRef4(null);
1275
1373
  const lastRectRef = useRef4(null);
@@ -1293,6 +1391,21 @@ var useTourTarget = () => {
1293
1391
  initialScrollStepRef.current = null;
1294
1392
  };
1295
1393
  }, [activeStep?.id]);
1394
+ useEffect4(() => {
1395
+ if (!isBrowser) return;
1396
+ if (!activeStep || !state || state.status !== "running") return;
1397
+ if (typeof activeStep.targetBehavior?.scrollDurationMs !== "number") return;
1398
+ const html = document.documentElement;
1399
+ const body = document.body;
1400
+ const previousHtmlScrollBehavior = html.style.scrollBehavior;
1401
+ const previousBodyScrollBehavior = body.style.scrollBehavior;
1402
+ html.style.scrollBehavior = "auto";
1403
+ body.style.scrollBehavior = "auto";
1404
+ return () => {
1405
+ html.style.scrollBehavior = previousHtmlScrollBehavior;
1406
+ body.style.scrollBehavior = previousBodyScrollBehavior;
1407
+ };
1408
+ }, [activeStep?.id, activeStep?.targetBehavior?.scrollDurationMs, state?.status]);
1296
1409
  useLayoutEffect(() => {
1297
1410
  if (!isBrowser) return;
1298
1411
  if (!activeStep) return;
@@ -1308,16 +1421,19 @@ var useTourTarget = () => {
1308
1421
  DEFAULT_SCROLL_MARGIN
1309
1422
  );
1310
1423
  const scrollMode = activeStep.targetBehavior?.scrollMode ?? DEFAULT_SCROLL_MODE;
1424
+ const scrollDurationMs = activeStep.targetBehavior?.scrollDurationMs;
1311
1425
  const hasLiveRect = targetInfo.rectSource === "live";
1312
1426
  const scrollBehavior = hasLiveRect ? "smooth" : "auto";
1313
1427
  ensureElementInView(targetInfo.element, margin, {
1314
1428
  behavior: scrollBehavior,
1429
+ durationMs: scrollBehavior === "smooth" ? scrollDurationMs : void 0,
1315
1430
  mode: scrollMode
1316
1431
  });
1317
1432
  }, [
1318
1433
  activeStep?.id,
1319
1434
  activeStep?.targetBehavior?.scrollMargin,
1320
1435
  activeStep?.targetBehavior?.scrollMode,
1436
+ activeStep?.targetBehavior?.scrollDurationMs,
1321
1437
  targetInfo.rect,
1322
1438
  targetInfo.lastResolvedRect,
1323
1439
  targetInfo.element,
@@ -1680,6 +1796,7 @@ var useTourTarget = () => {
1680
1796
  }
1681
1797
  const { element } = targetInfo;
1682
1798
  const scrollMode = activeStep.targetBehavior?.scrollMode ?? "center";
1799
+ const scrollDurationMs = activeStep.targetBehavior?.scrollDurationMs;
1683
1800
  const runCheck = () => {
1684
1801
  autoScrollRafRef.current = null;
1685
1802
  if (!isBrowser) return;
@@ -1713,10 +1830,14 @@ var useTourTarget = () => {
1713
1830
  autoState.stalledChecks += 1;
1714
1831
  }
1715
1832
  const behavior = autoState.stalledChecks >= STALLED_CHECKS_BEFORE_AUTO ? "auto" : "smooth";
1716
- ensureElementInView(element, margin, {
1717
- behavior,
1718
- mode: scrollMode
1719
- });
1833
+ const shouldDispatchScroll = behavior === "auto" || !hasProgress || autoState.checks <= 1;
1834
+ if (shouldDispatchScroll) {
1835
+ ensureElementInView(element, margin, {
1836
+ behavior,
1837
+ durationMs: behavior === "smooth" ? scrollDurationMs : void 0,
1838
+ mode: scrollMode
1839
+ });
1840
+ }
1720
1841
  autoScrollTimeoutRef.current = globalThis.setTimeout(() => {
1721
1842
  autoScrollRafRef.current = window.requestAnimationFrame(runCheck);
1722
1843
  }, 120);
@@ -1724,7 +1845,12 @@ var useTourTarget = () => {
1724
1845
  cancelAutoScrollLoop();
1725
1846
  autoScrollRafRef.current = window.requestAnimationFrame(runCheck);
1726
1847
  return cancelAutoScrollLoop;
1727
- }, [activeStep, activeStep?.targetBehavior?.scrollMode, targetInfo]);
1848
+ }, [
1849
+ activeStep,
1850
+ activeStep?.targetBehavior?.scrollMode,
1851
+ activeStep?.targetBehavior?.scrollDurationMs,
1852
+ targetInfo
1853
+ ]);
1728
1854
  return targetInfo;
1729
1855
  };
1730
1856
 
@@ -2696,6 +2822,7 @@ import { useEffect as useEffect13, useMemo as useMemo10, useRef as useRef9 } fro
2696
2822
  var DEFAULT_PADDING = 12;
2697
2823
  var DEFAULT_RADIUS = 12;
2698
2824
  var DEFAULT_EDGE_BUFFER = 0;
2825
+ var rectIntersectsViewport = (rect, viewport) => rect.bottom > 0 && rect.right > 0 && rect.top < viewport.height && rect.left < viewport.width;
2699
2826
  var useTourOverlay = (options) => {
2700
2827
  const {
2701
2828
  target,
@@ -2707,9 +2834,13 @@ var useTourOverlay = (options) => {
2707
2834
  } = options;
2708
2835
  const hasShownRef = useRef9(false);
2709
2836
  const lastReadyTargetRef = useRef9(null);
2837
+ const viewport = getViewportRect();
2838
+ const liveRectIsInViewport = Boolean(
2839
+ target.isScreen || target.rect && rectIntersectsViewport(target.rect, viewport)
2840
+ );
2710
2841
  useEffect13(() => {
2711
2842
  if (!isBrowser) return;
2712
- if (target.status === "ready") {
2843
+ if (target.status === "ready" && liveRectIsInViewport) {
2713
2844
  hasShownRef.current = true;
2714
2845
  lastReadyTargetRef.current = {
2715
2846
  ...target,
@@ -2721,11 +2852,10 @@ var useTourOverlay = (options) => {
2721
2852
  hasShownRef.current = false;
2722
2853
  lastReadyTargetRef.current = null;
2723
2854
  }
2724
- }, [target, isInGracePeriod]);
2725
- const viewport = getViewportRect();
2855
+ }, [target, isInGracePeriod, liveRectIsInViewport]);
2726
2856
  const cachedTarget = lastReadyTargetRef.current;
2727
- const highlightTarget = target.status === "ready" ? target : cachedTarget;
2728
- const resolvedRect = highlightTarget?.rect ?? target.rect;
2857
+ const highlightTarget = target.status === "ready" && liveRectIsInViewport ? target : cachedTarget;
2858
+ const resolvedRect = highlightTarget?.rect ?? (cachedTarget ? null : target.rect ?? null);
2729
2859
  const resolvedIsScreen = highlightTarget?.isScreen ?? target.isScreen;
2730
2860
  const expandedRect = resolvedIsScreen || !resolvedRect ? viewport : expandRect(resolvedRect, padding);
2731
2861
  const safeBuffer = Math.max(0, edgeBuffer);
@@ -3571,6 +3701,7 @@ var DEFAULT_POPOVER_CONTENT_TRANSITION = {
3571
3701
  ease: "easeOut"
3572
3702
  };
3573
3703
  var floatingPositionCache = /* @__PURE__ */ new Map();
3704
+ var rectIntersectsViewport2 = (rect, viewport) => rect.bottom > 0 && rect.right > 0 && rect.top < viewport.height && rect.left < viewport.width;
3574
3705
  var getFloatingCacheKey = (target) => {
3575
3706
  if (target.stepId) {
3576
3707
  return `step:${target.stepId}`;
@@ -3599,7 +3730,8 @@ var TourPopoverPortal = ({
3599
3730
  containerComponent,
3600
3731
  contentComponent,
3601
3732
  transitionsOverride,
3602
- isInGracePeriod = false
3733
+ isInGracePeriod = false,
3734
+ onHeightChange
3603
3735
  }) => {
3604
3736
  if (!isBrowser) return null;
3605
3737
  const host = portalHost();
@@ -3612,13 +3744,16 @@ var TourPopoverPortal = ({
3612
3744
  const popoverContentTransition = transitionsOverride?.popoverContent ?? adapter.transitions.popoverContent ?? DEFAULT_POPOVER_CONTENT_TRANSITION;
3613
3745
  const viewport = useViewportRect();
3614
3746
  const prefersMobileLayout = viewport.width <= MOBILE_BREAKPOINT || viewport.height <= MOBILE_HEIGHT_BREAKPOINT;
3747
+ const liveTargetUsable = Boolean(
3748
+ target.status === "ready" && (target.isScreen || target.rect && rectIntersectsViewport2(target.rect, viewport))
3749
+ );
3615
3750
  const prefersMobileRef = useRef12(prefersMobileLayout);
3616
3751
  useEffect17(() => {
3617
3752
  prefersMobileRef.current = prefersMobileLayout;
3618
3753
  }, [prefersMobileLayout]);
3619
3754
  const lastReadyTargetRef = useRef12(null);
3620
3755
  useEffect17(() => {
3621
- if (target.status === "ready" && target.rect) {
3756
+ if (liveTargetUsable && target.rect) {
3622
3757
  lastReadyTargetRef.current = {
3623
3758
  rect: { ...target.rect },
3624
3759
  isScreen: target.isScreen
@@ -3626,11 +3761,11 @@ var TourPopoverPortal = ({
3626
3761
  } else if (target.status === "idle" && !isInGracePeriod) {
3627
3762
  lastReadyTargetRef.current = null;
3628
3763
  }
3629
- }, [target.isScreen, target.rect, target.status, isInGracePeriod]);
3764
+ }, [target.isScreen, target.rect, target.status, isInGracePeriod, liveTargetUsable]);
3630
3765
  const cachedTarget = lastReadyTargetRef.current;
3631
- const resolvedRect = target.rect ?? target.lastResolvedRect ?? cachedTarget?.rect ?? null;
3632
- const resolvedIsScreen = target.status === "ready" ? target.isScreen : cachedTarget?.isScreen ?? target.isScreen;
3633
- const shouldHidePopover = !resolvedRect && !target.isScreen;
3766
+ const resolvedRect = liveTargetUsable ? target.rect ?? target.lastResolvedRect ?? cachedTarget?.rect ?? null : cachedTarget?.rect ?? (cachedTarget ? null : target.rect ?? target.lastResolvedRect ?? null);
3767
+ const resolvedIsScreen = liveTargetUsable ? target.isScreen : cachedTarget?.isScreen ?? target.isScreen;
3768
+ const shouldHidePopover = !resolvedRect && !resolvedIsScreen;
3634
3769
  const fallbackRect = resolvedRect ?? viewport;
3635
3770
  const fallbackIsScreen = resolvedIsScreen;
3636
3771
  const [floatingSize, setFloatingSize] = useState12(null);
@@ -3713,14 +3848,20 @@ var TourPopoverPortal = ({
3713
3848
  floatingPositionCache.set(cacheKey, floatingPosition);
3714
3849
  }
3715
3850
  }, [floatingPosition, target.isScreen, target.stepId]);
3716
- const dockedPosition = useMemo13(
3717
- () => ({
3851
+ const dockedPosition = useMemo13(() => {
3852
+ if (floatingSize) {
3853
+ return {
3854
+ top: viewport.height - DOCKED_MARGIN - floatingSize.height,
3855
+ left: viewport.width - DOCKED_MARGIN - floatingSize.width,
3856
+ transform: "translate3d(0px, 0px, 0px)"
3857
+ };
3858
+ }
3859
+ return {
3718
3860
  top: viewport.height - DOCKED_MARGIN,
3719
3861
  left: viewport.width - DOCKED_MARGIN,
3720
3862
  transform: "translate3d(-100%, -100%, 0px)"
3721
- }),
3722
- [viewport.height, viewport.width]
3723
- );
3863
+ };
3864
+ }, [viewport.height, viewport.width, floatingSize]);
3724
3865
  const mobilePosition = useMemo13(
3725
3866
  () => ({
3726
3867
  top: viewport.height - MOBILE_HORIZONTAL_GUTTER,
@@ -3734,6 +3875,10 @@ var TourPopoverPortal = ({
3734
3875
  setFloatingPosition(dockedPosition);
3735
3876
  }
3736
3877
  }, [dockedPosition, layoutMode]);
3878
+ useEffect17(() => {
3879
+ if (!onHeightChange) return;
3880
+ onHeightChange(floatingSize ? floatingSize.height + DOCKED_MARGIN : 0);
3881
+ }, [floatingSize, onHeightChange]);
3737
3882
  useEffect17(() => {
3738
3883
  if (layoutMode === "mobile") {
3739
3884
  setFloatingPosition(mobilePosition);
@@ -3833,10 +3978,11 @@ var TourPopoverPortal = ({
3833
3978
  useLayoutEffect2(() => {
3834
3979
  if (!isBrowser) return;
3835
3980
  const floatingEl = floatingRef.current;
3836
- const rectInfo = target.rect;
3981
+ const rectInfo = liveTargetUsable ? target.rect ?? target.lastResolvedRect ?? null : null;
3837
3982
  if (!floatingEl) return;
3983
+ if (!liveTargetUsable) return;
3838
3984
  if (target.status !== "ready") return;
3839
- if (!rectInfo || target.isScreen) return;
3985
+ if (!rectInfo || resolvedIsScreen) return;
3840
3986
  if (layoutMode === "mobile" || layoutMode === "manual") return;
3841
3987
  const cancelState = { cancelled: false };
3842
3988
  const retryState = overflowRetryRef.current;
@@ -3852,7 +3998,7 @@ var TourPopoverPortal = ({
3852
3998
  }
3853
3999
  };
3854
4000
  const virtualReference = {
3855
- contextElement: target.element ?? void 0,
4001
+ contextElement: liveTargetUsable ? target.element ?? void 0 : void 0,
3856
4002
  getBoundingClientRect: () => DOMRectReadOnly.fromRect({
3857
4003
  width: rectInfo.width,
3858
4004
  height: rectInfo.height,
@@ -3964,10 +4110,13 @@ var TourPopoverPortal = ({
3964
4110
  dockedPosition,
3965
4111
  isAutoPlacement,
3966
4112
  layoutMode,
4113
+ liveTargetUsable,
3967
4114
  offset,
4115
+ resolvedIsScreen,
3968
4116
  resolvedPlacement,
3969
4117
  target.element,
3970
4118
  target.isScreen,
4119
+ target.lastResolvedRect,
3971
4120
  target.lastUpdated,
3972
4121
  target.status,
3973
4122
  target.stepId
@@ -4602,6 +4751,7 @@ export {
4602
4751
  notifyRouteChange,
4603
4752
  reducedMotionAnimationAdapter,
4604
4753
  subscribeToRouteChanges,
4754
+ tweenAnimationAdapter,
4605
4755
  useAdvanceRules,
4606
4756
  useAnimationAdapter,
4607
4757
  useBodyScrollLock,
@@ -30,6 +30,7 @@ export interface AnimationAdapterProviderProps {
30
30
  export declare const AnimationAdapterProvider: ({ adapter, children, }: AnimationAdapterProviderProps) => import("react/jsx-runtime").JSX.Element;
31
31
  export declare const useAnimationAdapter: () => AnimationAdapter;
32
32
  export declare const defaultAnimationAdapter: AnimationAdapter;
33
+ export declare const tweenAnimationAdapter: AnimationAdapter;
33
34
  export declare const reducedMotionAnimationAdapter: AnimationAdapter;
34
35
  export interface UseAnimationAdapterOptions {
35
36
  defaultAdapter?: AnimationAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"animationAdapter.d.ts","sourceRoot":"","sources":["../../src/motion/animationAdapter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,OAAO,MAAM,CAAC,GAAG,CAAA;IAC5B,aAAa,EAAE,OAAO,MAAM,CAAC,OAAO,CAAA;IACpC,SAAS,EAAE,OAAO,MAAM,CAAC,GAAG,CAAA;IAC5B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,YAAY,EAAE,OAAO,MAAM,CAAC,MAAM,CAAA;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,CAAC,EAAE,UAAU,CAAA;IAC7B,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,eAAe,CAAC,EAAE,UAAU,CAAA;IAC5B,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,cAAc,CAAC,EAAE,UAAU,CAAA;IAC3B,cAAc,CAAC,EAAE,UAAU,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,0BAA0B,CAAA;IACtC,WAAW,EAAE,2BAA2B,CAAA;CACzC;AA+CD,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,eAAO,MAAM,wBAAwB,GAAI,wBAGtC,6BAA6B,4CAO/B,CAAA;AAED,eAAO,MAAM,mBAAmB,QAAO,gBAEtC,CAAA;AAED,eAAO,MAAM,uBAAuB,kBAAiB,CAAA;AAErD,eAAO,MAAM,6BAA6B,EAAE,gBA6B3C,CAAA;AAID,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,gBAAgB,CAAA;IACjC,oBAAoB,CAAC,EAAE,gBAAgB,CAAA;IACvC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,4BAA4B,GACvC,UAAU,0BAA0B,KACnC,gBA6BF,CAAA"}
1
+ {"version":3,"file":"animationAdapter.d.ts","sourceRoot":"","sources":["../../src/motion/animationAdapter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,OAAO,MAAM,CAAC,GAAG,CAAA;IAC5B,aAAa,EAAE,OAAO,MAAM,CAAC,OAAO,CAAA;IACpC,SAAS,EAAE,OAAO,MAAM,CAAC,GAAG,CAAA;IAC5B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,UAAU,EAAE,OAAO,MAAM,CAAC,IAAI,CAAA;IAC9B,YAAY,EAAE,OAAO,MAAM,CAAC,MAAM,CAAA;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,CAAC,EAAE,UAAU,CAAA;IAC7B,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,eAAe,CAAC,EAAE,UAAU,CAAA;IAC5B,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,cAAc,CAAC,EAAE,UAAU,CAAA;IAC3B,cAAc,CAAC,EAAE,UAAU,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,0BAA0B,CAAA;IACtC,WAAW,EAAE,2BAA2B,CAAA;CACzC;AA+CD,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,eAAO,MAAM,wBAAwB,GAAI,wBAGtC,6BAA6B,4CAO/B,CAAA;AAED,eAAO,MAAM,mBAAmB,QAAO,gBAEtC,CAAA;AAED,eAAO,MAAM,uBAAuB,kBAAiB,CAAA;AAErD,eAAO,MAAM,qBAAqB,EAAE,gBAcnC,CAAA;AAED,eAAO,MAAM,6BAA6B,EAAE,gBA6B3C,CAAA;AAID,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,gBAAgB,CAAA;IACjC,oBAAoB,CAAC,EAAE,gBAAgB,CAAA;IACvC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,4BAA4B,GACvC,UAAU,0BAA0B,KACnC,gBA6BF,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowsterix/react",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "React bindings for Flowsterix - guided tours and onboarding flows",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -73,7 +73,7 @@
73
73
  "@dnd-kit/sortable": "^10.0.0",
74
74
  "@dnd-kit/utilities": "^3.2.2",
75
75
  "@floating-ui/dom": "^1.7.4",
76
- "@flowsterix/core": "0.10.0"
76
+ "@flowsterix/core": "0.10.1"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "react": ">=18",
@@ -1,21 +0,0 @@
1
- // src/devtools/DevToolsContext.tsx
2
- import { createContext, useContext } from "react";
3
- var DevToolsContext = createContext(null);
4
- function useDevToolsContext() {
5
- return useContext(DevToolsContext);
6
- }
7
- function useDevToolsContextRequired() {
8
- const context = useContext(DevToolsContext);
9
- if (!context) {
10
- throw new Error(
11
- "useDevToolsContext must be used within a TourProvider with devtools enabled"
12
- );
13
- }
14
- return context;
15
- }
16
-
17
- export {
18
- DevToolsContext,
19
- useDevToolsContext,
20
- useDevToolsContextRequired
21
- };
@@ -1,21 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/devtools/DevToolsContext.tsx
2
- var _react = require('react');
3
- var DevToolsContext = _react.createContext.call(void 0, null);
4
- function useDevToolsContext() {
5
- return _react.useContext.call(void 0, DevToolsContext);
6
- }
7
- function useDevToolsContextRequired() {
8
- const context = _react.useContext.call(void 0, DevToolsContext);
9
- if (!context) {
10
- throw new Error(
11
- "useDevToolsContext must be used within a TourProvider with devtools enabled"
12
- );
13
- }
14
- return context;
15
- }
16
-
17
-
18
-
19
-
20
-
21
- exports.DevToolsContext = DevToolsContext; exports.useDevToolsContext = useDevToolsContext; exports.useDevToolsContextRequired = useDevToolsContextRequired;