diff --git a/packages/react-router/test-app/cypress/integration/dynamic-ionpage-classnames.js b/packages/react-router/test-app/cypress/integration/dynamic-ionpage-classnames.js new file mode 100644 index 0000000000..d41781fe21 --- /dev/null +++ b/packages/react-router/test-app/cypress/integration/dynamic-ionpage-classnames.js @@ -0,0 +1,18 @@ +const port = 3000; + +describe('Dynamic IonPage Classnames', () => { + /* + This spec tests that classnames can be added to IonPages dynamically and that the IonPage + doesn't get ion-page-invisible added back to it when it does change + Fixes bug reported in https://github.com/ionic-team/ionic-framework/issues/22631 + */ + + it('/dynamic-ionpage-classnames, when a class is added to an IonPage, the class should be applied to the element and the page should still be visible', () => { + cy.visit(`http://localhost:${port}/dynamic-ionpage-classnames`); + cy.ionPageVisible('dynamic-ionpage-classnames'); + cy.get('.initial-class'); + cy.contains('Add Class').click(); + cy.get('.other-class'); + cy.ionPageVisible('dynamic-ionpage-classnames'); + }); +}); diff --git a/packages/react-router/test-app/src/App.tsx b/packages/react-router/test-app/src/App.tsx index 16ded6277b..75ef0f0398 100644 --- a/packages/react-router/test-app/src/App.tsx +++ b/packages/react-router/test-app/src/App.tsx @@ -33,6 +33,7 @@ import TabsContext from './pages/tab-context/TabContext'; import { OutletRef } from './pages/outlet-ref/OutletRef'; import { SwipeToGoBack } from './pages/swipe-to-go-back/SwipToGoBack'; import Refs from './pages/refs/Refs'; +import DynamicIonpageClassnames from './pages/dynamic-ionpage-classnames/DynamicIonpageClassnames'; debugger; const App: React.FC = () => { return ( @@ -49,6 +50,7 @@ const App: React.FC = () => { + diff --git a/packages/react-router/test-app/src/pages/Main.tsx b/packages/react-router/test-app/src/pages/Main.tsx index 75b67f711a..6075da45f5 100644 --- a/packages/react-router/test-app/src/pages/Main.tsx +++ b/packages/react-router/test-app/src/pages/Main.tsx @@ -52,6 +52,9 @@ const Main: React.FC = () => { Swipe to go back + + Dynamic IonPage Classnames + Refs diff --git a/packages/react-router/test-app/src/pages/dynamic-ionpage-classnames/DynamicIonpageClassnames.tsx b/packages/react-router/test-app/src/pages/dynamic-ionpage-classnames/DynamicIonpageClassnames.tsx new file mode 100644 index 0000000000..baba236a0c --- /dev/null +++ b/packages/react-router/test-app/src/pages/dynamic-ionpage-classnames/DynamicIonpageClassnames.tsx @@ -0,0 +1,60 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { + IonButton, + IonContent, + IonHeader, + IonPage, + IonRouterOutlet, + IonTitle, + IonToolbar, +} from '@ionic/react'; +import { Route } from 'react-router'; + +interface DynamicIonpageClassnamesProps {} + +const DynamicIonpageClassnames: React.FC = () => { + return ( + + + + ); +}; + +export default DynamicIonpageClassnames; + +const Page: React.FC = (props) => { + const [styleClass, setStyleClass] = useState('initial-class'); + const [divClasses, setDivClasses] = useState(); + const ref = useRef(); + useEffect(() => { + if(ref.current) { + var observer = new MutationObserver(function (event) { + setDivClasses(ref.current?.className) + }) + + observer.observe(ref.current, { + attributes: true, + attributeFilter: ['class'], + childList: false, + characterData: false + }) + } + return () => observer.disconnect() + }, []) + + + return ( + + + + Dynamic Ionpage Classnames + + + + setStyleClass('other-class')}>Add Class +
+ Div classes: {divClasses} +
+
+ ); +}; diff --git a/packages/react/src/routing/PageManager.tsx b/packages/react/src/routing/PageManager.tsx index 078006dd29..f78f1e2095 100644 --- a/packages/react/src/routing/PageManager.tsx +++ b/packages/react/src/routing/PageManager.tsx @@ -23,6 +23,9 @@ export class PageManager extends React.PureComponent { componentDidMount() { if (this.ionPageElementRef.current) { + if (this.context.isInOutlet()) { + this.ionPageElementRef.current.classList.add('ion-page-invisible'); + } this.context.registerIonPage(this.ionPageElementRef.current, this.props.routeInfo!); this.ionPageElementRef.current.addEventListener( 'ionViewWillEnter', @@ -87,11 +90,10 @@ export class PageManager extends React.PureComponent { {(context) => { this.ionLifeCycleContext = context; - const hidePageClass = this.context.isInOutlet() ? 'ion-page-invisible' : ''; return (