Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions packages/vue/src/utils/overlays.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { VNode, ComponentOptions } from "vue";
import { defineComponent, h, ref, onMounted } from "vue";
import type { ComponentOptions, VNode } from "vue";
import { defineComponent, h, onMounted, ref } from "vue";

// TODO(FW-2969): types

Expand Down Expand Up @@ -147,23 +147,32 @@ export const defineOverlayContainer = <Props extends object>(
const elementRef = ref();

onMounted(() => {
// Convert name from kebab-case to camelCase
const componentName = name.replace(/-([a-z])/g, (_, letter) =>
letter.toUpperCase()
);
elementRef.value.addEventListener("ionMount", (ev: Event) => {
emit("ionMount", ev);
emit(componentName + "IonMount", ev);
isOpen.value = true;
});
elementRef.value.addEventListener("willPresent", (ev: Event) => {
emit("willPresent", ev);
emit(componentName + "WillPresent", ev);
isOpen.value = true;
});
elementRef.value.addEventListener("didDismiss", (ev: Event) => {
emit("didDismiss", ev);
emit(componentName + "DidDismiss", ev);
isOpen.value = false;
});
elementRef.value.addEventListener("willDismiss", (ev: Event) => {
emit("willDismiss", ev);
emit(componentName + "WillDismiss", ev);
});
elementRef.value.addEventListener("didPresent", (ev: Event) => {
emit("didPresent", ev);
emit(componentName + "DidPresent", ev);
});
});

Expand Down
37 changes: 37 additions & 0 deletions packages/vue/test/base/src/views/Overlays.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@
Modal onDidPresent: <div id="didPresent">{{ didPresent }}</div><br />
Modal onWillDismiss: <div id="willDismiss">{{ willDismiss }}</div><br />
Modal onDidDismiss: <div id="didDismiss">{{ didDismiss }}</div><br />
Modal ionModalWillPresent: <div id="ionModalWillPresent">{{ ionModalWillPresent }}</div><br />
Modal ionModalDidPresent: <div id="ionModalDidPresent">{{ ionModalDidPresent }}</div><br />
Modal ionModalWillDismiss: <div id="ionModalWillDismiss">{{ ionModalWillDismiss }}</div><br />
Modal ionModalDidDismiss: <div id="ionModalDidDismiss">{{ ionModalDidDismiss }}</div><br />
</div>

<ion-action-sheet
Expand Down Expand Up @@ -98,6 +102,10 @@
@didPresent="onModalDidPresent"
@willDismiss="onModalWillDismiss"
@didDismiss="onModalDidDismiss"
@ionModalWillPresent="onIonModalWillPresent"
@ionModalDidPresent="onIonModalDidPresent"
@ionModalWillDismiss="onIonModalWillDismiss"
@ionModalDidDismiss="onIonModalDidDismiss"
>
<ModalContent :title="overlayProps.title"></ModalContent>
</ion-modal>
Expand Down Expand Up @@ -266,6 +274,19 @@ export default defineComponent({

const openModal = async () => {
const modal = await modalController.create({ cssClass: "ion-modal-controller", component: ModalContent, componentProps: overlayProps });

// Attach lifecycle listeners for controller-created modal
modal.addEventListener('willPresent', () => { willPresent.value += 1; });
modal.addEventListener('didPresent', () => { didPresent.value += 1; });
modal.addEventListener('willDismiss', () => { willDismiss.value += 1; });
modal.addEventListener('didDismiss', () => { didDismiss.value += 1; });

// Long-form event names
modal.addEventListener('ionModalWillPresent', () => { ionModalWillPresent.value += 1; });
modal.addEventListener('ionModalDidPresent', () => { ionModalDidPresent.value += 1; });
modal.addEventListener('ionModalWillDismiss', () => { ionModalWillDismiss.value += 1; });
modal.addEventListener('ionModalDidDismiss', () => { ionModalDidDismiss.value += 1; });

await modal.present();
}

Expand Down Expand Up @@ -335,21 +356,37 @@ export default defineComponent({
const didPresent = ref(0);
const willDismiss = ref(0);
const didDismiss = ref(0);
const ionModalWillPresent = ref(0);
const ionModalDidPresent = ref(0);
const ionModalWillDismiss = ref(0);
const ionModalDidDismiss = ref(0);

const onModalWillPresent = () => willPresent.value += 1;
const onModalDidPresent = () => { didPresent.value += 1; setModalRef(true); }
const onModalWillDismiss = () => willDismiss.value += 1;
const onModalDidDismiss = () => { didDismiss.value += 1; setModalRef(false); }
const onIonModalWillPresent = () => ionModalWillPresent.value += 1;
const onIonModalDidPresent = () => ionModalDidPresent.value += 1;
const onIonModalWillDismiss = () => ionModalWillDismiss.value += 1;
const onIonModalDidDismiss = () => ionModalDidDismiss.value += 1;

return {
onModalWillPresent,
onModalDidPresent,
onModalWillDismiss,
onModalDidDismiss,
onIonModalWillPresent,
onIonModalDidPresent,
onIonModalWillDismiss,
onIonModalDidDismiss,
willPresent,
didPresent,
willDismiss,
didDismiss,
ionModalWillPresent,
ionModalDidPresent,
ionModalWillDismiss,
ionModalDidDismiss,
changeLoadingProps,
overlayProps,
present,
Expand Down
159 changes: 153 additions & 6 deletions packages/vue/test/base/tests/e2e/specs/overlays.cy.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const testController = (overlay, shadow = false) => {
const selector = `.${overlay}-controller`;
cy.get(`ion-radio#${overlay}`).click();
cy.get('ion-radio#controller').click();
cy.get(`ion-radio#${overlay}`)
.scrollIntoView({ offset: { top: -100, left: 0 } })
.click({ force: true });
cy.get('ion-radio#controller')
.scrollIntoView({ offset: { top: -100, left: 0 } })
.click({ force: true });

cy.get('ion-button#present-overlay').click();
cy.get(selector).should('exist').should('be.visible');
Expand All @@ -16,8 +20,12 @@ const testController = (overlay, shadow = false) => {
}

const testComponent = (overlay, shadow = false) => {
cy.get(`ion-radio#${overlay}`).click();
cy.get('ion-radio#component').click();
cy.get(`ion-radio#${overlay}`)
.scrollIntoView({ offset: { top: -100, left: 0 } })
.click({ force: true });
cy.get('ion-radio#component')
.scrollIntoView({ offset: { top: -100, left: 0 } })
.click({ force: true });

cy.get('ion-button#present-overlay').click();
cy.get(overlay).should('exist').should('be.visible');
Expand All @@ -40,8 +48,12 @@ const testComponent = (overlay, shadow = false) => {
}

const testInlineOverlay = (overlay, shadow = false) => {
cy.get(`ion-radio#${overlay}`).click();
cy.get('ion-radio#component').click();
cy.get(`ion-radio#${overlay}`)
.scrollIntoView({ offset: { top: -100, left: 0 } })
.click({ force: true });
cy.get('ion-radio#component')
.scrollIntoView({ offset: { top: -100, left: 0 } })
.click({ force: true });

cy.get('ion-button#present-overlay').click();
cy.get(overlay).should('exist').should('be.visible');
Expand Down Expand Up @@ -214,6 +226,135 @@ describe('Overlays', () => {
});
});

it('should fire long-form lifecycle events on overlays', () => {
cy.get('ion-radio#ion-modal').click();
cy.get('ion-radio#component').click();

cy.get('ion-button#present-overlay').click();
cy.get('ion-modal').should('exist');

testLongLifecycle('overlays', {
willPresent: 1,
didPresent: 1,
willDismiss: 0,
didDismiss: 0
});

cy.get('ion-modal #dismiss').click();

testLongLifecycle('overlays', {
willPresent: 1,
didPresent: 1,
willDismiss: 1,
didDismiss: 1
});

cy.get('ion-button#present-overlay').click();
cy.get('ion-modal').should('exist');

testLongLifecycle('overlays', {
willPresent: 2,
didPresent: 2,
willDismiss: 1,
didDismiss: 1
});

cy.get('ion-modal #dismiss').click();

testLongLifecycle('overlays', {
willPresent: 2,
didPresent: 2,
willDismiss: 2,
didDismiss: 2
});
});

it('should fire lifecycle events on controller overlays', () => {
cy.get('ion-radio#ion-modal').click();
cy.get('ion-radio#controller').click();

cy.get('ion-button#present-overlay').click();
cy.get('ion-modal').should('exist');

testLifecycle('overlays', {
willPresent: 1,
didPresent: 1,
willDismiss: 0,
didDismiss: 0
});

cy.get('ion-modal #dismiss').click();

testLifecycle('overlays', {
willPresent: 1,
didPresent: 1,
willDismiss: 1,
didDismiss: 1
});

cy.get('ion-button#present-overlay').click();
cy.get('ion-modal').should('exist');

testLifecycle('overlays', {
willPresent: 2,
didPresent: 2,
willDismiss: 1,
didDismiss: 1
});

cy.get('ion-modal #dismiss').click();

testLifecycle('overlays', {
willPresent: 2,
didPresent: 2,
willDismiss: 2,
didDismiss: 2
});
});

it('should fire long-form lifecycle events on controller overlays', () => {
cy.get('ion-radio#ion-modal').click();
cy.get('ion-radio#controller').click();

cy.get('ion-button#present-overlay').click();
cy.get('ion-modal').should('exist');

testLongLifecycle('overlays', {
willPresent: 1,
didPresent: 1,
willDismiss: 0,
didDismiss: 0
});

cy.get('ion-modal #dismiss').click();

testLongLifecycle('overlays', {
willPresent: 1,
didPresent: 1,
willDismiss: 1,
didDismiss: 1
});

cy.get('ion-button#present-overlay').click();
cy.get('ion-modal').should('exist');

testLongLifecycle('overlays', {
willPresent: 2,
didPresent: 2,
willDismiss: 1,
didDismiss: 1
});

cy.get('ion-modal #dismiss').click();

testLongLifecycle('overlays', {
willPresent: 2,
didPresent: 2,
willDismiss: 2,
didDismiss: 2
});
});

it('should unmount modal via component', () => {
cy.get('ion-radio#ion-modal').click();
cy.get('ion-radio#component').click();
Expand Down Expand Up @@ -260,3 +401,9 @@ const testLifecycle = (selector, expected = {}) => {
cy.get(`[data-pageid=${selector}] #didDismiss`).should('have.text', expected.didDismiss);
}

const testLongLifecycle = (selector, expected = {}) => {
cy.get(`[data-pageid=${selector}] #ionModalWillPresent`).should('have.text', expected.willPresent);
cy.get(`[data-pageid=${selector}] #ionModalDidPresent`).should('have.text', expected.didPresent);
cy.get(`[data-pageid=${selector}] #ionModalWillDismiss`).should('have.text', expected.willDismiss);
cy.get(`[data-pageid=${selector}] #ionModalDidDismiss`).should('have.text', expected.didDismiss);
}
Loading