@ionic/core 8.8.1-dev.11773432149.19826d0c → 8.8.1-dev.11773676615.1d6c4cf7

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 (81) hide show
  1. package/components/index.js +1 -1
  2. package/components/ion-action-sheet.js +1 -1
  3. package/components/ion-alert.js +1 -1
  4. package/components/ion-datetime.js +1 -1
  5. package/components/ion-loading.js +1 -1
  6. package/components/ion-menu.js +1 -1
  7. package/components/ion-modal.js +1 -1
  8. package/components/ion-picker-legacy.js +1 -1
  9. package/components/ion-popover.js +1 -1
  10. package/components/ion-select-modal.js +1 -1
  11. package/components/ion-select-popover.js +1 -1
  12. package/components/ion-select.js +1 -1
  13. package/components/ion-toast.js +1 -1
  14. package/components/p-0npDmDEs.js +4 -0
  15. package/components/p-7hlGym-0.js +4 -0
  16. package/components/p-BO_M4HrR.js +4 -0
  17. package/components/p-C5gHGV8-.js +4 -0
  18. package/components/{p-Bum_LjMh.js → p-CEmYm-1e.js} +1 -1
  19. package/components/p-CWnwVrC4.js +4 -0
  20. package/components/{p-CVF7ukTk.js → p-Dfrz4Vqg.js} +1 -1
  21. package/dist/cjs/index.cjs.js +1 -1
  22. package/dist/cjs/ion-action-sheet.cjs.entry.js +8 -4
  23. package/dist/cjs/ion-alert.cjs.entry.js +7 -3
  24. package/dist/cjs/ion-datetime_3.cjs.entry.js +7 -3
  25. package/dist/cjs/ion-loading.cjs.entry.js +7 -3
  26. package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
  27. package/dist/cjs/ion-modal.cjs.entry.js +9 -5
  28. package/dist/cjs/ion-popover.cjs.entry.js +7 -3
  29. package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
  30. package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
  31. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  32. package/dist/cjs/{overlays-C2jiBSNQ.js → overlays-MjvhwPt2.js} +24 -0
  33. package/dist/collection/components/action-sheet/action-sheet.js +8 -4
  34. package/dist/collection/components/alert/alert.js +7 -3
  35. package/dist/collection/components/loading/loading.js +7 -3
  36. package/dist/collection/components/modal/modal.js +9 -5
  37. package/dist/collection/components/picker-legacy/picker.js +7 -3
  38. package/dist/collection/components/popover/popover.js +7 -3
  39. package/dist/collection/utils/overlays.js +23 -0
  40. package/dist/docs.json +1 -1
  41. package/dist/esm/index.js +1 -1
  42. package/dist/esm/ion-action-sheet.entry.js +8 -4
  43. package/dist/esm/ion-alert.entry.js +7 -3
  44. package/dist/esm/ion-datetime_3.entry.js +7 -3
  45. package/dist/esm/ion-loading.entry.js +7 -3
  46. package/dist/esm/ion-menu_3.entry.js +1 -1
  47. package/dist/esm/ion-modal.entry.js +9 -5
  48. package/dist/esm/ion-popover.entry.js +7 -3
  49. package/dist/esm/ion-select-modal.entry.js +1 -1
  50. package/dist/esm/ion-select_3.entry.js +1 -1
  51. package/dist/esm/ion-toast.entry.js +1 -1
  52. package/dist/esm/{overlays-F8GHPo-e.js → overlays-CCsdmuZR.js} +24 -1
  53. package/dist/ionic/index.esm.js +1 -1
  54. package/dist/ionic/ionic.esm.js +1 -1
  55. package/dist/ionic/p-50b13f63.entry.js +4 -0
  56. package/dist/ionic/p-53399c0b.entry.js +4 -0
  57. package/dist/ionic/p-80bea9dd.entry.js +4 -0
  58. package/dist/ionic/p-Bx-dQ-64.js +4 -0
  59. package/dist/ionic/p-b30c0226.entry.js +4 -0
  60. package/dist/ionic/{p-7620be24.entry.js → p-c1854ee5.entry.js} +1 -1
  61. package/dist/ionic/p-c7f46ed5.entry.js +4 -0
  62. package/dist/ionic/{p-f69a5f71.entry.js → p-cfeb806a.entry.js} +1 -1
  63. package/dist/ionic/{p-4dd5e8e0.entry.js → p-e2e9d04e.entry.js} +1 -1
  64. package/dist/ionic/{p-e6c5f060.entry.js → p-f5506e4e.entry.js} +1 -1
  65. package/dist/ionic/p-f83088b5.entry.js +4 -0
  66. package/dist/types/utils/overlays.d.ts +10 -0
  67. package/hydrate/index.js +62 -15
  68. package/hydrate/index.mjs +62 -15
  69. package/package.json +1 -1
  70. package/components/p-1KVKSLu5.js +0 -4
  71. package/components/p-BVnB3eEn.js +0 -4
  72. package/components/p-CH0NYjKq.js +0 -4
  73. package/components/p-Cq8cQ0NL.js +0 -4
  74. package/components/p-DHsZWn1l.js +0 -4
  75. package/dist/ionic/p-16b65553.entry.js +0 -4
  76. package/dist/ionic/p-1b02923f.entry.js +0 -4
  77. package/dist/ionic/p-23fac490.entry.js +0 -4
  78. package/dist/ionic/p-51c11c47.entry.js +0 -4
  79. package/dist/ionic/p-7ca71c83.entry.js +0 -4
  80. package/dist/ionic/p-DTPR1Wpn.js +0 -4
  81. package/dist/ionic/p-aa47f46e.entry.js +0 -4
@@ -7,7 +7,7 @@ import { createButtonActiveGesture } from "../../utils/gesture/button-active";
7
7
  import { raf } from "../../utils/helpers";
8
8
  import { createLockController } from "../../utils/lock-controller";
9
9
  import { printIonWarning } from "../../utils/logging/index";
10
- import { createDelegateController, createTriggerController, BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall, setOverlayId, } from "../../utils/overlays";
10
+ import { BACKDROP, cleanupRootFocusTrapAccessibility, createDelegateController, createTriggerController, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall, setOverlayId, } from "../../utils/overlays";
11
11
  import { sanitizeDOMString } from "../../utils/sanitization/index";
12
12
  import { getClassMap } from "../../utils/theme";
13
13
  import { config } from "../../global/config";
@@ -207,6 +207,10 @@ export class Alert {
207
207
  this.gesture.destroy();
208
208
  this.gesture = undefined;
209
209
  }
210
+ // Clean up aria-hidden if removed without dismiss() being called
211
+ if (this.presented) {
212
+ cleanupRootFocusTrapAccessibility();
213
+ }
210
214
  }
