@ionic/core 8.7.12-dev.11764957130.14454872 → 8.7.12-dev.11764961567.138743ff

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/components/modal.js +77 -63
  2. package/components/overlays.js +15 -11
  3. package/css/core.css +1 -1
  4. package/css/core.css.map +1 -1
  5. package/css/ionic.bundle.css +1 -1
  6. package/css/ionic.bundle.css.map +1 -1
  7. package/dist/cjs/index.cjs.js +1 -1
  8. package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
  9. package/dist/cjs/ion-alert.cjs.entry.js +1 -1
  10. package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
  11. package/dist/cjs/ion-loading.cjs.entry.js +1 -1
  12. package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
  13. package/dist/cjs/ion-modal.cjs.entry.js +78 -64
  14. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  15. package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
  16. package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
  17. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  18. package/dist/cjs/{overlays-DxIZwUXI.js → overlays-D3xMmZCY.js} +15 -11
  19. package/dist/collection/components/modal/modal.ios.css +0 -14
  20. package/dist/collection/components/modal/modal.js +75 -61
  21. package/dist/collection/components/modal/modal.md.css +0 -14
  22. package/dist/collection/utils/overlays.js +15 -11
  23. package/dist/docs.json +1 -1
  24. package/dist/esm/index.js +1 -1
  25. package/dist/esm/ion-action-sheet.entry.js +1 -1
  26. package/dist/esm/ion-alert.entry.js +1 -1
  27. package/dist/esm/ion-datetime_3.entry.js +1 -1
  28. package/dist/esm/ion-loading.entry.js +1 -1
  29. package/dist/esm/ion-menu_3.entry.js +1 -1
  30. package/dist/esm/ion-modal.entry.js +78 -64
  31. package/dist/esm/ion-popover.entry.js +1 -1
  32. package/dist/esm/ion-select-modal.entry.js +1 -1
  33. package/dist/esm/ion-select_3.entry.js +1 -1
  34. package/dist/esm/ion-toast.entry.js +1 -1
  35. package/dist/esm/{overlays-BymNv-BL.js → overlays-DYKBVm6h.js} +15 -11
  36. package/dist/ionic/index.esm.js +1 -1
  37. package/dist/ionic/ionic.esm.js +1 -1
  38. package/dist/ionic/{p-e16b69e1.entry.js → p-038f3a87.entry.js} +1 -1
  39. package/dist/ionic/{p-510d86e1.entry.js → p-1cf19c5a.entry.js} +1 -1
  40. package/dist/ionic/{p-0b80d700.entry.js → p-3fad4ab5.entry.js} +1 -1
  41. package/dist/ionic/{p-98fc09eb.entry.js → p-7928cc4d.entry.js} +1 -1
  42. package/dist/ionic/p-90969bdf.entry.js +4 -0
  43. package/dist/ionic/{p-cb93126d.entry.js → p-985f02a8.entry.js} +1 -1
  44. package/dist/ionic/p-CHK505Co.js +4 -0
  45. package/dist/ionic/{p-15193d01.entry.js → p-a480563a.entry.js} +1 -1
  46. package/dist/ionic/{p-7da39a4d.entry.js → p-b4b6513a.entry.js} +1 -1
  47. package/dist/ionic/{p-83be404e.entry.js → p-caa8efa1.entry.js} +1 -1
  48. package/dist/ionic/{p-7380261c.entry.js → p-ede27a66.entry.js} +1 -1
  49. package/dist/types/components/modal/modal.d.ts +13 -1
  50. package/hydrate/index.js +92 -74
  51. package/hydrate/index.mjs +92 -74
  52. package/package.json +1 -1
  53. package/dist/ionic/p-1b1cb250.entry.js +0 -4
  54. package/dist/ionic/p-D87hU-Ly.js +0 -4
@@ -9,7 +9,7 @@ var frameworkDelegate = require('./framework-delegate-DMJRBuDi.js');
9
9
  var helpers = require('./helpers-DrTqNghc.js');
10
10
  var lockController = require('./lock-controller-aDB9wrEf.js');
11
11
  var capacitor = require('./capacitor-DmA66EwP.js');
12
- var overlays = require('./overlays-DxIZwUXI.js');
12
+ var overlays = require('./overlays-D3xMmZCY.js');
13
13
  var theme = require('./theme-CeDs6Hcv.js');
14
14
  var index$4 = require('./index-094mMFB-.js');
