@@ -279,6 +279,31 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
279279 return true ;
280280 }
281281
282+ /**
283+ * Handles root navigation by unmounting all non-entering views in this outlet.
284+ * Fires ionViewWillLeave / ionViewDidLeave only on views that are currently visible.
285+ * Views that are mounted but not visible (e.g., pages earlier in the back stack)
286+ * are silently unmounted without lifecycle events, consistent with the behavior
287+ * of out-of-scope outlet cleanup.
288+ */
289+ private handleRootNavigation ( enteringViewItem : ViewItem | undefined ) : void {
290+ const allViewsInOutlet = this . context . getViewItemsForOutlet ( this . id ) ;
291+ allViewsInOutlet . forEach ( ( viewItem ) => {
292+ if ( viewItem === enteringViewItem ) {
293+ return ;
294+ }
295+ if ( viewItem . ionPageElement && isViewVisible ( viewItem . ionPageElement ) ) {
296+ viewItem . ionPageElement . dispatchEvent (
297+ new CustomEvent ( 'ionViewWillLeave' , { bubbles : false , cancelable : false } )
298+ ) ;
299+ viewItem . ionPageElement . dispatchEvent (
300+ new CustomEvent ( 'ionViewDidLeave' , { bubbles : false , cancelable : false } )
301+ ) ;
302+ }
303+ this . context . unMountViewItem ( viewItem ) ;
304+ } ) ;
305+ }
306+
282307 /**
283308 * Handles nested outlet with relative routes but no parent path. Returns true to abort.
284309 */
@@ -875,8 +900,8 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
875900 // Find entering and leaving view items
876901 const viewItems = this . findViewItems ( routeInfo ) ;
877902 let enteringViewItem = viewItems . enteringViewItem ;
878- const leavingViewItem = viewItems . leavingViewItem ;
879- const shouldUnmountLeavingViewItem = this . shouldUnmountLeavingView ( routeInfo , enteringViewItem , leavingViewItem ) ;
903+ let leavingViewItem = viewItems . leavingViewItem ;
904+ let shouldUnmountLeavingViewItem = this . shouldUnmountLeavingView ( routeInfo , enteringViewItem , leavingViewItem ) ;
880905
881906 // Get parent path for nested outlets
882907 const parentPath = this . getParentPath ( ) ;
@@ -886,6 +911,13 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
886911 return ;
887912 }
888913
914+ // Handle root navigation: unmount all non-entering views
915+ if ( routeInfo . routeDirection === 'root' ) {
916+ this . handleRootNavigation ( enteringViewItem ) ;
917+ leavingViewItem = undefined ;
918+ shouldUnmountLeavingViewItem = false ;
919+ }
920+
889921 // Clear any pending out-of-scope unmount timeout
890922 if ( this . outOfScopeUnmountTimeout ) {
891923 clearTimeout ( this . outOfScopeUnmountTimeout ) ;
0 commit comments