@ionic/react-router 9.0.6-nightly.20260929 → 9.0.6

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 CHANGED
@@ -1,6 +1,7 @@
1
1
  import React, { useRef, useState, useEffect, useCallback } from 'react';
2
2
  import { Route, matchPath as matchPath$1, Routes, Navigate, UNSAFE_RouteContext, matchRoutes, useLocation, useNavigate, BrowserRouter, useNavigationType, HashRouter } from 'react-router-dom';
3
3
  import { IonRoute, ViewStacks, generateId, ViewLifeCycleManager, createDebugLogger, StackContext, RouteManagerContext, getConfig, LocationHistory, NavManager } from '@ionic/react';
4
+ import { LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_DID_ENTER } from '@ionic/core/components';
4
5
  import { MemoryRouter, useLocation as useLocation$1, useNavigationType as useNavigationType$1 } from 'react-router';
5
6
 
6
7
  const IonRouteInner = ({ path, index, caseSensitive, element }) => {
@@ -1452,6 +1453,12 @@ const revealIonPageForSwipeBack = (element) => {
1452
1453
  element.removeAttribute('aria-hidden');
1453
1454
  }
1454
1455
  };
1456
+ /** Dispatches a view lifecycle event the way core's `lifecycle()` does. */
1457
+ const dispatchLifecycleEvent = (element, eventName) => {
1458
+ if (element) {
1459
+ element.dispatchEvent(new CustomEvent(eventName, { bubbles: false, cancelable: false }));
1460
+ }
1461
+ };
1455
1462
  /**
1456
1463
  * A leaf view is "preservable" on browser-back (pop) when its React state
1457
1464
  * should survive a forward-pop round-trip. Non-parameterized leaf paths
@@ -1688,8 +1695,8 @@ class StackManager extends React.PureComponent {
1688
1695
  const allViewsInOutlet = this.context.getViewItemsForOutlet(this.id);
1689
1696
  allViewsInOutlet.forEach((viewItem) => {
1690
1697
  if (viewItem.ionPageElement && isViewVisible(viewItem.ionPageElement)) {
1691
- viewItem.ionPageElement.dispatchEvent(new CustomEvent('ionViewWillLeave', { bubbles: false, cancelable: false }));
1692
- viewItem.ionPageElement.dispatchEvent(new CustomEvent('ionViewDidLeave', { bubbles: false, cancelable: false }));
1698
+ dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_WILL_LEAVE);
1699
+ dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_DID_LEAVE);
1693
1700
  }
1694
1701
  });
1695
1702
  // Defer removal of view items to allow the parent outlet's leaving-page
@@ -1724,8 +1731,8 @@ class StackManager extends React.PureComponent {
1724
1731
  return;
1725
1732
  }
1726
1733
  if (viewItem.ionPageElement && isViewVisible(viewItem.ionPageElement)) {
1727
- viewItem.ionPageElement.dispatchEvent(new CustomEvent('ionViewWillLeave', { bubbles: false, cancelable: false }));
1728
- viewItem.ionPageElement.dispatchEvent(new CustomEvent('ionViewDidLeave', { bubbles: false, cancelable: false }));
1734
+ dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_WILL_LEAVE);
1735
+ dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_DID_LEAVE);
1729
1736
  }
1730
1737
  this.context.unMountViewItem(viewItem);
1731
1738
  });
@@ -2856,10 +2863,34 @@ class StackManager extends React.PureComponent {
2856
2863
  // Bail out if the component unmounted during waitForComponentsReady
2857
2864
  if (!this._isMounted)
2858
2865
  return;
2866
+ const isCurrent = myGeneration === this.transitionGeneration;
2867
+ // A page the newest transition is entering is not leaving after all.
2868
+ const isLeaving = isCurrent || leavingEl !== this.transitionEnteringElement;
2869
+ // Already hidden means the leave events have fired. This checks the class rather
2870
+ // than `isViewVisible` because a nested outlet marks its leaving page
2871
+ // `visibility: hidden` before we get here and still needs `ionViewDidLeave`.
2872
+ const announceLeaving = isLeaving && !leavingEl.classList.contains('ion-page-hidden');
2873
+ /**
2874
+ * Dispatch the lifecycle events, since we skipped `commit()`. Only the
2875
+ * newest transition fires the entering events, and the class swap follows
2876
+ * all four so the ordering matches core's `transition()`.
2877
+ *
2878
+ * These run after `waitForComponentsReady` because on a first mount the
2879
+ * page has not attached its listeners yet.
2880
+ */
2881
+ if (announceLeaving) {
2882
+ dispatchLifecycleEvent(leavingEl, LIFECYCLE_WILL_LEAVE);
2883
+ }
2884
+ if (isCurrent) {
2885
+ dispatchLifecycleEvent(enteringEl, LIFECYCLE_WILL_ENTER);
2886
+ dispatchLifecycleEvent(enteringEl, LIFECYCLE_DID_ENTER);
2887
+ }
2888
+ if (announceLeaving) {
2889
+ dispatchLifecycleEvent(leavingEl, LIFECYCLE_DID_LEAVE);
2890
+ }
2859
2891
  // Swap visibility synchronously - show entering, hide leaving
2860
- // Skip hiding if a newer transition already made leavingEl the entering view
2861
2892
  enteringEl.classList.remove('ion-page-invisible');
2862
- if (myGeneration === this.transitionGeneration || leavingEl !== this.transitionEnteringElement) {
2893
+ if (isLeaving) {
2863
2894
  leavingEl.classList.add('ion-page-hidden');
2864
2895
  leavingEl.setAttribute('aria-hidden', 'true');
2865
2896
  }