@ionic/core 8.8.15-nightly.20260717 → 8.8.15-nightly.20260721

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 (72) 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-dhLYXa7A.js → p-BIPPbW0M.js} +1 -1
  15. package/components/{p-0NRupjzW.js → p-BUYFy35a.js} +1 -1
  16. package/components/p-BWEZufiK.js +4 -0
  17. package/components/{p-nQi4oKcG.js → p-BqpciLfi.js} +1 -1
  18. package/components/{p-Bth-EzJ0.js → p-BsQPAqo9.js} +1 -1
  19. package/components/p-CRNiQiYf.js +4 -0
  20. package/components/{p-DS4Hk6R2.js → p-nyXeHk23.js} +1 -1
  21. package/dist/cjs/index.cjs.js +1 -1
  22. package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
  23. package/dist/cjs/ion-alert.cjs.entry.js +1 -1
  24. package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
  25. package/dist/cjs/ion-loading.cjs.entry.js +1 -1
  26. package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
  27. package/dist/cjs/ion-modal.cjs.entry.js +26 -6
  28. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  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-TbKsuC-K.js → overlays-DdtIYQUH.js} +24 -1
  33. package/dist/collection/components/modal/gestures/sheet.js +7 -0
  34. package/dist/collection/components/modal/gestures/swipe-to-close.js +7 -0
  35. package/dist/collection/components/modal/modal.ios.css +8 -0
  36. package/dist/collection/components/modal/modal.js +9 -3
  37. package/dist/collection/components/modal/modal.md.css +8 -0
  38. package/dist/collection/utils/overlays.js +24 -1
  39. package/dist/collection/utils/test/playwright/drag-element.js +5 -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 +1 -1
  43. package/dist/esm/ion-alert.entry.js +1 -1
  44. package/dist/esm/ion-datetime_3.entry.js +1 -1
  45. package/dist/esm/ion-loading.entry.js +1 -1
  46. package/dist/esm/ion-menu_3.entry.js +1 -1
  47. package/dist/esm/ion-modal.entry.js +26 -6
  48. package/dist/esm/ion-popover.entry.js +1 -1
  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-TbiM4mdr.js → overlays-Dg0q2_tJ.js} +25 -2
  53. package/dist/ionic/index.esm.js +1 -1
  54. package/dist/ionic/ionic.esm.js +1 -1
  55. package/dist/ionic/{p-30bf9737.entry.js → p-0dc33652.entry.js} +1 -1
  56. package/dist/ionic/{p-4dc1c33c.entry.js → p-2a05aa64.entry.js} +1 -1
  57. package/dist/ionic/{p-94f2a736.entry.js → p-34586ead.entry.js} +1 -1
  58. package/dist/ionic/{p-b1c6fdcf.entry.js → p-5018dfc8.entry.js} +1 -1
  59. package/dist/ionic/{p-00dbb17e.entry.js → p-5eb8e86d.entry.js} +1 -1
  60. package/dist/ionic/{p-e847a888.entry.js → p-65ebdf1b.entry.js} +1 -1
  61. package/dist/ionic/{p-2f55dc1a.entry.js → p-6ebdbebe.entry.js} +1 -1
  62. package/dist/ionic/{p-aa5d6b8f.entry.js → p-9f9db3a2.entry.js} +1 -1
  63. package/dist/ionic/p-D-3ycHmd.js +4 -0
  64. package/dist/ionic/{p-3a541154.entry.js → p-ca2ab74d.entry.js} +1 -1
  65. package/dist/ionic/p-e6a4bb56.entry.js +4 -0
  66. package/hydrate/index.js +49 -6
  67. package/hydrate/index.mjs +49 -6
  68. package/package.json +1 -1
  69. package/components/p-W9CZ2mWX.js +0 -4
  70. package/components/p-uVRyUM3z.js +0 -4
  71. package/dist/ionic/p-5fc7e542.entry.js +0 -4
  72. package/dist/ionic/p-xOfi7-Zn.js +0 -4
@@ -9,7 +9,7 @@ var frameworkDelegate = require('./framework-delegate-BtICZDHr.js');
9
9
  var helpers = require('./helpers-Cv23MFHM.js');
10
10
  var lockController = require('./lock-controller-aDB9wrEf.js');
11
11
  var capacitor = require('./capacitor-DmA66EwP.js');
