@ionic/react-router 9.0.6-nightly.20260930 → 9.0.7-dev.11790792026.1963eab3
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 +61 -17
- package/dist/index.js.map +1 -1
- package/dist/types/ReactRouter/IonReactMemoryRouter.d.ts +1 -1
- package/dist/types/ReactRouter/IonRouter.d.ts +1 -2
- package/dist/types/ReactRouter/utils/pathMatching.d.ts +1 -1
- package/dist/types/ReactRouter/utils/transitionDefaults.d.ts +10 -0
- package/package.json +16 -8
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useRef, useState, useEffect, useCallback } from 'react';
|
|
2
|
-
import { Route, matchPath as matchPath$1, Routes, Navigate, UNSAFE_RouteContext, matchRoutes, useLocation, useNavigate, BrowserRouter, useNavigationType, HashRouter } from 'react-router-dom';
|
|
2
|
+
import { Route, matchPath as matchPath$1, Routes, Navigate, UNSAFE_RouteContext, matchRoutes, useLocation, useNavigate, BrowserRouter, useNavigationType, MemoryRouter, HashRouter } from 'react-router-dom';
|
|
3
3
|
import { IonRoute, ViewStacks, generateId, ViewLifeCycleManager, createDebugLogger, StackContext, RouteManagerContext, getConfig, LocationHistory, NavManager } from '@ionic/react';
|
|
4
|
-
import {
|
|
4
|
+
import { LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_DID_ENTER } from '@ionic/core/components';
|
|
5
5
|
|
|
6
6
|
const IonRouteInner = ({ path, index, caseSensitive, element }) => {
|
|
7
7
|
return React.createElement(Route, { path: path, index: index, caseSensitive: caseSensitive, element: element });
|
|
@@ -621,14 +621,16 @@ const getFallbackParamsFromViewItems = (allViewItems, currentOutletId, currentPa
|
|
|
621
621
|
return params;
|
|
622
622
|
};
|
|
623
623
|
/**
|
|
624
|
-
* Builds the matches array for RouteContext.
|
|
624
|
+
* Builds the matches array for RouteContext. The leaf `pathname` uses the absolute base,
|
|
625
|
+
* because the raw match is relative for a route without a leading slash, which breaks
|
|
626
|
+
* relative links, and includes a splat's tail, which loops an index `<Navigate>`.
|
|
625
627
|
*/
|
|
626
|
-
const buildContextMatches = (parentMatches, combinedParams,
|
|
628
|
+
const buildContextMatches = (parentMatches, combinedParams, absolutePathnameBase, viewItem, routeElement, componentElement) => {
|
|
627
629
|
return [
|
|
628
630
|
...parentMatches,
|
|
629
631
|
{
|
|
630
632
|
params: combinedParams,
|
|
631
|
-
pathname:
|
|
633
|
+
pathname: absolutePathnameBase,
|
|
632
634
|
pathnameBase: absolutePathnameBase,
|
|
633
635
|
route: {
|
|
634
636
|
id: viewItem.id,
|
|
@@ -981,7 +983,7 @@ class ReactRouterViewStack extends ViewStacks {
|
|
|
981
983
|
const combinedParams = { ...accumulatedParentParams, ...(routeMatch?.params ?? {}) };
|
|
982
984
|
const parentPathnameBase = parentMatches.length > 0 ? parentMatches[parentMatches.length - 1].pathnameBase : '/';
|
|
983
985
|
const absolutePathnameBase = computeAbsolutePathnameBase(routeElement, routeMatch, parentPathnameBase, routeInfo.pathname);
|
|
984
|
-
const contextMatches = buildContextMatches(parentMatches, combinedParams,
|
|
986
|
+
const contextMatches = buildContextMatches(parentMatches, combinedParams, absolutePathnameBase, viewItem, routeElement, componentElement);
|
|
985
987
|
const routeContextValue = parentContext
|
|
986
988
|
? { ...parentContext, matches: contextMatches }
|
|
987
989
|
: { outlet: null, matches: contextMatches, isDataRoute: false };
|
|
@@ -1452,6 +1454,12 @@ const revealIonPageForSwipeBack = (element) => {
|
|
|
1452
1454
|
element.removeAttribute('aria-hidden');
|
|
1453
1455
|
}
|
|
1454
1456
|
};
|
|
1457
|
+
/** Dispatches a view lifecycle event the way core's `lifecycle()` does. */
|
|
1458
|
+
const dispatchLifecycleEvent = (element, eventName) => {
|
|
1459
|
+
if (element) {
|
|
1460
|
+
element.dispatchEvent(new CustomEvent(eventName, { bubbles: false, cancelable: false }));
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1455
1463
|
/**
|
|
1456
1464
|
* A leaf view is "preservable" on browser-back (pop) when its React state
|
|
1457
1465
|
* should survive a forward-pop round-trip. Non-parameterized leaf paths
|
|
@@ -1688,8 +1696,8 @@ class StackManager extends React.PureComponent {
|
|
|
1688
1696
|
const allViewsInOutlet = this.context.getViewItemsForOutlet(this.id);
|
|
1689
1697
|
allViewsInOutlet.forEach((viewItem) => {
|
|
1690
1698
|
if (viewItem.ionPageElement && isViewVisible(viewItem.ionPageElement)) {
|
|
1691
|
-
viewItem.ionPageElement
|
|
1692
|
-
viewItem.ionPageElement
|
|
1699
|
+
dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_WILL_LEAVE);
|
|
1700
|
+
dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_DID_LEAVE);
|
|
1693
1701
|
}
|
|
1694
1702
|
});
|
|
1695
1703
|
// Defer removal of view items to allow the parent outlet's leaving-page
|
|
@@ -1724,8 +1732,8 @@ class StackManager extends React.PureComponent {
|
|
|
1724
1732
|
return;
|
|
1725
1733
|
}
|
|
1726
1734
|
if (viewItem.ionPageElement && isViewVisible(viewItem.ionPageElement)) {
|
|
1727
|
-
viewItem.ionPageElement
|
|
1728
|
-
viewItem.ionPageElement
|
|
1735
|
+
dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_WILL_LEAVE);
|
|
1736
|
+
dispatchLifecycleEvent(viewItem.ionPageElement, LIFECYCLE_DID_LEAVE);
|
|
1729
1737
|
}
|
|
1730
1738
|
this.context.unMountViewItem(viewItem);
|
|
1731
1739
|
});
|
|
@@ -2856,10 +2864,34 @@ class StackManager extends React.PureComponent {
|
|
|
2856
2864
|
// Bail out if the component unmounted during waitForComponentsReady
|
|
2857
2865
|
if (!this._isMounted)
|
|
2858
2866
|
return;
|
|
2867
|
+
const isCurrent = myGeneration === this.transitionGeneration;
|
|
2868
|
+
// A page the newest transition is entering is not leaving after all.
|
|
2869
|
+
const isLeaving = isCurrent || leavingEl !== this.transitionEnteringElement;
|
|
2870
|
+
// Already hidden means the leave events have fired. This checks the class rather
|
|
2871
|
+
// than `isViewVisible` because a nested outlet marks its leaving page
|
|
2872
|
+
// `visibility: hidden` before we get here and still needs `ionViewDidLeave`.
|
|
2873
|
+
const announceLeaving = isLeaving && !leavingEl.classList.contains('ion-page-hidden');
|
|
2874
|
+
/**
|
|
2875
|
+
* Dispatch the lifecycle events, since we skipped `commit()`. Only the
|
|
2876
|
+
* newest transition fires the entering events, and the class swap follows
|
|
2877
|
+
* all four so the ordering matches core's `transition()`.
|
|
2878
|
+
*
|
|
2879
|
+
* These run after `waitForComponentsReady` because on a first mount the
|
|
2880
|
+
* page has not attached its listeners yet.
|
|
2881
|
+
*/
|
|
2882
|
+
if (announceLeaving) {
|
|
2883
|
+
dispatchLifecycleEvent(leavingEl, LIFECYCLE_WILL_LEAVE);
|
|
2884
|
+
}
|
|
2885
|
+
if (isCurrent) {
|
|
2886
|
+
dispatchLifecycleEvent(enteringEl, LIFECYCLE_WILL_ENTER);
|
|
2887
|
+
dispatchLifecycleEvent(enteringEl, LIFECYCLE_DID_ENTER);
|
|
2888
|
+
}
|
|
2889
|
+
if (announceLeaving) {
|
|
2890
|
+
dispatchLifecycleEvent(leavingEl, LIFECYCLE_DID_LEAVE);
|
|
2891
|
+
}
|
|
2859
2892
|
// Swap visibility synchronously - show entering, hide leaving
|
|
2860
|
-
// Skip hiding if a newer transition already made leavingEl the entering view
|
|
2861
2893
|
enteringEl.classList.remove('ion-page-invisible');
|
|
2862
|
-
if (
|
|
2894
|
+
if (isLeaving) {
|
|
2863
2895
|
leavingEl.classList.add('ion-page-hidden');
|
|
2864
2896
|
leavingEl.setAttribute('aria-hidden', 'true');
|
|
2865
2897
|
}
|
|
@@ -3677,6 +3709,18 @@ const IonRouter = ({ children, registerHistoryListener }) => {
|
|
|
3677
3709
|
};
|
|
3678
3710
|
IonRouter.displayName = 'IonRouter';
|
|
3679
3711
|
|
|
3712
|
+
/**
|
|
3713
|
+
* Defaults React Router 7's `useTransitions` to `false`, since a transition can defer the
|
|
3714
|
+
* commit past Ionic's page-visible signal. React Router 6 ignores the prop.
|
|
3715
|
+
*
|
|
3716
|
+
* Uses `??` instead of spreading a default first, because an explicit
|
|
3717
|
+
* `useTransitions={undefined}` would override it and React Router reads that as on.
|
|
3718
|
+
*/
|
|
3719
|
+
const withTransitionDefaults = (props) => {
|
|
3720
|
+
const { useTransitions } = props;
|
|
3721
|
+
return { ...props, useTransitions: useTransitions ?? false };
|
|
3722
|
+
};
|
|
3723
|
+
|
|
3680
3724
|
/**
|
|
3681
3725
|
* `IonReactRouter` facilitates the integration of Ionic's specific
|
|
3682
3726
|
* navigation and UI management with the standard React Router mechanisms,
|
|
@@ -3721,7 +3765,7 @@ const RouterContent$2 = ({ children }) => {
|
|
|
3721
3765
|
return React.createElement(IonRouter, { registerHistoryListener: registerHistoryListener }, children);
|
|
3722
3766
|
};
|
|
3723
3767
|
const IonReactRouter = ({ children, ...browserRouterProps }) => {
|
|
3724
|
-
return (React.createElement(BrowserRouter, { ...browserRouterProps },
|
|
3768
|
+
return (React.createElement(BrowserRouter, { ...withTransitionDefaults(browserRouterProps) },
|
|
3725
3769
|
React.createElement(RouterContent$2, null, children)));
|
|
3726
3770
|
};
|
|
3727
3771
|
|
|
@@ -3731,8 +3775,8 @@ const IonReactRouter = ({ children, ...browserRouterProps }) => {
|
|
|
3731
3775
|
* isn't available or desirable.
|
|
3732
3776
|
*/
|
|
3733
3777
|
const RouterContent$1 = ({ children }) => {
|
|
3734
|
-
const location = useLocation
|
|
3735
|
-
const navigationType = useNavigationType
|
|
3778
|
+
const location = useLocation();
|
|
3779
|
+
const navigationType = useNavigationType();
|
|
3736
3780
|
const historyListenHandler = useRef();
|
|
3737
3781
|
const registerHistoryListener = useCallback((cb) => {
|
|
3738
3782
|
historyListenHandler.current = cb;
|
|
@@ -3760,7 +3804,7 @@ const RouterContent$1 = ({ children }) => {
|
|
|
3760
3804
|
return React.createElement(IonRouter, { registerHistoryListener: registerHistoryListener }, children);
|
|
3761
3805
|
};
|
|
3762
3806
|
const IonReactMemoryRouter = ({ children, ...routerProps }) => {
|
|
3763
|
-
return (React.createElement(MemoryRouter, { ...routerProps },
|
|
3807
|
+
return (React.createElement(MemoryRouter, { ...withTransitionDefaults(routerProps) },
|
|
3764
3808
|
React.createElement(RouterContent$1, null, children)));
|
|
3765
3809
|
};
|
|
3766
3810
|
|
|
@@ -3798,7 +3842,7 @@ const RouterContent = ({ children }) => {
|
|
|
3798
3842
|
return React.createElement(IonRouter, { registerHistoryListener: registerHistoryListener }, children);
|
|
3799
3843
|
};
|
|
3800
3844
|
const IonReactHashRouter = ({ children, ...routerProps }) => {
|
|
3801
|
-
return (React.createElement(HashRouter, { ...routerProps },
|
|
3845
|
+
return (React.createElement(HashRouter, { ...withTransitionDefaults(routerProps) },
|
|
3802
3846
|
React.createElement(RouterContent, null, children)));
|
|
3803
3847
|
};
|
|
3804
3848
|
|