@ionic/core 8.7.3-dev.11755600455.1e79c35a → 8.7.3-dev.11755696506.17b8097b

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 (50) hide show
  1. package/components/ion-refresher.js +18 -1
  2. package/components/overlays.js +102 -2
  3. package/dist/cjs/index.cjs.js +1 -1
  4. package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
  5. package/dist/cjs/ion-alert.cjs.entry.js +1 -1
  6. package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
  7. package/dist/cjs/ion-loading.cjs.entry.js +1 -1
  8. package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
  9. package/dist/cjs/ion-modal.cjs.entry.js +1 -1
  10. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  11. package/dist/cjs/ion-refresher_2.cjs.entry.js +18 -1
  12. package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
  13. package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
  14. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  15. package/dist/cjs/{overlays-DUsEBICv.js → overlays-DFkeeMZX.js} +101 -1
  16. package/dist/collection/components/refresher/refresher.js +18 -1
  17. package/dist/collection/utils/overlays.js +102 -1
  18. package/dist/docs.json +1 -1
  19. package/dist/esm/index.js +1 -1
  20. package/dist/esm/ion-action-sheet.entry.js +1 -1
  21. package/dist/esm/ion-alert.entry.js +1 -1
  22. package/dist/esm/ion-datetime_3.entry.js +1 -1
  23. package/dist/esm/ion-loading.entry.js +1 -1
  24. package/dist/esm/ion-menu_3.entry.js +1 -1
  25. package/dist/esm/ion-modal.entry.js +1 -1
  26. package/dist/esm/ion-popover.entry.js +1 -1
  27. package/dist/esm/ion-refresher_2.entry.js +18 -1
  28. package/dist/esm/ion-select-modal.entry.js +1 -1
  29. package/dist/esm/ion-select_3.entry.js +1 -1
  30. package/dist/esm/ion-toast.entry.js +1 -1
  31. package/dist/esm/{overlays-B_dsLNe8.js → overlays-BfCgLYdD.js} +102 -2
  32. package/dist/ionic/index.esm.js +1 -1
  33. package/dist/ionic/ionic.esm.js +1 -1
  34. package/dist/ionic/{p-698fb72c.entry.js → p-1e6a6fde.entry.js} +1 -1
  35. package/dist/ionic/{p-98d0823e.entry.js → p-31f7216f.entry.js} +1 -1
  36. package/dist/ionic/{p-57bb1214.entry.js → p-4d57f91a.entry.js} +1 -1
  37. package/dist/ionic/{p-8bfe00f3.entry.js → p-5c138549.entry.js} +1 -1
  38. package/dist/ionic/p-8cdb4ff5.entry.js +4 -0
  39. package/dist/ionic/{p-09ed68cf.entry.js → p-9f8f01e6.entry.js} +1 -1
  40. package/dist/ionic/{p-84236acb.entry.js → p-b92a19c8.entry.js} +1 -1
  41. package/dist/ionic/{p-9c6fddc6.entry.js → p-e206b074.entry.js} +1 -1
  42. package/dist/ionic/{p-8b54aa01.entry.js → p-e61fd4b2.entry.js} +1 -1
  43. package/dist/ionic/{p-07d8f62a.entry.js → p-eb9b64a6.entry.js} +1 -1
  44. package/dist/ionic/{p-7ed24ba0.entry.js → p-ef5372b6.entry.js} +1 -1
  45. package/dist/ionic/p-ly6Zj1CK.js +4 -0
  46. package/hydrate/index.js +119 -2
  47. package/hydrate/index.mjs +119 -2
  48. package/package.json +1 -1
  49. package/dist/ionic/p-C3MD7jSK.js +0 -4
  50. package/dist/ionic/p-ac2be9d6.entry.js +0 -4
@@ -11,6 +11,7 @@ import { CoreDelegate } from "./framework-delegate";
11
11
  import { BACKDROP_NO_SCROLL } from "./gesture/gesture-controller";
