Skip to content

Conversation

@ShaneK
Copy link
Member

@ShaneK ShaneK commented Dec 5, 2025

Issue number: resolves #30700


What is the current behavior?

When a sheet modal with showBackdrop=false is rendered in a child route (nested ion-router-outlet), the parent content becomes non-interactive. Clicks on buttons or other interactive elements in the parent component are blocked, even though showBackdrop=false should allow background interaction.

Two separate issues contributed to this bug:

  1. Root locking with backdropBreakpoint: The shouldLockRoot logic in overlays.ts didn't account for backdropBreakpoint. Modals with backdropBreakpoint > 0 were still locking the root with aria-hidden, even though developers expect background interaction when the modal is below the backdrop breakpoint.
  2. Child route wrapper blocking: When a modal is in a child route, the child route's page wrapper (ion-page) and its parent ion-router-outlet remain in the DOM with position: absolute covering the viewport. Even after the modal is moved to ion-app and has pointer-events: none, these wrapper elements block clicks to the parent page's content.

This issue stems from #30563, which added root-locking behavior that didn't account for modals that allow background interaction. A partial fix in #30689 partially addressed showBackdrop=false and focusTrap=false, but missed backdropBreakpoint.

What is the new behavior?

Sheet modals with showBackdrop=false or focusTrap=false now correctly allow interaction with parent content when the modal is in a child route.
Improvements:

  • Recalculates isSheetModal in present() to handle Angular binding timing
  • Sets pointer-events: none on the modal element and its original parent elements when background interaction should be allowed
  • Cleans up pointer-events on dismiss
  • Adds regression tests

Does this introduce a breaking change?

  • Yes
  • No

Other information

Dev build:

8.7.12-dev.11765060985.14ad27fb

…e aren't allowing clicks through the background
@ShaneK ShaneK requested a review from a team as a code owner December 5, 2025 02:49
@ShaneK ShaneK requested a review from BenOsodrac December 5, 2025 02:49
@vercel
Copy link

vercel bot commented Dec 5, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
ionic-framework Ready Ready Preview Comment Dec 6, 2025 10:44pm

@ShaneK ShaneK marked this pull request as ready for review December 5, 2025 19:19
@ShaneK ShaneK changed the title fix(modal): allow interaction with parent content when sheet modal has showBackdrop=false in child routes fix(modal): allow interaction with parent content through sheet modals in child routes Dec 5, 2025
Copy link
Contributor

@thetaPC thetaPC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main thing is that I couldn't get the Angular page to interact for me. Please let me know if I just missed something.

* passthrough on child route page wrappers and nested router outlets.
*/
private setupChildRoutePassthrough() {
const pageParent = this.getOriginalPageParent();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that getOriginalPageParent() gets called twice, here and cleanupChildRoutePassthrough(). Is it possible to save the pageParent as a private variable instead? So we don't have to run the while loop more than once?

Comment on lines +5 to +8
/**
* Child route component containing only the sheet modal with showBackdrop=false.
* Verifies issue https://github.com/ionic-team/ionic-framework/issues/30700
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call on having this comment! I don't we're in the habit of doing like this when it comes to Angular, React, or Vue.

Comment on lines +21 to +26
test('should allow interacting with parent content while modal is open in child route', async ({ page }) => {
await expect(page.locator('ion-modal.show-modal')).toBeVisible();

await page.locator('#increment-btn').click();
await expect(page.locator('#background-action-count')).toHaveText('1');
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was testing this scenario manually and I'm not able to interact with the background. This is happening on Firefox, Chrome, and Safari.

Screen.Recording.2025-12-08.at.11.49.19.AM.mov

{ path: 'modal', loadComponent: () => import('../modal/modal.component').then(c => c.ModalComponent) },
{ path: 'modal-sheet-inline', loadComponent: () => import('../modal-sheet-inline/modal-sheet-inline.component').then(c => c.ModalSheetInlineComponent) },
{ path: 'modal-dynamic-wrapper', loadComponent: () => import('../modal-dynamic-wrapper/modal-dynamic-wrapper.component').then(c => c.ModalDynamicWrapperComponent) },
{ path: 'modal-child-route', redirectTo: '/standalone/modal-child-route/child', pathMatch: 'full' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I didn't see it, it would be great to add a link on the Standalone page.

*/
describe('IonModal: Sheet in Child Route with Nested Routing', () => {
beforeEach(() => {
cy.visit('/overlay-components/modal-sheet-child-route/child');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this link to the main page? It would make it easier to navigate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: angular @ionic/angular package package: core @ionic/core package package: react @ionic/react package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: sheet modals can't skip focus-traps on child routes

4 participants