12
- var overlays = require('./overlays-TbKsuC-K.js');
12
+ var overlays = require('./overlays-DdtIYQUH.js');
13
13
  var theme = require('./theme-CeDs6Hcv.js');
14
14
  var index$4 = require('./index-BERfRao3.js');
15
15
  var ionicGlobal = require('./ionic-global-B-cA6LkY.js');
@@ -333,7 +333,14 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onD
333
333
  return false;
334
334
  };
335
335
  const onStart = (detail) => {
336
+ var _a;
336
337
  const { deltaY } = detail;
338
+ /**
339
+ * Firefox automatically selects the header text during drag
340
+ * due to the focusable wrapper (tabindex="-1"). Remove any
341
+ * selection that may have occurred.
342
+ */
343
+ (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
337
344
  /**
338
345
  * Get the initial scrollY value so
339
346
  * that we can correctly reset the scrollY
@@ -1219,6 +1226,13 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1219
1226
  return true;
1220
1227
  };
1221
1228
  const onStart = (detail) => {
1229
+ var _a;
1230
+ /**
1231
+ * Firefox automatically selects the header text during drag
1232
+ * due to the focusable wrapper (tabindex="-1"). Remove any
1233
+ * selection that may have occurred.
1234
+ */
1235
+ (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
1222
1236
  /**
1223
1237
  * If canDismiss is anything other than `true`
1224
1238
  * then users should be able to swipe down
@@ -1821,9 +1835,9 @@ const clearSafeAreaOverrides = (hostEl) => {
1821
1835
  hostEl.style.removeProperty('--ion-safe-area-right');
1822
1836
  };
1823
1837
 
1824
- const modalIosCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}`;
1838
+ const modalIosCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-wrapper{outline:none}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}`;
1825
1839
 
1826
- const modalMdCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}`;
1840
+ const modalMdCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-wrapper{outline:none}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}`;
1827
1841
 
1828
1842
  const Modal = class {
1829
1843
  constructor(hostRef) {
@@ -2964,16 +2978,22 @@ const Modal = class {
2964
2978
  // Allow the modal to be navigable when the handle is focusable
2965
2979
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
2966
2980
  zIndex: `${20000 + this.overlayIndex}`,
2967
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: '5ba6315c7c8c64fa04c62f85fd493da5275b2cbd', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && index$3.h("div", { key: 'a76c48d41c67f86c18a7481e980e6925e614f85d', class: "modal-shadow" }), index$3.h("div", Object.assign({ key: '3f6c61ba60b063592784d76a9594073b3bf210a9',
2981
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: '5ba6315c7c8c64fa04c62f85fd493da5275b2cbd', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && index$3.h("div", { key: 'a76c48d41c67f86c18a7481e980e6925e614f85d', class: "modal-shadow" }), index$3.h("div", Object.assign({ key: 'dccf3c774355429bc0ea7461d9b1ef941ea91902',
2968
2982
  /*
2969
2983
  role and aria-modal must be used on the
2970
2984
  same element. They must also be set inside the
2971
2985
  shadow DOM otherwise ion-button will not be highlighted
2972
2986
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
2987
+
2988
+ tabIndex={-1} is required so present() can move focus to this
2989
+ element (which carries the dialog role) instead of the role-less
2990
+ host. role="dialog" alone does not make an element focusable, so
2991
+ without the tabindex focus() would be a no-op and screen readers
2992
+ may not properly announce the dialog and its content when it opens.
2973
2993
  */
2974
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: '7f66b4fdb3dec61a2b9aec4e9dbacf5d013d637c', class: "modal-handle",
2994
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", tabIndex: -1, class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: 'ba4ebd6364faba46ac8532d1c83cb655ae873a14', class: "modal-handle",
2975
2995
  // Prevents the handle from receiving keyboard focus when it does not cycle
2976
- tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), index$3.h("slot", { key: '2dfaaebe3d0b2a46be1224c25f9ab89bf1744332', onSlotchange: this.onSlotChange }))));
2996
+ tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), index$3.h("slot", { key: '11d5921a8ebbcd0017d4f28a33d68049253f63f0', onSlotchange: this.onSlotChange }))));
2977
2997
  }
2978
2998
  get el() { return index$3.getElement(this); }