12
12
  import { OVERLAY_BACK_BUTTON_PRIORITY } from "./hardware-back-button";
13
13
  import { addEventListener, componentOnReady, focusVisibleElement, getElementRoot, removeEventListener, } from "./helpers";
14
+ import { isPlatform } from "./platform";
14
15
  let lastOverlayIndex = 0;
15
16
  let lastId = 0;
16
17
  export const activeAnimations = new WeakMap();
@@ -429,6 +430,7 @@ export const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation
429
430
  if (overlay.presented) {
430
431
  return;
431
432
  }
433
+ console.log("presenting overlay...");
432
434
  /**
433
435
  * Due to accessibility guidelines, toasts do not have
434
436
  * focus traps.
@@ -438,8 +440,9 @@ export const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation
438
440
  */
439
441
  if (overlay.el.tagName !== 'ION-TOAST') {
440
442
  setRootAriaHidden(true);
441
- document.body.classList.add(BACKDROP_NO_SCROLL);
442
443
  }
444
+ hideUnderlyingOverlaysFromScreenReaders(overlay.el);
445
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
443
446
  overlay.presented = true;
444
447
  overlay.willPresent.emit();
445
448
  (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
@@ -486,6 +489,7 @@ export const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation
486
489
  * screen readers.
487
490
  */
488
491
  overlay.el.removeAttribute('aria-hidden');
492
+ overlay.el.removeAttribute('inert');
489
493
  };
490
494
  /**
491
495
  * When an overlay component is dismissed,
@@ -565,6 +569,12 @@ export const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLe
565
569
  }
566
570
  overlay.presented = false;
567
571
  try {
572
+ /**
573
+ * There is no need to show the overlay to screen readers during
574
+ * the dismiss animation. This is because the overlay will be removed
575
+ * from the DOM after the animation is complete.
576
+ */
577
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
568
578
  // Overlay contents should not be clickable during dismiss
569
579
  overlay.el.style.setProperty('pointer-events', 'none');
570
580
  overlay.willDismiss.emit({ data, role });
@@ -603,6 +613,7 @@ export const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLe
603
613
  printIonError(`[${overlay.el.tagName.toLowerCase()}] - `, err);
604
614
  }
605
615
  overlay.el.remove();
616
+ revealOverlaysToScreenReaders();
606
617
  return true;
607
618
  };
608
619
  const getAppRoot = (doc) => {
@@ -798,4 +809,94 @@ export const createTriggerController = () => {
798
809
  removeClickListener,
799
810
  };
800
811
  };
