From 2a80eb6bd0b16a9dab9bea600bb7f935d25c0e1b Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Thu, 31 Aug 2023 09:10:36 -0400 Subject: [PATCH] fix(popover): dynamic width popover is positioned correctly (#28072) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue number: resolves #27190, resolves #24780 --------- ## What is the current behavior? Popovers with dynamic widths were not being positioned correctly relative to the trigger element. This was happening because the child component always had dimensions of 0 x 0. Ionic has logic built-in to wait for the child components to be rendered, but this was not working as intended for two reasons: 1. `this.usersElement` was referencing the popover element itself not the user’s component. When calling `deepReady` on https://github.com/ionic-team/ionic-framework/blob/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a/core/src/components/popover/popover.tsx#L477 we are waiting for the popover to be hydrated, not the child content. The popover was already hydrated on page load, so this resolves immediately. However, the child content that was just added to the DOM has not yet been hydrated, so we aren’t waiting long enough. This is happening because we return `BaseComponent `from `attachComponent` which is a reference to the overlay: https://github.com/ionic-team/ionic-framework/blob/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a/core/src/utils/framework-delegate.ts#L133 Other framework delegates return the actual child content: - Core delegate with controller: https://github.com/ionic-team/ionic-framework/blob/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a/core/src/utils/framework-delegate.ts#L35 (this is part of why the controller popover works but the inline popover does not) - React delegate: https://github.com/ionic-team/ionic-framework/blob/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a/packages/react/src/framework-delegate.tsx#L31 - Vue delegate: https://github.com/ionic-team/ionic-framework/blob/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a/packages/vue/src/framework-delegate.ts#L45 2. `attachComponent` is unable to return the correct element currently because the child content has not been mounted yet in this scenario. `ionMount` is emitted after `attachComponent` resolves: https://github.com/ionic-team/ionic-framework/blob/01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a/core/src/components/popover/popover.tsx#L466 ## What is the new behavior? - `ionMount` is emitted before `attachComponent` runs - `attachComponent` now consistently returns the child view if present in the DOM - Added a test ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev build: `7.3.2-dev.11693321763.15a54694` --------- Co-authored-by: ionitron --- core/src/components/modal/modal.tsx | 8 ++- core/src/components/popover/popover.tsx | 10 +++- .../components/popover/test/async/index.html | 51 +++++++++++++++++ .../popover/test/async/popover.e2e.ts | 54 ++++++++++++++++++ ...over-async-ios-ltr-Mobile-Chrome-linux.png | Bin 0 -> 5722 bytes ...ver-async-ios-ltr-Mobile-Firefox-linux.png | Bin 0 -> 13572 bytes ...over-async-ios-ltr-Mobile-Safari-linux.png | Bin 0 -> 5454 bytes core/src/utils/framework-delegate.ts | 25 +++++++- 8 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 core/src/components/popover/test/async/index.html create mode 100644 core/src/components/popover/test/async/popover.e2e.ts create mode 100644 core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Chrome-linux.png create mode 100644 core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Firefox-linux.png create mode 100644 core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Safari-linux.png diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 0a2dd0f8a8..7d877fe39a 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -447,10 +447,16 @@ export class Modal implements ComponentInterface, OverlayInterface { this.currentBreakpoint = this.initialBreakpoint; const { inline, delegate } = this.getDelegate(true); - this.usersElement = await attachComponent(delegate, el, this.component, ['ion-page'], this.componentProps, inline); + /** + * Emit ionMount so JS Frameworks have an opportunity + * to add the child component to the DOM. The child + * component will be assigned to this.usersElement below. + */ this.ionMount.emit(); + this.usersElement = await attachComponent(delegate, el, this.component, ['ion-page'], this.componentProps, inline); + /** * When using the lazy loaded build of Stencil, we need to wait * for every Stencil component instance to be ready before presenting diff --git a/core/src/components/popover/popover.tsx b/core/src/components/popover/popover.tsx index d32856eedb..476b150d74 100644 --- a/core/src/components/popover/popover.tsx +++ b/core/src/components/popover/popover.tsx @@ -449,6 +449,14 @@ export class Popover implements ComponentInterface, PopoverInterface { const { el } = this; const { inline, delegate } = this.getDelegate(true); + + /** + * Emit ionMount so JS Frameworks have an opportunity + * to add the child component to the DOM. The child + * component will be assigned to this.usersElement below. + */ + this.ionMount.emit(); + this.usersElement = await attachComponent( delegate, el, @@ -463,8 +471,6 @@ export class Popover implements ComponentInterface, PopoverInterface { } this.configureDismissInteraction(); - this.ionMount.emit(); - /** * When using the lazy loaded build of Stencil, we need to wait * for every Stencil component instance to be ready before presenting diff --git a/core/src/components/popover/test/async/index.html b/core/src/components/popover/test/async/index.html new file mode 100644 index 0000000000..de480f6328 --- /dev/null +++ b/core/src/components/popover/test/async/index.html @@ -0,0 +1,51 @@ + + + + + Popover - Async + + + + + + + + + +
+ +
+ + +
+ + + + diff --git a/core/src/components/popover/test/async/popover.e2e.ts b/core/src/components/popover/test/async/popover.e2e.ts new file mode 100644 index 0000000000..f1630ec19a --- /dev/null +++ b/core/src/components/popover/test/async/popover.e2e.ts @@ -0,0 +1,54 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * This behavior does not vary across modes/directions + */ +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('popover: alignment with async component'), async () => { + test('should align popover centered with button when component is added async', async ({ page }) => { + await page.goto('/src/components/popover/test/async', config); + + const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent'); + + const button = page.locator('#button'); + await button.click(); + + await ionPopoverDidPresent.next(); + + await expect(page).toHaveScreenshot(screenshot(`popover-async`)); + }); + /** + * Framework delegate should fall back to returning the host + * component when no child content is passed otherwise + * the overlay will get stuck when trying to re-present. + */ + test('should open popover even if nothing was passed', async ({ page }) => { + await page.setContent( + ` + + `, + config + ); + + const popover = page.locator('ion-popover'); + const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent'); + const ionPopoverDidDismiss = await page.spyOnEvent('ionPopoverDidDismiss'); + + await popover.evaluate((el: HTMLIonPopoverElement) => el.present()); + + await ionPopoverDidPresent.next(); + await expect(popover).toBeVisible(); + + await popover.evaluate((el: HTMLIonPopoverElement) => el.dismiss()); + + await ionPopoverDidDismiss.next(); + await expect(popover).toBeHidden(); + + await popover.evaluate((el: HTMLIonPopoverElement) => el.present()); + + await ionPopoverDidPresent.next(); + await expect(popover).toBeVisible(); + }); + }); +}); diff --git a/core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Chrome-linux.png b/core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Chrome-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..1dbf1755ef2a70d37761df6791f4c2ef7f55f6a8 GIT binary patch literal 5722 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 Sx-0lu4D&l2=*>A8ap~XpKb}_r literal 0 HcmV?d00001 diff --git a/core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Firefox-linux.png b/core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Firefox-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..c1be140389b97414dbe68d468129f3442f6426b1 GIT binary patch literal 13572 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 literal 0 HcmV?d00001 diff --git a/core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Safari-linux.png b/core/src/components/popover/test/async/popover.e2e.ts-snapshots/popover-async-ios-ltr-Mobile-Safari-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..3b0f0b0601c1e9b6cb2dad788740cc299cd75376 GIT binary patch literal 5454 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 { cssClasses: string[] = [] ) => { BaseComponent = parentElement; + let ChildComponent; /** * If passing in a component via the `component` props * we need to append it inside of our overlay component. @@ -87,6 +88,8 @@ export const CoreDelegate = () => { */ BaseComponent.appendChild(el); + ChildComponent = el; + await new Promise((resolve) => componentOnReady(el, resolve)); } else if ( BaseComponent.children.length > 0 && @@ -96,7 +99,7 @@ export const CoreDelegate = () => { * The delegate host wrapper el is only needed for modals and popovers * because they allow the dev to provide custom content to the overlay. */ - const root = BaseComponent.children[0] as HTMLElement; + const root = (ChildComponent = BaseComponent.children[0] as HTMLElement); if (!root.classList.contains('ion-delegate-host')) { /** * If the root element is not a delegate host, it means @@ -111,6 +114,13 @@ export const CoreDelegate = () => { el.append(...BaseComponent.children); // Append the new parent element to the original parent element. BaseComponent.appendChild(el); + + /** + * Update the ChildComponent to be the + * newly created div in the event that one + * does not already exist. + */ + ChildComponent = el; } } @@ -130,7 +140,18 @@ export const CoreDelegate = () => { app.appendChild(BaseComponent); - return BaseComponent; + /** + * We return the child component rather than the overlay + * reference itself since modal and popover will + * use this to wait for any Ionic components in the child view + * to be ready (i.e. componentOnReady) when using the + * lazy loaded component bundle. + * + * However, we fall back to returning BaseComponent + * in the event that a modal or popover is presented + * with no child content. + */ + return ChildComponent ?? BaseComponent; }; const removeViewFromDom = () => {