2979
2999
  static get watchers() { return {
@@ -4,7 +4,7 @@
4
4
  'use strict';
5
5
 
6
6
  var index = require('./index-Ct7gcRif.js');
7
- var overlays = require('./overlays-TbKsuC-K.js');
7
+ var overlays = require('./overlays-DdtIYQUH.js');
8
8
  var frameworkDelegate = require('./framework-delegate-BtICZDHr.js');
9
9
  var helpers = require('./helpers-Cv23MFHM.js');
10
10
  var lockController = require('./lock-controller-aDB9wrEf.js');
@@ -5,7 +5,7 @@
5
5
 
6
6
  var index = require('./index-Ct7gcRif.js');
7
7
  var ionicGlobal = require('./ionic-global-B-cA6LkY.js');
8
- var overlays = require('./overlays-TbKsuC-K.js');
8
+ var overlays = require('./overlays-DdtIYQUH.js');
9
9
  var theme = require('./theme-CeDs6Hcv.js');
10
10
  require('./index-DkNv4J_i.js');
11
11
  require('./helpers-Cv23MFHM.js');
@@ -8,7 +8,7 @@ var notchController = require('./notch-controller-18PzRGXd.js');
8
8
  var compareWithUtils = require('./compare-with-utils-DSicavqM.js');
9
9
  var validity = require('./validity-BpS37YFM.js');
10
10
  var helpers = require('./helpers-Cv23MFHM.js');
11
- var overlays = require('./overlays-TbKsuC-K.js');
11
+ var overlays = require('./overlays-DdtIYQUH.js');
12
12
  var dir = require('./dir-Cn0z1rJH.js');
13
13
  var theme = require('./theme-CeDs6Hcv.js');
14
14
  var watchOptions = require('./watch-options-CviOsrTS.js');
@@ -7,7 +7,7 @@ var index$1 = require('./index-Ct7gcRif.js');
7
7
  var config = require('./config-xninhj0J.js');
8
8
  var helpers = require('./helpers-Cv23MFHM.js');
9
9
  var lockController = require('./lock-controller-aDB9wrEf.js');
10
- var overlays = require('./overlays-TbKsuC-K.js');
10
+ var overlays = require('./overlays-DdtIYQUH.js');
11
11
  var theme = require('./theme-CeDs6Hcv.js');
12
12
  var ionicGlobal = require('./ionic-global-B-cA6LkY.js');
13
13
  var animation = require('./animation-BJq0kcy2.js');
@@ -578,7 +578,30 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
578
578
  * to the overlay container.
579
579
  */
580
580
  if (overlay.keyboardClose && (document.activeElement === null || !overlay.el.contains(document.activeElement))) {
581
- overlay.el.focus();
581
+ /**
582
+ * Some overlays (e.g. modal) put the dialog role and accessible label
583
+ * on the `.ion-overlay-wrapper` instead of the host. Screen readers
584
+ * need focus on the element with `role="dialog"` to properly announce
585
+ * and navigate the dialog.
586
+ *
587
+ * We only target wrappers with `tabindex`, since `role="dialog"` alone
588
+ * does not make an element focusable. If no focusable dialog wrapper
589
+ * exists (e.g. picker-legacy), we fall back to the host.
590
+ */
591
+ const overlayWrapper = helpers.getElementRoot(overlay.el).querySelector('[role="dialog"][tabindex]');
592
+ const focusTarget = overlayWrapper !== null && overlayWrapper !== void 0 ? overlayWrapper : overlay.el;
593
+ /**
594
+ * `preventScroll` keeps this a pure focus move so the viewport does not
595
+ * jump when the wrapper is partially off-screen (e.g. a sheet modal).
596
+ * Guard the options call so an older engine that mishandles it can never
597
+ * reject present(); we fall back to a plain focus() in that case.
598
+ */
599
+ try {
600
+ focusTarget.focus({ preventScroll: true });
601
+ }
602
+ catch (_c) {
603
+ focusTarget.focus();
604
+ }
582
605
  }
583
606
  /**
584
607
  * If this overlay was previously dismissed without being
@@ -224,6 +224,13 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
224
224
  return true;
225
225
  };
226
226
  const onStart = (detail) => {
227
+ var _a;
228
+ /**
229
+ * Firefox automatically selects the header text during drag
230
+ * due to the focusable wrapper (tabindex="-1"). Remove any
231
+ * selection that may have occurred.
232
+ */
233
+ (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
227
234
  /**
228
235
  * If canDismiss is anything other than `true`
229
236
  * then users should be able to swipe down
@@ -96,7 +96,14 @@ export const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismi
96
96
  return false;
97
97
  };
98
98
  const onStart = (detail) => {
99
+ var _a;
99
100
  const { deltaY } = detail;
101
+ /**
102
+ * Firefox automatically selects the header text during drag
103
+ * due to the focusable wrapper (tabindex="-1"). Remove any
104
+ * selection that may have occurred.
105
+ */
106
+ (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
100
107
  /**
101
108
  * Get the initial scrollY value so
102
109
  * that we can correctly reset the scrollY
@@ -126,6 +126,14 @@ ion-backdrop {
126
126
  z-index: 10;
127
127
  }
128
128
 
129
+ /**
130
+ * The wrapper receives programmatic focus for screen readers but should not
131
+ * show a visible focus ring, which is meant only for keyboard navigation.
132
+ */
133
+ .modal-wrapper {
134
+ outline: none;
135
+ }
136
+
129
137
  .modal-shadow {
130
138
  position: absolute;
131
139
  background: transparent;
@@ -1166,16 +1166,22 @@ export class Modal {
1166
1166
  // Allow the modal to be navigable when the handle is focusable
1167
1167
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
1168
1168
  zIndex: `${20000 + this.overlayIndex}`,
1169
- }, 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: '5ba6315c7c8c64fa04c62f85fd493da5275b2cbd', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'a76c48d41c67f86c18a7481e980e6925e614f85d', class: "modal-shadow" }), h("div", Object.assign({ key: '3f6c61ba60b063592784d76a9594073b3bf210a9',
1169
+ }, 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: '5ba6315c7c8c64fa04c62f85fd493da5275b2cbd', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'a76c48d41c67f86c18a7481e980e6925e614f85d', class: "modal-shadow" }), h("div", Object.assign({ key: 'dccf3c774355429bc0ea7461d9b1ef941ea91902',
1170
1170
  /*
1171
1171
  role and aria-modal must be used on the
1172
1172
  same element. They must also be set inside the
1173
1173
  shadow DOM otherwise ion-button will not be highlighted
1174
1174
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
1175
+
1176
+ tabIndex={-1} is required so present() can move focus to this
1177
+ element (which carries the dialog role) instead of the role-less
1178
+ host. role="dialog" alone does not make an element focusable, so
1179
+ without the tabindex focus() would be a no-op and screen readers
1180
+ may not properly announce the dialog and its content when it opens.
1175
1181
  */
1176
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '7f66b4fdb3dec61a2b9aec4e9dbacf5d013d637c', class: "modal-handle",
1182
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", tabIndex: -1, class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: 'ba4ebd6364faba46ac8532d1c83cb655ae873a14', class: "modal-handle",
1177
1183
  // Prevents the handle from receiving keyboard focus when it does not cycle
1178
- 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: '2dfaaebe3d0b2a46be1224c25f9ab89bf1744332', onSlotchange: this.onSlotChange }))));
1184
+ 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: '11d5921a8ebbcd0017d4f28a33d68049253f63f0', onSlotchange: this.onSlotChange }))));
1179
1185
  }