15
15
  var ionicGlobal = require('./ionic-global-HMVqOFGO.js');
@@ -1474,9 +1474,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1474
1474
  };
1475
1475
  };
1476
1476
 
1477
- const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.ion-disable-focus-trap.show-modal){pointer-events:none}:host(.ion-disable-focus-trap.show-modal) ion-backdrop{pointer-events:none}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
1477
+ const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
1478
1478
 
1479
- const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.ion-disable-focus-trap.show-modal){pointer-events:none}:host(.ion-disable-focus-trap.show-modal) ion-backdrop{pointer-events:none}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
1479
+ const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
1480
1480
 
1481
1481
  const Modal = class {
1482
1482
  constructor(hostRef) {
@@ -1499,8 +1499,6 @@ const Modal = class {
1499
1499
  this.inline = false;
1500
1500
  // Whether or not modal is being dismissed via gesture
1501
1501
  this.gestureAnimationDismissing = false;
1502
- // Elements that had pointer-events disabled for background interaction
1503
- this.pointerEventsDisabledElements = [];
1504
1502
  this.presented = false;
1505
1503
  /** @internal */
1506
1504
  this.hasController = false;
@@ -1922,13 +1920,7 @@ const Modal = class {
1922
1920
  };
1923
1921
  window.addEventListener(keyboard.KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
1924
1922
  }
1925
- /**
1926
- * Recalculate isSheetModal here because framework bindings (e.g., Angular)
1927
- * may not have been applied when componentWillLoad ran.
1928
- */
1929
- const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
1930
- this.isSheetModal = isSheetModal;
1931
- if (isSheetModal) {
1923
+ if (this.isSheetModal) {
1932
1924
  this.initSheetGesture();
1933
1925
  }
1934
1926
  else if (hasCardModal) {
@@ -2011,49 +2003,77 @@ const Modal = class {
2011
2003
  this.moveSheetToBreakpoint = moveSheetToBreakpoint;
2012
2004
  this.gesture.enable(true);
2013
2005
  /**
2014
- * When the backdrop doesn't block pointer events (showBackdrop=false,
2015
- * focusTrap=false, or backdropBreakpoint > 0), the modal's original parent
2016
- * may block pointer events after the modal is moved to ion-app. This only
2017
- * applies when the modal is in a child route (detected by the modal being
2018
- * inside a route wrapper like ion-page). Disable pointer-events on the child
2019
- * route's wrapper elements up to (and including) the first ion-router-outlet.
2020
- * We stop there because parent elements may contain sibling content that
2021
- * should remain interactive.
2006
+ * When backdrop interaction is allowed, nested router outlets from child routes
2007
+ * may block pointer events to parent content. Apply passthrough styles only when
2008
+ * the modal was the sole content of a child route page.
2022
2009
  * See https://github.com/ionic-team/ionic-framework/issues/30700
2023
2010
  */
2024
- const backdropNotBlocking = this.showBackdrop === false || this.focusTrap === false || this.backdropBreakpoint > 0;
2025
- if (backdropNotBlocking && this.cachedOriginalParent) {
2026
- // Find the first meaningful parent (skip template and other non-semantic wrappers).
2027
- // In Ionic React, modals are wrapped in a <template> element.
2028
- let semanticParent = this.cachedOriginalParent;
2029
- while (semanticParent && (semanticParent.tagName === 'TEMPLATE' || semanticParent.tagName === 'SLOT')) {
2030
- semanticParent = semanticParent.parentElement;
2031
- }
2032
- // Check if the modal is inside a route wrapper (ion-page or div.ion-page)
2033
- // If the modal is inside ion-content or other content containers, this fix doesn't apply
2034
- const parentIsRouteWrapper = semanticParent && (semanticParent.tagName === 'ION-PAGE' || semanticParent.classList.contains('ion-page'));
2035
- if (parentIsRouteWrapper && semanticParent) {
2036
- this.pointerEventsDisabledElements = [];
2037
- let current = semanticParent;
2038
- while (current && current.tagName !== 'ION-APP') {
2039
- const tagName = current.tagName;
2040
- // Check for ion-page tag or elements with ion-page class
2041
- // (React renders IonPage as div.ion-page, not ion-page tag)
2042
- const isIonPage = tagName === 'ION-PAGE' || current.classList.contains('ion-page');
2043
- const isRouterOutlet = tagName === 'ION-ROUTER-OUTLET';
2044
- const isNav = tagName === 'ION-NAV';
2045
- if (isIonPage || isRouterOutlet || isNav) {
2046
- current.style.setProperty('pointer-events', 'none');
2047
- this.pointerEventsDisabledElements.push(current);
2048
- }
2049
- // Stop after processing the first ion-router-outlet - parent elements
2050
- // may contain sibling content (like buttons) that should remain interactive
2051
- if (isRouterOutlet) {
2052
- break;
2053
- }
2054
- current = current.parentElement;
2055
- }
2056
- }
2011
+ const backdropNotBlocking = this.showBackdrop === false || this.focusTrap === false || backdropBreakpoint > 0;
2012
+ if (backdropNotBlocking) {
2013
+ this.setupChildRoutePassthrough();
2014
+ }
2015
+ }
2016
+ /**
2017
+ * For sheet modals that allow background interaction, sets up pointer-events
2018
+ * passthrough on child route page wrappers and nested router outlets.
2019
+ */
2020
+ setupChildRoutePassthrough() {
2021
+ var _a;
2022
+ const pageParent = this.getOriginalPageParent();
2023
+ // Skip ion-app (controller modals) and pages with other content (inline modals)
2024
+ if (!pageParent || pageParent.tagName === 'ION-APP') {
2025
+ return;
2026
+ }
2027
+ const hasVisibleContent = Array.from(pageParent.children).some((child) => {
2028
+ var _a;
2029
+ if (child === this.el)
2030
+ return false;
2031
+ if (child instanceof HTMLElement && window.getComputedStyle(child).display === 'none')
2032
+ return false;
2033
+ if (child.tagName === 'TEMPLATE' || child.tagName === 'SLOT')
2034
+ return false;
2035
+ if (child.nodeType === Node.TEXT_NODE && !((_a = child.textContent) === null || _a === void 0 ? void 0 : _a.trim()))
2036
+ return false;
2037
+ return true;
2038
+ });
2039
+ if (hasVisibleContent) {
2040
+ return;
2041
+ }
2042
+ // Child route case: page only contained the modal
2043
+ pageParent.classList.add('ion-page-overlay-passthrough');
2044
+ // Also make nested router outlets passthrough
2045
+ const routerOutlet = pageParent.parentElement;
2046
+ if ((routerOutlet === null || routerOutlet === void 0 ? void 0 : routerOutlet.tagName) === 'ION-ROUTER-OUTLET' && ((_a = routerOutlet.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) !== 'ION-APP') {
2047
+ routerOutlet.style.setProperty('pointer-events', 'none');
2048
+ routerOutlet.setAttribute('data-overlay-passthrough', 'true');
2049
+ }
2050
+ }
2051
+ /**
2052
+ * Finds the ion-page ancestor of the modal's original parent location.
2053
+ */
2054
+ getOriginalPageParent() {
2055
+ if (!this.cachedOriginalParent) {
2056
+ return null;
2057
+ }
2058
+ let pageParent = this.cachedOriginalParent;
2059
+ while (pageParent && !pageParent.classList.contains('ion-page')) {
2060
+ pageParent = pageParent.parentElement;
2061
+ }
2062
+ return pageParent;
2063
+ }
2064
+ /**
2065
+ * Removes passthrough styles added by setupChildRoutePassthrough.
2066
+ */
2067
+ cleanupChildRoutePassthrough() {
2068
+ const pageParent = this.getOriginalPageParent();
2069
+ if (!pageParent) {
2070
+ return;
2071
+ }
2072
+ pageParent.classList.remove('ion-page-overlay-passthrough');
2073
+ const routerOutlet = pageParent.parentElement;
2074
+ if (routerOutlet === null || routerOutlet === void 0 ? void 0 : routerOutlet.hasAttribute('data-overlay-passthrough')) {
2075
+ routerOutlet.style.removeProperty('pointer-events');
2076
+ routerOutlet.removeAttribute('data-overlay-passthrough');
2057
2077
  }
2058
2078
  }
2059
2079
  sheetOnDismiss() {
@@ -2144,13 +2164,7 @@ const Modal = class {
2144
2164
  }
2145
2165
  this.cleanupViewTransitionListener();
2146
2166
  this.cleanupParentRemovalObserver();
2147
- /**
2148
- * Clean up pointer-events changes made in initSheetGesture.
2149
- */
2150
- for (const element of this.pointerEventsDisabledElements) {
2151
- element.style.removeProperty('pointer-events');
2152
- }
2153
- this.pointerEventsDisabledElements = [];
2167
+ this.cleanupChildRoutePassthrough();
2154
2168
  }
2155
2169
  this.currentBreakpoint = undefined;
2156
2170
  this.animation = undefined;
@@ -2388,20 +2402,20 @@ const Modal = class {
2388
2402
  const isCardModal = presentingElement !== undefined && mode === 'ios';
2389
2403
  const isHandleCycle = handleBehavior === 'cycle';
2390
2404
  const isSheetModalWithHandle = isSheetModal && showHandle;
2391
- return (index$3.h(index$3.Host, Object.assign({ key: 'd93e3750351017ef6f45a8a131a0722c31ef7c34', "no-router": true,
2405
+ return (index$3.h(index$3.Host, Object.assign({ key: '3bdb8abb1c5bccc9d3b20ed419c85144ccf4d209', "no-router": true,
2392
2406
  // Allow the modal to be navigable when the handle is focusable
2393
2407
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
2394
2408
  zIndex: `${20000 + this.overlayIndex}`,
2395
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: 'e76fd5404593e02c790e9cdf0ad7e03c7377fe93', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && index$3.h("div", { key: '1d57865a48d2ec5cf9c29388a05dd8c960aad079', class: "modal-shadow" }), index$3.h("div", Object.assign({ key: '44879f6ac725b09562a3f8a6d4be15634634a10d',
2409
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: '7d15fea01ca56670cfdfcfe1e3b86b6e6353ee65', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && index$3.h("div", { key: '875ed586a3c55dc19ba5ab97c37da8e09dc2afbe', class: "modal-shadow" }), index$3.h("div", Object.assign({ key: '4fc03a83d5b827c2aaaeaea386a966290f43eb99',
2396
2410
  /*
2397
2411
  role and aria-modal must be used on the
2398
2412
  same element. They must also be set inside the
2399
2413
  shadow DOM otherwise ion-button will not be highlighted
2400
2414
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
2401
2415
  */
2402
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: '1e4ee030c5993ea1e3a1fe7368a50eb349f4b5eb', class: "modal-handle",
2416
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: 'dbae13fa667f3c974e3c88da7067d6426a92e83a', class: "modal-handle",
2403
2417
  // Prevents the handle from receiving keyboard focus when it does not cycle
2404
- tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), index$3.h("slot", { key: '4bfacca293cd3b63a617235d90545e385c094379', onSlotchange: this.onSlotChange }))));
2418
+ tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), index$3.h("slot", { key: '0284e13c0dd87ba76e6b9982f25d1b41a1766bfc', onSlotchange: this.onSlotChange }))));
2405
2419
  }
2406
2420
  get el() { return index$3.getElement(this); }
2407
2421
  static get watchers() { return {
@@ -4,7 +4,7 @@
4
4
  'use strict';
5
5
 
6
6
  var index = require('./index-D6Wc6v08.js');
7
- var overlays = require('./overlays-DxIZwUXI.js');
7
+ var overlays = require('./overlays-D3xMmZCY.js');
8
8
  var frameworkDelegate = require('./framework-delegate-DMJRBuDi.js');
9
9
  var helpers = require('./helpers-DrTqNghc.js');
10
10
  var lockController = require('./lock-controller-aDB9wrEf.js');
@@ -5,7 +5,7 @@
5
5
 
6
6
  var index = require('./index-D6Wc6v08.js');
7
7
  var ionicGlobal = require('./ionic-global-HMVqOFGO.js');
8
- var overlays = require('./overlays-DxIZwUXI.js');
8
+ var overlays = require('./overlays-D3xMmZCY.js');
9
9
  var theme = require('./theme-CeDs6Hcv.js');
10
10
  require('./index-DkNv4J_i.js');
11
11
  require('./helpers-DrTqNghc.js');
@@ -8,7 +8,7 @@ var notchController = require('./notch-controller-Bzqhjm4f.js');
8
8
  var compareWithUtils = require('./compare-with-utils-DSicavqM.js');
9
9
  var validity = require('./validity-BpS37YFM.js');
10
10
  var helpers = require('./helpers-DrTqNghc.js');
11
- var overlays = require('./overlays-DxIZwUXI.js');
11
+ var overlays = require('./overlays-D3xMmZCY.js');
12
12
  var dir = require('./dir-Cn0z1rJH.js');
13
13
  var theme = require('./theme-CeDs6Hcv.js');
14
14
  var watchOptions = require('./watch-options-CviOsrTS.js');
@@ -7,7 +7,7 @@ var index$1 = require('./index-D6Wc6v08.js');
7
7
  var config = require('./config-C5fsO43a.js');
8
8
  var helpers = require('./helpers-DrTqNghc.js');
9
9
  var lockController = require('./lock-controller-aDB9wrEf.js');
10
- var overlays = require('./overlays-DxIZwUXI.js');
10
+ var overlays = require('./overlays-D3xMmZCY.js');
11
11
  var theme = require('./theme-CeDs6Hcv.js');
12
12
  var ionicGlobal = require('./ionic-global-HMVqOFGO.js');
13
13
  var animation = require('./animation-Bt3H9L1C.js');
@@ -504,7 +504,7 @@ const setRootAriaHidden = (hidden = false) => {
504
504
  }
505
505
  };
506
506
  const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
507
- var _a, _b;
507
+ var _a, _b, _c;
508
508
  if (overlay.presented) {
509
509
  return;
510
510
  }
@@ -538,9 +538,10 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
538
538
  */
539
539
  const overlayEl = overlay.el;
540
540
  const shouldTrapFocus = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false;
541
- // Only lock out root content when backdrop is active. Developers relying on showBackdrop=false
542
- // expect background interaction to remain enabled.
543
- const shouldLockRoot = shouldTrapFocus && overlayEl.showBackdrop !== false;
541
+ // Only lock out root content when backdrop is always active. Developers relying on
542
+ // showBackdrop=false or backdropBreakpoint expect background interaction at some point.
543
+ const backdropAlwaysActive = overlayEl.showBackdrop !== false && !(((_a = overlayEl.backdropBreakpoint) !== null && _a !== void 0 ? _a : 0) > 0);
544
+ const shouldLockRoot = shouldTrapFocus && backdropAlwaysActive;
544
545
  overlay.presented = true;
545
546
  overlay.willPresent.emit();
546
547
  if (shouldLockRoot) {
@@ -552,7 +553,7 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
552
553
  }
553
554
  document.body.classList.add(gestureController.BACKDROP_NO_SCROLL);
554
555
  }
555
- (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
556
+ (_b = overlay.willPresentShorthand) === null || _b === void 0 ? void 0 : _b.emit();
556
557
  const mode = ionicGlobal.getIonMode(overlay);
557
558
  // get the user's animation fn if one was provided
558
559
  const animationBuilder = overlay.enterAnimation
@@ -561,7 +562,7 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
561
562
  const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
562
563
  if (completed) {
563
564
  overlay.didPresent.emit();
564
- (_b = overlay.didPresentShorthand) === null || _b === void 0 ? void 0 : _b.emit();
565
+ (_c = overlay.didPresentShorthand) === null || _c === void 0 ? void 0 : _c.emit();
565
566
  }
566
567
  /**
567
568
  * If the focused element is already
@@ -639,7 +640,7 @@ const restoreElementFocus = async (overlayEl) => {
639
640
  }
640
641
  };
641
642
  const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnimation, opts) => {
642
- var _a, _b;
643
+ var _a, _b, _c;
643
644
  if (!overlay.presented) {
644
645
  return false;
645
646
  }
@@ -655,11 +656,14 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
655
656
  * is dismissed.
656
657
  */
657
658
  const overlaysLockingRoot = presentedOverlays.filter((o) => {
659
+ var _a;
658
660
  const el = o;
659
- return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && el.showBackdrop !== false;
661
+ const backdropAlwaysActive = el.showBackdrop !== false && !(((_a = el.backdropBreakpoint) !== null && _a !== void 0 ? _a : 0) > 0);
662
+ return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && backdropAlwaysActive;
660
663
  });
661
664
  const overlayEl = overlay.el;
662
- const locksRoot = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && overlayEl.showBackdrop !== false;
665
+ const backdropAlwaysActive = overlayEl.showBackdrop !== false && !(((_a = overlayEl.backdropBreakpoint) !== null && _a !== void 0 ? _a : 0) > 0);
666
+ const locksRoot = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && backdropAlwaysActive;
663
667
  /**
664
668
  * If this is the last visible overlay that is trapping focus
665
669
  * then we want to re-add the root to the accessibility tree.
@@ -674,7 +678,7 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
674
678
  // Overlay contents should not be clickable during dismiss
675
679
  overlay.el.style.setProperty('pointer-events', 'none');
676
680
  overlay.willDismiss.emit({ data, role });
677
- (_a = overlay.willDismissShorthand) === null || _a === void 0 ? void 0 : _a.emit({ data, role });
681
+ (_b = overlay.willDismissShorthand) === null || _b === void 0 ? void 0 : _b.emit({ data, role });
678
682
  const mode = ionicGlobal.getIonMode(overlay);
679
683
  const animationBuilder = overlay.leaveAnimation
680
684
  ? overlay.leaveAnimation
@@ -684,7 +688,7 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
684
688
  await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
685
689
  }
686
690
  overlay.didDismiss.emit({ data, role });
687
- (_b = overlay.didDismissShorthand) === null || _b === void 0 ? void 0 : _b.emit({ data, role });
691
+ (_c = overlay.didDismissShorthand) === null || _c === void 0 ? void 0 : _c.emit({ data, role });
688
692
  // Get a reference to all animations currently assigned to this overlay
689
693
  // Then tear them down to return the overlay to its initial visual state
690
694
  const animations = activeAnimations.get(overlay) || [];
@@ -104,20 +104,6 @@ ion-backdrop {
104
104
  pointer-events: auto;
105
105
  }
106
106
 
107
- /**
108
- * When focus trap is disabled on a visible modal, allow clicks to pass through
109
- * to content behind it. The .modal-wrapper retains pointer-events: auto so
110
- * modal content remains interactive. We only apply this when show-modal is
111
- * present to avoid affecting hidden modals that haven't presented.
112
- */
113
- :host(.ion-disable-focus-trap.show-modal) {
114
- pointer-events: none;
115
- }
116
-
117
- :host(.ion-disable-focus-trap.show-modal) ion-backdrop {
118
- pointer-events: none;
119
- }
120
-
121
107
  :host(.overlay-hidden) {
122
108
  display: none;
123
109
  }
@@ -42,8 +42,6 @@ export class Modal {
42
42
  this.inline = false;
43
43
  // Whether or not modal is being dismissed via gesture
44
44
  this.gestureAnimationDismissing = false;
45
- // Elements that had pointer-events disabled for background interaction
46
- this.pointerEventsDisabledElements = [];
47
45
  this.presented = false;
48
46
  /** @internal */
49
47
  this.hasController = false;
@@ -465,13 +463,7 @@ export class Modal {
465
463
  };
466
464
  window.addEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
467
465
  }
468
- /**
469
- * Recalculate isSheetModal here because framework bindings (e.g., Angular)
470
- * may not have been applied when componentWillLoad ran.
471
- */
472
- const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
473
- this.isSheetModal = isSheetModal;
474
- if (isSheetModal) {
466
+ if (this.isSheetModal) {
475
467
  this.initSheetGesture();
476
468
  }
477
469
  else if (hasCardModal) {
@@ -554,49 +546,77 @@ export class Modal {
554
546
  this.moveSheetToBreakpoint = moveSheetToBreakpoint;
555
547
  this.gesture.enable(true);
556
548
  /**
557
- * When the backdrop doesn't block pointer events (showBackdrop=false,
558
- * focusTrap=false, or backdropBreakpoint > 0), the modal's original parent
559
- * may block pointer events after the modal is moved to ion-app. This only
560
- * applies when the modal is in a child route (detected by the modal being
561
- * inside a route wrapper like ion-page). Disable pointer-events on the child
562
- * route's wrapper elements up to (and including) the first ion-router-outlet.
563
- * We stop there because parent elements may contain sibling content that
564
- * should remain interactive.
549
+ * When backdrop interaction is allowed, nested router outlets from child routes
550
+ * may block pointer events to parent content. Apply passthrough styles only when
551
+ * the modal was the sole content of a child route page.
565
552
  * See https://github.com/ionic-team/ionic-framework/issues/30700
566
553
  */
567
- const backdropNotBlocking = this.showBackdrop === false || this.focusTrap === false || this.backdropBreakpoint > 0;
568
- if (backdropNotBlocking && this.cachedOriginalParent) {
569
- // Find the first meaningful parent (skip template and other non-semantic wrappers).
570
- // In Ionic React, modals are wrapped in a <template> element.
571
- let semanticParent = this.cachedOriginalParent;
572
- while (semanticParent && (semanticParent.tagName === 'TEMPLATE' || semanticParent.tagName === 'SLOT')) {
573
- semanticParent = semanticParent.parentElement;
574
- }
575
- // Check if the modal is inside a route wrapper (ion-page or div.ion-page)
576
- // If the modal is inside ion-content or other content containers, this fix doesn't apply
577
- const parentIsRouteWrapper = semanticParent && (semanticParent.tagName === 'ION-PAGE' || semanticParent.classList.contains('ion-page'));
578
- if (parentIsRouteWrapper && semanticParent) {
579
- this.pointerEventsDisabledElements = [];
580
- let current = semanticParent;
581
- while (current && current.tagName !== 'ION-APP') {
582
- const tagName = current.tagName;
583
- // Check for ion-page tag or elements with ion-page class
584
- // (React renders IonPage as div.ion-page, not ion-page tag)
585
- const isIonPage = tagName === 'ION-PAGE' || current.classList.contains('ion-page');
586
- const isRouterOutlet = tagName === 'ION-ROUTER-OUTLET';
587
- const isNav = tagName === 'ION-NAV';
588
- if (isIonPage || isRouterOutlet || isNav) {
589
- current.style.setProperty('pointer-events', 'none');
590
- this.pointerEventsDisabledElements.push(current);
591
- }
592
- // Stop after processing the first ion-router-outlet - parent elements
593
- // may contain sibling content (like buttons) that should remain interactive
594
- if (isRouterOutlet) {
595
- break;
596
- }
597
- current = current.parentElement;
598
- }
599
- }
554
+ const backdropNotBlocking = this.showBackdrop === false || this.focusTrap === false || backdropBreakpoint > 0;
555
+ if (backdropNotBlocking) {
556
+ this.setupChildRoutePassthrough();
557
+ }
558
+ }
559
+ /**
560
+ * For sheet modals that allow background interaction, sets up pointer-events
561
+ * passthrough on child route page wrappers and nested router outlets.
562
+ */
563
+ setupChildRoutePassthrough() {
564
+ var _a;
565
+ const pageParent = this.getOriginalPageParent();
566
+ // Skip ion-app (controller modals) and pages with other content (inline modals)
567
+ if (!pageParent || pageParent.tagName === 'ION-APP') {
568
+ return;
569
+ }
570
+ const hasVisibleContent = Array.from(pageParent.children).some((child) => {
571
+ var _a;
572
+ if (child === this.el)
573
+ return false;
574
+ if (child instanceof HTMLElement && window.getComputedStyle(child).display === 'none')
575
+ return false;
576
+ if (child.tagName === 'TEMPLATE' || child.tagName === 'SLOT')
577
+ return false;
578
+ if (child.nodeType === Node.TEXT_NODE && !((_a = child.textContent) === null || _a === void 0 ? void 0 : _a.trim()))
579
+ return false;
580
+ return true;
581
+ });
582
+ if (hasVisibleContent) {
583
+ return;
584
+ }
585
+ // Child route case: page only contained the modal
586
+ pageParent.classList.add('ion-page-overlay-passthrough');
587
+ // Also make nested router outlets passthrough
588
+ const routerOutlet = pageParent.parentElement;
589
+ if ((routerOutlet === null || routerOutlet === void 0 ? void 0 : routerOutlet.tagName) === 'ION-ROUTER-OUTLET' && ((_a = routerOutlet.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) !== 'ION-APP') {
590
+ routerOutlet.style.setProperty('pointer-events', 'none');
591
+ routerOutlet.setAttribute('data-overlay-passthrough', 'true');
592
+ }
593
+ }
594
+ /**
595
+ * Finds the ion-page ancestor of the modal's original parent location.
596
+ */
597
+ getOriginalPageParent() {
598
+ if (!this.cachedOriginalParent) {
599
+ return null;
600
+ }
601
+ let pageParent = this.cachedOriginalParent;
602
+ while (pageParent && !pageParent.classList.contains('ion-page')) {
603
+ pageParent = pageParent.parentElement;
604
+ }
605
+ return pageParent;
606
+ }
607
+ /**
608
+ * Removes passthrough styles added by setupChildRoutePassthrough.
609
+ */
610
+ cleanupChildRoutePassthrough() {
611
+ const pageParent = this.getOriginalPageParent();
612
+ if (!pageParent) {
613
+ return;
614
+ }
615
+ pageParent.classList.remove('ion-page-overlay-passthrough');
616
+ const routerOutlet = pageParent.parentElement;
617
+ if (routerOutlet === null || routerOutlet === void 0 ? void 0 : routerOutlet.hasAttribute('data-overlay-passthrough')) {
618
+ routerOutlet.style.removeProperty('pointer-events');
619
+ routerOutlet.removeAttribute('data-overlay-passthrough');
600
620
  }
601
621
  }
602
622
  sheetOnDismiss() {
@@ -687,13 +707,7 @@ export class Modal {
687
707
  }
688
708
  this.cleanupViewTransitionListener();
689
709
  this.cleanupParentRemovalObserver();
690
- /**
691
- * Clean up pointer-events changes made in initSheetGesture.
692
- */
693
- for (const element of this.pointerEventsDisabledElements) {
694
- element.style.removeProperty('pointer-events');
695
- }
696
- this.pointerEventsDisabledElements = [];
710
+ this.cleanupChildRoutePassthrough();
697
711
  }
698
712
  this.currentBreakpoint = undefined;
699
713
  this.animation = undefined;
@@ -939,20 +953,20 @@ export class Modal {
939
953
  const isCardModal = presentingElement !== undefined && mode === 'ios';
940
954
  const isHandleCycle = handleBehavior === 'cycle';
941
955
  const isSheetModalWithHandle = isSheetModal && showHandle;
942
- return (h(Host, Object.assign({ key: 'd93e3750351017ef6f45a8a131a0722c31ef7c34', "no-router": true,
956
+ return (h(Host, Object.assign({ key: '3bdb8abb1c5bccc9d3b20ed419c85144ccf4d209', "no-router": true,
943
957
  // Allow the modal to be navigable when the handle is focusable
944
958
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
945
959
  zIndex: `${20000 + this.overlayIndex}`,
946
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: 'e76fd5404593e02c790e9cdf0ad7e03c7377fe93', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '1d57865a48d2ec5cf9c29388a05dd8c960aad079', class: "modal-shadow" }), h("div", Object.assign({ key: '44879f6ac725b09562a3f8a6d4be15634634a10d',
960
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), h("ion-backdrop", { key: '7d15fea01ca56670cfdfcfe1e3b86b6e6353ee65', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '875ed586a3c55dc19ba5ab97c37da8e09dc2afbe', class: "modal-shadow" }), h("div", Object.assign({ key: '4fc03a83d5b827c2aaaeaea386a966290f43eb99',
947
961
  /*
948
962
  role and aria-modal must be used on the
949
963
  same element. They must also be set inside the
950
964
  shadow DOM otherwise ion-button will not be highlighted
951
965
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
952
966
  */
953
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '1e4ee030c5993ea1e3a1fe7368a50eb349f4b5eb', class: "modal-handle",
967
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: 'dbae13fa667f3c974e3c88da7067d6426a92e83a', class: "modal-handle",
954
968
  // Prevents the handle from receiving keyboard focus when it does not cycle
955
- tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '4bfacca293cd3b63a617235d90545e385c094379', onSlotchange: this.onSlotChange }))));
969
+ tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), h("slot", { key: '0284e13c0dd87ba76e6b9982f25d1b41a1766bfc', onSlotchange: this.onSlotChange }))));
956
970
  }
957
971
  static get is() { return "ion-modal"; }
958
972
  static get encapsulation() { return "shadow"; }
@@ -104,20 +104,6 @@ ion-backdrop {
104
104
  pointer-events: auto;
105
105
  }
106
106
 
107
- /**
108
- * When focus trap is disabled on a visible modal, allow clicks to pass through
109
- * to content behind it. The .modal-wrapper retains pointer-events: auto so
110
- * modal content remains interactive. We only apply this when show-modal is
111
- * present to avoid affecting hidden modals that haven't presented.
112
- */
113
- :host(.ion-disable-focus-trap.show-modal) {
114
- pointer-events: none;
115
- }
116
-
117
- :host(.ion-disable-focus-trap.show-modal) ion-backdrop {
118
- pointer-events: none;
119
- }
120
-
121
107
  :host(.overlay-hidden) {
122
108
  display: none;
123
109
  }