From b9e3cf0f5aae79a1f27a07b102c77e51f24825f4 Mon Sep 17 00:00:00 2001 From: Shane Date: Wed, 10 Dec 2025 13:08:48 -0800 Subject: [PATCH 1/4] fix(modal): allow interaction with parent content through sheet modals in child routes (#30839) 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](https://github.com/ionic-team/ionic-framework/pull/30563), which added root-locking behavior that didn't account for modals that allow background interaction. A partial fix in [#30689](https://github.com/ionic-team/ionic-framework/pull/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 - [X] No ## Other information Dev build: ``` 8.7.12-dev.11765060985.14ad27fb ``` --- core/src/components/modal/modal.tsx | 100 +++++++++++++++++- core/src/css/core.scss | 9 ++ core/src/utils/overlays.ts | 28 +++-- .../src/standalone/modal-child-route.spec.ts | 38 +++++++ .../standalone/app-standalone/app.routes.ts | 8 ++ .../home-page/home-page.component.html | 5 + .../modal-child-route-child.component.ts | 33 ++++++ .../modal-child-route-parent.component.ts | 38 +++++++ .../ModalSheetChildRoute.tsx | 69 ++++++++++++ .../overlay-components/OverlayComponents.tsx | 6 ++ .../IonModalFocusTrap.cy.ts | 6 +- .../IonModalSheetChildRoute.cy.ts | 37 +++++++ 12 files changed, 365 insertions(+), 12 deletions(-) create mode 100644 packages/angular/test/base/e2e/src/standalone/modal-child-route.spec.ts create mode 100644 packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-child.component.ts create mode 100644 packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-parent.component.ts create mode 100644 packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx create mode 100644 packages/react/test/base/tests/e2e/specs/overlay-components/IonModalSheetChildRoute.cy.ts diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index b1a494430d..dbed406ca4 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -71,7 +71,7 @@ export class Modal implements ComponentInterface, OverlayInterface { private gesture?: Gesture; private coreDelegate: FrameworkDelegate = CoreDelegate(); private sheetTransition?: Promise; - private isSheetModal = false; + @State() private isSheetModal = false; private currentBreakpoint?: number; private wrapperEl?: HTMLElement; private backdropEl?: HTMLIonBackdropElement; @@ -100,6 +100,8 @@ export class Modal implements ComponentInterface, OverlayInterface { private parentRemovalObserver?: MutationObserver; // Cached original parent from before modal is moved to body during presentation private cachedOriginalParent?: HTMLElement; + // Cached ion-page ancestor for child route passthrough + private cachedPageParent?: HTMLElement | null; lastFocus?: HTMLElement; animation?: Animation; @@ -644,7 +646,14 @@ export class Modal implements ComponentInterface, OverlayInterface { window.addEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback); } - if (this.isSheetModal) { + /** + * Recalculate isSheetModal because framework bindings (e.g., Angular) + * may not have been applied when componentWillLoad ran. + */ + const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined; + this.isSheetModal = isSheetModal; + + if (isSheetModal) { this.initSheetGesture(); } else if (hasCardModal) { this.initSwipeToClose(); @@ -753,6 +762,91 @@ export class Modal implements ComponentInterface, OverlayInterface { this.moveSheetToBreakpoint = moveSheetToBreakpoint; this.gesture.enable(true); + + /** + * When backdrop interaction is allowed, nested router outlets from child routes + * may block pointer events to parent content. Apply passthrough styles only when + * the modal was the sole content of a child route page. + * See https://github.com/ionic-team/ionic-framework/issues/30700 + */ + const backdropNotBlocking = this.showBackdrop === false || this.focusTrap === false || backdropBreakpoint > 0; + if (backdropNotBlocking) { + this.setupChildRoutePassthrough(); + } + } + + /** + * For sheet modals that allow background interaction, sets up pointer-events + * passthrough on child route page wrappers and nested router outlets. + */ + private setupChildRoutePassthrough() { + // Cache the page parent for cleanup + this.cachedPageParent = this.getOriginalPageParent(); + const pageParent = this.cachedPageParent; + + // Skip ion-app (controller modals) and pages with visible sibling content next to the modal + if (!pageParent || pageParent.tagName === 'ION-APP') { + return; + } + + const hasVisibleContent = Array.from(pageParent.children).some( + (child) => + child !== this.el && + !(child instanceof HTMLElement && window.getComputedStyle(child).display === 'none') && + child.tagName !== 'TEMPLATE' && + child.tagName !== 'SLOT' && + !(child.nodeType === Node.TEXT_NODE && !child.textContent?.trim()) + ); + + if (hasVisibleContent) { + return; + } + + // Child route case: page only contained the modal + pageParent.classList.add('ion-page-overlay-passthrough'); + + // Also make nested router outlets passthrough + const routerOutlet = pageParent.parentElement; + if (routerOutlet?.tagName === 'ION-ROUTER-OUTLET' && routerOutlet.parentElement?.tagName !== 'ION-APP') { + routerOutlet.style.setProperty('pointer-events', 'none'); + routerOutlet.setAttribute('data-overlay-passthrough', 'true'); + } + } + + /** + * Finds the ion-page ancestor of the modal's original parent location. + */ + private getOriginalPageParent(): HTMLElement | null { + if (!this.cachedOriginalParent) { + return null; + } + + let pageParent: HTMLElement | null = this.cachedOriginalParent; + while (pageParent && !pageParent.classList.contains('ion-page')) { + pageParent = pageParent.parentElement; + } + return pageParent; + } + + /** + * Removes passthrough styles added by setupChildRoutePassthrough. + */ + private cleanupChildRoutePassthrough() { + const pageParent = this.cachedPageParent; + if (!pageParent) { + return; + } + + pageParent.classList.remove('ion-page-overlay-passthrough'); + + const routerOutlet = pageParent.parentElement; + if (routerOutlet?.hasAttribute('data-overlay-passthrough')) { + routerOutlet.style.removeProperty('pointer-events'); + routerOutlet.removeAttribute('data-overlay-passthrough'); + } + + // Clear the cached reference + this.cachedPageParent = undefined; } private sheetOnDismiss() { @@ -862,6 +956,8 @@ export class Modal implements ComponentInterface, OverlayInterface { } this.cleanupViewTransitionListener(); this.cleanupParentRemovalObserver(); + + this.cleanupChildRoutePassthrough(); } this.currentBreakpoint = undefined; this.animation = undefined; diff --git a/core/src/css/core.scss b/core/src/css/core.scss index cf7560bd34..db694fc6a0 100644 --- a/core/src/css/core.scss +++ b/core/src/css/core.scss @@ -181,6 +181,15 @@ html.ios ion-modal.modal-card .ion-page { z-index: $z-index-page-container; } +/** + * Allows pointer events to pass through child route page wrappers + * when they only contain a sheet modal that permits background interaction. + * https://github.com/ionic-team/ionic-framework/issues/30700 + */ +.ion-page.ion-page-overlay-passthrough { + pointer-events: none; +} + /** * When making custom dialogs, using * ion-content is not required. As a result, diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 5b983158aa..472a57559d 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -38,6 +38,20 @@ let lastId = 0; export const activeAnimations = new WeakMap(); +type OverlayWithFocusTrapProps = HTMLIonOverlayElement & { + focusTrap?: boolean; + showBackdrop?: boolean; + backdropBreakpoint?: number; +}; + +/** + * Determines if the overlay's backdrop is always blocking (no background interaction). + * Returns false if showBackdrop=false or backdropBreakpoint > 0. + */ +const isBackdropAlwaysBlocking = (el: OverlayWithFocusTrapProps): boolean => { + return el.showBackdrop !== false && !((el.backdropBreakpoint ?? 0) > 0); +}; + const createController = (tagName: string) => { return { create(options: Opts): Promise { @@ -539,11 +553,9 @@ export const present = async ( * view container subtree, skip adding aria-hidden/inert there * to avoid disabling the overlay. */ - const overlayEl = overlay.el as HTMLIonOverlayElement & { focusTrap?: boolean; showBackdrop?: boolean }; + const overlayEl = overlay.el as OverlayWithFocusTrapProps; const shouldTrapFocus = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false; - // Only lock out root content when backdrop is active. Developers relying on showBackdrop=false - // expect background interaction to remain enabled. - const shouldLockRoot = shouldTrapFocus && overlayEl.showBackdrop !== false; + const shouldLockRoot = shouldTrapFocus && isBackdropAlwaysBlocking(overlayEl); overlay.presented = true; overlay.willPresent.emit(); @@ -680,12 +692,12 @@ export const dismiss = async ( * is dismissed. */ const overlaysLockingRoot = presentedOverlays.filter((o) => { - const el = o as HTMLIonOverlayElement & { focusTrap?: boolean; showBackdrop?: boolean }; - return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && el.showBackdrop !== false; + const el = o as OverlayWithFocusTrapProps; + return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && isBackdropAlwaysBlocking(el); }); - const overlayEl = overlay.el as HTMLIonOverlayElement & { focusTrap?: boolean; showBackdrop?: boolean }; + const overlayEl = overlay.el as OverlayWithFocusTrapProps; const locksRoot = - overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && overlayEl.showBackdrop !== false; + overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && isBackdropAlwaysBlocking(overlayEl); /** * If this is the last visible overlay that is trapping focus diff --git a/packages/angular/test/base/e2e/src/standalone/modal-child-route.spec.ts b/packages/angular/test/base/e2e/src/standalone/modal-child-route.spec.ts new file mode 100644 index 0000000000..d479599bcc --- /dev/null +++ b/packages/angular/test/base/e2e/src/standalone/modal-child-route.spec.ts @@ -0,0 +1,38 @@ +import { expect, test } from '@playwright/test'; + +/** + * Tests for sheet modals in child routes with showBackdrop=false. + * Parent has buttons + nested outlet; child route contains only the modal. + * See https://github.com/ionic-team/ionic-framework/issues/30700 + */ +test.describe('Modals: Inline Sheet in Child Route (standalone)', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/standalone/modal-child-route/child'); + }); + + test('should render parent content and child modal', async ({ page }) => { + await expect(page.locator('#increment-btn')).toBeVisible(); + await expect(page.locator('#decrement-btn')).toBeVisible(); + await expect(page.locator('#background-action-count')).toHaveText('0'); + await expect(page.locator('ion-modal.show-modal')).toBeVisible(); + await expect(page.locator('#modal-content-loaded')).toBeVisible(); + }); + + 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'); + }); + + test('should allow multiple interactions with parent content while modal is open', async ({ page }) => { + await expect(page.locator('ion-modal.show-modal')).toBeVisible(); + + await page.locator('#increment-btn').click(); + await page.locator('#increment-btn').click(); + await expect(page.locator('#background-action-count')).toHaveText('2'); + + await page.locator('#decrement-btn').click(); + await expect(page.locator('#background-action-count')).toHaveText('1'); + }); +}); diff --git a/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts b/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts index 007743f905..667ef672e8 100644 --- a/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts +++ b/packages/angular/test/base/src/app/standalone/app-standalone/app.routes.ts @@ -13,6 +13,14 @@ export const routes: Routes = [ { 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' }, + { + path: 'modal-child-route', + loadComponent: () => import('../modal-child-route/modal-child-route-parent.component').then(c => c.ModalChildRouteParentComponent), + children: [ + { path: 'child', loadComponent: () => import('../modal-child-route/modal-child-route-child.component').then(c => c.ModalChildRouteChildComponent) }, + ] + }, { path: 'programmatic-modal', loadComponent: () => import('../programmatic-modal/programmatic-modal.component').then(c => c.ProgrammaticModalComponent) }, { path: 'router-outlet', loadComponent: () => import('../router-outlet/router-outlet.component').then(c => c.RouterOutletComponent) }, { path: 'back-button', loadComponent: () => import('../back-button/back-button.component').then(c => c.BackButtonComponent) }, diff --git a/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html b/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html index 7ac9c61918..6dbad643eb 100644 --- a/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html +++ b/packages/angular/test/base/src/app/standalone/home-page/home-page.component.html @@ -100,6 +100,11 @@ Modal Dynamic Wrapper Test + + + Modal Child Route Test + + Programmatic Modal Test diff --git a/packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-child.component.ts b/packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-child.component.ts new file mode 100644 index 0000000000..6fa573fa19 --- /dev/null +++ b/packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-child.component.ts @@ -0,0 +1,33 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { IonContent, IonHeader, IonModal, IonTitle, IonToolbar } from '@ionic/angular/standalone'; + +/** + * Child route component containing only the sheet modal with showBackdrop=false. + * Verifies issue https://github.com/ionic-team/ionic-framework/issues/30700 + */ +@Component({ + selector: 'app-modal-child-route-child', + template: ` + + + + + Modal in Child Route + + + + + + + + `, + standalone: true, + imports: [CommonModule, IonContent, IonHeader, IonModal, IonTitle, IonToolbar], +}) +export class ModalChildRouteChildComponent {} diff --git a/packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-parent.component.ts b/packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-parent.component.ts new file mode 100644 index 0000000000..fdd5465ad1 --- /dev/null +++ b/packages/angular/test/base/src/app/standalone/modal-child-route/modal-child-route-parent.component.ts @@ -0,0 +1,38 @@ +import { Component } from '@angular/core'; +import { IonButton, IonContent, IonHeader, IonRouterOutlet, IonTitle, IonToolbar } from '@ionic/angular/standalone'; + +/** + * Parent with interactive buttons and nested outlet for child route modal. + * See https://github.com/ionic-team/ionic-framework/issues/30700 + */ +@Component({ + selector: 'app-modal-child-route-parent', + template: ` + + + Parent Page with Nested Route + + + +
+ - +

{{ count }}

+ + +
+ +
+ `, + standalone: true, + imports: [IonButton, IonContent, IonHeader, IonRouterOutlet, IonTitle, IonToolbar], +}) +export class ModalChildRouteParentComponent { + count = 0; + + increment() { + this.count++; + } + + decrement() { + this.count--; + } +} diff --git a/packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx b/packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx new file mode 100644 index 0000000000..e686bbd00e --- /dev/null +++ b/packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx @@ -0,0 +1,69 @@ +import React, { useState } from 'react'; +import { + IonButton, + IonContent, + IonHeader, + IonModal, + IonPage, + IonRouterOutlet, + IonTitle, + IonToolbar, +} from '@ionic/react'; +import { Route } from 'react-router'; + +/** + * Parent component with counter buttons and nested router outlet. + * This reproduces the issue from https://github.com/ionic-team/ionic-framework/issues/30700 + * where sheet modals in child routes with showBackdrop=false block interaction with parent content. + */ +const ModalSheetChildRouteParent: React.FC = () => { + const [count, setCount] = useState(0); + + return ( + + + + Parent Page with Nested Route + + + +
+ setCount((c) => c - 1)}> + - + +

{count}

+ setCount((c) => c + 1)}> + + + +
+
+ + + +
+ ); +}; + +const ModalSheetChildRouteChild: React.FC = () => { + return ( + + + + + Modal in Child Route + + + + + + + + ); +}; + +export default ModalSheetChildRouteParent; diff --git a/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx b/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx index 19aebc9081..75bf98bb73 100644 --- a/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx +++ b/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx @@ -15,6 +15,7 @@ import AlertComponent from './AlertComponent'; import LoadingComponent from './LoadingComponent'; import ModalComponent from './ModalComponent'; import ModalFocusTrap from './ModalFocusTrap'; +import ModalSheetChildRoute from './ModalSheetChildRoute'; import ModalTeleport from './ModalTeleport'; import PickerComponent from './PickerComponent'; import PopoverComponent from './PopoverComponent'; @@ -32,6 +33,7 @@ const OverlayHooks: React.FC = () => { + @@ -62,6 +64,10 @@ const OverlayHooks: React.FC = () => { Modal Teleport + + + Sheet Child + Picker diff --git a/packages/react/test/base/tests/e2e/specs/overlay-components/IonModalFocusTrap.cy.ts b/packages/react/test/base/tests/e2e/specs/overlay-components/IonModalFocusTrap.cy.ts index 395c642dcc..78ca7a581e 100644 --- a/packages/react/test/base/tests/e2e/specs/overlay-components/IonModalFocusTrap.cy.ts +++ b/packages/react/test/base/tests/e2e/specs/overlay-components/IonModalFocusTrap.cy.ts @@ -5,7 +5,9 @@ describe('IonModal: focusTrap regression', () => { it('should allow interacting with background when focusTrap=false', () => { cy.get('#open-non-trapped-modal').click(); - cy.get('ion-modal').should('be.visible'); + // Use 'exist' instead of 'be.visible' because the modal has pointer-events: none + // to allow background interaction, which Cypress interprets as "covered" + cy.get('ion-modal.show-modal').should('exist'); cy.get('#background-action').click(); cy.get('#background-action-count').should('have.text', '1'); @@ -13,7 +15,7 @@ describe('IonModal: focusTrap regression', () => { it('should prevent interacting with background when focusTrap=true', () => { cy.get('#open-trapped-modal').click(); - cy.get('ion-modal').should('be.visible'); + cy.get('ion-modal.show-modal').should('be.visible'); // Ensure backdrop is active and capturing pointer events cy.get('ion-backdrop').should('exist'); diff --git a/packages/react/test/base/tests/e2e/specs/overlay-components/IonModalSheetChildRoute.cy.ts b/packages/react/test/base/tests/e2e/specs/overlay-components/IonModalSheetChildRoute.cy.ts new file mode 100644 index 0000000000..ff791f3aad --- /dev/null +++ b/packages/react/test/base/tests/e2e/specs/overlay-components/IonModalSheetChildRoute.cy.ts @@ -0,0 +1,37 @@ +/** + * Tests for sheet modals in child routes with showBackdrop=false. + * See https://github.com/ionic-team/ionic-framework/issues/30700 + */ +describe('IonModal: Sheet in Child Route with Nested Routing', () => { + beforeEach(() => { + cy.visit('/overlay-components/modal-sheet-child-route/child'); + }); + + it('should render parent content and child modal', () => { + cy.get('#increment-btn').should('exist'); + cy.get('#decrement-btn').should('exist'); + cy.get('#background-action-count').should('have.text', '0'); + cy.get('ion-modal.show-modal').should('exist'); + cy.get('#modal-content-loaded').should('exist'); + }); + + it('should allow interacting with parent content while modal is open in child route', () => { + // Wait for modal to be presented + cy.get('ion-modal.show-modal').should('exist'); + + // Click the increment button in the parent content + cy.get('#increment-btn').click(); + cy.get('#background-action-count').should('have.text', '1'); + }); + + it('should allow multiple interactions with parent content while modal is open', () => { + cy.get('ion-modal.show-modal').should('exist'); + + cy.get('#increment-btn').click(); + cy.get('#increment-btn').click(); + cy.get('#background-action-count').should('have.text', '2'); + + cy.get('#decrement-btn').click(); + cy.get('#background-action-count').should('have.text', '1'); + }); +}); From b1645168a7fb9378dc39a081c207b2de0e180089 Mon Sep 17 00:00:00 2001 From: Shane Date: Wed, 10 Dec 2025 13:11:49 -0800 Subject: [PATCH 2/4] fix(modal): prevent browser hang when using ModalController in Angular (#30845) Issue number: resolves internal --------- ## What is the current behavior? When using ModalController to present a modal in Angular applications, the browser becomes non-responsive and hangs in some circumstances. This regression was introduced in #30544 with the addition of a MutationObserver that watches document.body with subtree: true to detect when a modal's parent element is removed from the DOM. For controller-based modals, this observer fires on every DOM mutation in the document, causing severe performance issues during Angular's change detection cycles. ## What is the new behavior? The MutationObserver for parent removal detection is now skipped for controller-based modals and when the cached parent is the app root (document.body or ion-app). These parents are never removed from the DOM, so observing them is unnecessary. This prevents the performance issues while still maintaining the parent removal detection behavior for inline modals with meaningful parent elements. ## Does this introduce a breaking change? - [ ] Yes - [X] No ## Other information Current dev build: ``` 8.7.12-dev.11765231260.1def96ab ``` --------- Co-authored-by: Maria Hutt --- core/src/components/modal/modal.tsx | 14 +++++++++++ .../components/modal/test/basic/modal.e2e.ts | 24 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index dbed406ca4..174ac2f9d8 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -1279,6 +1279,20 @@ export class Modal implements ComponentInterface, OverlayInterface { return; } + /** + * Don't observe for controller-based modals or when the parent is the + * app root (document.body or ion-app). These parents won't be removed, + * and observing document.body with subtree: true causes performance + * issues with frameworks like Angular during change detection. + */ + if ( + this.hasController || + this.cachedOriginalParent === document.body || + this.cachedOriginalParent.tagName === 'ION-APP' + ) { + return; + } + this.parentRemovalObserver = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList' && mutation.removedNodes.length > 0) { diff --git a/core/src/components/modal/test/basic/modal.e2e.ts b/core/src/components/modal/test/basic/modal.e2e.ts index 325c4b3fbb..1c9ac92743 100644 --- a/core/src/components/modal/test/basic/modal.e2e.ts +++ b/core/src/components/modal/test/basic/modal.e2e.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; -import { configs, test, Viewports } from '@utils/test/playwright'; import type { E2EPage } from '@utils/test/playwright'; +import { configs, test, Viewports } from '@utils/test/playwright'; configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { test.describe(title('modal: focus trapping'), () => { @@ -104,6 +104,28 @@ configs().forEach(({ title, screenshot, config }) => { }); configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('modal: parent removal observer'), () => { + test('should not set up parentRemovalObserver for controller-created modals', async ({ page }, testInfo) => { + testInfo.annotations.push({ + type: 'issue', + description: 'FW-6766', + }); + + await page.goto('/src/components/modal/test/basic', config); + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await page.click('#basic-modal'); + await ionModalDidPresent.next(); + + const modal = page.locator('ion-modal'); + const hasObserver = await modal.evaluate((el: any) => { + return el.parentRemovalObserver !== undefined; + }); + + expect(hasObserver).toBe(false); + }); + }); + test.describe(title('modal: backdrop'), () => { test.beforeEach(async ({ page }) => { await page.goto('/src/components/modal/test/basic', config); From afa15d23d21f34aebb3ab33ca446efb986bc4d84 Mon Sep 17 00:00:00 2001 From: ionitron Date: Wed, 10 Dec 2025 21:33:15 +0000 Subject: [PATCH 3/4] v8.7.12 --- CHANGELOG.md | 14 ++++++++++++++ core/CHANGELOG.md | 14 ++++++++++++++ core/package-lock.json | 6 +++--- core/package.json | 2 +- lerna.json | 2 +- packages/angular-server/CHANGELOG.md | 8 ++++++++ packages/angular-server/package-lock.json | 8 ++++---- packages/angular-server/package.json | 4 ++-- packages/angular/CHANGELOG.md | 11 +++++++++++ packages/angular/package-lock.json | 8 ++++---- packages/angular/package.json | 4 ++-- packages/docs/CHANGELOG.md | 8 ++++++++ packages/docs/package-lock.json | 4 ++-- packages/docs/package.json | 2 +- packages/react-router/CHANGELOG.md | 8 ++++++++ packages/react-router/package-lock.json | 8 ++++---- packages/react-router/package.json | 4 ++-- packages/react/CHANGELOG.md | 11 +++++++++++ packages/react/package-lock.json | 8 ++++---- packages/react/package.json | 4 ++-- packages/vue-router/CHANGELOG.md | 8 ++++++++ packages/vue-router/package-lock.json | 8 ++++---- packages/vue-router/package.json | 4 ++-- packages/vue/CHANGELOG.md | 8 ++++++++ packages/vue/package-lock.json | 8 ++++---- packages/vue/package.json | 4 ++-- 26 files changed, 134 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59418196b5..44039ae110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + + +### Bug Fixes + +* **modal:** allow interaction with parent content through sheet modals in child routes ([#30839](https://github.com/ionic-team/ionic-framework/issues/30839)) ([b9e3cf0](https://github.com/ionic-team/ionic-framework/commit/b9e3cf0f5aae79a1f27a07b102c77e51f24825f4)), closes [#30700](https://github.com/ionic-team/ionic-framework/issues/30700) +* **modal:** prevent browser hang when using ModalController in Angular ([#30845](https://github.com/ionic-team/ionic-framework/issues/30845)) ([b164516](https://github.com/ionic-team/ionic-framework/commit/b1645168a7fb9378dc39a081c207b2de0e180089)) +* **popover:** recalculate the content dimensions after the header has fully loaded ([#30853](https://github.com/ionic-team/ionic-framework/issues/30853)) ([99dcf38](https://github.com/ionic-team/ionic-framework/commit/99dcf3810a0c32416996d1e992ddf63359965cfc)) +* **select, action-sheet:** use radio role for options ([#30769](https://github.com/ionic-team/ionic-framework/issues/30769)) ([1c89cf0](https://github.com/ionic-team/ionic-framework/commit/1c89cf06ac959f9c9a35a66f811227c244d3198b)) + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index d1a8667938..3edf5cd89c 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + + +### Bug Fixes + +* **modal:** allow interaction with parent content through sheet modals in child routes ([#30839](https://github.com/ionic-team/ionic-framework/issues/30839)) ([b9e3cf0](https://github.com/ionic-team/ionic-framework/commit/b9e3cf0f5aae79a1f27a07b102c77e51f24825f4)), closes [#30700](https://github.com/ionic-team/ionic-framework/issues/30700) +* **modal:** prevent browser hang when using ModalController in Angular ([#30845](https://github.com/ionic-team/ionic-framework/issues/30845)) ([b164516](https://github.com/ionic-team/ionic-framework/commit/b1645168a7fb9378dc39a081c207b2de0e180089)) +* **popover:** recalculate the content dimensions after the header has fully loaded ([#30853](https://github.com/ionic-team/ionic-framework/issues/30853)) ([99dcf38](https://github.com/ionic-team/ionic-framework/commit/99dcf3810a0c32416996d1e992ddf63359965cfc)) +* **select, action-sheet:** use radio role for options ([#30769](https://github.com/ionic-team/ionic-framework/issues/30769)) ([1c89cf0](https://github.com/ionic-team/ionic-framework/commit/1c89cf06ac959f9c9a35a66f811227c244d3198b)) + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) diff --git a/core/package-lock.json b/core/package-lock.json index b4f227b4c4..4aa5600d56 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/core", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/core", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", @@ -9823,4 +9823,4 @@ } } } -} +} \ No newline at end of file diff --git a/core/package.json b/core/package.json index b0f0db7b18..11f7814227 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/core", - "version": "8.7.11", + "version": "8.7.12", "description": "Base components for Ionic", "engines": { "node": "24.x" diff --git a/lerna.json b/lerna.json index 5134a3baff..3e932560e2 100644 --- a/lerna.json +++ b/lerna.json @@ -3,5 +3,5 @@ "core", "packages/*" ], - "version": "8.7.11" + "version": "8.7.12" } \ No newline at end of file diff --git a/packages/angular-server/CHANGELOG.md b/packages/angular-server/CHANGELOG.md index 55109a0728..cdce885d0d 100644 --- a/packages/angular-server/CHANGELOG.md +++ b/packages/angular-server/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + +**Note:** Version bump only for package @ionic/angular-server + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) **Note:** Version bump only for package @ionic/angular-server diff --git a/packages/angular-server/package-lock.json b/packages/angular-server/package-lock.json index fdddce185b..36674a7cd4 100644 --- a/packages/angular-server/package-lock.json +++ b/packages/angular-server/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular-server", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/angular-server", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.11" + "@ionic/core": "^8.7.12" }, "devDependencies": { "@angular-eslint/eslint-plugin": "^16.0.0", @@ -11286,4 +11286,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/angular-server/package.json b/packages/angular-server/package.json index 47aafb0182..b5c6bd7ea1 100644 --- a/packages/angular-server/package.json +++ b/packages/angular-server/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular-server", - "version": "8.7.11", + "version": "8.7.12", "description": "Angular SSR Module for Ionic", "keywords": [ "ionic", @@ -62,6 +62,6 @@ }, "prettier": "@ionic/prettier-config", "dependencies": { - "@ionic/core": "^8.7.11" + "@ionic/core": "^8.7.12" } } diff --git a/packages/angular/CHANGELOG.md b/packages/angular/CHANGELOG.md index af9a74674e..41c9a25bec 100644 --- a/packages/angular/CHANGELOG.md +++ b/packages/angular/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + + +### Bug Fixes + +* **modal:** allow interaction with parent content through sheet modals in child routes ([#30839](https://github.com/ionic-team/ionic-framework/issues/30839)) ([b9e3cf0](https://github.com/ionic-team/ionic-framework/commit/b9e3cf0f5aae79a1f27a07b102c77e51f24825f4)), closes [#30700](https://github.com/ionic-team/ionic-framework/issues/30700) + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) **Note:** Version bump only for package @ionic/angular diff --git a/packages/angular/package-lock.json b/packages/angular/package-lock.json index 2f8f71c735..9c785ef51b 100644 --- a/packages/angular/package-lock.json +++ b/packages/angular/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/angular", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/angular", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.11", + "@ionic/core": "^8.7.12", "ionicons": "^8.0.13", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" @@ -9092,4 +9092,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/angular/package.json b/packages/angular/package.json index 6dc90b223c..2c015fd921 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/angular", - "version": "8.7.11", + "version": "8.7.12", "description": "Angular specific wrappers for @ionic/core", "keywords": [ "ionic", @@ -48,7 +48,7 @@ } }, "dependencies": { - "@ionic/core": "^8.7.11", + "@ionic/core": "^8.7.12", "ionicons": "^8.0.13", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" diff --git a/packages/docs/CHANGELOG.md b/packages/docs/CHANGELOG.md index 63638865fa..4cc3c8f7f8 100644 --- a/packages/docs/CHANGELOG.md +++ b/packages/docs/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + +**Note:** Version bump only for package @ionic/docs + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) **Note:** Version bump only for package @ionic/docs diff --git a/packages/docs/package-lock.json b/packages/docs/package-lock.json index 3c1391b8cf..c3e6ed1d23 100644 --- a/packages/docs/package-lock.json +++ b/packages/docs/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ionic/docs", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/docs", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT" } } diff --git a/packages/docs/package.json b/packages/docs/package.json index 018947033c..0c0f81bbf9 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/docs", - "version": "8.7.11", + "version": "8.7.12", "description": "Pre-packaged API documentation for the Ionic docs.", "main": "core.json", "types": "core.d.ts", diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index dcc56dc20c..5b01d669ed 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + +**Note:** Version bump only for package @ionic/react-router + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) **Note:** Version bump only for package @ionic/react-router diff --git a/packages/react-router/package-lock.json b/packages/react-router/package-lock.json index ca60000c58..e1366ec946 100644 --- a/packages/react-router/package-lock.json +++ b/packages/react-router/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react-router", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/react-router", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT", "dependencies": { - "@ionic/react": "^8.7.11", + "@ionic/react": "^8.7.12", "tslib": "*" }, "devDependencies": { @@ -6844,4 +6844,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 6caca04b3d..7e2f11fc05 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react-router", - "version": "8.7.11", + "version": "8.7.12", "description": "React Router wrapper for @ionic/react", "keywords": [ "ionic", @@ -36,7 +36,7 @@ "dist/" ], "dependencies": { - "@ionic/react": "^8.7.11", + "@ionic/react": "^8.7.12", "tslib": "*" }, "peerDependencies": { diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index d0dfb6d60d..550acf8a07 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + + +### Bug Fixes + +* **modal:** allow interaction with parent content through sheet modals in child routes ([#30839](https://github.com/ionic-team/ionic-framework/issues/30839)) ([b9e3cf0](https://github.com/ionic-team/ionic-framework/commit/b9e3cf0f5aae79a1f27a07b102c77e51f24825f4)), closes [#30700](https://github.com/ionic-team/ionic-framework/issues/30700) + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) **Note:** Version bump only for package @ionic/react diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 909959cda1..0d3b0edc67 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/react", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/react", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.11", + "@ionic/core": "^8.7.12", "ionicons": "^8.0.13", "tslib": "*" }, @@ -11913,4 +11913,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/react/package.json b/packages/react/package.json index f9407abde6..bb2bfa74b7 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/react", - "version": "8.7.11", + "version": "8.7.12", "description": "React specific wrapper for @ionic/core", "keywords": [ "ionic", @@ -40,7 +40,7 @@ "css/" ], "dependencies": { - "@ionic/core": "^8.7.11", + "@ionic/core": "^8.7.12", "ionicons": "^8.0.13", "tslib": "*" }, diff --git a/packages/vue-router/CHANGELOG.md b/packages/vue-router/CHANGELOG.md index 21cc70cb95..a80b6d0a24 100644 --- a/packages/vue-router/CHANGELOG.md +++ b/packages/vue-router/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + +**Note:** Version bump only for package @ionic/vue-router + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) **Note:** Version bump only for package @ionic/vue-router diff --git a/packages/vue-router/package-lock.json b/packages/vue-router/package-lock.json index fa90874899..5223376839 100644 --- a/packages/vue-router/package-lock.json +++ b/packages/vue-router/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue-router", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@ionic/vue-router", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT", "dependencies": { - "@ionic/vue": "^8.7.11" + "@ionic/vue": "^8.7.12" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", @@ -12991,4 +12991,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index 2d7e95b40f..cee8f5e4e5 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue-router", - "version": "8.7.11", + "version": "8.7.12", "description": "Vue Router integration for @ionic/vue", "scripts": { "test.spec": "jest", @@ -44,7 +44,7 @@ }, "homepage": "https://github.com/ionic-team/ionic-framework#readme", "dependencies": { - "@ionic/vue": "^8.7.11" + "@ionic/vue": "^8.7.12" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", diff --git a/packages/vue/CHANGELOG.md b/packages/vue/CHANGELOG.md index 2d82d381e8..e00ea2c377 100644 --- a/packages/vue/CHANGELOG.md +++ b/packages/vue/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.7.12](https://github.com/ionic-team/ionic-framework/compare/v8.7.11...v8.7.12) (2025-12-10) + +**Note:** Version bump only for package @ionic/vue + + + + + ## [8.7.11](https://github.com/ionic-team/ionic-framework/compare/v8.7.10...v8.7.11) (2025-11-26) **Note:** Version bump only for package @ionic/vue diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index 1c127c6af9..70c1dbfd59 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -1,15 +1,15 @@ { "name": "@ionic/vue", - "version": "8.7.11", + "version": "8.7.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ionic/vue", - "version": "8.7.11", + "version": "8.7.12", "license": "MIT", "dependencies": { - "@ionic/core": "^8.7.11", + "@ionic/core": "^8.7.12", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" }, @@ -4019,4 +4019,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/packages/vue/package.json b/packages/vue/package.json index b10b5b65a0..d89aa3cf61 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@ionic/vue", - "version": "8.7.11", + "version": "8.7.12", "description": "Vue specific wrapper for @ionic/core", "scripts": { "eslint": "eslint src", @@ -68,7 +68,7 @@ "vue-router": "^4.0.16" }, "dependencies": { - "@ionic/core": "^8.7.11", + "@ionic/core": "^8.7.12", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" }, From 5bf6f6e8251c819af192576e40ea072d87f38471 Mon Sep 17 00:00:00 2001 From: ionitron Date: Wed, 10 Dec 2025 21:34:28 +0000 Subject: [PATCH 4/4] chore(): update package lock files --- core/package-lock.json | 42 ++++++++++++++--------- packages/angular-server/package-lock.json | 17 +++++---- packages/angular/package-lock.json | 11 +++--- packages/docs/package-lock.json | 2 +- packages/react-router/package-lock.json | 33 ++++++++++-------- packages/react/package-lock.json | 11 +++--- packages/vue-router/package-lock.json | 33 ++++++++++-------- packages/vue/package-lock.json | 11 +++--- 8 files changed, 93 insertions(+), 67 deletions(-) diff --git a/core/package-lock.json b/core/package-lock.json index 4aa5600d56..362a93bb79 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -50,6 +50,9 @@ "serve": "^14.0.1", "stylelint": "^13.13.1", "stylelint-order": "^4.1.0" + }, + "engines": { + "node": "24.x" } }, "custom-rules": { @@ -91,7 +94,6 @@ "version": "7.16.12", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.16.7", "@babel/generator": "^7.16.8", @@ -629,7 +631,6 @@ "version": "7.4.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -861,7 +862,6 @@ "version": "4.33.0", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", @@ -1799,7 +1799,6 @@ "node_modules/@stencil/core": { "version": "4.38.0", "license": "MIT", - "peer": true, "bin": { "stencil": "bin/stencil" }, @@ -2224,7 +2223,6 @@ "version": "6.7.2", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.7.2", "@typescript-eslint/types": "6.7.2", @@ -2450,6 +2448,7 @@ "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/parser": "^7.28.5", "@vue/shared": "3.5.25", @@ -2464,6 +2463,7 @@ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=0.12" }, @@ -2476,7 +2476,8 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@vue/compiler-dom": { "version": "3.5.25", @@ -2484,6 +2485,7 @@ "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-core": "3.5.25", "@vue/shared": "3.5.25" @@ -2495,6 +2497,7 @@ "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/parser": "^7.28.5", "@vue/compiler-core": "3.5.25", @@ -2512,7 +2515,8 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@vue/compiler-sfc/node_modules/postcss": { "version": "8.5.6", @@ -2534,6 +2538,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -2549,6 +2554,7 @@ "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.25", "@vue/shared": "3.5.25" @@ -2560,6 +2566,7 @@ "integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vue/shared": "3.5.25" } @@ -2570,6 +2577,7 @@ "integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vue/reactivity": "3.5.25", "@vue/shared": "3.5.25" @@ -2581,6 +2589,7 @@ "integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vue/reactivity": "3.5.25", "@vue/runtime-core": "3.5.25", @@ -2594,6 +2603,7 @@ "integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-ssr": "3.5.25", "@vue/shared": "3.5.25" @@ -2607,7 +2617,8 @@ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz", "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@zeit/schemas": { "version": "2.21.0", @@ -2630,7 +2641,6 @@ "version": "7.4.0", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3791,7 +3801,8 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/debug": { "version": "2.6.9", @@ -4085,7 +4096,6 @@ "version": "7.32.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -7281,6 +7291,7 @@ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } @@ -7602,6 +7613,7 @@ } ], "license": "MIT", + "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7956,7 +7968,6 @@ "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "playwright-core": "cli.js" }, @@ -7968,7 +7979,6 @@ "version": "7.0.35", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -8074,7 +8084,6 @@ "version": "0.36.2", "dev": true, "license": "MIT", - "peer": true, "peerDependencies": { "postcss": ">=5.0.0" } @@ -8123,7 +8132,6 @@ "version": "2.6.1", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin-prettier.js" }, @@ -8481,7 +8489,6 @@ "version": "2.35.1", "dev": true, "license": "MIT", - "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -8703,6 +8710,7 @@ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -9823,4 +9831,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/angular-server/package-lock.json b/packages/angular-server/package-lock.json index 36674a7cd4..4eee627f8d 100644 --- a/packages/angular-server/package-lock.json +++ b/packages/angular-server/package-lock.json @@ -1031,14 +1031,17 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", "tslib": "^2.1.0" + }, + "engines": { + "node": "24.x" } }, "node_modules/@ionic/eslint-config": { @@ -7306,9 +7309,9 @@ "dev": true }, "@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "requires": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", @@ -11286,4 +11289,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/angular/package-lock.json b/packages/angular/package-lock.json index 9c785ef51b..18d9d9e5f7 100644 --- a/packages/angular/package-lock.json +++ b/packages/angular/package-lock.json @@ -1398,14 +1398,17 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", "tslib": "^2.1.0" + }, + "engines": { + "node": "24.x" } }, "node_modules/@ionic/eslint-config": { @@ -9092,4 +9095,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/docs/package-lock.json b/packages/docs/package-lock.json index c3e6ed1d23..999970780c 100644 --- a/packages/docs/package-lock.json +++ b/packages/docs/package-lock.json @@ -10,4 +10,4 @@ "license": "MIT" } } -} \ No newline at end of file +} diff --git a/packages/react-router/package-lock.json b/packages/react-router/package-lock.json index e1366ec946..56b884f97c 100644 --- a/packages/react-router/package-lock.json +++ b/packages/react-router/package-lock.json @@ -238,14 +238,17 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", "tslib": "^2.1.0" + }, + "engines": { + "node": "24.x" } }, "node_modules/@ionic/eslint-config": { @@ -415,12 +418,12 @@ } }, "node_modules/@ionic/react": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.11.tgz", - "integrity": "sha512-h4j2SVRMgoxZBdr1bluKGrb0xNYEqEDcjHDuHsok669tKH3RnTMfD276zytfhFh3R8gIKWIqxb76NIsW/hfZcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.12.tgz", + "integrity": "sha512-gNm5L++aiwkwJrUFKhcHUUgjqnj9n03gK7UcoL7Oz+271arzmwF/FNd47G85b6PovwiYQXY2CUBvNJ7Nh4qE/A==", "license": "MIT", "dependencies": { - "@ionic/core": "8.7.11", + "@ionic/core": "8.7.12", "ionicons": "^8.0.13", "tslib": "*" }, @@ -4175,9 +4178,9 @@ "dev": true }, "@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "requires": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", @@ -4281,11 +4284,11 @@ "requires": {} }, "@ionic/react": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.11.tgz", - "integrity": "sha512-h4j2SVRMgoxZBdr1bluKGrb0xNYEqEDcjHDuHsok669tKH3RnTMfD276zytfhFh3R8gIKWIqxb76NIsW/hfZcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.12.tgz", + "integrity": "sha512-gNm5L++aiwkwJrUFKhcHUUgjqnj9n03gK7UcoL7Oz+271arzmwF/FNd47G85b6PovwiYQXY2CUBvNJ7Nh4qE/A==", "requires": { - "@ionic/core": "8.7.11", + "@ionic/core": "8.7.12", "ionicons": "^8.0.13", "tslib": "*" } @@ -6844,4 +6847,4 @@ "dev": true } } -} \ No newline at end of file +} diff --git a/packages/react/package-lock.json b/packages/react/package-lock.json index 0d3b0edc67..3f35a39caa 100644 --- a/packages/react/package-lock.json +++ b/packages/react/package-lock.json @@ -736,14 +736,17 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", "tslib": "^2.1.0" + }, + "engines": { + "node": "24.x" } }, "node_modules/@ionic/eslint-config": { @@ -11913,4 +11916,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/vue-router/package-lock.json b/packages/vue-router/package-lock.json index 5223376839..f7e737b374 100644 --- a/packages/vue-router/package-lock.json +++ b/packages/vue-router/package-lock.json @@ -673,14 +673,17 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", "tslib": "^2.1.0" + }, + "engines": { + "node": "24.x" } }, "node_modules/@ionic/eslint-config": { @@ -865,12 +868,12 @@ } }, "node_modules/@ionic/vue": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.11.tgz", - "integrity": "sha512-HDEcjhxWfimVQxvXfghrqlAWpXnJvcUDTIVE2Mvq8ul+s7gL/OZCpXTAODJOfFCBAGJ0o9QXyC7OPjyN4UbO8Q==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.12.tgz", + "integrity": "sha512-fH/acQ7dYYd1XY1HFqKf0Th6klbfNNzhlnYUf9kNQpkHqUpMamSzA8TWDOV5f4PNKYq6X4oKAPPeIQA4DOayUQ==", "license": "MIT", "dependencies": { - "@ionic/core": "8.7.11", + "@ionic/core": "8.7.12", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" } @@ -8041,9 +8044,9 @@ "dev": true }, "@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "requires": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", @@ -8156,11 +8159,11 @@ "requires": {} }, "@ionic/vue": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.11.tgz", - "integrity": "sha512-HDEcjhxWfimVQxvXfghrqlAWpXnJvcUDTIVE2Mvq8ul+s7gL/OZCpXTAODJOfFCBAGJ0o9QXyC7OPjyN4UbO8Q==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.12.tgz", + "integrity": "sha512-fH/acQ7dYYd1XY1HFqKf0Th6klbfNNzhlnYUf9kNQpkHqUpMamSzA8TWDOV5f4PNKYq6X4oKAPPeIQA4DOayUQ==", "requires": { - "@ionic/core": "8.7.11", + "@ionic/core": "8.7.12", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" } @@ -12991,4 +12994,4 @@ "dev": true } } -} \ No newline at end of file +} diff --git a/packages/vue/package-lock.json b/packages/vue/package-lock.json index 70c1dbfd59..12314e4f7a 100644 --- a/packages/vue/package-lock.json +++ b/packages/vue/package-lock.json @@ -222,14 +222,17 @@ "dev": true }, "node_modules/@ionic/core": { - "version": "8.7.11", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz", - "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", + "version": "8.7.12", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", + "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", "license": "MIT", "dependencies": { "@stencil/core": "4.38.0", "ionicons": "^8.0.13", "tslib": "^2.1.0" + }, + "engines": { + "node": "24.x" } }, "node_modules/@ionic/core/node_modules/tslib": { @@ -4019,4 +4022,4 @@ "dev": true } } -} \ No newline at end of file +}