1180
1186
  static get is() { return "ion-modal"; }
1181
1187
  static get encapsulation() { return "shadow"; }
@@ -126,6 +126,14 @@ ion-backdrop {
126
126
  z-index: 10;
127
127
  }
128
128
 
129
+ /**
130
+ * The wrapper receives programmatic focus for screen readers but should not
131
+ * show a visible focus ring, which is meant only for keyboard navigation.
132
+ */
133
+ .modal-wrapper {
134
+ outline: none;
135
+ }
136
+
129
137
  .modal-shadow {
130
138
  position: absolute;
131
139
  background: transparent;
@@ -497,7 +497,30 @@ export const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation
497
497
  * to the overlay container.
498
498
  */
499
499
  if (overlay.keyboardClose && (document.activeElement === null || !overlay.el.contains(document.activeElement))) {
500
- overlay.el.focus();
500
+ /**
501
+ * Some overlays (e.g. modal) put the dialog role and accessible label
502
+ * on the `.ion-overlay-wrapper` instead of the host. Screen readers
503
+ * need focus on the element with `role="dialog"` to properly announce
504
+ * and navigate the dialog.
505
+ *
506
+ * We only target wrappers with `tabindex`, since `role="dialog"` alone
507
+ * does not make an element focusable. If no focusable dialog wrapper
508
+ * exists (e.g. picker-legacy), we fall back to the host.
509
+ */
510
+ const overlayWrapper = getElementRoot(overlay.el).querySelector('[role="dialog"][tabindex]');
511
+ const focusTarget = overlayWrapper !== null && overlayWrapper !== void 0 ? overlayWrapper : overlay.el;
512
+ /**
513
+ * `preventScroll` keeps this a pure focus move so the viewport does not
514
+ * jump when the wrapper is partially off-screen (e.g. a sheet modal).
515
+ * Guard the options call so an older engine that mishandles it can never
516
+ * reject present(); we fall back to a plain focus() in that case.
517
+ */
518
+ try {
519
+ focusTarget.focus({ preventScroll: true });
520
+ }
521
+ catch (_c) {
522
+ focusTarget.focus();
523
+ }
501
524
  }
502
525
  /**
503
526
  * If this overlay was previously dismissed without being
@@ -18,6 +18,11 @@ export const dragElementBy = async (el, page, dragByX = 0, dragByY = 0, startXCo
18
18
  // Navigate to the start position.
19
19
  await page.mouse.move(startX, startY);
20
20
  await page.mouse.down();
21
+ // Firefox treats focusable elements (tabindex="-1") as draggable text and
22
+ // initiates text selection on mouse.down(). In Playwright, this selection
23
+ // locks in before the gesture detector fires, blocking pointer events.
24
+ // Clearing it here allows the drag gesture to proceed normally.
25
+ await page.evaluate(() => { var _a; return (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges(); });
21
26
  // Drag the element.
22
27
  await moveElement(page, startX, startY, dragByX, dragByY);
23
28
  if (releaseDrag) {
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-07-17T06:50:58",
2
+ "timestamp": "2026-07-21T06:54:46",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.43.5",
package/dist/esm/index.js CHANGED
@@ -13,7 +13,7 @@ export { L as LogLevel } from './index-tcQvqkiX.js';
13
13
  export { I as IonicSafeString, g as getMode, s as setupConfig } from './config-DQCONYYp.js';
14
14
  export { o as openURL } from './theme-DiVJyqlX.js';
15
15
  export { m as menuController } from './index-Q6UPU0Ay.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-TbiM4mdr.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-Dg0q2_tJ.js';
17
17
  import './index-ZjP4CjeZ.js';
18
18
  import './gesture-controller-BTEOs1at.js';
19
19
  import './hardware-back-button-B93Gru0Y.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-BSpTQmS9.js';
6
6
  import { r as raf } from './helpers-HEqiOzXb.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-TbiM4mdr.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-Dg0q2_tJ.js';
9
9
  import { g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-Cp_eT4sZ.js';
11
11
  import { c as createAnimation } from './animation-DLJpuoEz.js';
@@ -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-BSpTQmS9.js';
7
7
  import { r as raf } from './helpers-HEqiOzXb.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-TbiM4mdr.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-Dg0q2_tJ.js';
10
10
  import { g as getClassMap } from './theme-DiVJyqlX.js';
11
11
  import { b as getIonMode } from './ionic-global-Cp_eT4sZ.js';
12
12
  import { c as createAnimation } from './animation-DLJpuoEz.js';
@@ -4,7 +4,7 @@
4
4
  import { j as printIonError, f as printIonWarning, r as registerInstance, c as createEvent, w as writeTask, e as config, h, d as Host, g as getElement } from './index-tcQvqkiX.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-HEqiOzXb.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-TbiM4mdr.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-Dg0q2_tJ.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';
@@ -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-DQCONYYp.js';
6
6
  import { r as raf } from './helpers-HEqiOzXb.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-TbiM4mdr.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-Dg0q2_tJ.js';
9
9
  import { g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-Cp_eT4sZ.js';
11
11
  import { c as createAnimation } from './animation-DLJpuoEz.js';
@@ -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-tcQvqkiX.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-TbiM4mdr.js';
6
+ import { o as getPresentedOverlay, B as BACKDROP, n as focusFirstDescendant, q as focusLastDescendant, G as GESTURE } from './overlays-Dg0q2_tJ.js';
7
7
  import { G as GESTURE_CONTROLLER } from './gesture-controller-BTEOs1at.js';
8
8
  import { shouldUseCloseWatcher } from './hardware-back-button-B93Gru0Y.js';
9
9
  import { o as isEndSide, i as inheritAriaAttributes, l as assert, e as clamp } from './helpers-HEqiOzXb.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-HEqiOzXb.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-TbiM4mdr.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-Dg0q2_tJ.js';
11
11
  import { g as getClassMap } from './theme-DiVJyqlX.js';
12
12
  import { e as deepReady, w as waitForMount } from './index-B_dQk_WE.js';
13
13
  import { b as getIonMode } from './ionic-global-Cp_eT4sZ.js';
@@ -331,7 +331,14 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onD
331
331
  return false;
332
332
  };
333
333
  const onStart = (detail) => {
334
+ var _a;
334
335
  const { deltaY } = detail;
336
+ /**
337
+ * Firefox automatically selects the header text during drag
338
+ * due to the focusable wrapper (tabindex="-1"). Remove any
339
+ * selection that may have occurred.
340
+ */
341
+ (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
335
342
  /**
336
343
  * Get the initial scrollY value so
337
344
  * that we can correctly reset the scrollY
@@ -1217,6 +1224,13 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1217
1224
  return true;
1218
1225
  };
1219
1226
  const onStart = (detail) => {
1227
+ var _a;
1228
+ /**
1229
+ * Firefox automatically selects the header text during drag
1230
+ * due to the focusable wrapper (tabindex="-1"). Remove any
1231
+ * selection that may have occurred.
1232
+ */
1233
+ (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
1220
1234
  /**
1221
1235
  * If canDismiss is anything other than `true`
1222
1236
  * then users should be able to swipe down
@@ -1819,9 +1833,9 @@ const clearSafeAreaOverrides = (hostEl) => {
1819
1833
  hostEl.style.removeProperty('--ion-safe-area-right');
1820
1834
  };
1821
1835
 
1822
- const modalIosCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}`;
1836
+ const modalIosCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-wrapper{outline:none}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}`;
1823
1837
 
1824
- const modalMdCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}`;
1838
+ const modalMdCss = () => `:host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-wrapper{outline:none}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:""}:host(.modal-sheet){--height:calc(100% - (var(--ion-modal-offset-top, 0px) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}`;
1825
1839
 
1826
1840
  const Modal = class {
1827
1841
  constructor(hostRef) {
@@ -2962,16 +2976,22 @@ const Modal = class {
2962
2976
  // Allow the modal to be navigable when the handle is focusable
2963
2977
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
2964
2978
  zIndex: `${20000 + this.overlayIndex}`,
2965
- }, 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: '5ba6315c7c8c64fa04c62f85fd493da5275b2cbd', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'a76c48d41c67f86c18a7481e980e6925e614f85d', class: "modal-shadow" }), h("div", Object.assign({ key: '3f6c61ba60b063592784d76a9594073b3bf210a9',
2979
+ }, 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: '5ba6315c7c8c64fa04c62f85fd493da5275b2cbd', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'a76c48d41c67f86c18a7481e980e6925e614f85d', class: "modal-shadow" }), h("div", Object.assign({ key: 'dccf3c774355429bc0ea7461d9b1ef941ea91902',
2966
2980
  /*
2967
2981
  role and aria-modal must be used on the
2968
2982
  same element. They must also be set inside the
2969
2983
  shadow DOM otherwise ion-button will not be highlighted
2970
2984
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
2985
+
2986
+ tabIndex={-1} is required so present() can move focus to this
2987
+ element (which carries the dialog role) instead of the role-less
2988
+ host. role="dialog" alone does not make an element focusable, so
2989
+ without the tabindex focus() would be a no-op and screen readers
2990
+ may not properly announce the dialog and its content when it opens.
2971
2991
  */
2972
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '7f66b4fdb3dec61a2b9aec4e9dbacf5d013d637c', class: "modal-handle",
2992
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", tabIndex: -1, class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: 'ba4ebd6364faba46ac8532d1c83cb655ae873a14', class: "modal-handle",
2973
2993
  // Prevents the handle from receiving keyboard focus when it does not cycle
2974
- 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: '2dfaaebe3d0b2a46be1224c25f9ab89bf1744332', onSlotchange: this.onSlotChange }))));
2994
+ 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: '11d5921a8ebbcd0017d4f28a33d68049253f63f0', onSlotchange: this.onSlotChange }))));
2975
2995
  }