812
+ /**
813
+ * The overlay that is being animated also needs to hide from screen
814
+ * readers during its animation. This ensures that assistive technologies
815
+ * like TalkBack do not announce or interact with the content until the
816
+ * animation is complete, avoiding confusion for users.
817
+ *
818
+ * When the overlay is presented on an Android device, TalkBack's focus rings
819
+ * may appear in the wrong position due to the transition (specifically
820
+ * `transform` styles). This occurs because the focus rings are initially
821
+ * displayed at the starting position of the elements before the transition
822
+ * begins. This workaround ensures the focus rings do not appear in the
823
+ * incorrect location.
824
+ *
825
+ * If this solution is applied to iOS devices, then it leads to a bug where
826
+ * the overlays cannot be accessed by screen readers. This is due to
827
+ * VoiceOver not being able to update the accessibility tree when the
828
+ * `aria-hidden` is removed.
829
+ *
830
+ * @param overlay - The overlay that is being animated.
831
+ */
832
+ const hideAnimatingOverlayFromScreenReaders = (overlay) => {
833
+ if (doc === undefined)
834
+ return;
835
+ if (isPlatform('android')) {
836
+ /**
837
+ * Once the animation is complete, this attribute will be removed.
838
+ * This is done at the end of the `present` method.
839
+ */
840
+ overlay.setAttribute('aria-hidden', 'true');
841
+ overlay.setAttribute('inert', '');
842
+ }
843
+ };
844
+ /**
845
+ * Ensure that underlying overlays have aria-hidden if necessary so that screen readers
846
+ * cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
847
+ * events here because those events do not fire when the screen readers moves to a non-focusable
848
+ * element such as text.
849
+ * Without this logic screen readers would be able to move focus outside of the top focus-trapped overlay.
850
+ *
851
+ * @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
852
+ * fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
853
+ */
854
+ const hideUnderlyingOverlaysFromScreenReaders = (newTopMostOverlay) => {
855
+ var _a;
856
+ if (doc === undefined)
857
+ return;
858
+ const overlays = getPresentedOverlays(doc);
859
+ for (let i = overlays.length - 1; i >= 0; i--) {
860
+ const presentedOverlay = overlays[i];
861
+ const nextPresentedOverlay = (_a = overlays[i + 1]) !== null && _a !== void 0 ? _a : newTopMostOverlay;
862
+ /**
863
+ * If next overlay has aria-hidden then all remaining overlays will have it too.
864
+ * Or, if the next overlay is a Toast that does not have aria-hidden then current overlay
865
+ * should not have aria-hidden either so focus can remain in the current overlay.
866
+ */
867
+ if (nextPresentedOverlay.hasAttribute('aria-hidden') || nextPresentedOverlay.tagName !== 'ION-TOAST') {
868
+ presentedOverlay.setAttribute('aria-hidden', 'true');
869
+ presentedOverlay.setAttribute('inert', '');
870
+ }
871
+ }
872
+ };
873
+ /**
874
+ * When dismissing an overlay we need to reveal the new top-most overlay to screen readers.
875
+ * If the top-most overlay is a Toast we potentially need to reveal more overlays since
876
+ * focus is never automatically moved to the Toast.
877
+ */
878
+ const revealOverlaysToScreenReaders = () => {
879
+ if (doc === undefined)
880
+ return;
881
+ const overlays = getPresentedOverlays(doc);
882
+ for (let i = overlays.length - 1; i >= 0; i--) {
883
+ const currentOverlay = overlays[i];
884
+ /**
885
+ * If the current we are looking at is a Toast then we can remove aria-hidden.
886
+ * However, we potentially need to keep looking at the overlay stack because there
887
+ * could be more Toasts underneath. Additionally, we need to unhide the closest non-Toast
888
+ * overlay too so focus can move there since focus is never automatically moved to the Toast.
889
+ */
890
+ currentOverlay.removeAttribute('aria-hidden');
891
+ currentOverlay.removeAttribute('inert');
892
+ /**
893
+ * If we found a non-Toast element then we can just remove aria-hidden and stop searching entirely
894
+ * since this overlay should always receive focus. As a result, all underlying overlays should still
895
+ * be hidden from screen readers.
896
+ */
897
+ if (currentOverlay.tagName !== 'ION-TOAST') {
898
+ break;
899
+ }
900
+ }
901
+ };
801
902
  export const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2025-08-19T10:49:17",
2
+ "timestamp": "2025-08-20T13:30:19",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.36.2",
package/dist/esm/index.js CHANGED
@@ -13,7 +13,7 @@ export { L as LogLevel } from './index-4DxY6_gG.js';
13
13
  export { I as IonicSafeString, g as getMode, s as setupConfig } from './config-Dx_6wPIJ.js';
14
14
  export { o as openURL } from './theme-DiVJyqlX.js';
15
15
  export { m as menuController } from './index-CXSTcaAW.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-B_dsLNe8.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-BfCgLYdD.js';
17
17
  import './index-ZjP4CjeZ.js';
18
18
  import './gesture-controller-BTEOs1at.js';
19
19
  import './hardware-back-button-Dhbd-23H.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-DBUPuLNw.js';
6
6
  import { r as raf } from './helpers-8KSQQGQy.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-B_dsLNe8.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-BfCgLYdD.js';
