From 240905b4e841655dcbece89d0ea0e2dff72eca30 Mon Sep 17 00:00:00 2001 From: Austin-Spriggs Date: Mon, 29 Jun 2026 06:56:53 -0500 Subject: [PATCH 1/3] fix: Modal content-size now gets recalculated when the header is finished rendering --- core/src/components/modal/modal.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 0ea66ce8cfe..bbe6f2504d2 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -644,6 +644,10 @@ export class Modal implements ComponentInterface, OverlayInterface { await waitForMount(); } + // Recalculate content dimensions before showing the modal so the initial + // paint uses the final content offset and background geometry. + await this.recalculateContentDimensions(); + writeTask(() => this.el.classList.add('show-modal')); // Recalculate isSheetModal before safe-area setup because framework @@ -1517,6 +1521,18 @@ export class Modal implements ComponentInterface, OverlayInterface { this.applyFullscreenSafeAreaTo(contentEl, hasFooter); } + /** + * Recalculates the inner ion-content dimensions after the modal has mounted so + * its offsets and background geometry reflect the modal's final size before it is shown. + */ + private async recalculateContentDimensions(): Promise { + const contentEl = this.el.querySelector('ion-content') as HTMLIonContentElement | null; + + if (contentEl) { + await contentEl.recalculateDimensions(); + } + } + /** * Sets --internal-content-safe-area-padding-bottom on the given ion-content * when no footer is present, so ion-content's .inner-scroll includes From 4d29b27fcd8a81466a9329066d950ba324ae2a0e Mon Sep 17 00:00:00 2001 From: Austin-Spriggs Date: Mon, 29 Jun 2026 06:57:20 -0500 Subject: [PATCH 2/3] fix: Test for the recalculated content dimensions on a Modal --- .../modal/test/basic/modal.spec.tsx | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/core/src/components/modal/test/basic/modal.spec.tsx b/core/src/components/modal/test/basic/modal.spec.tsx index 67996e2ad18..f39556db823 100644 --- a/core/src/components/modal/test/basic/modal.spec.tsx +++ b/core/src/components/modal/test/basic/modal.spec.tsx @@ -2,6 +2,7 @@ import { h } from '@stencil/core'; import { newSpecPage } from '@stencil/core/testing'; import { Modal } from '../../modal'; +import { Content } from '../../../content/content' import { FOCUS_TRAP_DISABLE_CLASS } from '@utils/overlays'; describe('modal: htmlAttributes inheritance', () => { @@ -39,3 +40,27 @@ describe('modal: focus trap', () => { expect(modal.classList.contains(FOCUS_TRAP_DISABLE_CLASS)).toBe(false); }); }); + +describe('modal: content dimensions', () => { + it('should recalculate ion-content dimensions before presenting', async () => { + const page = await newSpecPage({ + components: [Content, Modal], + template: () => ( + + Test Content + + ), + }); + + const modal = page.body.querySelector('ion-modal')!; + + const recalculateSpy = jest + .spyOn(Content.prototype, 'recalculateDimensions') + .mockResolvedValue(undefined); + + await modal.present(); + await page.waitForChanges(); + + expect(recalculateSpy).toHaveBeenCalledTimes(1); + }); +}); From a4cf092f1de1f2345d241cb92b9486ddb7946ef4 Mon Sep 17 00:00:00 2001 From: Austin-Spriggs Date: Mon, 29 Jun 2026 07:00:35 -0500 Subject: [PATCH 3/3] fix: Missed semi-colon --- core/src/components/modal/test/basic/modal.spec.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/components/modal/test/basic/modal.spec.tsx b/core/src/components/modal/test/basic/modal.spec.tsx index f39556db823..70800e3cc71 100644 --- a/core/src/components/modal/test/basic/modal.spec.tsx +++ b/core/src/components/modal/test/basic/modal.spec.tsx @@ -2,7 +2,7 @@ import { h } from '@stencil/core'; import { newSpecPage } from '@stencil/core/testing'; import { Modal } from '../../modal'; -import { Content } from '../../../content/content' +import { Content } from '../../../content/content'; import { FOCUS_TRAP_DISABLE_CLASS } from '@utils/overlays'; describe('modal: htmlAttributes inheritance', () => { @@ -54,9 +54,7 @@ describe('modal: content dimensions', () => { const modal = page.body.querySelector('ion-modal')!; - const recalculateSpy = jest - .spyOn(Content.prototype, 'recalculateDimensions') - .mockResolvedValue(undefined); + const recalculateSpy = jest.spyOn(Content.prototype, 'recalculateDimensions').mockResolvedValue(undefined); await modal.present(); await page.waitForChanges();