@ionic/react-router 8.7.12-dev.11765307927.1f491e92 → 8.7.12-dev.11765377112.16762e5b
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 +50 -104
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -13,10 +13,13 @@ const IonRouteInner = ({ path, element }) => {
|
|
|
13
13
|
* @see https://reactrouter.com/v6/utils/match-path
|
|
14
14
|
*/
|
|
15
15
|
const matchPath = ({ pathname, componentProps }) => {
|
|
16
|
-
var _a, _b;
|
|
17
16
|
const { path, index } = componentProps, restProps = __rest(componentProps, ["path", "index"]);
|
|
18
|
-
// Handle index routes
|
|
17
|
+
// Handle index routes
|
|
19
18
|
if (index && !path) {
|
|
19
|
+
// Index routes match when there's no additional path after the parent route
|
|
20
|
+
// For example, in a nested outlet at /routing/*, the index route matches
|
|
21
|
+
// when the relative path is empty (i.e., we're exactly at /routing)
|
|
22
|
+
// If pathname is empty or just "/", it should match the index route
|
|
20
23
|
if (pathname === '' || pathname === '/') {
|
|
21
24
|
return {
|
|
22
25
|
params: {},
|
|
@@ -29,25 +32,14 @@ const matchPath = ({ pathname, componentProps }) => {
|
|
|
29
32
|
},
|
|
30
33
|
};
|
|
31
34
|
}
|
|
35
|
+
// Otherwise, index routes don't match when there's additional path
|
|
32
36
|
return null;
|
|
33
37
|
}
|
|
34
|
-
|
|
35
|
-
if (path === '' || path === undefined) {
|
|
36
|
-
if (pathname === '' || pathname === '/') {
|
|
37
|
-
return {
|
|
38
|
-
params: {},
|
|
39
|
-
pathname: pathname,
|
|
40
|
-
pathnameBase: pathname || '/',
|
|
41
|
-
pattern: {
|
|
42
|
-
path: '',
|
|
43
|
-
caseSensitive: (_a = restProps.caseSensitive) !== null && _a !== void 0 ? _a : false,
|
|
44
|
-
end: (_b = restProps.end) !== null && _b !== void 0 ? _b : true,
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
38
|
+
if (!path) {
|
|
48
39
|
return null;
|
|
49
40
|
}
|
|
50
|
-
// For relative paths (don't start with '/'),
|
|
41
|
+
// For relative paths in nested routes (those that don't start with '/'),
|
|
42
|
+
// use React Router's matcher against a normalized path.
|
|
51
43
|
if (!path.startsWith('/')) {
|
|
52
44
|
const matchOptions = Object.assign({ path: `/${path}` }, restProps);
|
|
53
45
|
if ((matchOptions === null || matchOptions === void 0 ? void 0 : matchOptions.end) === undefined) {
|
|
@@ -59,6 +51,7 @@ const matchPath = ({ pathname, componentProps }) => {
|
|
|
59
51
|
// Adjust the match to remove the leading '/' we added
|
|
60
52
|
return Object.assign(Object.assign({}, match), { pathname: pathname, pathnameBase: match.pathnameBase === '/' ? '' : match.pathnameBase.slice(1), pattern: Object.assign(Object.assign({}, match.pattern), { path: path }) });
|
|
61
53
|
}
|
|
54
|
+
// No match found
|
|
62
55
|
return null;
|
|
63
56
|
}
|
|
64
57
|
// For absolute paths, use React Router's matcher directly.
|
|
@@ -78,16 +71,12 @@ const matchPath = ({ pathname, componentProps }) => {
|
|
|
78
71
|
*/
|
|
79
72
|
const derivePathnameToMatch = (fullPathname, routePath) => {
|
|
80
73
|
var _a;
|
|
81
|
-
// For absolute or empty routes, use the full pathname as-is
|
|
82
74
|
if (!routePath || routePath === '' || routePath.startsWith('/')) {
|
|
83
75
|
return fullPathname;
|
|
84
76
|
}
|
|
85
77
|
const trimmedPath = fullPathname.startsWith('/') ? fullPathname.slice(1) : fullPathname;
|
|
86
78
|
if (!trimmedPath) {
|
|
87
|
-
|
|
88
|
-
// return the full pathname so matchPath can normalize both.
|
|
89
|
-
// This allows routes like <Route path="foo/*" .../> at root level to work correctly.
|
|
90
|
-
return fullPathname;
|
|
79
|
+
return '';
|
|
91
80
|
}
|
|
92
81
|
const fullSegments = trimmedPath.split('/').filter(Boolean);
|
|
93
82
|
if (fullSegments.length === 0) {
|
|
@@ -815,9 +804,7 @@ class ReactRouterViewStack extends ViewStacks {
|
|
|
815
804
|
let parentPath = undefined;
|
|
816
805
|
try {
|
|
817
806
|
// Only attempt parent path computation for non-root outlets
|
|
818
|
-
|
|
819
|
-
const isRootOutlet = outletId.startsWith('routerOutlet');
|
|
820
|
-
if (!isRootOutlet) {
|
|
807
|
+
if (outletId !== 'routerOutlet') {
|
|
821
808
|
const routeChildren = extractRouteChildren(ionRouterOutlet.props.children);
|
|
822
809
|
const { hasRelativeRoutes, hasIndexRoute, hasWildcardRoute } = analyzeRouteChildren(routeChildren);
|
|
823
810
|
if (hasRelativeRoutes || hasIndexRoute) {
|
|
@@ -1059,7 +1046,7 @@ class ReactRouterViewStack extends ViewStacks {
|
|
|
1059
1046
|
* Matches a view with no path prop (default fallback route) or index route.
|
|
1060
1047
|
*/
|
|
1061
1048
|
function matchDefaultRoute(v) {
|
|
1062
|
-
var _a
|
|
1049
|
+
var _a;
|
|
1063
1050
|
const childProps = v.routeData.childProps;
|
|
1064
1051
|
const isDefaultRoute = childProps.path === undefined || childProps.path === '';
|
|
1065
1052
|
const isIndexRoute = !!childProps.index;
|
|
@@ -1072,22 +1059,14 @@ class ReactRouterViewStack extends ViewStacks {
|
|
|
1072
1059
|
}
|
|
1073
1060
|
return false;
|
|
1074
1061
|
}
|
|
1075
|
-
// For empty path routes, only match if we're at the same level as when the view was created.
|
|
1076
|
-
// This prevents an empty path view item from being reused for different routes.
|
|
1077
1062
|
if (isDefaultRoute) {
|
|
1078
|
-
const previousPathnameBase = ((_b = (_a = v.routeData) === null || _a === void 0 ? void 0 : _a.match) === null || _b === void 0 ? void 0 : _b.pathnameBase) || '';
|
|
1079
|
-
const normalizedBase = normalizePathnameForComparison(previousPathnameBase);
|
|
1080
|
-
const normalizedPathname = normalizePathnameForComparison(pathname);
|
|
1081
|
-
if (normalizedPathname !== normalizedBase) {
|
|
1082
|
-
return false;
|
|
1083
|
-
}
|
|
1084
1063
|
match = {
|
|
1085
1064
|
params: {},
|
|
1086
1065
|
pathname,
|
|
1087
1066
|
pathnameBase: pathname === '' ? '/' : pathname,
|
|
1088
1067
|
pattern: {
|
|
1089
1068
|
path: '',
|
|
1090
|
-
caseSensitive: (
|
|
1069
|
+
caseSensitive: (_a = childProps.caseSensitive) !== null && _a !== void 0 ? _a : false,
|
|
1091
1070
|
end: true,
|
|
1092
1071
|
},
|
|
1093
1072
|
};
|
|
@@ -1212,30 +1191,24 @@ class StackManager extends React.PureComponent {
|
|
|
1212
1191
|
if (this.outletMountPath && !currentPathname.startsWith(this.outletMountPath)) {
|
|
1213
1192
|
return undefined;
|
|
1214
1193
|
}
|
|
1215
|
-
//
|
|
1216
|
-
|
|
1194
|
+
// If this is a nested outlet (has an explicit ID like "main"),
|
|
1195
|
+
// we need to figure out what part of the path was already matched
|
|
1196
|
+
if (this.id !== 'routerOutlet' && this.ionRouterOutlet) {
|
|
1217
1197
|
const routeChildren = extractRouteChildren(this.ionRouterOutlet.props.children);
|
|
1218
1198
|
const { hasRelativeRoutes, hasIndexRoute, hasWildcardRoute } = analyzeRouteChildren(routeChildren);
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
hasIndexRoute,
|
|
1231
|
-
hasWildcardRoute,
|
|
1232
|
-
});
|
|
1233
|
-
// Update the outlet mount path if it was set
|
|
1234
|
-
if (result.outletMountPath && !this.outletMountPath) {
|
|
1235
|
-
this.outletMountPath = result.outletMountPath;
|
|
1236
|
-
}
|
|
1237
|
-
return result.parentPath;
|
|
1199
|
+
const result = computeParentPath({
|
|
1200
|
+
currentPathname,
|
|
1201
|
+
outletMountPath: this.outletMountPath,
|
|
1202
|
+
routeChildren,
|
|
1203
|
+
hasRelativeRoutes,
|
|
1204
|
+
hasIndexRoute,
|
|
1205
|
+
hasWildcardRoute,
|
|
1206
|
+
});
|
|
1207
|
+
// Update the outlet mount path if it was set
|
|
1208
|
+
if (result.outletMountPath && !this.outletMountPath) {
|
|
1209
|
+
this.outletMountPath = result.outletMountPath;
|
|
1238
1210
|
}
|
|
1211
|
+
return result.parentPath;
|
|
1239
1212
|
}
|
|
1240
1213
|
return this.outletMountPath;
|
|
1241
1214
|
}
|
|
@@ -1324,9 +1297,7 @@ class StackManager extends React.PureComponent {
|
|
|
1324
1297
|
*/
|
|
1325
1298
|
handleOutOfContextNestedOutlet(parentPath, leavingViewItem) {
|
|
1326
1299
|
var _a;
|
|
1327
|
-
|
|
1328
|
-
const isRootOutlet = this.id.startsWith('routerOutlet');
|
|
1329
|
-
if (isRootOutlet || parentPath !== undefined || !this.ionRouterOutlet) {
|
|
1300
|
+
if (this.id === 'routerOutlet' || parentPath !== undefined || !this.ionRouterOutlet) {
|
|
1330
1301
|
return false;
|
|
1331
1302
|
}
|
|
1332
1303
|
const routesChildren = (_a = getRoutesChildren(this.ionRouterOutlet.props.children)) !== null && _a !== void 0 ? _a : this.ionRouterOutlet.props.children;
|
|
@@ -1351,9 +1322,7 @@ class StackManager extends React.PureComponent {
|
|
|
1351
1322
|
* Returns true if the transition should be aborted.
|
|
1352
1323
|
*/
|
|
1353
1324
|
handleNoMatchingRoute(enteringRoute, enteringViewItem, leavingViewItem) {
|
|
1354
|
-
|
|
1355
|
-
const isRootOutlet = this.id.startsWith('routerOutlet');
|
|
1356
|
-
if (isRootOutlet || enteringRoute || enteringViewItem) {
|
|
1325
|
+
if (this.id === 'routerOutlet' || enteringRoute || enteringViewItem) {
|
|
1357
1326
|
return false;
|
|
1358
1327
|
}
|
|
1359
1328
|
// Hide any visible views in this outlet since it has no matching route
|
|
@@ -1900,59 +1869,27 @@ function findRouteByRouteInfo(node, routeInfo, parentPath) {
|
|
|
1900
1869
|
});
|
|
1901
1870
|
// For nested routes in React Router 6, we need to extract the relative path
|
|
1902
1871
|
// that this outlet should be responsible for matching
|
|
1903
|
-
|
|
1904
|
-
let relativePathnameToMatch = routeInfo.pathname;
|
|
1872
|
+
let pathnameToMatch = routeInfo.pathname;
|
|
1905
1873
|
// Check if we have relative routes (routes that don't start with '/')
|
|
1906
1874
|
const hasRelativeRoutes = sortedRoutes.some((r) => r.props.path && !r.props.path.startsWith('/'));
|
|
1907
1875
|
const hasIndexRoute = sortedRoutes.some((r) => r.props.index);
|
|
1908
1876
|
// SIMPLIFIED: Trust React Router 6's matching more, compute relative path when parent is known
|
|
1909
1877
|
if ((hasRelativeRoutes || hasIndexRoute) && parentPath) {
|
|
1910
1878
|
const parentPrefix = parentPath.replace('/*', '');
|
|
1911
|
-
|
|
1912
|
-
const normalizedParent = stripTrailingSlash(parentPrefix.startsWith('/') ? parentPrefix : `/${parentPrefix}`);
|
|
1879
|
+
const normalizedParent = stripTrailingSlash(parentPrefix);
|
|
1913
1880
|
const normalizedPathname = stripTrailingSlash(routeInfo.pathname);
|
|
1914
1881
|
// Only compute relative path if pathname is within parent scope
|
|
1915
1882
|
if (normalizedPathname.startsWith(normalizedParent + '/') || normalizedPathname === normalizedParent) {
|
|
1916
1883
|
const pathSegments = routeInfo.pathname.split('/').filter(Boolean);
|
|
1917
1884
|
const parentSegments = normalizedParent.split('/').filter(Boolean);
|
|
1918
1885
|
const relativeSegments = pathSegments.slice(parentSegments.length);
|
|
1919
|
-
|
|
1886
|
+
pathnameToMatch = relativeSegments.join('/'); // Empty string is valid for index routes
|
|
1920
1887
|
}
|
|
1921
1888
|
}
|
|
1922
1889
|
// Find the first matching route
|
|
1923
1890
|
for (const child of sortedRoutes) {
|
|
1924
|
-
const childPath = child.props.path;
|
|
1925
|
-
const isAbsoluteRoute = childPath && childPath.startsWith('/');
|
|
1926
|
-
// Determine which pathname to match against:
|
|
1927
|
-
// - For absolute routes: use the original full pathname
|
|
1928
|
-
// - For relative routes with a parent: use the computed relative pathname
|
|
1929
|
-
// - For relative routes at root level (no parent): use the original pathname
|
|
1930
|
-
// (matchPath will handle the relative-to-absolute normalization)
|
|
1931
|
-
const pathnameToMatch = isAbsoluteRoute ? originalPathname : relativePathnameToMatch;
|
|
1932
|
-
// Determine the path portion to match:
|
|
1933
|
-
// - For absolute routes: use derivePathnameToMatch
|
|
1934
|
-
// - For relative routes at root level (no parent): use original pathname
|
|
1935
|
-
// directly since matchPath normalizes both path and pathname
|
|
1936
|
-
// - For relative routes with parent: use derivePathnameToMatch for wildcards,
|
|
1937
|
-
// or the computed relative pathname for non-wildcards
|
|
1938
|
-
let pathForMatch;
|
|
1939
|
-
if (isAbsoluteRoute) {
|
|
1940
|
-
pathForMatch = derivePathnameToMatch(pathnameToMatch, childPath);
|
|
1941
|
-
}
|
|
1942
|
-
else if (!parentPath && childPath) {
|
|
1943
|
-
// Root-level relative route: use the full pathname and let matchPath
|
|
1944
|
-
// handle the normalization (it adds '/' to both path and pathname)
|
|
1945
|
-
pathForMatch = originalPathname;
|
|
1946
|
-
}
|
|
1947
|
-
else if (childPath && childPath.includes('*')) {
|
|
1948
|
-
// Relative wildcard route with parent path: use derivePathnameToMatch
|
|
1949
|
-
pathForMatch = derivePathnameToMatch(pathnameToMatch, childPath);
|
|
1950
|
-
}
|
|
1951
|
-
else {
|
|
1952
|
-
pathForMatch = pathnameToMatch;
|
|
1953
|
-
}
|
|
1954
1891
|
const match = matchPath({
|
|
1955
|
-
pathname:
|
|
1892
|
+
pathname: pathnameToMatch,
|
|
1956
1893
|
componentProps: child.props,
|
|
1957
1894
|
});
|
|
1958
1895
|
if (match) {
|
|
@@ -2210,10 +2147,16 @@ const IonRouter = ({ children, registerHistoryListener }) => {
|
|
|
2210
2147
|
* tab and use its `pushedByRoute`.
|
|
2211
2148
|
*/
|
|
2212
2149
|
const lastRoute = locationHistory.current.getCurrentRouteInfoForTab(routeInfo.tab);
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2150
|
+
/**
|
|
2151
|
+
* Tab bar switches (direction 'none') should not create cross-tab back
|
|
2152
|
+
* navigation. Only inherit pushedByRoute from the tab's own history.
|
|
2153
|
+
*/
|
|
2154
|
+
if (routeInfo.routeDirection === 'none') {
|
|
2155
|
+
routeInfo.pushedByRoute = lastRoute === null || lastRoute === void 0 ? void 0 : lastRoute.pushedByRoute;
|
|
2156
|
+
}
|
|
2157
|
+
else {
|
|
2158
|
+
routeInfo.pushedByRoute = (_e = lastRoute === null || lastRoute === void 0 ? void 0 : lastRoute.pushedByRoute) !== null && _e !== void 0 ? _e : leavingLocationInfo.pathname;
|
|
2159
|
+
}
|
|
2217
2160
|
// Triggered by `history.replace()` or a `<Redirect />` component, etc.
|
|
2218
2161
|
}
|
|
2219
2162
|
else if (routeInfo.routeAction === 'replace') {
|
|
@@ -2380,11 +2323,14 @@ const IonRouter = ({ children, registerHistoryListener }) => {
|
|
|
2380
2323
|
handleNavigate(defaultHref, 'pop', 'back', routeAnimation);
|
|
2381
2324
|
}
|
|
2382
2325
|
/**
|
|
2383
|
-
* No `pushedByRoute`
|
|
2384
|
-
*
|
|
2326
|
+
* No `pushedByRoute` (e.g., initial page load or tab root).
|
|
2327
|
+
* Tabs with no back history should not navigate.
|
|
2385
2328
|
*/
|
|
2386
2329
|
}
|
|
2387
2330
|
else {
|
|
2331
|
+
if (routeInfo && routeInfo.tab) {
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2388
2334
|
handleNavigate(defaultHref, 'pop', 'back', routeAnimation);
|
|
2389
2335
|
}
|
|
2390
2336
|
};
|