@appfunnel-dev/sdk 2.0.0-canary.0 → 2.0.0-canary.1

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.cts CHANGED
@@ -1243,6 +1243,14 @@ interface NavigationState {
1243
1243
  */
1244
1244
  nextCandidates: string[];
1245
1245
  canGoBack: boolean;
1246
+ /**
1247
+ * True while a navigation's target page chunk is still resolving (a cold,
1248
+ * un-prefetched lazy chunk). The current page stays on screen during this window
1249
+ * (no Suspense-fallback flicker); read this to show a subtle "working" affordance
1250
+ * so a tapped button doesn't feel dead. Usually false/instant when the next chunk
1251
+ * was prefetched.
1252
+ */
1253
+ isNavigating: boolean;
1246
1254
  }
1247
1255
  /**
1248
1256
  * `const variant = useExperiment('welcome-headline')` — the variant key this
package/dist/index.d.ts CHANGED
@@ -1243,6 +1243,14 @@ interface NavigationState {
1243
1243
  */
1244
1244
  nextCandidates: string[];
1245
1245
  canGoBack: boolean;
1246
+ /**
1247
+ * True while a navigation's target page chunk is still resolving (a cold,
1248
+ * un-prefetched lazy chunk). The current page stays on screen during this window
1249
+ * (no Suspense-fallback flicker); read this to show a subtle "working" affordance
1250
+ * so a tapped button doesn't feel dead. Usually false/instant when the next chunk
1251
+ * was prefetched.
1252
+ */
1253
+ isNavigating: boolean;
1246
1254
  }
1247
1255
  /**
1248
1256
  * `const variant = useExperiment('welcome-headline')` — the variant key this
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, createElement, useCallback, useContext, useMemo, lazy, useState, useRef, useEffect, Suspense, Fragment, isValidElement, cloneElement, useReducer, useSyncExternalStore } from 'react';
1
+ import { createContext, createElement, useCallback, useContext, useMemo, lazy, useState, useRef, useEffect, useTransition, Suspense, Fragment, isValidElement, cloneElement, useReducer, useSyncExternalStore } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
  import { Toaster } from 'sonner';
4
4
  export { toast } from 'sonner';
@@ -959,17 +959,18 @@ function FunnelView({
959
959
  timer.current = { key: currentKey, enteredAt: now(), hidden: 0, hiddenSince: hidden ? now() : null };
960
960
  }, [currentKey, emitExit]);
961
961
  useEffect(() => () => emitExit(), [emitExit]);
962
+ const [isNavigating, startNav] = useTransition();
962
963
  const next = useCallback(() => {
963
964
  const target = nextPage(flow, currentKey, funnel.snapshot());
964
965
  const resolved = target ? experiments.slotOf[target] ?? target : target;
965
- if (resolved) setHistory((h) => [...h, resolved]);
966
+ if (resolved) startNav(() => setHistory((h) => [...h, resolved]));
966
967
  }, [flow, currentKey, funnel, experiments]);
967
968
  const back = useCallback(
968
- () => setHistory((h) => h.length > 1 ? h.slice(0, -1) : h),
969
+ () => startNav(() => setHistory((h) => h.length > 1 ? h.slice(0, -1) : h)),
969
970
  []
970
971
  );
971
972
  const go = useCallback(
972
- (key) => setHistory((h) => [...h, experiments.slotOf[key] ?? key]),
973
+ (key) => startNav(() => setHistory((h) => [...h, experiments.slotOf[key] ?? key])),
973
974
  [experiments]
974
975
  );
975
976
  const prefetched = useRef(/* @__PURE__ */ new Set());
@@ -998,7 +999,8 @@ function FunnelView({
998
999
  go,
999
1000
  prefetch,
1000
1001
  nextCandidates,
1001
- canGoBack: history.length > 1
1002
+ canGoBack: history.length > 1,
1003
+ isNavigating
1002
1004
  };
1003
1005
  const renderKey = experiments.render[currentKey] ?? currentKey;
1004
1006
  const Current = components.get(renderKey);