@ionic/react-router 8.8.1-dev.11774384072.1e807ca8 → 8.8.1-dev.11774636992.1511ce70
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.js +40 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1406,6 +1406,12 @@ class StackManager extends React.PureComponent {
|
|
|
1406
1406
|
this._isMounted = false;
|
|
1407
1407
|
/** In-flight requestAnimationFrame IDs from transitionPage, cancelled on unmount. */
|
|
1408
1408
|
this.transitionRafIds = [];
|
|
1409
|
+
/**
|
|
1410
|
+
* Monotonically increasing counter incremented at the start of each transitionPage call.
|
|
1411
|
+
* Used to detect when an async commit() resolves after a newer transition has already run,
|
|
1412
|
+
* preventing the stale commit from hiding an element that the newer transition made visible.
|
|
1413
|
+
*/
|
|
1414
|
+
this.transitionGeneration = 0;
|
|
1409
1415
|
this.outletMountPath = undefined;
|
|
1410
1416
|
/**
|
|
1411
1417
|
* Whether this outlet is at the root level (no parent route matches).
|
|
@@ -1993,7 +1999,15 @@ class StackManager extends React.PureComponent {
|
|
|
1993
1999
|
this._isMounted = true;
|
|
1994
2000
|
if (this.routerOutletElement) {
|
|
1995
2001
|
this.setupRouterOutlet(this.routerOutletElement);
|
|
1996
|
-
|
|
2002
|
+
// Defer to a microtask to avoid calling forceUpdate() synchronously during
|
|
2003
|
+
// React 19's reappearLayoutEffects phase, which re-runs componentDidMount
|
|
2004
|
+
// without a preceding componentWillUnmount and causes "Maximum update depth exceeded".
|
|
2005
|
+
const routeInfo = this.props.routeInfo;
|
|
2006
|
+
queueMicrotask(() => {
|
|
2007
|
+
if (this._isMounted && this.props.routeInfo.pathname === routeInfo.pathname) {
|
|
2008
|
+
this.handlePageTransition(routeInfo);
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
1997
2011
|
}
|
|
1998
2012
|
}
|
|
1999
2013
|
componentDidUpdate(prevProps) {
|
|
@@ -2326,6 +2340,7 @@ class StackManager extends React.PureComponent {
|
|
|
2326
2340
|
* overlapping content during the transition. Defaults to `false`.
|
|
2327
2341
|
*/
|
|
2328
2342
|
async transitionPage(routeInfo, enteringViewItem, leavingViewItem, direction, progressAnimation = false, skipAnimation = false) {
|
|
2343
|
+
const myGeneration = ++this.transitionGeneration;
|
|
2329
2344
|
const runCommit = async (enteringEl, leavingEl) => {
|
|
2330
2345
|
const skipTransition = this.skipTransition;
|
|
2331
2346
|
/**
|
|
@@ -2375,10 +2390,22 @@ class StackManager extends React.PureComponent {
|
|
|
2375
2390
|
const timeoutMs = 5000;
|
|
2376
2391
|
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve('timeout'), timeoutMs));
|
|
2377
2392
|
const result = await Promise.race([commitPromise.then(() => 'done'), timeoutPromise]);
|
|
2393
|
+
// Bail out if the component unmounted during the commit animation
|
|
2394
|
+
if (!this._isMounted)
|
|
2395
|
+
return;
|
|
2378
2396
|
if (result === 'timeout') {
|
|
2379
2397
|
// Force entering page visible even though commit hung
|
|
2380
2398
|
enteringEl.classList.remove('ion-page-invisible');
|
|
2381
2399
|
}
|
|
2400
|
+
/**
|
|
2401
|
+
* If a newer transitionPage call ran while this commit was in-flight (e.g., a tab
|
|
2402
|
+
* switch fired during a forward animation), the core commit may have applied
|
|
2403
|
+
* ion-page-hidden to leavingEl even though the newer transition already made it
|
|
2404
|
+
* visible. Undo that stale hide so the newer transition's DOM state wins.
|
|
2405
|
+
*/
|
|
2406
|
+
if (myGeneration !== this.transitionGeneration && leavingEl && leavingEl === this.transitionEnteringElement) {
|
|
2407
|
+
showIonPageElement(leavingEl);
|
|
2408
|
+
}
|
|
2382
2409
|
if (!progressAnimation) {
|
|
2383
2410
|
enteringEl.classList.remove('ion-page-invisible');
|
|
2384
2411
|
}
|
|
@@ -2387,6 +2414,7 @@ class StackManager extends React.PureComponent {
|
|
|
2387
2414
|
const routeInfoFallbackDirection = routeInfo.routeDirection === 'none' || routeInfo.routeDirection === 'root' ? undefined : routeInfo.routeDirection;
|
|
2388
2415
|
const directionToUse = direction !== null && direction !== void 0 ? direction : routeInfoFallbackDirection;
|
|
2389
2416
|
if (enteringViewItem && enteringViewItem.ionPageElement && this.routerOutletElement) {
|
|
2417
|
+
this.transitionEnteringElement = enteringViewItem.ionPageElement;
|
|
2390
2418
|
if (leavingViewItem && leavingViewItem.ionPageElement && enteringViewItem === leavingViewItem) {
|
|
2391
2419
|
// Clone page for same-view transitions (e.g., /user/1 → /user/2)
|
|
2392
2420
|
const match = matchComponent(leavingViewItem.reactElement, routeInfo.pathname, undefined, this.outletMountPath);
|
|
@@ -2487,15 +2515,22 @@ class StackManager extends React.PureComponent {
|
|
|
2487
2515
|
if (!this._isMounted)
|
|
2488
2516
|
return;
|
|
2489
2517
|
// Swap visibility synchronously - show entering, hide leaving
|
|
2518
|
+
// Skip hiding if a newer transition already made leavingEl the entering view
|
|
2490
2519
|
enteringEl.classList.remove('ion-page-invisible');
|
|
2491
|
-
leavingEl.
|
|
2492
|
-
|
|
2520
|
+
if (myGeneration === this.transitionGeneration || leavingEl !== this.transitionEnteringElement) {
|
|
2521
|
+
leavingEl.classList.add('ion-page-hidden');
|
|
2522
|
+
leavingEl.setAttribute('aria-hidden', 'true');
|
|
2523
|
+
}
|
|
2493
2524
|
}
|
|
2494
2525
|
else {
|
|
2495
2526
|
await runCommit(enteringViewItem.ionPageElement, leavingEl);
|
|
2496
2527
|
if (leavingEl && !progressAnimation) {
|
|
2497
|
-
leavingEl
|
|
2498
|
-
|
|
2528
|
+
// Skip hiding if a newer transition already made leavingEl the entering view
|
|
2529
|
+
// runCommit's generation check has already restored its visibility in that case
|
|
2530
|
+
if (myGeneration === this.transitionGeneration || leavingEl !== this.transitionEnteringElement) {
|
|
2531
|
+
leavingEl.classList.add('ion-page-hidden');
|
|
2532
|
+
leavingEl.setAttribute('aria-hidden', 'true');
|
|
2533
|
+
}
|
|
2499
2534
|
}
|
|
2500
2535
|
}
|
|
2501
2536
|
}
|