diff --git a/angular/src/directives/overlays/modal.ts b/angular/src/directives/overlays/modal.ts index 10f1120906a..5db8c6749df 100644 --- a/angular/src/directives/overlays/modal.ts +++ b/angular/src/directives/overlays/modal.ts @@ -54,6 +54,7 @@ export declare interface IonModal extends Components.IonModal { @ProxyCmp({ inputs: [ 'animated', + 'keepContentsMounted', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', @@ -78,9 +79,12 @@ export declare interface IonModal extends Components.IonModal { @Component({ selector: 'ion-modal', changeDetection: ChangeDetectionStrategy.OnPush, - template: `
`, + template: `
+ +
`, inputs: [ 'animated', + 'keepContentsMounted', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', diff --git a/angular/src/directives/overlays/popover.ts b/angular/src/directives/overlays/popover.ts index 0bcf5f7e262..aedbb97f9c8 100644 --- a/angular/src/directives/overlays/popover.ts +++ b/angular/src/directives/overlays/popover.ts @@ -51,6 +51,7 @@ export declare interface IonPopover extends Components.IonPopover { 'alignment', 'animated', 'arrow', + 'keepContentsMounted', 'backdropDismiss', 'cssClass', 'dismissOnSelect', @@ -73,11 +74,12 @@ export declare interface IonPopover extends Components.IonPopover { @Component({ selector: 'ion-popover', changeDetection: ChangeDetectionStrategy.OnPush, - template: ``, + template: ``, inputs: [ 'alignment', 'animated', 'arrow', + 'keepContentsMounted', 'backdropDismiss', 'cssClass', 'dismissOnSelect', diff --git a/angular/test/test-app/e2e/src/keep-contents-mounted.spec.ts b/angular/test/test-app/e2e/src/keep-contents-mounted.spec.ts new file mode 100644 index 00000000000..a4bc99167fb --- /dev/null +++ b/angular/test/test-app/e2e/src/keep-contents-mounted.spec.ts @@ -0,0 +1,60 @@ +describe('overlays - keepContentsMounted', () => { + describe('modal', () => { + it('should not mount component if false', () => { + cy.visit('/modal-inline'); + + cy.get('ion-modal ion-content').should('not.exist'); + }); + + it('should mount component if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('ion-modal ion-content').should('exist'); + }); + + it('should keep component mounted after dismissing if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('#open-modal').click(); + + cy.get('ion-modal ion-content').should('exist'); + + cy.get('ion-modal ion-button').click(); + + cy.get('ion-modal') + .should('not.be.visible') + .should('have.class', 'overlay-hidden'); + + cy.get('ion-modal ion-content').should('exist'); + }); + }) + describe('popover', () => { + it('should not mount component if false', () => { + cy.visit('/popover-inline'); + + cy.get('ion-popover ion-content').should('not.exist'); + }); + + it('should mount component if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('ion-popover ion-content').should('exist'); + }); + + it('should keep component mounted after dismissing if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('#open-popover').click(); + + cy.get('ion-popover ion-content').should('exist'); + + cy.get('ion-popover ion-button').click(); + + cy.get('ion-popover') + .should('not.be.visible') + .should('have.class', 'overlay-hidden'); + + cy.get('ion-popover ion-content').should('exist'); + }); + }); +}); diff --git a/angular/test/test-app/e2e/src/popover.spec.ts b/angular/test/test-app/e2e/src/popover.spec.ts index abf1c06fa10..17f8fe64455 100644 --- a/angular/test/test-app/e2e/src/popover.spec.ts +++ b/angular/test/test-app/e2e/src/popover.spec.ts @@ -4,10 +4,17 @@ describe('Popovers: Inline', () => { }); it('should initially have no items', () => { + cy.get('ion-button').click(); + + cy.get('ion-popover').should('be.visible'); cy.get('ion-list ion-item').should('not.exist'); }); it('should have items after 1500ms', () => { + cy.get('ion-button').click(); + + cy.get('ion-popover').should('be.visible'); + cy.wait(1500); cy.get('ion-list ion-item:nth-child(1)').should('have.text', 'A'); diff --git a/angular/test/test-app/src/app/app-routing.module.ts b/angular/test/test-app/src/app/app-routing.module.ts index be5ad94bb54..6ffdfd8d324 100644 --- a/angular/test/test-app/src/app/app-routing.module.ts +++ b/angular/test/test-app/src/app/app-routing.module.ts @@ -31,6 +31,7 @@ const routes: Routes = [ { path: 'modals', component: ModalComponent }, { path: 'modal-inline', loadChildren: () => import('./modal-inline').then(m => m.ModalInlineModule) }, { path: 'view-child', component: ViewChildComponent }, + { path: 'keep-contents-mounted', loadChildren: () => import('./keep-contents-mounted').then(m => m.OverlayAutoMountModule) }, { path: 'popover-inline', loadChildren: () => import('./popover-inline').then(m => m.PopoverInlineModule) }, { path: 'providers', component: ProvidersComponent }, { path: 'router-link', component: RouterLinkComponent }, diff --git a/angular/test/test-app/src/app/keep-contents-mounted/index.ts b/angular/test/test-app/src/app/keep-contents-mounted/index.ts new file mode 100644 index 00000000000..c949db9a98f --- /dev/null +++ b/angular/test/test-app/src/app/keep-contents-mounted/index.ts @@ -0,0 +1,2 @@ +export * from './keep-contents-mounted.component'; +export * from './keep-contents-mounted.module'; diff --git a/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted-routing.module.ts b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted-routing.module.ts new file mode 100644 index 00000000000..e453cb212e0 --- /dev/null +++ b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from "@angular/core"; +import { RouterModule } from "@angular/router"; +import { OverlayKeepContentsMounted } from "."; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { + path: '', + component: OverlayKeepContentsMounted + } + ]) + ], + exports: [RouterModule] +}) +export class OverlayKeepContentsMountedRoutingModule { } diff --git a/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.component.html b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.component.html new file mode 100644 index 00000000000..8311ecd5a72 --- /dev/null +++ b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.component.html @@ -0,0 +1,22 @@ + + Open Modal + Open Popover + + + + + Dismiss + Modal Content + + + + + + + + Dismiss + Popover Content + + + + diff --git a/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.component.ts b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.component.ts new file mode 100644 index 00000000000..ccf0e901652 --- /dev/null +++ b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.component.ts @@ -0,0 +1,13 @@ +import { Component } from "@angular/core"; + +/** + * Validates that inline modals correctly mount + * inner components when keepContentsMounted is + * enabled. + */ +@Component({ + selector: 'app-keep-contents-mounted', + templateUrl: 'keep-contents-mounted.component.html' +}) +export class OverlayKeepContentsMounted { +} diff --git a/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.module.ts b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.module.ts new file mode 100644 index 00000000000..265e8501267 --- /dev/null +++ b/angular/test/test-app/src/app/keep-contents-mounted/keep-contents-mounted.module.ts @@ -0,0 +1,12 @@ +import { CommonModule } from "@angular/common"; +import { NgModule } from "@angular/core"; +import { IonicModule } from "@ionic/angular"; +import { OverlayKeepContentsMountedRoutingModule } from "./keep-contents-mounted-routing.module"; +import { OverlayKeepContentsMounted } from "./keep-contents-mounted.component"; + +@NgModule({ + imports: [CommonModule, IonicModule, OverlayKeepContentsMountedRoutingModule], + declarations: [OverlayKeepContentsMounted], + exports: [OverlayKeepContentsMounted] +}) +export class OverlayAutoMountModule { } diff --git a/angular/test/test-app/src/app/popover-inline/popover-inline.component.html b/angular/test/test-app/src/app/popover-inline/popover-inline.component.html index 1de4bc20aff..f4f311646cd 100644 --- a/angular/test/test-app/src/app/popover-inline/popover-inline.component.html +++ b/angular/test/test-app/src/app/popover-inline/popover-inline.component.html @@ -1,4 +1,6 @@ - +Open Popover + + diff --git a/angular/test/test-app/src/app/popover-inline/popover-inline.component.ts b/angular/test/test-app/src/app/popover-inline/popover-inline.component.ts index d162795795a..36e472900ca 100644 --- a/angular/test/test-app/src/app/popover-inline/popover-inline.component.ts +++ b/angular/test/test-app/src/app/popover-inline/popover-inline.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component } from "@angular/core"; +import { Component } from "@angular/core"; /** * Validates that inline popovers will correctly display @@ -9,11 +9,13 @@ import { AfterViewInit, Component } from "@angular/core"; selector: 'app-popover-inline', templateUrl: 'popover-inline.component.html' }) -export class PopoverInlineComponent implements AfterViewInit { +export class PopoverInlineComponent { items: string[] = []; - ngAfterViewInit(): void { + openPopover(popover: HTMLIonPopoverElement) { + popover.present(); + setTimeout(() => { this.items = ['A', 'B', 'C', 'D']; }, 1000); diff --git a/core/api.txt b/core/api.txt index e72c296273c..dec444946d4 100644 --- a/core/api.txt +++ b/core/api.txt @@ -776,6 +776,7 @@ ion-modal,prop,handle,boolean | undefined,undefined,false,false ion-modal,prop,htmlAttributes,undefined | { [key: string]: any; },undefined,false,false ion-modal,prop,initialBreakpoint,number | undefined,undefined,false,false ion-modal,prop,isOpen,boolean,false,false,false +ion-modal,prop,keepContentsMounted,boolean,false,false,false ion-modal,prop,keyboardClose,boolean,true,false,false ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-modal,prop,mode,"ios" | "md",undefined,false,false @@ -895,6 +896,7 @@ ion-popover,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undef ion-popover,prop,event,any,undefined,false,false ion-popover,prop,htmlAttributes,undefined | { [key: string]: any; },undefined,false,false ion-popover,prop,isOpen,boolean,false,false,false +ion-popover,prop,keepContentsMounted,boolean,false,false,false ion-popover,prop,keyboardClose,boolean,true,false,false ion-popover,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false ion-popover,prop,mode,"ios" | "md",undefined,false,false diff --git a/core/src/components.d.ts b/core/src/components.d.ts index a2c0e8f9621..dce67a1407d 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -1571,6 +1571,10 @@ export namespace Components { * If `true`, the modal will open. If `false`, the modal will close. Use this if you need finer grained control over presentation, otherwise just use the modalController or the `trigger` property. Note: `isOpen` will not automatically be set back to `false` when the modal dismisses. You will need to do that in your code. */ "isOpen": boolean; + /** + * If `true`, the component passed into `ion-modal` will automatically be mounted when the modal is created. The component will remain mounted even when the modal is dismissed. However, the component will be destroyed when the modal is destroyed. This property is not reactive and should only be used when initially creating a modal. Note: This feature only applies to inline modals in JavaScript frameworks such as Angular, React, and Vue. + */ + "keepContentsMounted": boolean; /** * If `true`, the keyboard will be automatically dismissed when the overlay is presented. */ @@ -1936,6 +1940,10 @@ export namespace Components { * If `true`, the popover will open. If `false`, the popover will close. Use this if you need finer grained control over presentation, otherwise just use the popoverController or the `trigger` property. Note: `isOpen` will not automatically be set back to `false` when the popover dismisses. You will need to do that in your code. */ "isOpen": boolean; + /** + * If `true`, the component passed into `ion-popover` will automatically be mounted when the popover is created. The component will remain mounted even when the popover is dismissed. However, the component will be destroyed when the popover is destroyed. This property is not reactive and should only be used when initially creating a popover. Note: This feature only applies to inline popovers in JavaScript frameworks such as Angular, React, and Vue. + */ + "keepContentsMounted": boolean; /** * If `true`, the keyboard will be automatically dismissed when the overlay is presented. */ @@ -5484,6 +5492,10 @@ declare namespace LocalJSX { * If `true`, the modal will open. If `false`, the modal will close. Use this if you need finer grained control over presentation, otherwise just use the modalController or the `trigger` property. Note: `isOpen` will not automatically be set back to `false` when the modal dismisses. You will need to do that in your code. */ "isOpen"?: boolean; + /** + * If `true`, the component passed into `ion-modal` will automatically be mounted when the modal is created. The component will remain mounted even when the modal is dismissed. However, the component will be destroyed when the modal is destroyed. This property is not reactive and should only be used when initially creating a modal. Note: This feature only applies to inline modals in JavaScript frameworks such as Angular, React, and Vue. + */ + "keepContentsMounted"?: boolean; /** * If `true`, the keyboard will be automatically dismissed when the overlay is presented. */ @@ -5775,6 +5787,10 @@ declare namespace LocalJSX { * If `true`, the popover will open. If `false`, the popover will close. Use this if you need finer grained control over presentation, otherwise just use the popoverController or the `trigger` property. Note: `isOpen` will not automatically be set back to `false` when the popover dismisses. You will need to do that in your code. */ "isOpen"?: boolean; + /** + * If `true`, the component passed into `ion-popover` will automatically be mounted when the popover is created. The component will remain mounted even when the popover is dismissed. However, the component will be destroyed when the popover is destroyed. This property is not reactive and should only be used when initially creating a popover. Note: This feature only applies to inline popovers in JavaScript frameworks such as Angular, React, and Vue. + */ + "keepContentsMounted"?: boolean; /** * If `true`, the keyboard will be automatically dismissed when the overlay is presented. */ diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 766423a9485..873a4148188 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -222,6 +222,19 @@ export class Modal implements ComponentInterface, OverlayInterface { this.configureTriggerInteraction(); } + /** + * If `true`, the component passed into `ion-modal` will + * automatically be mounted when the modal is created. The + * component will remain mounted even when the modal is dismissed. + * However, the component will be destroyed when the modal is + * destroyed. This property is not reactive and should only be + * used when initially creating a modal. + * + * Note: This feature only applies to inline modals in JavaScript + * frameworks such as Angular, React, and Vue. + */ + @Prop() keepContentsMounted = false; + /** * TODO (FW-937) * This needs to default to true in the next diff --git a/core/src/components/popover/popover.tsx b/core/src/components/popover/popover.tsx index 42374439112..e9d6bacfc96 100644 --- a/core/src/components/popover/popover.tsx +++ b/core/src/components/popover/popover.tsx @@ -253,6 +253,19 @@ export class Popover implements ComponentInterface, PopoverInterface { } } + /** + * If `true`, the component passed into `ion-popover` will + * automatically be mounted when the popover is created. The + * component will remain mounted even when the popover is dismissed. + * However, the component will be destroyed when the popover is + * destroyed. This property is not reactive and should only be + * used when initially creating a popover. + * + * Note: This feature only applies to inline popovers in JavaScript + * frameworks such as Angular, React, and Vue. + */ + @Prop() keepContentsMounted = false; + /** * Emitted after the popover has presented. */ diff --git a/packages/react/src/components/createInlineOverlayComponent.tsx b/packages/react/src/components/createInlineOverlayComponent.tsx index 783ba5b4950..2851a371b8f 100644 --- a/packages/react/src/components/createInlineOverlayComponent.tsx +++ b/packages/react/src/components/createInlineOverlayComponent.tsx @@ -21,6 +21,7 @@ interface IonicReactInternalProps extends React.HTMLAttributes) => void; onWillDismiss?: (event: CustomEvent) => void; onWillPresent?: (event: CustomEvent) => void; + keepContentsMounted?: boolean; } export const createInlineOverlayComponent = ( @@ -128,7 +129,7 @@ export const createInlineOverlayComponent = ( * so conditionally render the component * based on the isOpen state. */ - return createElement(tagName, newProps, (this.state.isOpen) ? + return createElement(tagName, newProps, (this.state.isOpen || this.props.keepContentsMounted) ? createElement('div', { id: 'ion-react-wrapper', ref: this.wrapperRef, diff --git a/packages/react/test-app/cypress/integration/overlay-components/KeepContentsMounted.spec.ts b/packages/react/test-app/cypress/integration/overlay-components/KeepContentsMounted.spec.ts new file mode 100644 index 00000000000..b466e0e7536 --- /dev/null +++ b/packages/react/test-app/cypress/integration/overlay-components/KeepContentsMounted.spec.ts @@ -0,0 +1,60 @@ +describe('keepContentsMounted', () => { + describe('modal', () => { + it('should not mount component if false', () => { + cy.visit('/overlay-components/modal'); + + cy.get('ion-modal ion-content').should('not.exist'); + }); + + it('should mount component if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('ion-modal ion-content').should('exist'); + }); + + it('should keep component mounted after dismissing if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('#open-modal').click(); + + cy.get('ion-modal ion-content').should('exist'); + + cy.get('ion-modal ion-button').click(); + + cy.get('ion-modal') + .should('not.be.visible') + .should('have.class', 'overlay-hidden'); + + cy.get('ion-modal ion-content').should('exist'); + }); + }) + describe('popover', () => { + it('should not mount component if false', () => { + cy.visit('/overlay-components/popover'); + + cy.get('ion-popover ion-content').should('not.exist'); + }); + + it('should mount component if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('ion-popover ion-content').should('exist'); + }); + + it('should keep component mounted after dismissing if true', () => { + cy.visit('/keep-contents-mounted'); + + cy.get('#open-popover').click(); + + cy.get('ion-popover ion-content').should('exist'); + + cy.get('ion-popover ion-button').click(); + + cy.get('ion-popover') + .should('not.be.visible') + .should('have.class', 'overlay-hidden'); + + cy.get('ion-popover ion-content').should('exist'); + }); + }) +}); diff --git a/packages/react/test-app/src/App.tsx b/packages/react/test-app/src/App.tsx index 11cb79fba13..c499afbf9f5 100644 --- a/packages/react/test-app/src/App.tsx +++ b/packages/react/test-app/src/App.tsx @@ -24,6 +24,7 @@ import './theme/variables.css'; import Main from './pages/Main'; import OverlayHooks from './pages/overlay-hooks/OverlayHooks'; import OverlayComponents from './pages/overlay-components/OverlayComponents'; +import KeepContentsMounted from './pages/overlay-components/KeepContentsMounted'; import Tabs from './pages/Tabs'; setupIonicReact(); @@ -35,6 +36,7 @@ const App: React.FC = () => ( + diff --git a/packages/react/test-app/src/pages/Main.tsx b/packages/react/test-app/src/pages/Main.tsx index 944ac25419c..f4800b69db2 100644 --- a/packages/react/test-app/src/pages/Main.tsx +++ b/packages/react/test-app/src/pages/Main.tsx @@ -31,6 +31,11 @@ const Main: React.FC = () => { Overlay Components + + + Keep Contents Mounted Overlay Components + + Tabs diff --git a/packages/react/test-app/src/pages/overlay-components/KeepContentsMounted.tsx b/packages/react/test-app/src/pages/overlay-components/KeepContentsMounted.tsx new file mode 100644 index 00000000000..8f4e852737b --- /dev/null +++ b/packages/react/test-app/src/pages/overlay-components/KeepContentsMounted.tsx @@ -0,0 +1,38 @@ +import React, { useState } from 'react'; +import { + IonButton, + IonContent, + IonPage, + IonModal, + IonPopover, +} from '@ionic/react'; + +const KeepContentsMounted: React.FC = () => { + const [showModal, setShowModal] = useState(false); + const [showPopover, setShowPopover] = useState(false); + + return ( + + + setShowModal(true)}>Open Modal + setShowPopover(true)}>Open Popover + + setShowPopover(false)}> + + setShowModal(false)}>Dismiss + Modal Content + + + + setShowPopover(false)}> + + setShowPopover(false)}>Dismiss + Popover Content + + + + + ); +}; + +export default KeepContentsMounted; diff --git a/packages/vue/src/components/Overlays.ts b/packages/vue/src/components/Overlays.ts index 95f40dda760..a5f9d104a9e 100644 --- a/packages/vue/src/components/Overlays.ts +++ b/packages/vue/src/components/Overlays.ts @@ -29,7 +29,7 @@ export const IonPicker = /*@__PURE__*/ defineOverlayContainer('io export const IonToast = /*@__PURE__*/ defineOverlayContainer('ion-toast', defineIonToastCustomElement, ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'position', 'translucent'], toastController); -export const IonModal = /*@__PURE__*/ defineOverlayContainer('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'handle', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'swipeToClose', 'trigger']); +export const IonModal = /*@__PURE__*/ defineOverlayContainer('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'handle', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'swipeToClose', 'trigger']); -export const IonPopover = /*@__PURE__*/ defineOverlayContainer('ion-popover', defineIonPopoverCustomElement, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'translucent', 'trigger', 'triggerAction']); +export const IonPopover = /*@__PURE__*/ defineOverlayContainer('ion-popover', defineIonPopoverCustomElement, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'htmlAttributes', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'translucent', 'trigger', 'triggerAction']); diff --git a/packages/vue/src/vue-component-lib/overlays.ts b/packages/vue/src/vue-component-lib/overlays.ts index a59e72d7b5a..ede3ac4a379 100644 --- a/packages/vue/src/vue-component-lib/overlays.ts +++ b/packages/vue/src/vue-component-lib/overlays.ts @@ -162,7 +162,7 @@ export const defineOverlayContainer = (name: string, defin return h( name, { ...restOfProps, ref: elementRef }, - (isOpen.value) ? slots : undefined + (isOpen.value || restOfProps.keepContentsMounted) ? slots : undefined ) } }); diff --git a/packages/vue/test-app/src/components/PopoverContent.vue b/packages/vue/test-app/src/components/PopoverContent.vue index 8a3717968d5..94534e57da6 100644 --- a/packages/vue/test-app/src/components/PopoverContent.vue +++ b/packages/vue/test-app/src/components/PopoverContent.vue @@ -1,11 +1,16 @@ diff --git a/packages/vue/test-app/tests/e2e/specs/overlays-keep-contents-mounted.js b/packages/vue/test-app/tests/e2e/specs/overlays-keep-contents-mounted.js new file mode 100644 index 00000000000..269f3fc25c7 --- /dev/null +++ b/packages/vue/test-app/tests/e2e/specs/overlays-keep-contents-mounted.js @@ -0,0 +1,52 @@ +describe('overlays - keepContentsMounted', () => { + beforeEach(() => { + cy.viewport(1000, 900); + cy.visit('http://localhost:8080/keep-contents-mounted') + }) + describe('modal', () => { + it('should not mount component if false', () => { + cy.get('ion-modal#default-modal ion-content').should('not.exist'); + }); + + it('should mount component if true', () => { + cy.get('ion-modal#auto-mount-modal ion-content').should('exist'); + }); + + it('should keep component mounted after dismissing if true', () => { + cy.get('#open-auto-mount-modal').click(); + + cy.get('ion-modal#auto-mount-modal ion-content').should('exist'); + + cy.get('ion-modal#auto-mount-modal #dismiss').click(); + + cy.get('ion-modal#auto-mount-modal') + .should('not.be.visible') + .should('have.class', 'overlay-hidden'); + + cy.get('ion-modal#auto-mount-modal ion-content').should('exist'); + }); + }) + describe('popover', () => { + it('should not mount component if false', () => { + cy.get('ion-popover#default-popover ion-content').should('not.exist'); + }); + + it('should mount component if true', () => { + cy.get('ion-popover#auto-mount-popover ion-content').should('exist'); + }); + + it('should keep component mounted after dismissing if true', () => { + cy.get('#open-auto-mount-popover').click(); + + cy.get('ion-popover#auto-mount-popover ion-content').should('exist'); + + cy.get('ion-popover#auto-mount-popover #dismiss').click(); + + cy.get('ion-popover#auto-mount-popover') + .should('not.be.visible') + .should('have.class', 'overlay-hidden'); + + cy.get('ion-popover#auto-mount-popover ion-content').should('exist'); + }); + }) +}) diff --git a/packages/vue/test-app/tests/e2e/specs/overlays.js b/packages/vue/test-app/tests/e2e/specs/overlays.js index 5026fd244a6..fcb0360d3b0 100644 --- a/packages/vue/test-app/tests/e2e/specs/overlays.js +++ b/packages/vue/test-app/tests/e2e/specs/overlays.js @@ -134,7 +134,7 @@ describe('Overlays', () => { cy.get('ion-button#present-overlay').click(); cy.get('ion-popover.ion-popover-controller').should('exist'); - cy.get('ion-popover.ion-popover-controller ion-content').should('have.text', 'Custom Title'); + cy.get('ion-popover.ion-popover-controller ion-content #title').should('have.text', 'Custom Title'); }); it('should pass props to popover via component', () => { @@ -144,7 +144,7 @@ describe('Overlays', () => { cy.get('ion-button#present-overlay').click(); cy.get('ion-popover').should('exist'); - cy.get('ion-popover.popover-inline ion-content').should('have.text', 'Custom Title'); + cy.get('ion-popover.popover-inline ion-content #title').should('have.text', 'Custom Title'); }); it('should only open one instance at a time when props change quickly on component', () => {