@ionic/core 8.7.5-nightly.20250923 → 8.7.5
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.
- package/components/modal.js +12 -2
- package/components/overlays.js +39 -17
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
- package/dist/cjs/ion-alert.cjs.entry.js +1 -1
- package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-loading.cjs.entry.js +1 -1
- package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-modal.cjs.entry.js +13 -3
- package/dist/cjs/ion-popover.cjs.entry.js +1 -1
- package/dist/cjs/ion-select-modal.cjs.entry.js +1 -1
- package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-toast.cjs.entry.js +1 -1
- package/dist/cjs/{overlays-v_jc1Hok.js → overlays-czPyT6xP.js} +39 -17
- package/dist/collection/components/modal/gestures/sheet.js +12 -2
- package/dist/collection/utils/overlays.js +39 -17
- package/dist/docs.json +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/ion-action-sheet.entry.js +1 -1
- package/dist/esm/ion-alert.entry.js +1 -1
- package/dist/esm/ion-datetime_3.entry.js +1 -1
- package/dist/esm/ion-loading.entry.js +1 -1
- package/dist/esm/ion-menu_3.entry.js +1 -1
- package/dist/esm/ion-modal.entry.js +13 -3
- package/dist/esm/ion-popover.entry.js +1 -1
- package/dist/esm/ion-select-modal.entry.js +1 -1
- package/dist/esm/ion-select_3.entry.js +1 -1
- package/dist/esm/ion-toast.entry.js +1 -1
- package/dist/esm/{overlays-BJaRj3Rj.js → overlays-BYcYBCrx.js} +39 -17
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-b17f0554.entry.js → p-0793aea6.entry.js} +1 -1
- package/dist/ionic/{p-89c2e0a3.entry.js → p-0e1904a0.entry.js} +1 -1
- package/dist/ionic/{p-5a9be5a3.entry.js → p-117e7a3f.entry.js} +1 -1
- package/dist/ionic/{p-095073c6.entry.js → p-1f68cb59.entry.js} +1 -1
- package/dist/ionic/{p-60ff6bf6.entry.js → p-25e5e5cc.entry.js} +1 -1
- package/dist/ionic/{p-1ab0fc21.entry.js → p-568efea2.entry.js} +1 -1
- package/dist/ionic/{p-22a0f820.entry.js → p-63852736.entry.js} +1 -1
- package/dist/ionic/p-6e43c86a.entry.js +4 -0
- package/dist/ionic/p-746cd400.entry.js +4 -0
- package/dist/ionic/{p-cd93c119.entry.js → p-90f4cc71.entry.js} +1 -1
- package/dist/ionic/p-Cnh7O81W.js +4 -0
- package/hydrate/index.js +53 -21
- package/hydrate/index.mjs +53 -21
- package/package.json +2 -2
- package/dist/ionic/p-2060feb1.entry.js +0 -4
- package/dist/ionic/p-CoDfkBuk.js +0 -4
- package/dist/ionic/p-dc8d0bb9.entry.js +0 -4
package/components/modal.js
CHANGED
|
@@ -984,6 +984,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
984
984
|
const backdropAnimation = animation.childAnimations.find((ani) => ani.id === 'backdropAnimation');
|
|
985
985
|
const contentAnimation = animation.childAnimations.find((ani) => ani.id === 'contentAnimation');
|
|
986
986
|
const enableBackdrop = () => {
|
|
987
|
+
// Respect explicit opt-out of focus trapping/backdrop interactions
|
|
988
|
+
// If focusTrap is false or showBackdrop is false, do not enable the backdrop or re-enable focus trap
|
|
989
|
+
const el = baseEl;
|
|
990
|
+
if (el.focusTrap === false || el.showBackdrop === false) {
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
987
993
|
baseEl.style.setProperty('pointer-events', 'auto');
|
|
988
994
|
backdropEl.style.setProperty('pointer-events', 'auto');
|
|
989
995
|
/**
|
|
@@ -1108,7 +1114,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1108
1114
|
* ion-backdrop and .modal-wrapper always have pointer-events: auto
|
|
1109
1115
|
* applied, so the modal content can still be interacted with.
|
|
1110
1116
|
*/
|
|
1111
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
1117
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
1118
|
+
baseEl.focusTrap !== false &&
|
|
1119
|
+
baseEl.showBackdrop !== false;
|
|
1112
1120
|
if (shouldEnableBackdrop) {
|
|
1113
1121
|
enableBackdrop();
|
|
1114
1122
|
}
|
|
@@ -1416,7 +1424,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1416
1424
|
* Backdrop should become enabled
|
|
1417
1425
|
* after the backdropBreakpoint value
|
|
1418
1426
|
*/
|
|
1419
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
1427
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
1428
|
+
baseEl.focusTrap !== false &&
|
|
1429
|
+
baseEl.showBackdrop !== false;
|
|
1420
1430
|
if (shouldEnableBackdrop) {
|
|
1421
1431
|
enableBackdrop();
|
|
1422
1432
|
}
|
package/components/overlays.js
CHANGED
|
@@ -496,11 +496,9 @@ const setRootAriaHidden = (hidden = false) => {
|
|
|
496
496
|
}
|
|
497
497
|
if (hidden) {
|
|
498
498
|
viewContainer.setAttribute('aria-hidden', 'true');
|
|
499
|
-
viewContainer.setAttribute('inert', '');
|
|
500
499
|
}
|
|
501
500
|
else {
|
|
502
501
|
viewContainer.removeAttribute('aria-hidden');
|
|
503
|
-
viewContainer.removeAttribute('inert');
|
|
504
502
|
}
|
|
505
503
|
};
|
|
506
504
|
const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
|
|
@@ -524,14 +522,34 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
|
|
|
524
522
|
* focus traps.
|
|
525
523
|
*
|
|
526
524
|
* All other overlays should have focus traps to prevent
|
|
527
|
-
* the keyboard focus from leaving the overlay
|
|
525
|
+
* the keyboard focus from leaving the overlay unless
|
|
526
|
+
* developers explicitly opt out (for example, sheet
|
|
527
|
+
* modals that should permit background interaction).
|
|
528
|
+
*
|
|
529
|
+
* Note: Some apps move inline overlays to a specific container
|
|
530
|
+
* during the willPresent lifecycle (e.g., React portals via
|
|
531
|
+
* onWillPresent). Defer applying aria-hidden/inert to the app
|
|
532
|
+
* root until after willPresent so we can detect where the
|
|
533
|
+
* overlay is finally inserted. If the overlay is inside the
|
|
534
|
+
* view container subtree, skip adding aria-hidden/inert there
|
|
535
|
+
* to avoid disabling the overlay.
|
|
528
536
|
*/
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
537
|
+
const overlayEl = overlay.el;
|
|
538
|
+
const shouldTrapFocus = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false;
|
|
539
|
+
// Only lock out root content when backdrop is active. Developers relying on showBackdrop=false
|
|
540
|
+
// expect background interaction to remain enabled.
|
|
541
|
+
const shouldLockRoot = shouldTrapFocus && overlayEl.showBackdrop !== false;
|
|
533
542
|
overlay.presented = true;
|
|
534
543
|
overlay.willPresent.emit();
|
|
544
|
+
if (shouldLockRoot) {
|
|
545
|
+
const root = getAppRoot(document);
|
|
546
|
+
const viewContainer = root.querySelector('ion-router-outlet, #ion-view-container-root');
|
|
547
|
+
const overlayInsideViewContainer = viewContainer ? viewContainer.contains(overlayEl) : false;
|
|
548
|
+
if (!overlayInsideViewContainer) {
|
|
549
|
+
setRootAriaHidden(true);
|
|
550
|
+
}
|
|
551
|
+
document.body.classList.add(BACKDROP_NO_SCROLL);
|
|
552
|
+
}
|
|
535
553
|
(_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
|
|
536
554
|
const mode = getIonMode(overlay);
|
|
537
555
|
// get the user's animation fn if one was provided
|
|
@@ -628,20 +646,24 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
|
|
|
628
646
|
* For accessibility, toasts lack focus traps and don't receive
|
|
629
647
|
* `aria-hidden` on the root element when presented.
|
|
630
648
|
*
|
|
631
|
-
*
|
|
632
|
-
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
* when the last non-toast overlay is dismissed.
|
|
649
|
+
* Overlays that opt into focus trapping set `aria-hidden`
|
|
650
|
+
* on the root element to keep keyboard focus and pointer
|
|
651
|
+
* events inside the overlay. We must remove `aria-hidden`
|
|
652
|
+
* from the root element when the last focus-trapping overlay
|
|
653
|
+
* is dismissed.
|
|
637
654
|
*/
|
|
638
|
-
const
|
|
639
|
-
|
|
655
|
+
const overlaysLockingRoot = presentedOverlays.filter((o) => {
|
|
656
|
+
const el = o;
|
|
657
|
+
return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && el.showBackdrop !== false;
|
|
658
|
+
});
|
|
659
|
+
const overlayEl = overlay.el;
|
|
660
|
+
const locksRoot = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && overlayEl.showBackdrop !== false;
|
|
640
661
|
/**
|
|
641
|
-
* If this is the last visible overlay that is
|
|
662
|
+
* If this is the last visible overlay that is trapping focus
|
|
642
663
|
* then we want to re-add the root to the accessibility tree.
|
|
643
664
|
*/
|
|
644
|
-
|
|
665
|
+
const lastOverlayTrappingFocus = locksRoot && overlaysLockingRoot.length === 1 && overlaysLockingRoot[0].id === overlayEl.id;
|
|
666
|
+
if (lastOverlayTrappingFocus) {
|
|
645
667
|
setRootAriaHidden(false);
|
|
646
668
|
document.body.classList.remove(BACKDROP_NO_SCROLL);
|
|
647
669
|
}
|
package/dist/cjs/index.cjs.js
CHANGED
|
@@ -15,7 +15,7 @@ var index$2 = require('./index-DNh170BW.js');
|
|
|
15
15
|
var config = require('./config-CKhELRRu.js');
|
|
16
16
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
17
17
|
var index$3 = require('./index-D24wggHR.js');
|
|
18
|
-
var overlays = require('./overlays-
|
|
18
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
19
19
|
require('./index-DkNv4J_i.js');
|
|
20
20
|
require('./gesture-controller-dtqlP_q4.js');
|
|
21
21
|
require('./hardware-back-button-BxdNu76F.js');
|
|
@@ -7,7 +7,7 @@ var index = require('./index-DNh170BW.js');
|
|
|
7
7
|
var buttonActive = require('./button-active-BzZenWWH.js');
|
|
8
8
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
9
9
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
10
|
-
var overlays = require('./overlays-
|
|
10
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
11
11
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
12
12
|
var ionicGlobal = require('./ionic-global-UI5YPSi-.js');
|
|
13
13
|
var animation = require('./animation-ZJ1lAkZD.js');
|
|
@@ -8,7 +8,7 @@ var config = require('./config-CKhELRRu.js');
|
|
|
8
8
|
var buttonActive = require('./button-active-BzZenWWH.js');
|
|
9
9
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
10
10
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
11
|
-
var overlays = require('./overlays-
|
|
11
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
12
12
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
13
13
|
var ionicGlobal = require('./ionic-global-UI5YPSi-.js');
|
|
14
14
|
var animation = require('./animation-ZJ1lAkZD.js');
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
var index = require('./index-DNh170BW.js');
|
|
7
7
|
var focusVisible = require('./focus-visible-CCvKiLh3.js');
|
|
8
8
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
9
|
-
var overlays = require('./overlays-
|
|
9
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
10
10
|
var dir = require('./dir-Cn0z1rJH.js');
|
|
11
11
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
12
12
|
var index$1 = require('./index-DqmRDbxg.js');
|
|
@@ -7,7 +7,7 @@ var index = require('./index-DNh170BW.js');
|
|
|
7
7
|
var config = require('./config-CKhELRRu.js');
|
|
8
8
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
9
9
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
10
|
-
var overlays = require('./overlays-
|
|
10
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
11
11
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
12
12
|
var ionicGlobal = require('./ionic-global-UI5YPSi-.js');
|
|
13
13
|
var animation = require('./animation-ZJ1lAkZD.js');
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
var index = require('./index-DNh170BW.js');
|
|
7
7
|
var cubicBezier = require('./cubic-bezier-DAjy1V-e.js');
|
|
8
|
-
var overlays = require('./overlays-
|
|
8
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
9
9
|
var gestureController = require('./gesture-controller-dtqlP_q4.js');
|
|
10
10
|
var hardwareBackButton = require('./hardware-back-button-BxdNu76F.js');
|
|
11
11
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
@@ -9,7 +9,7 @@ var frameworkDelegate = require('./framework-delegate-WkyjrnCx.js');
|
|
|
9
9
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
10
10
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
11
11
|
var capacitor = require('./capacitor-DmA66EwP.js');
|
|
12
|
-
var overlays = require('./overlays-
|
|
12
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
13
13
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
14
14
|
var index$4 = require('./index-BzEyuIww.js');
|
|
15
15
|
var ionicGlobal = require('./ionic-global-UI5YPSi-.js');
|
|
@@ -987,6 +987,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
987
987
|
const backdropAnimation = animation.childAnimations.find((ani) => ani.id === 'backdropAnimation');
|
|
988
988
|
const contentAnimation = animation.childAnimations.find((ani) => ani.id === 'contentAnimation');
|
|
989
989
|
const enableBackdrop = () => {
|
|
990
|
+
// Respect explicit opt-out of focus trapping/backdrop interactions
|
|
991
|
+
// If focusTrap is false or showBackdrop is false, do not enable the backdrop or re-enable focus trap
|
|
992
|
+
const el = baseEl;
|
|
993
|
+
if (el.focusTrap === false || el.showBackdrop === false) {
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
990
996
|
baseEl.style.setProperty('pointer-events', 'auto');
|
|
991
997
|
backdropEl.style.setProperty('pointer-events', 'auto');
|
|
992
998
|
/**
|
|
@@ -1111,7 +1117,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1111
1117
|
* ion-backdrop and .modal-wrapper always have pointer-events: auto
|
|
1112
1118
|
* applied, so the modal content can still be interacted with.
|
|
1113
1119
|
*/
|
|
1114
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
1120
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
1121
|
+
baseEl.focusTrap !== false &&
|
|
1122
|
+
baseEl.showBackdrop !== false;
|
|
1115
1123
|
if (shouldEnableBackdrop) {
|
|
1116
1124
|
enableBackdrop();
|
|
1117
1125
|
}
|
|
@@ -1419,7 +1427,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1419
1427
|
* Backdrop should become enabled
|
|
1420
1428
|
* after the backdropBreakpoint value
|
|
1421
1429
|
*/
|
|
1422
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
1430
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
1431
|
+
baseEl.focusTrap !== false &&
|
|
1432
|
+
baseEl.showBackdrop !== false;
|
|
1423
1433
|
if (shouldEnableBackdrop) {
|
|
1424
1434
|
enableBackdrop();
|
|
1425
1435
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
6
|
var index = require('./index-DNh170BW.js');
|
|
7
|
-
var overlays = require('./overlays-
|
|
7
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
8
8
|
var frameworkDelegate = require('./framework-delegate-WkyjrnCx.js');
|
|
9
9
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
10
10
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
var index = require('./index-DNh170BW.js');
|
|
7
7
|
var ionicGlobal = require('./ionic-global-UI5YPSi-.js');
|
|
8
|
-
var overlays = require('./overlays-
|
|
8
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
9
9
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
10
10
|
require('./index-DkNv4J_i.js');
|
|
11
11
|
require('./helpers-DgwmcYAu.js');
|
|
@@ -7,7 +7,7 @@ var index = require('./index-DNh170BW.js');
|
|
|
7
7
|
var notchController = require('./notch-controller-Bf5Rr4R5.js');
|
|
8
8
|
var compareWithUtils = require('./compare-with-utils-DSicavqM.js');
|
|
9
9
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
10
|
-
var overlays = require('./overlays-
|
|
10
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
11
11
|
var dir = require('./dir-Cn0z1rJH.js');
|
|
12
12
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
13
13
|
var watchOptions = require('./watch-options-CviOsrTS.js');
|
|
@@ -7,7 +7,7 @@ var index$1 = require('./index-DNh170BW.js');
|
|
|
7
7
|
var config = require('./config-CKhELRRu.js');
|
|
8
8
|
var helpers = require('./helpers-DgwmcYAu.js');
|
|
9
9
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
10
|
-
var overlays = require('./overlays-
|
|
10
|
+
var overlays = require('./overlays-czPyT6xP.js');
|
|
11
11
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
12
12
|
var ionicGlobal = require('./ionic-global-UI5YPSi-.js');
|
|
13
13
|
var animation = require('./animation-ZJ1lAkZD.js');
|
|
@@ -498,11 +498,9 @@ const setRootAriaHidden = (hidden = false) => {
|
|
|
498
498
|
}
|
|
499
499
|
if (hidden) {
|
|
500
500
|
viewContainer.setAttribute('aria-hidden', 'true');
|
|
501
|
-
viewContainer.setAttribute('inert', '');
|
|
502
501
|
}
|
|
503
502
|
else {
|
|
504
503
|
viewContainer.removeAttribute('aria-hidden');
|
|
505
|
-
viewContainer.removeAttribute('inert');
|
|
506
504
|
}
|
|
507
505
|
};
|
|
508
506
|
const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
|
|
@@ -526,14 +524,34 @@ const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts)
|
|
|
526
524
|
* focus traps.
|
|
527
525
|
*
|
|
528
526
|
* All other overlays should have focus traps to prevent
|
|
529
|
-
* the keyboard focus from leaving the overlay
|
|
527
|
+
* the keyboard focus from leaving the overlay unless
|
|
528
|
+
* developers explicitly opt out (for example, sheet
|
|
529
|
+
* modals that should permit background interaction).
|
|
530
|
+
*
|
|
531
|
+
* Note: Some apps move inline overlays to a specific container
|
|
532
|
+
* during the willPresent lifecycle (e.g., React portals via
|
|
533
|
+
* onWillPresent). Defer applying aria-hidden/inert to the app
|
|
534
|
+
* root until after willPresent so we can detect where the
|
|
535
|
+
* overlay is finally inserted. If the overlay is inside the
|
|
536
|
+
* view container subtree, skip adding aria-hidden/inert there
|
|
537
|
+
* to avoid disabling the overlay.
|
|
530
538
|
*/
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
539
|
+
const overlayEl = overlay.el;
|
|
540
|
+
const shouldTrapFocus = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false;
|
|
541
|
+
// Only lock out root content when backdrop is active. Developers relying on showBackdrop=false
|
|
542
|
+
// expect background interaction to remain enabled.
|
|
543
|
+
const shouldLockRoot = shouldTrapFocus && overlayEl.showBackdrop !== false;
|
|
535
544
|
overlay.presented = true;
|
|
536
545
|
overlay.willPresent.emit();
|
|
546
|
+
if (shouldLockRoot) {
|
|
547
|
+
const root = getAppRoot(document);
|
|
548
|
+
const viewContainer = root.querySelector('ion-router-outlet, #ion-view-container-root');
|
|
549
|
+
const overlayInsideViewContainer = viewContainer ? viewContainer.contains(overlayEl) : false;
|
|
550
|
+
if (!overlayInsideViewContainer) {
|
|
551
|
+
setRootAriaHidden(true);
|
|
552
|
+
}
|
|
553
|
+
document.body.classList.add(gestureController.BACKDROP_NO_SCROLL);
|
|
554
|
+
}
|
|
537
555
|
(_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
|
|
538
556
|
const mode = ionicGlobal.getIonMode(overlay);
|
|
539
557
|
// get the user's animation fn if one was provided
|
|
@@ -630,20 +648,24 @@ const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnim
|
|
|
630
648
|
* For accessibility, toasts lack focus traps and don't receive
|
|
631
649
|
* `aria-hidden` on the root element when presented.
|
|
632
650
|
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
* when the last non-toast overlay is dismissed.
|
|
651
|
+
* Overlays that opt into focus trapping set `aria-hidden`
|
|
652
|
+
* on the root element to keep keyboard focus and pointer
|
|
653
|
+
* events inside the overlay. We must remove `aria-hidden`
|
|
654
|
+
* from the root element when the last focus-trapping overlay
|
|
655
|
+
* is dismissed.
|
|
639
656
|
*/
|
|
640
|
-
const
|
|
641
|
-
|
|
657
|
+
const overlaysLockingRoot = presentedOverlays.filter((o) => {
|
|
658
|
+
const el = o;
|
|
659
|
+
return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && el.showBackdrop !== false;
|
|
660
|
+
});
|
|
661
|
+
const overlayEl = overlay.el;
|
|
662
|
+
const locksRoot = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && overlayEl.showBackdrop !== false;
|
|
642
663
|
/**
|
|
643
|
-
* If this is the last visible overlay that is
|
|
664
|
+
* If this is the last visible overlay that is trapping focus
|
|
644
665
|
* then we want to re-add the root to the accessibility tree.
|
|
645
666
|
*/
|
|
646
|
-
|
|
667
|
+
const lastOverlayTrappingFocus = locksRoot && overlaysLockingRoot.length === 1 && overlaysLockingRoot[0].id === overlayEl.id;
|
|
668
|
+
if (lastOverlayTrappingFocus) {
|
|
647
669
|
setRootAriaHidden(false);
|
|
648
670
|
document.body.classList.remove(gestureController.BACKDROP_NO_SCROLL);
|
|
649
671
|
}
|
|
@@ -45,6 +45,12 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
|
|
|
45
45
|
const backdropAnimation = animation.childAnimations.find((ani) => ani.id === 'backdropAnimation');
|
|
46
46
|
const contentAnimation = animation.childAnimations.find((ani) => ani.id === 'contentAnimation');
|
|
47
47
|
const enableBackdrop = () => {
|
|
48
|
+
// Respect explicit opt-out of focus trapping/backdrop interactions
|
|
49
|
+
// If focusTrap is false or showBackdrop is false, do not enable the backdrop or re-enable focus trap
|
|
50
|
+
const el = baseEl;
|
|
51
|
+
if (el.focusTrap === false || el.showBackdrop === false) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
48
54
|
baseEl.style.setProperty('pointer-events', 'auto');
|
|
49
55
|
backdropEl.style.setProperty('pointer-events', 'auto');
|
|
50
56
|
/**
|
|
@@ -169,7 +175,9 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
|
|
|
169
175
|
* ion-backdrop and .modal-wrapper always have pointer-events: auto
|
|
170
176
|
* applied, so the modal content can still be interacted with.
|
|
171
177
|
*/
|
|
172
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
178
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
179
|
+
baseEl.focusTrap !== false &&
|
|
180
|
+
baseEl.showBackdrop !== false;
|
|
173
181
|
if (shouldEnableBackdrop) {
|
|
174
182
|
enableBackdrop();
|
|
175
183
|
}
|
|
@@ -477,7 +485,9 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
|
|
|
477
485
|
* Backdrop should become enabled
|
|
478
486
|
* after the backdropBreakpoint value
|
|
479
487
|
*/
|
|
480
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
488
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
489
|
+
baseEl.focusTrap !== false &&
|
|
490
|
+
baseEl.showBackdrop !== false;
|
|
481
491
|
if (shouldEnableBackdrop) {
|
|
482
492
|
enableBackdrop();
|
|
483
493
|
}
|
|
@@ -417,11 +417,9 @@ export const setRootAriaHidden = (hidden = false) => {
|
|
|
417
417
|
}
|
|
418
418
|
if (hidden) {
|
|
419
419
|
viewContainer.setAttribute('aria-hidden', 'true');
|
|
420
|
-
viewContainer.setAttribute('inert', '');
|
|
421
420
|
}
|
|
422
421
|
else {
|
|
423
422
|
viewContainer.removeAttribute('aria-hidden');
|
|
424
|
-
viewContainer.removeAttribute('inert');
|
|
425
423
|
}
|
|
426
424
|
};
|
|
427
425
|
export const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
|
|
@@ -445,14 +443,34 @@ export const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation
|
|
|
445
443
|
* focus traps.
|
|
446
444
|
*
|
|
447
445
|
* All other overlays should have focus traps to prevent
|
|
448
|
-
* the keyboard focus from leaving the overlay
|
|
446
|
+
* the keyboard focus from leaving the overlay unless
|
|
447
|
+
* developers explicitly opt out (for example, sheet
|
|
448
|
+
* modals that should permit background interaction).
|
|
449
|
+
*
|
|
450
|
+
* Note: Some apps move inline overlays to a specific container
|
|
451
|
+
* during the willPresent lifecycle (e.g., React portals via
|
|
452
|
+
* onWillPresent). Defer applying aria-hidden/inert to the app
|
|
453
|
+
* root until after willPresent so we can detect where the
|
|
454
|
+
* overlay is finally inserted. If the overlay is inside the
|
|
455
|
+
* view container subtree, skip adding aria-hidden/inert there
|
|
456
|
+
* to avoid disabling the overlay.
|
|
449
457
|
*/
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
458
|
+
const overlayEl = overlay.el;
|
|
459
|
+
const shouldTrapFocus = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false;
|
|
460
|
+
// Only lock out root content when backdrop is active. Developers relying on showBackdrop=false
|
|
461
|
+
// expect background interaction to remain enabled.
|
|
462
|
+
const shouldLockRoot = shouldTrapFocus && overlayEl.showBackdrop !== false;
|
|
454
463
|
overlay.presented = true;
|
|
455
464
|
overlay.willPresent.emit();
|
|
465
|
+
if (shouldLockRoot) {
|
|
466
|
+
const root = getAppRoot(document);
|
|
467
|
+
const viewContainer = root.querySelector('ion-router-outlet, #ion-view-container-root');
|
|
468
|
+
const overlayInsideViewContainer = viewContainer ? viewContainer.contains(overlayEl) : false;
|
|
469
|
+
if (!overlayInsideViewContainer) {
|
|
470
|
+
setRootAriaHidden(true);
|
|
471
|
+
}
|
|
472
|
+
document.body.classList.add(BACKDROP_NO_SCROLL);
|
|
473
|
+
}
|
|
456
474
|
(_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
|
|
457
475
|
const mode = getIonMode(overlay);
|
|
458
476
|
// get the user's animation fn if one was provided
|
|
@@ -549,20 +567,24 @@ export const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLe
|
|
|
549
567
|
* For accessibility, toasts lack focus traps and don't receive
|
|
550
568
|
* `aria-hidden` on the root element when presented.
|
|
551
569
|
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
* when the last non-toast overlay is dismissed.
|
|
570
|
+
* Overlays that opt into focus trapping set `aria-hidden`
|
|
571
|
+
* on the root element to keep keyboard focus and pointer
|
|
572
|
+
* events inside the overlay. We must remove `aria-hidden`
|
|
573
|
+
* from the root element when the last focus-trapping overlay
|
|
574
|
+
* is dismissed.
|
|
558
575
|
*/
|
|
559
|
-
const
|
|
560
|
-
|
|
576
|
+
const overlaysLockingRoot = presentedOverlays.filter((o) => {
|
|
577
|
+
const el = o;
|
|
578
|
+
return el.tagName !== 'ION-TOAST' && el.focusTrap !== false && el.showBackdrop !== false;
|
|
579
|
+
});
|
|
580
|
+
const overlayEl = overlay.el;
|
|
581
|
+
const locksRoot = overlayEl.tagName !== 'ION-TOAST' && overlayEl.focusTrap !== false && overlayEl.showBackdrop !== false;
|
|
561
582
|
/**
|
|
562
|
-
* If this is the last visible overlay that is
|
|
583
|
+
* If this is the last visible overlay that is trapping focus
|
|
563
584
|
* then we want to re-add the root to the accessibility tree.
|
|
564
585
|
*/
|
|
565
|
-
|
|
586
|
+
const lastOverlayTrappingFocus = locksRoot && overlaysLockingRoot.length === 1 && overlaysLockingRoot[0].id === overlayEl.id;
|
|
587
|
+
if (lastOverlayTrappingFocus) {
|
|
566
588
|
setRootAriaHidden(false);
|
|
567
589
|
document.body.classList.remove(BACKDROP_NO_SCROLL);
|
|
568
590
|
}
|
package/dist/docs.json
CHANGED
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-
|
|
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-BYcYBCrx.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-
|
|
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-BYcYBCrx.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-
|
|
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-BYcYBCrx.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-
|
|
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-BYcYBCrx.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-
|
|
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-BYcYBCrx.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-
|
|
6
|
+
import { o as getPresentedOverlay, B as BACKDROP, n as focusFirstDescendant, q as focusLastDescendant, G as GESTURE } from './overlays-BYcYBCrx.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-
|
|
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-BYcYBCrx.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';
|
|
@@ -985,6 +985,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
985
985
|
const backdropAnimation = animation.childAnimations.find((ani) => ani.id === 'backdropAnimation');
|
|
986
986
|
const contentAnimation = animation.childAnimations.find((ani) => ani.id === 'contentAnimation');
|
|
987
987
|
const enableBackdrop = () => {
|
|
988
|
+
// Respect explicit opt-out of focus trapping/backdrop interactions
|
|
989
|
+
// If focusTrap is false or showBackdrop is false, do not enable the backdrop or re-enable focus trap
|
|
990
|
+
const el = baseEl;
|
|
991
|
+
if (el.focusTrap === false || el.showBackdrop === false) {
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
988
994
|
baseEl.style.setProperty('pointer-events', 'auto');
|
|
989
995
|
backdropEl.style.setProperty('pointer-events', 'auto');
|
|
990
996
|
/**
|
|
@@ -1109,7 +1115,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1109
1115
|
* ion-backdrop and .modal-wrapper always have pointer-events: auto
|
|
1110
1116
|
* applied, so the modal content can still be interacted with.
|
|
1111
1117
|
*/
|
|
1112
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
1118
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
1119
|
+
baseEl.focusTrap !== false &&
|
|
1120
|
+
baseEl.showBackdrop !== false;
|
|
1113
1121
|
if (shouldEnableBackdrop) {
|
|
1114
1122
|
enableBackdrop();
|
|
1115
1123
|
}
|
|
@@ -1417,7 +1425,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1417
1425
|
* Backdrop should become enabled
|
|
1418
1426
|
* after the backdropBreakpoint value
|
|
1419
1427
|
*/
|
|
1420
|
-
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint
|
|
1428
|
+
const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint &&
|
|
1429
|
+
baseEl.focusTrap !== false &&
|
|
1430
|
+
baseEl.showBackdrop !== false;
|
|
1421
1431
|
if (shouldEnableBackdrop) {
|
|
1422
1432
|
enableBackdrop();
|
|
1423
1433
|
}
|
|
@@ -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-
|
|
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-BYcYBCrx.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';
|
|
@@ -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-
|
|
6
|
+
import { s as safeCall } from './overlays-BYcYBCrx.js';
|
|
7
7
|
import { g as getClassMap } from './theme-DiVJyqlX.js';
|
|
8
8
|
import './index-ZjP4CjeZ.js';
|
|
9
9
|
import './helpers-8KSQQGQy.js';
|