fix(react): adding dynamic class to ion-page no longer hides component (#22666)

resolves #22631
This commit is contained in:
Ely Lucas
2020-12-15 09:02:06 -07:00
committed by GitHub
parent 09a5ed6a0d
commit a01bdb8c8d
5 changed files with 87 additions and 2 deletions

View File

@ -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');
});
});

View File

@ -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 = () => {
<Route path="/tab-context" component={TabsContext} />
<Route path="/outlet-ref" component={OutletRef} />
<Route path="/swipe-to-go-back" component={SwipeToGoBack} />
<Route path="/dynamic-ionpage-classnames" component={DynamicIonpageClassnames} />
<Route path="/refs" component={Refs} />
</IonReactRouter>
</IonApp>

View File

@ -52,6 +52,9 @@ const Main: React.FC<MainProps> = () => {
<IonItem routerLink="/swipe-to-go-back">
<IonLabel>Swipe to go back</IonLabel>
</IonItem>
<IonItem routerLink="/dynamic-ionpage-classnames">
<IonLabel>Dynamic IonPage Classnames</IonLabel>
</IonItem>
<IonItem routerLink="/Refs">
<IonLabel>Refs</IonLabel>
</IonItem>

View File

@ -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<DynamicIonpageClassnamesProps> = () => {
return (
<IonRouterOutlet>
<Route path="/dynamic-ionpage-classnames" component={Page} />
</IonRouterOutlet>
);
};
export default DynamicIonpageClassnames;
const Page: React.FC = (props) => {
const [styleClass, setStyleClass] = useState('initial-class');
const [divClasses, setDivClasses] = useState<string>();
const ref = useRef<HTMLDivElement>();
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 (
<IonPage className={styleClass} ref={ref} data-pageid="dynamic-ionpage-classnames">
<IonHeader>
<IonToolbar>
<IonTitle>Dynamic Ionpage Classnames</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonButton onClick={() => setStyleClass('other-class')}>Add Class</IonButton>
<br />
Div classes: {divClasses}
</IonContent>
</IonPage>
);
};

View File

@ -23,6 +23,9 @@ export class PageManager extends React.PureComponent<PageManagerProps> {
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<PageManagerProps> {
<IonLifeCycleContext.Consumer>
{(context) => {
this.ionLifeCycleContext = context;
const hidePageClass = this.context.isInOutlet() ? 'ion-page-invisible' : '';
return (
<div
className={
className ? `${className} ion-page ${hidePageClass}` : `ion-page ${hidePageClass}`
className ? `${className} ion-page` : `ion-page`
}
ref={this.ionPageElementRef}
{...props}