2976
2996
  get el() { return getElement(this); }
2977
2997
  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-tcQvqkiX.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-TbiM4mdr.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-Dg0q2_tJ.js';
6
6
  import { C as CoreDelegate, a as attachComponent, d as detachComponent } from './framework-delegate-FnPGymXL.js';
7
7
  import { g as getElementRoot, r as raf, f as addEventListener, h as hasLazyBuild } from './helpers-HEqiOzXb.js';
8
8
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { r as registerInstance, h, i as forceUpdate, d as Host, g as getElement } from './index-tcQvqkiX.js';
5
5
  import { b as getIonMode } from './ionic-global-Cp_eT4sZ.js';
6
- import { s as safeCall } from './overlays-TbiM4mdr.js';
6
+ import { s as safeCall } from './overlays-Dg0q2_tJ.js';
7
7
  import { g as getClassMap } from './theme-DiVJyqlX.js';
8
8
  import './index-ZjP4CjeZ.js';
9
9
  import './helpers-HEqiOzXb.js';
@@ -6,7 +6,7 @@ import { c as createNotchController } from './notch-controller-DKDjU_O7.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-HEqiOzXb.js';
9
- import { c as popoverController, b as actionSheetController, a as alertController, m as modalController, s as safeCall } from './overlays-TbiM4mdr.js';
9
+ import { c as popoverController, b as actionSheetController, a as alertController, m as modalController, s as safeCall } from './overlays-Dg0q2_tJ.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-DQCONYYp.js';
6
6
  import { g as getElementRoot, r as raf } from './helpers-HEqiOzXb.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-TbiM4mdr.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-Dg0q2_tJ.js';