211
215
  componentDidLoad() {
212
216
  /**
@@ -440,9 +444,9 @@ export class Alert {
440
444
  * If neither are defined, do not set aria-labelledby.
441
445
  */
442
446
  const ariaLabelledBy = header && subHeader ? `${hdrId} ${subHdrId}` : header ? hdrId : subHeader ? subHdrId : null;
443
- return (h(Host, { key: '6025440b9cd369d4fac89e7e4296c84a10a0b8e0', tabindex: "-1", style: {
447
+ return (h(Host, { key: '51ccec282f165dbaa02d7ee0c6413b870abae1d5', tabindex: "-1", style: {
444
448
  zIndex: `${20000 + overlayIndex}`,
445
- }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, h("ion-backdrop", { key: '3cd5ca8b99cb95b11dd22ab41a820d841142896f', tappable: this.backdropDismiss }), h("div", { key: '4cc62ae6e21424057d22aeef1e8fc77011e77cd5', tabindex: "0", "aria-hidden": "true" }), h("div", Object.assign({ key: '364057a69f25aa88904df17bdcf7e5bf714e7830', class: "alert-wrapper ion-overlay-wrapper", role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "0", ref: (el) => (this.wrapperEl = el) }, htmlAttributes), h("div", { key: '78694e3c0db2d408df3899fb1a90859bcc8d14cc', class: "alert-head" }, header && (h("h2", { key: 'ec88ff3e4e1ea871b5975133fdcf4cac38b05e0f', id: hdrId, class: "alert-title" }, header)), subHeader && !header && (h("h2", { key: '9b09bc8bb68af255ef8b7d22587acc946148e544', id: subHdrId, class: "alert-sub-title" }, subHeader)), subHeader && header && (h("h3", { key: '99abe815f75d2df7f1b77c0df9f3436724fea76f', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), h("div", { key: 'a43d0c22c0e46b1ef911f92ffeb253d7911b85f7', tabindex: "0", "aria-hidden": "true" })));
449
+ }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, h("ion-backdrop", { key: '555fb7a0048d1ada0182925ca460956e65f43322', tappable: this.backdropDismiss }), h("div", { key: 'bce7b1466f5d3c2615a7478ec8903f9567c9b101', tabindex: "0", "aria-hidden": "true" }), h("div", Object.assign({ key: '8b0e8793070fee6cb3a69f0fc9b828b07672d0f9', class: "alert-wrapper ion-overlay-wrapper", role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "0", ref: (el) => (this.wrapperEl = el) }, htmlAttributes), h("div", { key: 'f9c99afdd4389421e9eaabaa7e2f9c17e2cb88f4', class: "alert-head" }, header && (h("h2", { key: '7aa37fe49189d714e7d4bc786d9895ab8191f25c', id: hdrId, class: "alert-title" }, header)), subHeader && !header && (h("h2", { key: '1c32cbb4d615672b669bfacff35079791a0ab50a', id: subHdrId, class: "alert-sub-title" }, subHeader)), subHeader && header && (h("h3", { key: 'fc7285499cee4cef323085e501d974d423102e94', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), h("div", { key: 'b69334b5643b2592053bc408a9ab3b623e2d2b9d', tabindex: "0", "aria-hidden": "true" })));
446
450
  }
447
451
  static get is() { return "ion-alert"; }
448
452
  static get encapsulation() { return "scoped"; }
@@ -5,7 +5,7 @@ import { Host, h } from "@stencil/core";
5
5
  import { ENABLE_HTML_CONTENT_DEFAULT } from "../../utils/config";
6
6
  import { raf } from "../../utils/helpers";
7
7
  import { createLockController } from "../../utils/lock-controller";
8
- import { BACKDROP, dismiss, eventMethod, prepareOverlay, present, createDelegateController, createTriggerController, setOverlayId, } from "../../utils/overlays";
8
+ import { BACKDROP, cleanupRootFocusTrapAccessibility, createDelegateController, createTriggerController, dismiss, eventMethod, prepareOverlay, present, setOverlayId, } from "../../utils/overlays";
9
9
  import { sanitizeDOMString } from "../../utils/sanitization/index";
10
10
  import { getClassMap } from "../../utils/theme";
11
11
  import { config } from "../../global/config";
@@ -114,6 +114,10 @@ export class Loading {
114
114
  }
115
115
  disconnectedCallback() {
116
116
  this.triggerController.removeClickListener();
117
+ // Clean up aria-hidden if removed without dismiss() being called
118
+ if (this.presented) {
119
+ cleanupRootFocusTrapAccessibility();
120
+ }
117
121
  }
118
122
  /**
119
123
  * Present the loading overlay after it has been created.
@@ -179,9 +183,9 @@ export class Loading {
179
183
  * Otherwise, don't set aria-labelledby.
180
184
  */
181
185
  const ariaLabelledBy = message !== undefined ? msgId : null;
182
- return (h(Host, Object.assign({ key: 'f86ddbc600cb5c396b7de38fb5f49625388c3c3f', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
186
+ return (h(Host, Object.assign({ key: 'ab48bfcee8f7e3e33847a2f262fdc08b9ea804ca', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
183
187
  zIndex: `${40000 + this.overlayIndex}`,
184
- }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), h("ion-backdrop", { key: 'b53727aaddc37ef3c685fcc150c6d5193290a847', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '4c61bede8e0a4e47daa6f1f9d0f364ef6aec0bc3', tabindex: "0", "aria-hidden": "true" }), h("div", { key: '84e51ceb07118f1eaeb757df28801c255496931b', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (h("div", { key: 'fc97f1912e0fc558b7c309a5bc084415f5f620b2', class: "loading-spinner" }, h("ion-spinner", { key: '6e186d856cd3f10f22c3e317ef00f31b4216459c', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), h("div", { key: 'dcbe9d9a619daa1c08174e73827bdabeb59dde92', tabindex: "0", "aria-hidden": "true" })));
188
+ }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), h("ion-backdrop", { key: '41baccc7fb6474389a3a3431c208e829ef738b75', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '7b7290974abbe8db8739b19835aca9f8b5c271c2', tabindex: "0", "aria-hidden": "true" }), h("div", { key: 'e32466abfcc92aaad47ea03b1dcb49f66abe4b63', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (h("div", { key: 'c5e6e6f9e3f39dba0225d08d7dd2c1b96a1d83c7', class: "loading-spinner" }, h("ion-spinner", { key: 'f428038959d879404ea898011363aac0b807ad11', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), h("div", { key: '490e531367b86c319fa4260722dcff4dd631fa88', tabindex: "0", "aria-hidden": "true" })));
185
189
  }
186
190
  static get is() { return "ion-loading"; }
187
191
  static get encapsulation() { return "scoped"; }
@@ -8,7 +8,7 @@ import { raf, inheritAttributes, hasLazyBuild, getElementRoot } from "../../util
8
8
  import { createLockController } from "../../utils/lock-controller";
9
9
  import { printIonWarning } from "../../utils/logging/index";
10
10
  import { Style as StatusBarStyle, StatusBar } from "../../utils/native/status-bar";
11
- import { GESTURE, BACKDROP, dismiss, eventMethod, prepareOverlay, present, createTriggerController, setOverlayId, FOCUS_TRAP_DISABLE_CLASS, } from "../../utils/overlays";
11
+ import { BACKDROP, cleanupRootFocusTrapAccessibility, createTriggerController, dismiss, eventMethod, FOCUS_TRAP_DISABLE_CLASS, GESTURE, prepareOverlay, present, setOverlayId, } from "../../utils/overlays";
12
12
  import { getClassMap } from "../../utils/theme";
13
13
  import { deepReady, waitForMount } from "../../utils/transition/index";
14
14
  import { config } from "../../global/config";
@@ -277,6 +277,10 @@ export class Modal {
277
277
  // Also called in dismiss() — intentional dual cleanup covers both
278
278
  // dismiss-then-remove and direct DOM removal without dismiss.
279
279
  this.cleanupSafeAreaOverrides();
280
+ // Clean up aria-hidden if removed without dismiss() being called
281
+ if (this.presented) {
282
+ cleanupRootFocusTrapAccessibility();
283
+ }
280
284
  }
281
285
  componentWillLoad() {
282
286
  var _a;
@@ -1133,20 +1137,20 @@ export class Modal {
1133
1137
  const isCardModal = presentingElement !== undefined && mode === 'ios';
1134
1138
  const isHandleCycle = handleBehavior === 'cycle';
1135
1139
  const isSheetModalWithHandle = isSheetModal && showHandle;
1136
- return (h(Host, Object.assign({ key: '1a53e8f87532abccc169ca4b24973a39c5f9ba16', "no-router": true,
1140
+ return (h(Host, Object.assign({ key: 'e6df0917ac03a8d6bf67cc9bebf075d2b804ba22', "no-router": true,
1137
1141
  // Allow the modal to be navigable when the handle is focusable
1138
1142
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
1139
1143
  zIndex: `${20000 + this.overlayIndex}`,
1140
- }, 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: 'fa8e0a436c0d458331402e1850f87af3dc97b582', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'f00de6027d3c8b5bc93db3b0f7a50a87628d40bb', class: "modal-shadow" }), h("div", Object.assign({ key: 'ae5e33bd6c58e541edb2edbca92420ea02dd5175',
1144
+ }, 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: '710ed1cbb6ae9c1a1fa7ae774fd44aa3bbee8381', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'c9051fcd099e9b73e17f015dea6e16fbd73e4df4', class: "modal-shadow" }), h("div", Object.assign({ key: '21e42d40099a569d95a4e04aa6d314c7d45c6192',
1141
1145
  /*
1142
1146
  role and aria-modal must be used on the
1143
1147
  same element. They must also be set inside the
1144
1148
  shadow DOM otherwise ion-button will not be highlighted
1145
1149
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
1146
1150
  */
1147
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '141cdd8f8522331f4b764e2a4d79ec6596b1eb3a', class: "modal-handle",
1151
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: 'b48a6c32c9a7ebe5e070e8d9f3510d55d4bd1f9f', class: "modal-handle",
1148
1152
  // Prevents the handle from receiving keyboard focus when it does not cycle
1149
- 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: '7de20298b61abee67a16d275c9ebd9a25ce7dd26', onSlotchange: this.onSlotChange }))));
1153
+ 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: '2a20160f66629c14e3414bbe01e5ee89101d02be', onSlotchange: this.onSlotChange }))));
1150
1154
  }
1151
1155
  static get is() { return "ion-modal"; }
1152
1156
  static get encapsulation() { return "shadow"; }
@@ -5,7 +5,7 @@ import { Host, h } from "@stencil/core";
5
5
  import { raf } from "../../utils/helpers";
6
6
  import { createLockController } from "../../utils/lock-controller";
7
7
  import { printIonWarning } from "../../utils/logging/index";
8
- import { createDelegateController, createTriggerController, BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall, setOverlayId, } from "../../utils/overlays";
8
+ import { BACKDROP, cleanupRootFocusTrapAccessibility, createDelegateController, createTriggerController, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall, setOverlayId, } from "../../utils/overlays";
9
9
  import { getClassMap } from "../../utils/theme";
10
10
  import { getIonMode } from "../../global/ionic-global";
11
11
  import { iosEnterAnimation } from "./animations/ios.enter";
@@ -89,6 +89,10 @@ export class Picker {
89
89
  }
90
90
  disconnectedCallback() {
91
91
  this.triggerController.removeClickListener();
92
+ // Clean up aria-hidden if removed without dismiss() being called
93
+ if (this.presented) {
94
+ cleanupRootFocusTrapAccessibility();
95
+ }
92
96
  }
93
97
  componentWillLoad() {
94
98
  var _a;
@@ -207,11 +211,11 @@ export class Picker {
207
211
  render() {
208
212
  const { htmlAttributes } = this;
209
213
  const mode = getIonMode(this);
210
- return (h(Host, Object.assign({ key: '80f66d33780d8a1352d24be9cb63a0cc03d01ab5', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
214
+ return (h(Host, Object.assign({ key: '4d6531bfff4eb466f897cf2227d51783604ff439', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
211
215
  zIndex: `${20000 + this.overlayIndex}`,
212
216
  }, class: Object.assign({ [mode]: true,
213
217
  // Used internally for styling
214
- [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), h("ion-backdrop", { key: '97fb8e10ba08b197610cb8c0cdea61103883d55f', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: 'b3969cb6fbf7153623d14e3ca1493d3370efb211', tabindex: "0", "aria-hidden": "true" }), h("div", { key: '299268483c3727e698d9135bfdf40349a7050ac1', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, h("div", { key: '95394de3ef691899b7dbf416f56fd3e86bbdce3f', class: "picker-toolbar" }, this.buttons.map((b) => (h("div", { class: buttonWrapperClass(b) }, h("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass(b) }, b.text))))), h("div", { key: '05f18bb8d00dc0e22f691b7e41f90f729a6c66d7', class: "picker-columns" }, h("div", { key: '4a8fdf224effc0af67fd413e2e6aca8a78d1cf43', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => h("ion-picker-legacy-column", { col: c })), h("div", { key: 'e50a31db45e3f39e9d0fed36a21be9257eec09bf', class: "picker-below-highlight" }))), h("div", { key: '5a78cb2176ac807ea0c195c6b76cd0e8eef9d4c0', tabindex: "0", "aria-hidden": "true" })));
218
+ [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), h("ion-backdrop", { key: '754a80de29087f7e793b232c4276fc1f6b1c937f', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '9fcffb91109d6082ed338cd37a997254e5ea5bce', tabindex: "0", "aria-hidden": "true" }), h("div", { key: 'de066bda70a9cb831fc88493873d7ebf879122d0', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, h("div", { key: '03a502e2e1aa38abd582ecfca60da8b7d1045701', class: "picker-toolbar" }, this.buttons.map((b) => (h("div", { class: buttonWrapperClass(b) }, h("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass(b) }, b.text))))), h("div", { key: 'f9e4d9eff3c2df866f15eed63f715a51c912eac6', class: "picker-columns" }, h("div", { key: '78656d3265f9d4c82387f942c896a9d67c1fcedf', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => h("ion-picker-legacy-column", { col: c })), h("div", { key: '1afd96cfa38fa9f52f61a867f2aa116a9ef3bedb', class: "picker-below-highlight" }))), h("div", { key: '4d533e132d70f6ab32c461e3e4f6f9dfbe6bab15', tabindex: "0", "aria-hidden": "true" })));
215
219
  }
216
220
  static get is() { return "ion-picker-legacy"; }
217
221
  static get encapsulation() { return "scoped"; }
@@ -7,7 +7,7 @@ import { CoreDelegate, attachComponent, detachComponent } from "../../utils/fram
7
7
  import { addEventListener, raf, hasLazyBuild } from "../../utils/helpers";
8
8
  import { createLockController } from "../../utils/lock-controller";
9
9
  import { printIonWarning } from "../../utils/logging/index";
10
- import { BACKDROP, dismiss, eventMethod, prepareOverlay, present, setOverlayId, FOCUS_TRAP_DISABLE_CLASS, } from "../../utils/overlays";
10
+ import { BACKDROP, cleanupRootFocusTrapAccessibility, dismiss, eventMethod, FOCUS_TRAP_DISABLE_CLASS, prepareOverlay, present, setOverlayId, } from "../../utils/overlays";
11
11
  import { isPlatform } from "../../utils/platform";
12
12
  import { getClassMap } from "../../utils/theme";
13
13
  import { deepReady, waitForMount } from "../../utils/transition/index";
@@ -229,6 +229,10 @@ export class Popover {
229
229
  this.headerResizeObserver.disconnect();
230
230
  this.headerResizeObserver = undefined;
231
231
  }
232
+ // Clean up aria-hidden if removed without dismiss() being called
233
+ if (this.presented) {
234
+ cleanupRootFocusTrapAccessibility();
235
+ }
232
236
  }
233
237
  componentWillLoad() {
234
238
  var _a, _b;
@@ -467,9 +471,9 @@ export class Popover {
467
471
  const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes, focusTrap } = this;
468
472
  const desktop = isPlatform('desktop');
469
473
  const enableArrow = arrow && !parentPopover;
470
- return (h(Host, Object.assign({ key: '2edd8333c630efbce59071f8a383e4326e928dbc', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
474
+ return (h(Host, Object.assign({ key: 'afc292b6b4eeb571c1cd832bc7ac03e0fea3dc28', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
471
475
  zIndex: `${20000 + this.overlayIndex}`,
472
- }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { key: 'aac4e68b08197534375e8ea3f8c9ea0c10ab2af4', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: 'b7f4ebf57d4148b32856b0075d286f454be8de5d', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && h("div", { key: '607d94c28d73e8e957175a7c0f6e8a99ec4dcd53', class: "popover-arrow", part: "arrow" }), h("div", { key: '4366a5a5de550c09895e923f345583508e1ec30c', class: "popover-content", part: "content" }, h("slot", { key: 'eb7886fbc99c15b667b7d825d24f1c12d9380f03' })))));
476
+ }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { key: '301a33645918c7feb807a6fe857e462b83291c40', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: 'f66123d36601ce61af3bce3c68c73002fe3a6d73', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && h("div", { key: '39c92c94d01748d499f2db2513ecf022be2577dd', class: "popover-arrow", part: "arrow" }), h("div", { key: '827552221533f7b5676e6e313cd7517275ea76d7', class: "popover-content", part: "content" }, h("slot", { key: 'f874b8dfb78bfbc02e3bcad104819bf8d181d42f' })))));
473
477
  }
474
478
  static get is() { return "ion-popover"; }
475
479
  static get encapsulation() { return "shadow"; }
@@ -432,6 +432,29 @@ export const setRootAriaHidden = (hidden = false) => {
432
432
  viewContainer.removeAttribute('aria-hidden');
433
433
  }
434
434
  };
435
+ /**
436
+ * Cleans up root `aria-hidden` and `backdrop-no-scroll` when
437
+ * an overlay is removed from the DOM without going through
438
+ * the `dismiss()` flow (e.g., when a framework unmounts the
439
+ * overlay during a route change).
440
+ *
441
+ * Should be called from an overlay's `disconnectedCallback`
442
+ * when the overlay was still presented at the time of removal.
443
+ */
444
+ export const cleanupRootFocusTrapAccessibility = () => {
445
+ if (typeof document === 'undefined') {
446
+ return;
447
+ }
448
+ const remainingOverlays = getPresentedOverlays(document);
449
+ const hasRemainingLocking = remainingOverlays.some((o) => {
450
+ const el = o;
451
+ return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && isBackdropAlwaysBlocking(el);
452
+ });
453
+ if (!hasRemainingLocking) {
454
+ setRootAriaHidden(false);
455
+ document.body.classList.remove(BACKDROP_NO_SCROLL);
456
+ }
457
+ };
435
458
  export const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
436
459
  var _a, _b;
437
460
  if (overlay.presented) {
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-03-13T20:04:20",
2
+ "timestamp": "2026-03-16T15:58:52",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.43.0",
package/dist/esm/index.js CHANGED
@@ -13,7 +13,7 @@ export { L as LogLevel } from './index-IGIE5vDm.js';
13
13
  export { I as IonicSafeString, g as getMode, s as setupConfig } from './config-TO1rZH52.js';
14
14
  export { o as openURL } from './theme-DiVJyqlX.js';
15
15
  export { m as menuController } from './index-B2KwgBLx.js';
16
- export { b as actionSheetController, a as alertController, l as loadingController, m as modalController, p as pickerController, c as popoverController, t as toastController } from './overlays-F8GHPo-e.js';
16
+ export { b as actionSheetController, a as alertController, l as loadingController, m as modalController, p as pickerController, c as popoverController, t as toastController } from './overlays-CCsdmuZR.js';
17
17
  import './index-ZjP4CjeZ.js';
18
18
  import './gesture-controller-BTEOs1at.js';
19
19
  import './hardware-back-button-CTe4XmL7.js';
@@ -5,7 +5,7 @@ import { r as registerInstance, c as createEvent, a as readTask, h, d as Host, g
5
5
  import { c as createButtonActiveGesture } from './button-active-BBx21brx.js';
6
6
  import { r as raf } from './helpers-Tl8jw6S2.js';
7
7
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
8
- import { d as createDelegateController, e as createTriggerController, B as BACKDROP, i as isCancel, f as present, g as dismiss, h as eventMethod, s as safeCall, j as prepareOverlay, k as setOverlayId } from './overlays-F8GHPo-e.js';
8
+ import { d as createDelegateController, e as createTriggerController, B as BACKDROP, i as isCancel, f as present, g as dismiss, h as eventMethod, s as safeCall, j as prepareOverlay, k as cleanupRootFocusTrapAccessibility, n as setOverlayId } from './overlays-CCsdmuZR.js';
9
9
  import { g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-DfbeLwcV.js';
11
11
  import { c as createAnimation } from './animation-CnGMT4ji.js';
@@ -383,6 +383,10 @@ const ActionSheet = class {
383
383
  this.gesture = undefined;
384
384
  }
385
385
  this.triggerController.removeClickListener();
386
+ // Clean up aria-hidden if removed without dismiss() being called
387
+ if (this.presented) {
388
+ cleanupRootFocusTrapAccessibility();
389
+ }
386
390
  }
387
391
  componentWillLoad() {
388
392
  var _a;
@@ -486,12 +490,12 @@ const ActionSheet = class {
486
490
  const cancelButton = allButtons.find((b) => b.role === 'cancel');
487
491
  const buttons = allButtons.filter((b) => b.role !== 'cancel');
488
492
  const headerID = `action-sheet-${overlayIndex}-header`;
489
- return (h(Host, Object.assign({ key: '173fcff5b1da7c33c267de4667591c946b8c8d03', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
493
+ return (h(Host, Object.assign({ key: 'fc8e6c837c7e16d78348a3109f5dc992f111784a', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
490
494
  zIndex: `${20000 + this.overlayIndex}`,
491
- }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), h("ion-backdrop", { key: '521ede659f747864f6c974e09016436eceb7158c', tappable: this.backdropDismiss }), h("div", { key: '7a7946fc434bc444f16a70638f5e948c69d33fcd', tabindex: "0", "aria-hidden": "true" }), h("div", { key: 'bcff39a580489dbafa255842e57aa8602c6d0f18', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, h("div", { key: '84bba13ce14261f0f0daa3f9c77648c9e7f36e0e', class: "action-sheet-container" }, h("div", { key: 'd9c8ac404fd6719a7adf8cb36549f67616f9a0c4', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (h("div", { key: '180433a8ad03ef5c54728a1a8f34715b6921d658', id: headerID, class: {
495
+ }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), h("ion-backdrop", { key: 'e558804050a8ba80dcca73308bbcb4b31687ba70', tappable: this.backdropDismiss }), h("div", { key: '6697622f6a62a460eac489afc5cd504eda002140', tabindex: "0", "aria-hidden": "true" }), h("div", { key: '4c05e7a9a20953faaa8ea0eab739b9b400895137', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, h("div", { key: '43bbc9b7217570cfc62789b4987e61a6e51a1c5f', class: "action-sheet-container" }, h("div", { key: '5f9b36b5396043997d7b74e29ad3738b2af8821e', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (h("div", { key: '3306e90dace90046d226b1eb95b06af11eebba5e', id: headerID, class: {
492
496
  'action-sheet-title': true,
493
497
  'action-sheet-has-sub-title': this.subHeader !== undefined,
494
- } }, header, this.subHeader && h("div", { key: '7138e79e61b1a8f42bc5a9175c57fa2f15d7ec5a', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (h("div", { key: 'b617c722f5b8028d73ed34b69310f312c65f34a7', class: "action-sheet-group action-sheet-group-cancel" }, h("button", Object.assign({ key: 'd0dd876fc48815df3710413c201c0b445a8e16c0' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass(cancelButton), onClick: () => this.buttonClick(cancelButton) }), h("span", { key: 'e7b960157cc6fc5fe92a12090b2be55e8ae072e4', class: "action-sheet-button-inner" }, cancelButton.icon && (h("ion-icon", { key: '05498ffc60cab911dbff0ecbc6168dea59ada9a5', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && h("ion-ripple-effect", { key: '3d401346cea301be4ca03671f7370f6f4b0b6bde' })))))), h("div", { key: '971f3c5fcc07f36c28eb469a47ec0290c692e139', tabindex: "0", "aria-hidden": "true" })));
498
+ } }, header, this.subHeader && h("div", { key: 'ee8e87e627e8eb6afdb1f4c3f0ef34c29a2b69c6', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (h("div", { key: 'cb568ea8502afd8d913c0d0107db4fc98b5e50c6', class: "action-sheet-group action-sheet-group-cancel" }, h("button", Object.assign({ key: 'd11ca6898fa308f494f2183ffc45bbcf971c14cb' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass(cancelButton), onClick: () => this.buttonClick(cancelButton) }), h("span", { key: 'b18e80930fdd0515d3647846729d392971c7c511', class: "action-sheet-button-inner" }, cancelButton.icon && (h("ion-icon", { key: '4e0a3fdcedaa480329080a8597df29746c14fd06', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && h("ion-ripple-effect", { key: 'fd2be8895b57b74bc83ee54a5d738472ad5fdb00' })))))), h("div", { key: 'b08dba5d658f9a5a64d76dc7eb8aba720c9333c3', tabindex: "0", "aria-hidden": "true" })));
495
499
  }
496
500
  get el() { return getElement(this); }
497
501
  static get watchers() { return {
@@ -6,7 +6,7 @@ import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './conf
6
6
  import { c as createButtonActiveGesture } from './button-active-BBx21brx.js';
7
7
  import { r as raf } from './helpers-Tl8jw6S2.js';
8
8
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
9
- import { d as createDelegateController, e as createTriggerController, B as BACKDROP, i as isCancel, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod, s as safeCall } from './overlays-F8GHPo-e.js';
9
+ import { d as createDelegateController, e as createTriggerController, B as BACKDROP, i as isCancel, j as prepareOverlay, n as setOverlayId, k as cleanupRootFocusTrapAccessibility, f as present, g as dismiss, h as eventMethod, s as safeCall } from './overlays-CCsdmuZR.js';
10
10
  import { g as getClassMap } from './theme-DiVJyqlX.js';
11
11
  import { b as getIonMode } from './ionic-global-DfbeLwcV.js';
12
12
  import { c as createAnimation } from './animation-CnGMT4ji.js';
@@ -303,6 +303,10 @@ const Alert = class {
303
303
  this.gesture.destroy();
304
304
  this.gesture = undefined;
305
305
  }
306
+ // Clean up aria-hidden if removed without dismiss() being called
307
+ if (this.presented) {
308
+ cleanupRootFocusTrapAccessibility();
309
+ }
306
310
  }
307
311
  componentDidLoad() {
308
312
  /**
@@ -536,9 +540,9 @@ const Alert = class {
536
540
  * If neither are defined, do not set aria-labelledby.
537
541
  */
538
542
  const ariaLabelledBy = header && subHeader ? `${hdrId} ${subHdrId}` : header ? hdrId : subHeader ? subHdrId : null;
539
- return (h(Host, { key: '6025440b9cd369d4fac89e7e4296c84a10a0b8e0', tabindex: "-1", style: {
543
+ return (h(Host, { key: '51ccec282f165dbaa02d7ee0c6413b870abae1d5', tabindex: "-1", style: {
540
544
  zIndex: `${20000 + overlayIndex}`,
541
- }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, h("ion-backdrop", { key: '3cd5ca8b99cb95b11dd22ab41a820d841142896f', tappable: this.backdropDismiss }), h("div", { key: '4cc62ae6e21424057d22aeef1e8fc77011e77cd5', tabindex: "0", "aria-hidden": "true" }), h("div", Object.assign({ key: '364057a69f25aa88904df17bdcf7e5bf714e7830', class: "alert-wrapper ion-overlay-wrapper", role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "0", ref: (el) => (this.wrapperEl = el) }, htmlAttributes), h("div", { key: '78694e3c0db2d408df3899fb1a90859bcc8d14cc', class: "alert-head" }, header && (h("h2", { key: 'ec88ff3e4e1ea871b5975133fdcf4cac38b05e0f', id: hdrId, class: "alert-title" }, header)), subHeader && !header && (h("h2", { key: '9b09bc8bb68af255ef8b7d22587acc946148e544', id: subHdrId, class: "alert-sub-title" }, subHeader)), subHeader && header && (h("h3", { key: '99abe815f75d2df7f1b77c0df9f3436724fea76f', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), h("div", { key: 'a43d0c22c0e46b1ef911f92ffeb253d7911b85f7', tabindex: "0", "aria-hidden": "true" })));
545
+ }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, h("ion-backdrop", { key: '555fb7a0048d1ada0182925ca460956e65f43322', tappable: this.backdropDismiss }), h("div", { key: 'bce7b1466f5d3c2615a7478ec8903f9567c9b101', tabindex: "0", "aria-hidden": "true" }), h("div", Object.assign({ key: '8b0e8793070fee6cb3a69f0fc9b828b07672d0f9', class: "alert-wrapper ion-overlay-wrapper", role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "0", ref: (el) => (this.wrapperEl = el) }, htmlAttributes), h("div", { key: 'f9c99afdd4389421e9eaabaa7e2f9c17e2cb88f4', class: "alert-head" }, header && (h("h2", { key: '7aa37fe49189d714e7d4bc786d9895ab8191f25c', id: hdrId, class: "alert-title" }, header)), subHeader && !header && (h("h2", { key: '1c32cbb4d615672b669bfacff35079791a0ab50a', id: subHdrId, class: "alert-sub-title" }, subHeader)), subHeader && header && (h("h3", { key: 'fc7285499cee4cef323085e501d974d423102e94', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), h("div", { key: 'b69334b5643b2592053bc408a9ab3b623e2d2b9d', tabindex: "0", "aria-hidden": "true" })));
542
546
  }
543
547
  get el() { return getElement(this); }
544
548
  static get watchers() { return {
@@ -4,7 +4,7 @@
4
4
  import { j as printIonError, f as printIonWarning, r as registerInstance, c as createEvent, w as writeTask, h, d as Host, g as getElement } from './index-IGIE5vDm.js';
5
5
  import { startFocusVisible } from './focus-visible-BmVRXR1y.js';
6
6
  import { r as raf, g as getElementRoot, a as renderHiddenInput, e as clamp } from './helpers-Tl8jw6S2.js';
7
- import { F as FOCUS_TRAP_DISABLE_CLASS, d as createDelegateController, e as createTriggerController, B as BACKDROP, i as isCancel, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod, s as safeCall } from './overlays-F8GHPo-e.js';
7
+ import { F as FOCUS_TRAP_DISABLE_CLASS, d as createDelegateController, e as createTriggerController, B as BACKDROP, i as isCancel, j as prepareOverlay, k as cleanupRootFocusTrapAccessibility, n as setOverlayId, f as present, g as dismiss, h as eventMethod, s as safeCall } from './overlays-CCsdmuZR.js';
8
8
  import { i as isRTL } from './dir-C53feagD.js';
9
9
  import { c as createColorClasses, g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { l as chevronDown, o as caretUpSharp, p as chevronForward, q as caretDownSharp, c as chevronBack } from './index-DV3sJJW8.js';
@@ -2084,6 +2084,10 @@ const Picker = class {
2084
2084
  }
2085
2085
  disconnectedCallback() {
2086
2086
  this.triggerController.removeClickListener();
2087
+ // Clean up aria-hidden if removed without dismiss() being called
2088
+ if (this.presented) {
2089
+ cleanupRootFocusTrapAccessibility();
2090
+ }
2087
2091
  }
2088
2092
  componentWillLoad() {
2089
2093
  var _a;
@@ -2202,11 +2206,11 @@ const Picker = class {
2202
2206
  render() {
2203
2207
  const { htmlAttributes } = this;
2204
2208
  const mode = getIonMode(this);
2205
- return (h(Host, Object.assign({ key: '80f66d33780d8a1352d24be9cb63a0cc03d01ab5', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
2209
+ return (h(Host, Object.assign({ key: '4d6531bfff4eb466f897cf2227d51783604ff439', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
2206
2210
  zIndex: `${20000 + this.overlayIndex}`,
2207
2211
  }, class: Object.assign({ [mode]: true,
2208
2212
  // Used internally for styling
2209
- [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), h("ion-backdrop", { key: '97fb8e10ba08b197610cb8c0cdea61103883d55f', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: 'b3969cb6fbf7153623d14e3ca1493d3370efb211', tabindex: "0", "aria-hidden": "true" }), h("div", { key: '299268483c3727e698d9135bfdf40349a7050ac1', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, h("div", { key: '95394de3ef691899b7dbf416f56fd3e86bbdce3f', class: "picker-toolbar" }, this.buttons.map((b) => (h("div", { class: buttonWrapperClass(b) }, h("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass(b) }, b.text))))), h("div", { key: '05f18bb8d00dc0e22f691b7e41f90f729a6c66d7', class: "picker-columns" }, h("div", { key: '4a8fdf224effc0af67fd413e2e6aca8a78d1cf43', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => h("ion-picker-legacy-column", { col: c })), h("div", { key: 'e50a31db45e3f39e9d0fed36a21be9257eec09bf', class: "picker-below-highlight" }))), h("div", { key: '5a78cb2176ac807ea0c195c6b76cd0e8eef9d4c0', tabindex: "0", "aria-hidden": "true" })));
2213
+ [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), h("ion-backdrop", { key: '754a80de29087f7e793b232c4276fc1f6b1c937f', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '9fcffb91109d6082ed338cd37a997254e5ea5bce', tabindex: "0", "aria-hidden": "true" }), h("div", { key: 'de066bda70a9cb831fc88493873d7ebf879122d0', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, h("div", { key: '03a502e2e1aa38abd582ecfca60da8b7d1045701', class: "picker-toolbar" }, this.buttons.map((b) => (h("div", { class: buttonWrapperClass(b) }, h("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass(b) }, b.text))))), h("div", { key: 'f9e4d9eff3c2df866f15eed63f715a51c912eac6', class: "picker-columns" }, h("div", { key: '78656d3265f9d4c82387f942c896a9d67c1fcedf', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => h("ion-picker-legacy-column", { col: c })), h("div", { key: '1afd96cfa38fa9f52f61a867f2aa116a9ef3bedb', class: "picker-below-highlight" }))), h("div", { key: '4d533e132d70f6ab32c461e3e4f6f9dfbe6bab15', tabindex: "0", "aria-hidden": "true" })));
2210
2214
  }
2211
2215
  get el() { return getElement(this); }
2212
2216
  static get watchers() { return {
@@ -5,7 +5,7 @@ import { r as registerInstance, c as createEvent, e as config, h, d as Host, g a
5
5
  import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-TO1rZH52.js';
6
6
  import { r as raf } from './helpers-Tl8jw6S2.js';
7
7
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
8
- import { d as createDelegateController, e as createTriggerController, B as BACKDROP, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod } from './overlays-F8GHPo-e.js';
8
+ import { d as createDelegateController, e as createTriggerController, B as BACKDROP, j as prepareOverlay, n as setOverlayId, k as cleanupRootFocusTrapAccessibility, f as present, g as dismiss, h as eventMethod } from './overlays-CCsdmuZR.js';
9
9
  import { g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-DfbeLwcV.js';
11
11
  import { c as createAnimation } from './animation-CnGMT4ji.js';
@@ -211,6 +211,10 @@ const Loading = class {
211
211
  }
212
212
  disconnectedCallback() {
213
213
  this.triggerController.removeClickListener();
214
+ // Clean up aria-hidden if removed without dismiss() being called
215
+ if (this.presented) {
216
+ cleanupRootFocusTrapAccessibility();
217
+ }
214
218
  }
215
219
  /**
216
220
  * Present the loading overlay after it has been created.
@@ -276,9 +280,9 @@ const Loading = class {
276
280
  * Otherwise, don't set aria-labelledby.
277
281
  */
278
282
  const ariaLabelledBy = message !== undefined ? msgId : null;
279
- return (h(Host, Object.assign({ key: 'f86ddbc600cb5c396b7de38fb5f49625388c3c3f', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
283
+ return (h(Host, Object.assign({ key: 'ab48bfcee8f7e3e33847a2f262fdc08b9ea804ca', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
280
284
  zIndex: `${40000 + this.overlayIndex}`,
281
- }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), h("ion-backdrop", { key: 'b53727aaddc37ef3c685fcc150c6d5193290a847', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '4c61bede8e0a4e47daa6f1f9d0f364ef6aec0bc3', tabindex: "0", "aria-hidden": "true" }), h("div", { key: '84e51ceb07118f1eaeb757df28801c255496931b', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (h("div", { key: 'fc97f1912e0fc558b7c309a5bc084415f5f620b2', class: "loading-spinner" }, h("ion-spinner", { key: '6e186d856cd3f10f22c3e317ef00f31b4216459c', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), h("div", { key: 'dcbe9d9a619daa1c08174e73827bdabeb59dde92', tabindex: "0", "aria-hidden": "true" })));
285
+ }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), h("ion-backdrop", { key: '41baccc7fb6474389a3a3431c208e829ef738b75', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '7b7290974abbe8db8739b19835aca9f8b5c271c2', tabindex: "0", "aria-hidden": "true" }), h("div", { key: 'e32466abfcc92aaad47ea03b1dcb49f66abe4b63', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (h("div", { key: 'c5e6e6f9e3f39dba0225d08d7dd2c1b96a1d83c7', class: "loading-spinner" }, h("ion-spinner", { key: 'f428038959d879404ea898011363aac0b807ad11', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), h("div", { key: '490e531367b86c319fa4260722dcff4dd631fa88', tabindex: "0", "aria-hidden": "true" })));
282
286
  }
283
287
  get el() { return getElement(this); }
284
288
  static get watchers() { return {
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { r as registerInstance, c as createEvent, e as config, j as printIonError, h, d as Host, g as getElement } from './index-IGIE5vDm.js';
5
5
  import { g as getTimeGivenProgression } from './cubic-bezier-hHmYLOfE.js';
6
- import { o as getPresentedOverlay, B as BACKDROP, n as focusFirstDescendant, q as focusLastDescendant, G as GESTURE } from './overlays-F8GHPo-e.js';
6
+ import { q as getPresentedOverlay, B as BACKDROP, o as focusFirstDescendant, r as focusLastDescendant, G as GESTURE } from './overlays-CCsdmuZR.js';
7
7
  import { G as GESTURE_CONTROLLER } from './gesture-controller-BTEOs1at.js';
8
8
  import { shouldUseCloseWatcher } from './hardware-back-button-CTe4XmL7.js';
9
9
  import { o as isEndSide, i as inheritAriaAttributes, l as assert, e as clamp } from './helpers-Tl8jw6S2.js';
@@ -7,7 +7,7 @@ import { C as CoreDelegate, a as attachComponent, d as detachComponent } from '.
7
7
  import { e as clamp, g as getElementRoot, r as raf, b as inheritAttributes, h as hasLazyBuild } from './helpers-Tl8jw6S2.js';
8
8
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
9
9
  import { g as getCapacitor } from './capacitor-CFERIeaU.js';
10
- import { G as GESTURE, O as OVERLAY_GESTURE_PRIORITY, F as FOCUS_TRAP_DISABLE_CLASS, e as createTriggerController, B as BACKDROP, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod } from './overlays-F8GHPo-e.js';
10
+ import { G as GESTURE, O as OVERLAY_GESTURE_PRIORITY, F as FOCUS_TRAP_DISABLE_CLASS, e as createTriggerController, B as BACKDROP, j as prepareOverlay, k as cleanupRootFocusTrapAccessibility, n as setOverlayId, f as present, g as dismiss, h as eventMethod } from './overlays-CCsdmuZR.js';
11
11
  import { g as getClassMap } from './theme-DiVJyqlX.js';
12
12
  import { e as deepReady, w as waitForMount } from './index-B-hkiOUh.js';
13
13
  import { b as getIonMode } from './ionic-global-DfbeLwcV.js';
@@ -2056,6 +2056,10 @@ const Modal = class {
2056
2056
  // Also called in dismiss() — intentional dual cleanup covers both
2057
2057
  // dismiss-then-remove and direct DOM removal without dismiss.
2058
2058
  this.cleanupSafeAreaOverrides();
2059
+ // Clean up aria-hidden if removed without dismiss() being called
2060
+ if (this.presented) {
2061
+ cleanupRootFocusTrapAccessibility();
2062
+ }
2059
2063
  }
2060
2064
  componentWillLoad() {
2061
2065
  var _a;
@@ -2904,20 +2908,20 @@ const Modal = class {
2904
2908
  const isCardModal = presentingElement !== undefined && mode === 'ios';
2905
2909
  const isHandleCycle = handleBehavior === 'cycle';
2906
2910
  const isSheetModalWithHandle = isSheetModal && showHandle;
2907
- return (h(Host, Object.assign({ key: '1a53e8f87532abccc169ca4b24973a39c5f9ba16', "no-router": true,
2911
+ return (h(Host, Object.assign({ key: 'e6df0917ac03a8d6bf67cc9bebf075d2b804ba22', "no-router": true,
2908
2912
  // Allow the modal to be navigable when the handle is focusable
2909
2913
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
2910
2914
  zIndex: `${20000 + this.overlayIndex}`,
2911
- }, 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: 'fa8e0a436c0d458331402e1850f87af3dc97b582', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'f00de6027d3c8b5bc93db3b0f7a50a87628d40bb', class: "modal-shadow" }), h("div", Object.assign({ key: 'ae5e33bd6c58e541edb2edbca92420ea02dd5175',
2915
+ }, 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: '710ed1cbb6ae9c1a1fa7ae774fd44aa3bbee8381', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'c9051fcd099e9b73e17f015dea6e16fbd73e4df4', class: "modal-shadow" }), h("div", Object.assign({ key: '21e42d40099a569d95a4e04aa6d314c7d45c6192',
2912
2916
  /*
2913
2917
  role and aria-modal must be used on the
2914
2918
  same element. They must also be set inside the
2915
2919
  shadow DOM otherwise ion-button will not be highlighted
2916
2920
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
2917
2921
  */
2918
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '141cdd8f8522331f4b764e2a4d79ec6596b1eb3a', class: "modal-handle",
2922
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: 'b48a6c32c9a7ebe5e070e8d9f3510d55d4bd1f9f', class: "modal-handle",
2919
2923
  // Prevents the handle from receiving keyboard focus when it does not cycle
2920
- 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: '7de20298b61abee67a16d275c9ebd9a25ce7dd26', onSlotchange: this.onSlotChange }))));
2924
+ 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: '2a20160f66629c14e3414bbe01e5ee89101d02be', onSlotchange: this.onSlotChange }))));
2921
2925
  }
2922
2926
  get el() { return getElement(this); }
2923
2927
  static get watchers() { return {
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { r as registerInstance, c as createEvent, f as printIonWarning, h, d as Host, g as getElement } from './index-IGIE5vDm.js';
5
- import { B as BACKDROP, j as prepareOverlay, k as setOverlayId, f as present, n as focusFirstDescendant, g as dismiss, h as eventMethod, F as FOCUS_TRAP_DISABLE_CLASS } from './overlays-F8GHPo-e.js';
5
+ import { B as BACKDROP, j as prepareOverlay, k as cleanupRootFocusTrapAccessibility, n as setOverlayId, f as present, o as focusFirstDescendant, g as dismiss, h as eventMethod, F as FOCUS_TRAP_DISABLE_CLASS } from './overlays-CCsdmuZR.js';
6
6
  import { C as CoreDelegate, a as attachComponent, d as detachComponent } from './framework-delegate-CyxE1S_P.js';
7
7
  import { g as getElementRoot, r as raf, f as addEventListener, h as hasLazyBuild } from './helpers-Tl8jw6S2.js';
8
8
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
@@ -1304,6 +1304,10 @@ const Popover = class {
1304
1304
  this.headerResizeObserver.disconnect();
1305
1305
  this.headerResizeObserver = undefined;
1306
1306
  }
1307
+ // Clean up aria-hidden if removed without dismiss() being called
1308
+ if (this.presented) {
1309
+ cleanupRootFocusTrapAccessibility();
1310
+ }
1307
1311
  }
1308
1312
  componentWillLoad() {
1309
1313
  var _a, _b;
@@ -1542,9 +1546,9 @@ const Popover = class {
1542
1546
  const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes, focusTrap } = this;
1543
1547
  const desktop = isPlatform('desktop');
1544
1548
  const enableArrow = arrow && !parentPopover;
1545
- return (h(Host, Object.assign({ key: '2edd8333c630efbce59071f8a383e4326e928dbc', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
1549
+ return (h(Host, Object.assign({ key: 'afc292b6b4eeb571c1cd832bc7ac03e0fea3dc28', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
1546
1550
  zIndex: `${20000 + this.overlayIndex}`,
1547
- }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { key: 'aac4e68b08197534375e8ea3f8c9ea0c10ab2af4', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: 'b7f4ebf57d4148b32856b0075d286f454be8de5d', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && h("div", { key: '607d94c28d73e8e957175a7c0f6e8a99ec4dcd53', class: "popover-arrow", part: "arrow" }), h("div", { key: '4366a5a5de550c09895e923f345583508e1ec30c', class: "popover-content", part: "content" }, h("slot", { key: 'eb7886fbc99c15b667b7d825d24f1c12d9380f03' })))));
1551
+ }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { key: '301a33645918c7feb807a6fe857e462b83291c40', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: 'f66123d36601ce61af3bce3c68c73002fe3a6d73', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && h("div", { key: '39c92c94d01748d499f2db2513ecf022be2577dd', class: "popover-arrow", part: "arrow" }), h("div", { key: '827552221533f7b5676e6e313cd7517275ea76d7', class: "popover-content", part: "content" }, h("slot", { key: 'f874b8dfb78bfbc02e3bcad104819bf8d181d42f' })))));
1548
1552
  }
1549
1553
  get el() { return getElement(this); }
1550
1554
  static get watchers() { return {
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { r as registerInstance, h, i as forceUpdate, d as Host, g as getElement } from './index-IGIE5vDm.js';
5
5
  import { b as getIonMode } from './ionic-global-DfbeLwcV.js';
6
- import { s as safeCall } from './overlays-F8GHPo-e.js';
6
+ import { s as safeCall } from './overlays-CCsdmuZR.js';
7
7
  import { g as getClassMap } from './theme-DiVJyqlX.js';
8
8
  import './index-ZjP4CjeZ.js';
9
9
  import './helpers-Tl8jw6S2.js';
@@ -6,7 +6,7 @@ import { c as createNotchController } from './notch-controller-DAcvKU57.js';
6
6
  import { i as isOptionSelected, c as compareOptions } from './compare-with-utils-sObYyvOy.js';
7
7
  import { c as checkInvalidState } from './validity-DJztqcrH.js';
8
8
  import { b as inheritAttributes, a as renderHiddenInput, n as focusVisibleElement } from './helpers-Tl8jw6S2.js';
9
- import { c as popoverController, b as actionSheetController, a as alertController, m as modalController, s as safeCall } from './overlays-F8GHPo-e.js';
9
+ import { c as popoverController, b as actionSheetController, a as alertController, m as modalController, s as safeCall } from './overlays-CCsdmuZR.js';
10
10
  import { i as isRTL } from './dir-C53feagD.js';
11
11
  import { h as hostContext, c as createColorClasses, g as getClassMap } from './theme-DiVJyqlX.js';
12
12
  import { w as watchForOptions } from './watch-options-Dtdm8lKC.js';
@@ -5,7 +5,7 @@ import { f as printIonWarning, r as registerInstance, c as createEvent, e as con
5
5
  import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-TO1rZH52.js';
6
6
  import { g as getElementRoot, r as raf } from './helpers-Tl8jw6S2.js';
7
7
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
8
- import { O as OVERLAY_GESTURE_PRIORITY, d as createDelegateController, e as createTriggerController, i as isCancel, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod, s as safeCall, G as GESTURE } from './overlays-F8GHPo-e.js';
8
+ import { O as OVERLAY_GESTURE_PRIORITY, d as createDelegateController, e as createTriggerController, i as isCancel, j as prepareOverlay, n as setOverlayId, f as present, g as dismiss, h as eventMethod, s as safeCall, G as GESTURE } from './overlays-CCsdmuZR.js';
9
9
  import { c as createColorClasses, g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-DfbeLwcV.js';
11
11
  import { c as createAnimation } from './animation-CnGMT4ji.js';
@@ -511,6 +511,29 @@ const setRootAriaHidden = (hidden = false) => {
511
511
  viewContainer.removeAttribute('aria-hidden');
512
512
  }
513
513
  };
514
+ /**
515
+ * Cleans up root `aria-hidden` and `backdrop-no-scroll` when
516
+ * an overlay is removed from the DOM without going through
517
+ * the `dismiss()` flow (e.g., when a framework unmounts the
518
+ * overlay during a route change).
519
+ *
520
+ * Should be called from an overlay's `disconnectedCallback`
521
+ * when the overlay was still presented at the time of removal.
522
+ */
523
+ const cleanupRootFocusTrapAccessibility = () => {
524
+ if (typeof document === 'undefined') {
525
+ return;
526
+ }
527
+ const remainingOverlays = getPresentedOverlays(document);
528
+ const hasRemainingLocking = remainingOverlays.some((o) => {
529
+ const el = o;
530
+ return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && isBackdropAlwaysBlocking(el);
531
+ });
532
+ if (!hasRemainingLocking) {
533
+ setRootAriaHidden(false);
534
+ document.body.classList.remove(BACKDROP_NO_SCROLL);
535
+ }
536
+ };
514
537
  const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
515
538
  var _a, _b;
516
539
  if (overlay.presented) {
@@ -912,4 +935,4 @@ const createTriggerController = () => {
912
935
  };
913
936
  const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
914
937
 
915
- export { BACKDROP as B, FOCUS_TRAP_DISABLE_CLASS as F, GESTURE as G, OVERLAY_GESTURE_PRIORITY as O, alertController as a, actionSheetController as b, popoverController as c, createDelegateController as d, createTriggerController as e, present as f, dismiss as g, eventMethod as h, isCancel as i, prepareOverlay as j, setOverlayId as k, loadingController as l, modalController as m, focusFirstDescendant as n, getPresentedOverlay as o, pickerController as p, focusLastDescendant as q, safeCall as s, toastController as t };
938
+ export { BACKDROP as B, FOCUS_TRAP_DISABLE_CLASS as F, GESTURE as G, OVERLAY_GESTURE_PRIORITY as O, alertController as a, actionSheetController as b, popoverController as c, createDelegateController as d, createTriggerController as e, present as f, dismiss as g, eventMethod as h, isCancel as i, prepareOverlay as j, cleanupRootFocusTrapAccessibility as k, loadingController as l, modalController as m, setOverlayId as n, focusFirstDescendant as o, pickerController as p, getPresentedOverlay as q, focusLastDescendant as r, safeCall as s, toastController as t };