@@ -113,7 +113,6 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
113113 this . registerIonPage = this . registerIonPage . bind ( this ) ;
114114 this . transitionPage = this . transitionPage . bind ( this ) ;
115115 this . handlePageTransition = this . handlePageTransition . bind ( this ) ;
116- // Use provided id prop if available; otherwise generate a unique id.
117116 this . id = props . id || `routerOutlet-${ generateId ( 'routerOutlet' ) } ` ;
118117 this . prevProps = undefined ;
119118 this . skipTransition = false ;
@@ -436,13 +435,6 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
436435 return false ;
437436 }
438437
439- // routeOptions.unmount should NOT trigger view removal - it just hides the view
440- // The view needs to remain in the stack for tab navigation and back navigation
441- // Don't set mount = false, just let the transition hide the page
442- // if (routeInfo.routeOptions?.unmount) {
443- // return true;
444- // }
445-
446438 if ( routeInfo . routeAction === 'replace' ) {
447439 return true ;
448440 }
@@ -799,16 +791,12 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
799791 leavingViewItem . ionPageElement . classList . add ( 'ion-page-hidden' ) ;
800792 leavingViewItem . ionPageElement . setAttribute ( 'aria-hidden' , 'true' ) ;
801793 }
802- if ( shouldUnmountLeavingViewItem && leavingViewItem ) {
794+ if ( shouldUnmountLeavingViewItem ) {
803795 leavingViewItem . mount = false ;
804796 }
805- } else {
806- // No entering or leaving view - this might be a routing issue
807- // Don't retry endlessly to avoid infinite loops
808797 }
809798 }
810799
811- // Force re-render so views update according to their new mount/visible status
812800 this . forceUpdate ( ) ;
813801 }
814802 }
@@ -1054,11 +1042,8 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
10541042 await runCommit ( enteringViewItem . ionPageElement , undefined ) ;
10551043 }
10561044 } else {
1057- // The leaving view is not the same as the entering view
1058- // (e.g., `/home` → `/settings` or initial load `/`)
10591045 await runCommit ( enteringViewItem . ionPageElement , leavingViewItem ?. ionPageElement ) ;
10601046 if ( leavingViewItem && leavingViewItem . ionPageElement && ! progressAnimation ) {
1061- // An initiial load will not have a leaving view.
10621047 leavingViewItem . ionPageElement . classList . add ( 'ion-page-hidden' ) ;
10631048 leavingViewItem . ionPageElement . setAttribute ( 'aria-hidden' , 'true' ) ;
10641049 }
@@ -1213,7 +1198,7 @@ function findRouteByRouteInfo(node: React.ReactNode, routeInfo: RouteInfo, paren
12131198 if ( absolutePathRoutes . length > 0 ) {
12141199 // Find common prefix of all absolute paths to determine outlet scope
12151200 const absolutePaths = absolutePathRoutes . map ( ( r ) => r . props . path as string ) ;
1216- const commonPrefix = findCommonPrefix ( absolutePaths ) ;
1201+ const commonPrefix = computeCommonPrefix ( absolutePaths ) ;
12171202
12181203 // If we have a common prefix, check if the current pathname is within that scope
12191204 if ( commonPrefix && commonPrefix !== '/' ) {
@@ -1234,44 +1219,6 @@ function findRouteByRouteInfo(node: React.ReactNode, routeInfo: RouteInfo, paren
12341219 return matchedNode ?? fallbackNode ;
12351220}
12361221
1237- /**
1238- * Finds the longest common prefix among an array of paths.
1239- * Used to determine the scope of an outlet with absolute routes.
1240- */
1241- function findCommonPrefix ( paths : string [ ] ) : string {
1242- if ( paths . length === 0 ) return '' ;
1243- if ( paths . length === 1 ) {
1244- // For a single path, extract the directory-like prefix
1245- // e.g., /dynamic-routes/home -> /dynamic-routes
1246- const segments = paths [ 0 ] . split ( '/' ) . filter ( Boolean ) ;
1247- if ( segments . length > 1 ) {
1248- return '/' + segments . slice ( 0 , - 1 ) . join ( '/' ) ;
1249- }
1250- return '/' + segments [ 0 ] ;
1251- }
1252-
1253- // Split all paths into segments
1254- const segmentArrays = paths . map ( ( p ) => p . split ( '/' ) . filter ( Boolean ) ) ;
1255- const minLength = Math . min ( ...segmentArrays . map ( ( s ) => s . length ) ) ;
1256-
1257- const commonSegments : string [ ] = [ ] ;
1258- for ( let i = 0 ; i < minLength ; i ++ ) {
1259- const segment = segmentArrays [ 0 ] [ i ] ;
1260- // Skip segments with route parameters or wildcards
1261- if ( segment . includes ( ':' ) || segment . includes ( '*' ) ) {
1262- break ;
1263- }
1264- const allMatch = segmentArrays . every ( ( s ) => s [ i ] === segment ) ;
1265- if ( allMatch ) {
1266- commonSegments . push ( segment ) ;
1267- } else {
1268- break ;
1269- }
1270- }
1271-
1272- return commonSegments . length > 0 ? '/' + commonSegments . join ( '/' ) : '' ;
1273- }
1274-
12751222function matchComponent ( node : React . ReactElement , pathname : string , forceExact ?: boolean ) {
12761223 const routePath : string | undefined = node ?. props ?. path ;
12771224 const pathnameToMatch = derivePathnameToMatch ( pathname , routePath ) ;
0 commit comments