@ionic/core 8.8.3 → 8.8.4-dev.11775078622.1402ffa2

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-D6pdfDIA.js → p-BZ6v19WN.js} +1 -1
  18. package/components/p-C5gHGV8-.js +4 -0
  19. package/components/p-CWnwVrC4.js +4 -0
  20. package/components/{p-e-EDj2CO.js → p-MT7pYfQI.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-2876a692.entry.js +4 -0
  56. package/dist/ionic/p-50b13f63.entry.js +4 -0
  57. package/dist/ionic/p-53399c0b.entry.js +4 -0
  58. package/dist/ionic/p-80bea9dd.entry.js +4 -0
  59. package/dist/ionic/p-Bx-dQ-64.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-5b52aa7d.entry.js +0 -4
  80. package/dist/ionic/p-7ca71c83.entry.js +0 -4
  81. package/dist/ionic/p-DTPR1Wpn.js +0 -4
@@ -5,7 +5,7 @@ import { Host, h, readTask } from "@stencil/core";
5
5
  import { createButtonActiveGesture } from "../../utils/gesture/button-active";
6
6
  import { raf } from "../../utils/helpers";
7
7
  import { createLockController } from "../../utils/lock-controller";
8
- import { BACKDROP, createDelegateController, createTriggerController, 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";
@@ -284,6 +284,10 @@ export class ActionSheet {
284
284
  this.gesture = undefined;
285
285
  }
286
286
  this.triggerController.removeClickListener();
287
+ // Clean up aria-hidden if removed without dismiss() being called
288
+ if (this.presented) {
289
+ cleanupRootFocusTrapAccessibility();
290
+ }
287
291
  }
288
292
  componentWillLoad() {
289
293
  var _a;
@@ -387,12 +391,12 @@ export class ActionSheet {
387
391
  const cancelButton = allButtons.find((b) => b.role === 'cancel');
388
392
  const buttons = allButtons.filter((b) => b.role !== 'cancel');
389
393
  const headerID = `action-sheet-${overlayIndex}-header`;
390
- return (h(Host, Object.assign({ key: '173fcff5b1da7c33c267de4667591c946b8c8d03', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
394
+ return (h(Host, Object.assign({ key: 'fc8e6c837c7e16d78348a3109f5dc992f111784a', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
391
395
  zIndex: `${20000 + this.overlayIndex}`,
392
- }, 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: {
396
+ }, 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: {
393
397
  'action-sheet-title': true,
394
398
  'action-sheet-has-sub-title': this.subHeader !== undefined,
395
- } }, 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" })));
399
+ } }, 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" })));
396
400
  }
397
401
  static get is() { return "ion-action-sheet"; }
398
402
  static get encapsulation() { return "scoped"; }
@@ -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-04-01T19:48:30",
2
+ "timestamp": "2026-04-01T21:25:39",
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';
@@ -2090,6 +2090,10 @@ const Picker = class {
2090
2090
  }
2091
2091
  disconnectedCallback() {
2092
2092
  this.triggerController.removeClickListener();
2093
+ // Clean up aria-hidden if removed without dismiss() being called
2094
+ if (this.presented) {
2095
+ cleanupRootFocusTrapAccessibility();
2096
+ }
2093
2097
  }
2094
2098
  componentWillLoad() {
2095
2099
  var _a;
@@ -2208,11 +2212,11 @@ const Picker = class {
2208
2212
  render() {
2209
2213
  const { htmlAttributes } = this;
2210
2214
  const mode = getIonMode(this);
2211
- return (h(Host, Object.assign({ key: '80f66d33780d8a1352d24be9cb63a0cc03d01ab5', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
2215
+ return (h(Host, Object.assign({ key: '4d6531bfff4eb466f897cf2227d51783604ff439', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
2212
2216
  zIndex: `${20000 + this.overlayIndex}`,
2213
2217
  }, class: Object.assign({ [mode]: true,
2214
2218
  // Used internally for styling
2215
- [`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" })));
2219
+ [`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" })));
2216
2220
  }
2217
2221
  get el() { return getElement(this); }
2218
2222
  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';