9
9
  import { g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-CTSyufhF.js';
11
11
  import { c as createAnimation } from './animation-BvhAtgca.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-DBUPuLNw.js';
7
7
  import { r as raf } from './helpers-8KSQQGQy.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-B_dsLNe8.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-BfCgLYdD.js';
10
10
  import { g as getClassMap } from './theme-DiVJyqlX.js';
11
11
  import { b as getIonMode } from './ionic-global-CTSyufhF.js';
12
12
  import { c as createAnimation } from './animation-BvhAtgca.js';
@@ -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-4DxY6_gG.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-8KSQQGQy.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-B_dsLNe8.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-BfCgLYdD.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-Dx_6wPIJ.js';
6
6
  import { r as raf } from './helpers-8KSQQGQy.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-B_dsLNe8.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-BfCgLYdD.js';
9
9
  import { g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-CTSyufhF.js';
11
11
  import { c as createAnimation } from './animation-BvhAtgca.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-4DxY6_gG.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-B_dsLNe8.js';
6
+ import { o as getPresentedOverlay, B as BACKDROP, n as focusFirstDescendant, q as focusLastDescendant, G as GESTURE } from './overlays-BfCgLYdD.js';
7
7
  import { G as GESTURE_CONTROLLER } from './gesture-controller-BTEOs1at.js';
8
8
  import { shouldUseCloseWatcher } from './hardware-back-button-Dhbd-23H.js';
9
9
  import { o as isEndSide, i as inheritAriaAttributes, l as assert, e as clamp } from './helpers-8KSQQGQy.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-8KSQQGQy.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-B_dsLNe8.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-BfCgLYdD.js';
11
11
  import { g as getClassMap } from './theme-DiVJyqlX.js';
12
12
  import { e as deepReady, w as waitForMount } from './index-Dp7GXH1z.js';
13
13
  import { b as getIonMode } from './ionic-global-CTSyufhF.js';
@@ -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-4DxY6_gG.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-B_dsLNe8.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-BfCgLYdD.js';
6
6
  import { C as CoreDelegate, a as attachComponent, d as detachComponent } from './framework-delegate-BLEBgH06.js';
7
7
  import { g as getElementRoot, r as raf, f as addEventListener, h as hasLazyBuild } from './helpers-8KSQQGQy.js';
8
8
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
@@ -373,6 +373,14 @@ const Refresher = class {
373
373
  this.beginRefresh();
374
374
  this.didRefresh = true;
375
375
  hapticImpact({ style: ImpactStyle.Light });
376
+ /**
377
+ * Clear focus from any active element to prevent scroll jumps
378
+ * when the refresh completes
379
+ */
380
+ const activeElement = document.activeElement;
381
+ if ((activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) !== undefined) {
382
+ activeElement.blur();
383
+ }
376
384
  /**
377
385
  * Translate the content element otherwise when pointer is removed
378
386
  * from screen the scroll content will bounce back over the refresher
@@ -788,6 +796,15 @@ const Refresher = class {
788
796
  this.state = 8 /* RefresherState.Refreshing */;
789
797
  // place the content in a hangout position while it thinks
790
798
  this.setCss(this.pullMin, this.snapbackDuration, true, '');
799
+ /**
800
+ * Clear focus from any active element to prevent the browser
801
+ * from restoring focus and causing scroll jumps after refresh.
802
+ * This ensures the view stays at the top after refresh completes.
803
+ */
804
+ const activeElement = document.activeElement;
805
+ if ((activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) !== undefined) {
806
+ activeElement.blur();
807
+ }
791
808
  // emit "refresh" because it was pulled down far enough
792
809
  // and they let go to begin refreshing
793
810
  this.ionRefresh.emit({
@@ -870,7 +887,7 @@ const Refresher = class {
870
887
  }
871
888
  render() {
872
889
  const mode = getIonMode(this);
873
- return (h(Host, { key: '8c7a5cc32da02a9cbeaa954258148683f60a6d1b', slot: "fixed", class: {
890
+ return (h(Host, { key: '2d1bd880877b698604542ab2d602d38b9504d975', slot: "fixed", class: {
874
891
  [mode]: true,
875
892
  // Used internally for styling
876
893
  [`refresher-${mode}`]: true,
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { r as registerInstance, h, i as forceUpdate, d as Host, g as getElement } from './index-4DxY6_gG.js';
5
5
  import { b as getIonMode } from './ionic-global-CTSyufhF.js';
6
- import { s as safeCall } from './overlays-B_dsLNe8.js';
6
+ import { s as safeCall } from './overlays-BfCgLYdD.js';
7
7
  import { g as getClassMap } from './theme-DiVJyqlX.js';
8
8
  import './index-ZjP4CjeZ.js';
9
9
  import './helpers-8KSQQGQy.js';
@@ -5,7 +5,7 @@ import { r as registerInstance, c as createEvent, f as printIonWarning, h, d as
5
5
  import { c as createNotchController } from './notch-controller-lb417-kU.js';
6
6
  import { i as isOptionSelected, c as compareOptions } from './compare-with-utils-sObYyvOy.js';
7
7
  import { b as inheritAttributes, a as renderHiddenInput, n as focusVisibleElement } from './helpers-8KSQQGQy.js';
8
- import { c as popoverController, b as actionSheetController, a as alertController, m as modalController, s as safeCall } from './overlays-B_dsLNe8.js';
8
+ import { c as popoverController, b as actionSheetController, a as alertController, m as modalController, s as safeCall } from './overlays-BfCgLYdD.js';
9
9
  import { i as isRTL } from './dir-C53feagD.js';
10
10
  import { h as hostContext, c as createColorClasses, g as getClassMap } from './theme-DiVJyqlX.js';
11
11
  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-Dx_6wPIJ.js';
6
6
  import { g as getElementRoot, r as raf } from './helpers-8KSQQGQy.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-B_dsLNe8.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-BfCgLYdD.js';
9
9
  import { c as createColorClasses, g as getClassMap } from './theme-DiVJyqlX.js';
10
10
  import { b as getIonMode } from './ionic-global-CTSyufhF.js';
11
11
  import { c as createAnimation } from './animation-BvhAtgca.js';
@@ -5,7 +5,7 @@ import { d as doc } from './index-ZjP4CjeZ.js';
5
5
  import { n as focusVisibleElement, c as componentOnReady, f as addEventListener, m as removeEventListener, g as getElementRoot } from './helpers-8KSQQGQy.js';
6
6
  import { OVERLAY_BACK_BUTTON_PRIORITY, shouldUseCloseWatcher } from './hardware-back-button-Dhbd-23H.js';
7
7
  import { e as config, j as printIonError, f as printIonWarning } from './index-4DxY6_gG.js';
8
- import { b as getIonMode } from './ionic-global-CTSyufhF.js';
8
+ import { b as getIonMode, a as isPlatform } from './ionic-global-CTSyufhF.js';
9
9
  import { C as CoreDelegate } from './framework-delegate-BLEBgH06.js';
10
10
  import { B as BACKDROP_NO_SCROLL } from './gesture-controller-BTEOs1at.js';
11
11
 
@@ -508,6 +508,7 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
508
508
  if (overlay.presented) {
509
509
  return;
510
510
  }
511
+ console.log("presenting overlay...");
511
512
  /**
512
513
  * Due to accessibility guidelines, toasts do not have
513
514
  * focus traps.
@@ -517,8 +518,9 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
517
518
  */
518
519
  if (overlay.el.tagName !== 'ION-TOAST') {
519
520
  setRootAriaHidden(true);
520
- document.body.classList.add(BACKDROP_NO_SCROLL);
521
521
  }
522
+ hideUnderlyingOverlaysFromScreenReaders(overlay.el);
523
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
522
524
  overlay.presented = true;
523
525
  overlay.willPresent.emit();
524
526
  (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
@@ -565,6 +567,7 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
565
567
  * screen readers.
566
568
  */
567
569
  overlay.el.removeAttribute('aria-hidden');
570
+ overlay.el.removeAttribute('inert');
568
571
  };
569
572
  /**
570
573
  * When an overlay component is dismissed,
@@ -644,6 +647,12 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
644
647
  }
645
648
  overlay.presented = false;
646
649
  try {
650
+ /**
651
+ * There is no need to show the overlay to screen readers during
652
+ * the dismiss animation. This is because the overlay will be removed
653
+ * from the DOM after the animation is complete.
654
+ */
655
+ hideAnimatingOverlayFromScreenReaders(overlay.el);
647
656
  // Overlay contents should not be clickable during dismiss
648
657
  overlay.el.style.setProperty('pointer-events', 'none');
649
658
  overlay.willDismiss.emit({ data, role });
@@ -682,6 +691,7 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
682
691
  printIonError(`[${overlay.el.tagName.toLowerCase()}] - `, err);
683
692
  }
684
693
  overlay.el.remove();
694
+ revealOverlaysToScreenReaders();
685
695
  return true;
686
696
  };
687
697
  const getAppRoot = (doc) => {
@@ -877,6 +887,96 @@ const createTriggerController = () => {
877
887
  removeClickListener,
878
888
  };
879
889
  };
890
+ /**
891
+ * The overlay that is being animated also needs to hide from screen
892
+ * readers during its animation. This ensures that assistive technologies
893
+ * like TalkBack do not announce or interact with the content until the
894
+ * animation is complete, avoiding confusion for users.
895
+ *
896
+ * When the overlay is presented on an Android device, TalkBack's focus rings
897
+ * may appear in the wrong position due to the transition (specifically
898
+ * `transform` styles). This occurs because the focus rings are initially
899
+ * displayed at the starting position of the elements before the transition
900
+ * begins. This workaround ensures the focus rings do not appear in the
901
+ * incorrect location.
902
+ *
903
+ * If this solution is applied to iOS devices, then it leads to a bug where
904
+ * the overlays cannot be accessed by screen readers. This is due to
905
+ * VoiceOver not being able to update the accessibility tree when the
906
+ * `aria-hidden` is removed.
907
+ *
908
+ * @param overlay - The overlay that is being animated.
909
+ */
910
+ const hideAnimatingOverlayFromScreenReaders = (overlay) => {
911
+ if (doc === undefined)
912
+ return;
913
+ if (isPlatform('android')) {
914
+ /**
915
+ * Once the animation is complete, this attribute will be removed.
916
+ * This is done at the end of the `present` method.
917
+ */
918
+ overlay.setAttribute('aria-hidden', 'true');
919
+ overlay.setAttribute('inert', '');
920
+ }
921
+ };
922
+ /**
923
+ * Ensure that underlying overlays have aria-hidden if necessary so that screen readers
924
+ * cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
925
+ * events here because those events do not fire when the screen readers moves to a non-focusable
926
+ * element such as text.
927
+ * Without this logic screen readers would be able to move focus outside of the top focus-trapped overlay.
928
+ *
929
+ * @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
930
+ * fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
931
+ */
932
+ const hideUnderlyingOverlaysFromScreenReaders = (newTopMostOverlay) => {
933
+ var _a;
934
+ if (doc === undefined)
935
+ return;
936
+ const overlays = getPresentedOverlays(doc);
937
+ for (let i = overlays.length - 1; i >= 0; i--) {
938
+ const presentedOverlay = overlays[i];
939
+ const nextPresentedOverlay = (_a = overlays[i + 1]) !== null && _a !== void 0 ? _a : newTopMostOverlay;
940
+ /**
941
+ * If next overlay has aria-hidden then all remaining overlays will have it too.
942
+ * Or, if the next overlay is a Toast that does not have aria-hidden then current overlay
943
+ * should not have aria-hidden either so focus can remain in the current overlay.
944
+ */
945
+ if (nextPresentedOverlay.hasAttribute('aria-hidden') || nextPresentedOverlay.tagName !== 'ION-TOAST') {
946
+ presentedOverlay.setAttribute('aria-hidden', 'true');
947
+ presentedOverlay.setAttribute('inert', '');
948
+ }
949
+ }
950
+ };
951
+ /**
952
+ * When dismissing an overlay we need to reveal the new top-most overlay to screen readers.
953
+ * If the top-most overlay is a Toast we potentially need to reveal more overlays since
954
+ * focus is never automatically moved to the Toast.
955
+ */
956
+ const revealOverlaysToScreenReaders = () => {
957
+ if (doc === undefined)
958
+ return;
959
+ const overlays = getPresentedOverlays(doc);
960
+ for (let i = overlays.length - 1; i >= 0; i--) {
961
+ const currentOverlay = overlays[i];
962
+ /**
963
+ * If the current we are looking at is a Toast then we can remove aria-hidden.
964
+ * However, we potentially need to keep looking at the overlay stack because there
965
+ * could be more Toasts underneath. Additionally, we need to unhide the closest non-Toast
966
+ * overlay too so focus can move there since focus is never automatically moved to the Toast.
967
+ */
968
+ currentOverlay.removeAttribute('aria-hidden');
969
+ currentOverlay.removeAttribute('inert');
970
+ /**
971
+ * If we found a non-Toast element then we can just remove aria-hidden and stop searching entirely
972
+ * since this overlay should always receive focus. As a result, all underlying overlays should still
973
+ * be hidden from screen readers.
974
+ */
975
+ if (currentOverlay.tagName !== 'ION-TOAST') {
976
+ break;
977
+ }
978
+ }
979
+ };
880
980
  const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
881
981
 
882
982
  export { BACKDROP as B, FOCUS_TRAP_DISABLE_CLASS as F, GESTURE as G, OVERLAY_GESTURE_PRIORITY as O, alertController as a, actionSheetController as b, popoverController as c, createDelegateController as d, createTriggerController as e, present as f, dismiss as g, eventMethod as h, isCancel as i, prepareOverlay as j, setOverlayId as k, loadingController as l, modalController as m, focusFirstDescendant as n, getPresentedOverlay as o, pickerController as p, focusLastDescendant as q, safeCall as s, toastController as t };
@@ -1,4 +1,4 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- export{c as createAnimation}from"./p-C87oPMMF.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-DCuOL88l.js";export{iosTransitionAnimation}from"./p-BB-JoKGB.js";export{mdTransitionAnimation}from"./p-LaGjiAVo.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-Br3vSlYh.js";export{c as componentOnReady}from"./p-C-Cct-6D.js";export{L as LogLevel}from"./p-4DxY6_gG.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./p-EnaLTYYj.js";export{o as openURL}from"./p-DiVJyqlX.js";export{m as menuController}from"./p-C8d2ebIg.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-C3MD7jSK.js";import"./p-ZjP4CjeZ.js";import"./p-BTEOs1at.js";import"./p-CvaZMP6T.js";import"./p-DAfH9Iif.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-C87oPMMF.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-DCuOL88l.js";export{iosTransitionAnimation}from"./p-BB-JoKGB.js";export{mdTransitionAnimation}from"./p-LaGjiAVo.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-Br3vSlYh.js";export{c as componentOnReady}from"./p-C-Cct-6D.js";export{L as LogLevel}from"./p-4DxY6_gG.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./p-EnaLTYYj.js";export{o as openURL}from"./p-DiVJyqlX.js";export{m as menuController}from"./p-C8d2ebIg.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-ly6Zj1CK.js";import"./p-ZjP4CjeZ.js";import"./p-BTEOs1at.js";import"./p-CvaZMP6T.js";import"./p-DAfH9Iif.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}