From c4f811f1dde0dcbcdaebaa3a4f5ef87e192b5cc5 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 3 May 2022 10:36:41 -0400 Subject: [PATCH] fix(modal): card modal no longer dismisses from content with refresher (#25227) --- .../modal/gestures/swipe-to-close.ts | 12 +- .../modal/test/card-refresher/index.html | 111 ++++++++++++++++++ .../modal/test/card-refresher/modal.e2e.ts | 25 ++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 core/src/components/modal/test/card-refresher/index.html create mode 100644 core/src/components/modal/test/card-refresher/modal.e2e.ts diff --git a/core/src/components/modal/gestures/swipe-to-close.ts b/core/src/components/modal/gestures/swipe-to-close.ts index 7ce0d255b1..375d53565e 100644 --- a/core/src/components/modal/gestures/swipe-to-close.ts +++ b/core/src/components/modal/gestures/swipe-to-close.ts @@ -23,6 +23,7 @@ export const createSwipeToCloseGesture = ( let isOpen = false; let canDismissBlocksGesture = false; const canDismissMaxStep = 0.2; + const hasRefresherInContent = !!contentEl.querySelector('ion-refresher'); const getScrollY = () => { if (isIonContent(contentEl)) { return (contentEl as HTMLIonContentElement).scrollY; @@ -69,7 +70,16 @@ export const createSwipeToCloseGesture = ( */ const content = target.closest('ion-content'); if (content) { - return scrollEl.scrollTop === 0; + /** + * The card should never swipe to close + * on the content with a refresher. + * Note: We cannot solve this by making the + * swipeToClose gesture have a higher priority + * than the refresher gesture as the iOS native + * refresh gesture uses a scroll listener in + * addition to a gesture. + */ + return !hasRefresherInContent && scrollEl.scrollTop === 0; } /** diff --git a/core/src/components/modal/test/card-refresher/index.html b/core/src/components/modal/test/card-refresher/index.html new file mode 100644 index 0000000000..3b387b2c58 --- /dev/null +++ b/core/src/components/modal/test/card-refresher/index.html @@ -0,0 +1,111 @@ + + + + + Modal - Card + + + + + + + + + + + + + +
+ + + Card + + + + + Card Modal + +
+
+ + + + diff --git a/core/src/components/modal/test/card-refresher/modal.e2e.ts b/core/src/components/modal/test/card-refresher/modal.e2e.ts new file mode 100644 index 0000000000..2c6f8521fb --- /dev/null +++ b/core/src/components/modal/test/card-refresher/modal.e2e.ts @@ -0,0 +1,25 @@ +import { expect } from '@playwright/test'; +import { dragElementBy, test } from '@utils/test/playwright'; + +test.describe('card modal - with refresher', () => { + test.beforeEach(async ({ page }, testInfo) => { + test.skip(testInfo.project.metadata.mode !== 'ios', 'Card style modal is only available on iOS'); + + await page.goto('/src/components/modal/test/card-refresher'); + }); + test('it should not swipe to close on the content due to the presence of the refresher', async ({ page }) => { + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await page.click('#card'); + await ionModalDidPresent.next(); + + const modal = await page.locator('ion-modal'); + const content = (await page.$('ion-modal ion-content'))!; + + await dragElementBy(content, page, 0, 500); + + await content.waitForElementState('stable'); + + expect(modal).toBeVisible(); + }); +});