@@ -28,18 +28,20 @@ import { extractRouteChildren, getRoutesChildren, isNavigateElement } from './ut
2828const VIEW_UNMOUNT_DELAY_MS = 250 ;
2929
3030/**
31- * Delay in milliseconds to wait for an IonPage element to be mounted before
32- * proceeding with a page transition.
31+ * Delay (ms) to wait for an IonPage to mount before proceeding with a
32+ * page transition. Only container routes (nested outlets with no direct
33+ * IonPage) actually hit this timeout; normal routes clear it early via
34+ * registerIonPage, so a larger value here doesn't affect the happy path.
3335 */
34- const ION_PAGE_WAIT_TIMEOUT_MS = 50 ;
36+ const ION_PAGE_WAIT_TIMEOUT_MS = 300 ;
3537
3638interface StackManagerProps {
3739 routeInfo : RouteInfo ;
3840 id ?: string ;
3941}
4042
4143const isViewVisible = ( el : HTMLElement ) =>
42- ! el . classList . contains ( 'ion-page-invisible' ) && ! el . classList . contains ( 'ion-page-hidden' ) && el . style . display !== 'none ' ;
44+ ! el . classList . contains ( 'ion-page-invisible' ) && ! el . classList . contains ( 'ion-page-hidden' ) && el . style . visibility !== 'hidden ' ;
4345
4446const hideIonPageElement = ( element : HTMLElement | undefined ) : void => {
4547 if ( element ) {
@@ -50,7 +52,7 @@ const hideIonPageElement = (element: HTMLElement | undefined): void => {
5052
5153const showIonPageElement = ( element : HTMLElement | undefined ) : void => {
5254 if ( element ) {
53- element . style . removeProperty ( 'display ' ) ;
55+ element . style . removeProperty ( 'visibility ' ) ;
5456 element . classList . remove ( 'ion-page-hidden' ) ;
5557 element . removeAttribute ( 'aria-hidden' ) ;
5658 }
@@ -586,10 +588,12 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
586588 * nested scrollbars (each page has its own IonContent). Top-level outlets
587589 * are unaffected and animate normally.
588590 *
589- * Uses inline display:none rather than ion-page-hidden class because core's
590- * beforeTransition() removes ion-page-hidden via setPageHidden().
591- * Inline display:none survives that removal, keeping the page hidden
592- * until React unmounts it after ionViewDidLeave fires.
591+ * Uses inline visibility:hidden rather than ion-page-hidden class because
592+ * core's beforeTransition() removes ion-page-hidden via setPageHidden().
593+ * Inline visibility:hidden survives that removal, keeping the page hidden
594+ * until React unmounts it after ionViewDidLeave fires. Unlike display:none,
595+ * visibility:hidden preserves element geometry so commit() animations
596+ * can resolve normally.
593597 */
594598 private applySkipAnimationIfNeeded (
595599 enteringViewItem : ViewItem ,
@@ -599,7 +603,7 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
599603 const shouldSkip = isNestedOutlet && ! ! leavingViewItem && enteringViewItem !== leavingViewItem ;
600604
601605 if ( shouldSkip && leavingViewItem ?. ionPageElement ) {
602- leavingViewItem . ionPageElement . style . setProperty ( 'display ' , 'none ' ) ;
606+ leavingViewItem . ionPageElement . style . setProperty ( 'visibility ' , 'hidden ' ) ;
603607 leavingViewItem . ionPageElement . setAttribute ( 'aria-hidden' , 'true' ) ;
604608 }
605609
@@ -1152,6 +1156,13 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
11521156 progressAnimation,
11531157 animationBuilder : routeInfo . routeAnimation ,
11541158 } ) ;
1159+
1160+ // Ensure entering page is visible after commit. The animation should
1161+ // have removed ion-page-invisible, but in slower environments the
1162+ // commit can resolve before the class is cleaned up.
1163+ if ( ! progressAnimation ) {
1164+ enteringEl . classList . remove ( 'ion-page-invisible' ) ;
1165+ }
11551166 } ;
11561167
11571168 const routerOutlet = this . routerOutletElement ! ;
@@ -1298,7 +1309,6 @@ export class StackManager extends React.PureComponent<StackManagerProps> {
12981309 } ) ;
12991310 } else {
13001311 await runCommit ( enteringViewItem . ionPageElement , leavingEl ) ;
1301- // For animated transitions, hide leaving element after commit completes
13021312 if ( leavingEl && ! progressAnimation ) {
13031313 leavingEl . classList . add ( 'ion-page-hidden' ) ;
13041314 leavingEl . setAttribute ( 'aria-hidden' , 'true' ) ;
0 commit comments