9
9
  import { c as createColorClasses, g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-Cp_eT4sZ.js';
11
11
  import { c as createAnimation } from './animation-DLJpuoEz.js';
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { d as doc } from './index-ZjP4CjeZ.js';
5
- import { n as focusVisibleElement, c as componentOnReady, f as addEventListener, m as removeEventListener, g as getElementRoot } from './helpers-HEqiOzXb.js';
5
+ import { n as focusVisibleElement, c as componentOnReady, g as getElementRoot, f as addEventListener, m as removeEventListener } from './helpers-HEqiOzXb.js';
6
6
  import { OVERLAY_BACK_BUTTON_PRIORITY, shouldUseCloseWatcher } from './hardware-back-button-B93Gru0Y.js';
7
7
  import { e as config, j as printIonError, f as printIonWarning } from './index-tcQvqkiX.js';
8
8
  import { b as getIonMode } from './ionic-global-Cp_eT4sZ.js';
@@ -576,7 +576,30 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
576
576
  * to the overlay container.
577
577
  */
578
578
  if (overlay.keyboardClose && (document.activeElement === null || !overlay.el.contains(document.activeElement))) {
579
- overlay.el.focus();
579
+ /**
580
+ * Some overlays (e.g. modal) put the dialog role and accessible label
581
+ * on the `.ion-overlay-wrapper` instead of the host. Screen readers
582
+ * need focus on the element with `role="dialog"` to properly announce
583
+ * and navigate the dialog.
584
+ *
585
+ * We only target wrappers with `tabindex`, since `role="dialog"` alone
586
+ * does not make an element focusable. If no focusable dialog wrapper
587
+ * exists (e.g. picker-legacy), we fall back to the host.
588
+ */
589
+ const overlayWrapper = getElementRoot(overlay.el).querySelector('[role="dialog"][tabindex]');
590
+ const focusTarget = overlayWrapper !== null && overlayWrapper !== void 0 ? overlayWrapper : overlay.el;
591
+ /**
592
+ * `preventScroll` keeps this a pure focus move so the viewport does not
593
+ * jump when the wrapper is partially off-screen (e.g. a sheet modal).
594
+ * Guard the options call so an older engine that mishandles it can never
595
+ * reject present(); we fall back to a plain focus() in that case.
596
+ */
597
+ try {
598
+ focusTarget.focus({ preventScroll: true });
599
+ }
600
+ catch (_c) {
601
+ focusTarget.focus();
602
+ }
580
603
  }
581
604
  /**
582
605
  * If this overlay was previously dismissed without being
@@ -1,4 +1,4 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- export{c as createAnimation}from"./p-mjKAFv89.js";export{a as LIFECYCLE_DID_ENTER,c as LIFECYCLE_DID_LEAVE,L as LIFECYCLE_WILL_ENTER,b as LIFECYCLE_WILL_LEAVE,d as LIFECYCLE_WILL_UNLOAD,g as getIonPageElement}from"./p-VAemlbDS.js";export{iosTransitionAnimation}from"./p-BGqMS-oh.js";export{mdTransitionAnimation}from"./p-Cx3IXROA.js";export{g as getTimeGivenProgression}from"./p-hHmYLOfE.js";export{createGesture}from"./p-Cl0B-RWe.js";export{g as getPlatforms,i as initialize,a as isPlatform}from"./p-Nqf6uvGh.js";export{c as componentOnReady}from"./p-DIuEbVLu.js";export{L as LogLevel}from"./p-tcQvqkiX.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./p-DzWaWHGc.js";export{o as openURL}from"./p-DiVJyqlX.js";export{m as menuController}from"./p-KjNvRoEp.js";export{b as actionSheetController,a as alertController,l as loadingController,m as modalController,p as pickerController,c as popoverController,t as toastController}from"./p-xOfi7-Zn.js";import"./p-ZjP4CjeZ.js";import"./p-BTEOs1at.js";import"./p-BUFIpxKM.js";import"./p-CFlfIb2g.js";const e=e=>{const{swiper:o,extendParams:t}=e,s={effect:void 0,direction:"horizontal",initialSlide:0,loop:!1,parallax:!1,slidesPerView:1,spaceBetween:0,speed:300,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,touchEventsTarget:"container",freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,zoom:{maxRatio:3,minRatio:1,toggle:!1},touchRatio:1,touchAngle:45,simulateTouch:!0,touchStartPreventDefault:!1,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,threshold:0,touchMoveStopPropagation:!0,touchReleaseOnEdges:!1,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,watchSlidesVisibility:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,loopAdditionalSlides:0,noSwiping:!0,runCallbacksOnInit:!0,coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},flipEffect:{slideShadows:!0,limitRotation:!0},cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fadeEffect:{crossFade:!1},a11y:{prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide"}};o.pagination&&(s.pagination={type:"bullets",clickable:!1,hideOnClick:!1}),o.scrollbar&&(s.scrollbar={hide:!0}),t(s)};export{e as IonicSlides}
4
+ export{c as createAnimation}from"./p-mjKAFv89.js";export{a as LIFECYCLE_DID_ENTER,c as LIFECYCLE_DID_LEAVE,L as LIFECYCLE_WILL_ENTER,b as LIFECYCLE_WILL_LEAVE,d as LIFECYCLE_WILL_UNLOAD,g as getIonPageElement}from"./p-VAemlbDS.js";export{iosTransitionAnimation}from"./p-BGqMS-oh.js";export{mdTransitionAnimation}from"./p-Cx3IXROA.js";export{g as getTimeGivenProgression}from"./p-hHmYLOfE.js";export{createGesture}from"./p-Cl0B-RWe.js";export{g as getPlatforms,i as initialize,a as isPlatform}from"./p-Nqf6uvGh.js";export{c as componentOnReady}from"./p-DIuEbVLu.js";export{L as LogLevel}from"./p-tcQvqkiX.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./p-DzWaWHGc.js";export{o as openURL}from"./p-DiVJyqlX.js";export{m as menuController}from"./p-KjNvRoEp.js";export{b as actionSheetController,a as alertController,l as loadingController,m as modalController,p as pickerController,c as popoverController,t as toastController}from"./p-D-3ycHmd.js";import"./p-ZjP4CjeZ.js";import"./p-BTEOs1at.js";import"./p-BUFIpxKM.js";import"./p-CFlfIb2g.js";const e=e=>{const{swiper:o,extendParams:t}=e,s={effect:void 0,direction:"horizontal",initialSlide:0,loop:!1,parallax:!1,slidesPerView:1,spaceBetween:0,speed:300,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,touchEventsTarget:"container",freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,zoom:{maxRatio:3,minRatio:1,toggle:!1},touchRatio:1,touchAngle:45,simulateTouch:!0,touchStartPreventDefault:!1,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,threshold:0,touchMoveStopPropagation:!0,touchReleaseOnEdges:!1,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,watchSlidesVisibility:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,loopAdditionalSlides:0,noSwiping:!0,runCallbacksOnInit:!0,coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},flipEffect:{slideShadows:!0,limitRotation:!0},cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fadeEffect:{crossFade:!1},a11y:{prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide"}};o.pagination&&(s.pagination={type:"bullets",clickable:!1,hideOnClick:!1}),o.scrollbar&&(s.scrollbar={hide:!0}),t(s)};export{e as IonicSlides}