mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 01:03:03 +08:00
fix(react): adding dynamic class to ion-page no longer hides component (#22666)
resolves #22631
This commit is contained in:
18
packages/react-router/test-app/cypress/integration/dynamic-ionpage-classnames.js
vendored
Normal file
18
packages/react-router/test-app/cypress/integration/dynamic-ionpage-classnames.js
vendored
Normal 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');
|
||||||
|
});
|
||||||
|
});
|
@ -33,6 +33,7 @@ import TabsContext from './pages/tab-context/TabContext';
|
|||||||
import { OutletRef } from './pages/outlet-ref/OutletRef';
|
import { OutletRef } from './pages/outlet-ref/OutletRef';
|
||||||
import { SwipeToGoBack } from './pages/swipe-to-go-back/SwipToGoBack';
|
import { SwipeToGoBack } from './pages/swipe-to-go-back/SwipToGoBack';
|
||||||
import Refs from './pages/refs/Refs';
|
import Refs from './pages/refs/Refs';
|
||||||
|
import DynamicIonpageClassnames from './pages/dynamic-ionpage-classnames/DynamicIonpageClassnames';
|
||||||
debugger;
|
debugger;
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
@ -49,6 +50,7 @@ const App: React.FC = () => {
|
|||||||
<Route path="/tab-context" component={TabsContext} />
|
<Route path="/tab-context" component={TabsContext} />
|
||||||
<Route path="/outlet-ref" component={OutletRef} />
|
<Route path="/outlet-ref" component={OutletRef} />
|
||||||
<Route path="/swipe-to-go-back" component={SwipeToGoBack} />
|
<Route path="/swipe-to-go-back" component={SwipeToGoBack} />
|
||||||
|
<Route path="/dynamic-ionpage-classnames" component={DynamicIonpageClassnames} />
|
||||||
<Route path="/refs" component={Refs} />
|
<Route path="/refs" component={Refs} />
|
||||||
</IonReactRouter>
|
</IonReactRouter>
|
||||||
</IonApp>
|
</IonApp>
|
||||||
|
@ -52,6 +52,9 @@ const Main: React.FC<MainProps> = () => {
|
|||||||
<IonItem routerLink="/swipe-to-go-back">
|
<IonItem routerLink="/swipe-to-go-back">
|
||||||
<IonLabel>Swipe to go back</IonLabel>
|
<IonLabel>Swipe to go back</IonLabel>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
|
<IonItem routerLink="/dynamic-ionpage-classnames">
|
||||||
|
<IonLabel>Dynamic IonPage Classnames</IonLabel>
|
||||||
|
</IonItem>
|
||||||
<IonItem routerLink="/Refs">
|
<IonItem routerLink="/Refs">
|
||||||
<IonLabel>Refs</IonLabel>
|
<IonLabel>Refs</IonLabel>
|
||||||
</IonItem>
|
</IonItem>
|
||||||
|
@ -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>
|
||||||
|
);
|
||||||
|
};
|
@ -23,6 +23,9 @@ export class PageManager extends React.PureComponent<PageManagerProps> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.ionPageElementRef.current) {
|
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.context.registerIonPage(this.ionPageElementRef.current, this.props.routeInfo!);
|
||||||
this.ionPageElementRef.current.addEventListener(
|
this.ionPageElementRef.current.addEventListener(
|
||||||
'ionViewWillEnter',
|
'ionViewWillEnter',
|
||||||
@ -87,11 +90,10 @@ export class PageManager extends React.PureComponent<PageManagerProps> {
|
|||||||
<IonLifeCycleContext.Consumer>
|
<IonLifeCycleContext.Consumer>
|
||||||
{(context) => {
|
{(context) => {
|
||||||
this.ionLifeCycleContext = context;
|
this.ionLifeCycleContext = context;
|
||||||
const hidePageClass = this.context.isInOutlet() ? 'ion-page-invisible' : '';
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
className ? `${className} ion-page ${hidePageClass}` : `ion-page ${hidePageClass}`
|
className ? `${className} ion-page` : `ion-page`
|
||||||
}
|
}
|
||||||
ref={this.ionPageElementRef}
|
ref={this.ionPageElementRef}
|
||||||
{...props}
|
{...props}
|
||||||
|
Reference in New Issue
Block a user