@ionic/core 8.7.17-dev.11767796972.148e4bc4 → 8.7.17-dev.11767891829.1a63afa3
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/content.js +22 -7
- package/components/modal.js +36 -23
- package/components/popover.js +11 -2
- package/dist/cjs/ion-app_8.cjs.entry.js +34 -20
- package/dist/cjs/ion-modal.cjs.entry.js +36 -23
- package/dist/cjs/ion-popover.cjs.entry.js +11 -2
- package/dist/collection/components/content/content.js +22 -7
- package/dist/collection/components/modal/modal.js +36 -22
- package/dist/collection/components/popover/animations/md.enter.js +11 -2
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +22 -8
- package/dist/esm/ion-modal.entry.js +36 -23
- package/dist/esm/ion-popover.entry.js +11 -2
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-968a55d1.entry.js +4 -0
- package/dist/ionic/p-d9fd799f.entry.js +4 -0
- package/dist/ionic/p-ec9ca3fe.entry.js +4 -0
- package/dist/types/components/modal/modal.d.ts +6 -0
- package/hydrate/index.js +60 -30
- package/hydrate/index.mjs +60 -30
- package/package.json +1 -1
- package/dist/ionic/p-3830217a.entry.js +0 -4
- package/dist/ionic/p-a4827773.entry.js +0 -4
- package/dist/ionic/p-cecd141b.entry.js +0 -4
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
4
|
import { Build, Host, forceUpdate, h, readTask } from "@stencil/core";
|
|
5
|
+
import { win } from "../../utils/browser/index";
|
|
5
6
|
import { componentOnReady, hasLazyBuild, inheritAriaAttributes } from "../../utils/helpers";
|
|
6
7
|
import { isPlatform } from "../../utils/platform";
|
|
7
8
|
import { isRTL } from "../../utils/rtl/index";
|
|
@@ -85,7 +86,11 @@ export class Content {
|
|
|
85
86
|
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
|
86
87
|
}
|
|
87
88
|
connectedCallback() {
|
|
88
|
-
|
|
89
|
+
var _a;
|
|
90
|
+
// Content is "main" if not inside menu/popover/modal and not nested in another ion-content
|
|
91
|
+
this.isMainContent =
|
|
92
|
+
this.el.closest('ion-menu, ion-popover, ion-modal') === null &&
|
|
93
|
+
((_a = this.el.parentElement) === null || _a === void 0 ? void 0 : _a.closest('ion-content')) === null;
|
|
89
94
|
// Detect sibling header/footer for safe-area handling
|
|
90
95
|
this.detectSiblingElements();
|
|
91
96
|
/**
|
|
@@ -118,7 +123,12 @@ export class Content {
|
|
|
118
123
|
* bubbles, we can catch any instances of child tab bars loading by listening
|
|
119
124
|
* on IonTabs.
|
|
120
125
|
*/
|
|
121
|
-
this.tabsLoadCallback = () =>
|
|
126
|
+
this.tabsLoadCallback = () => {
|
|
127
|
+
this.resize();
|
|
128
|
+
// Re-detect footer when tab bar loads (it may not exist during initial detection)
|
|
129
|
+
this.updateSiblingDetection();
|
|
130
|
+
forceUpdate(this);
|
|
131
|
+
};
|
|
122
132
|
closestTabs.addEventListener('ionTabBarLoaded', this.tabsLoadCallback);
|
|
123
133
|
}
|
|
124
134
|
}
|
|
@@ -131,10 +141,15 @@ export class Content {
|
|
|
131
141
|
this.updateSiblingDetection();
|
|
132
142
|
// Watch for dynamic header/footer changes (common in React conditional rendering)
|
|
133
143
|
const parent = this.el.parentElement;
|
|
134
|
-
if (parent && !this.parentMutationObserver) {
|
|
144
|
+
if (parent && !this.parentMutationObserver && win !== undefined && 'MutationObserver' in win) {
|
|
135
145
|
this.parentMutationObserver = new MutationObserver(() => {
|
|
146
|
+
const prevHasHeader = this.hasHeader;
|
|
147
|
+
const prevHasFooter = this.hasFooter;
|
|
136
148
|
this.updateSiblingDetection();
|
|
137
|
-
|
|
149
|
+
// Only trigger re-render if header/footer detection actually changed
|
|
150
|
+
if (prevHasHeader !== this.hasHeader || prevHasFooter !== this.hasFooter) {
|
|
151
|
+
forceUpdate(this);
|
|
152
|
+
}
|
|
138
153
|
});
|
|
139
154
|
this.parentMutationObserver.observe(parent, { childList: true });
|
|
140
155
|
}
|
|
@@ -440,7 +455,7 @@ export class Content {
|
|
|
440
455
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
441
456
|
const transitionShadow = mode === 'ios';
|
|
442
457
|
this.resize();
|
|
443
|
-
return (h(Host, Object.assign({ key: '
|
|
458
|
+
return (h(Host, Object.assign({ key: 'f7218f733e4022a30875441bd949747537d28aa1', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
444
459
|
[mode]: true,
|
|
445
460
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
446
461
|
overscroll: forceOverscroll,
|
|
@@ -450,12 +465,12 @@ export class Content {
|
|
|
450
465
|
}), style: {
|
|
451
466
|
'--offset-top': `${this.cTop}px`,
|
|
452
467
|
'--offset-bottom': `${this.cBottom}px`,
|
|
453
|
-
} }, inheritedAttributes), h("div", { key: '
|
|
468
|
+
} }, inheritedAttributes), h("div", { key: 'b735ec68c18c0b99c3595bb194029830e6542cde', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: 'e76c00d030342d44ade6648c3f9e32ca990787ba', class: {
|
|
454
469
|
'inner-scroll': true,
|
|
455
470
|
'scroll-x': scrollX,
|
|
456
471
|
'scroll-y': scrollY,
|
|
457
472
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
458
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '
|
|
473
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '9049be4cea9b5da5ec1e1012248b05286fddeb7a' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
|
|
459
474
|
}
|
|
460
475
|
static get is() { return "ion-content"; }
|
|
461
476
|
static get encapsulation() { return "shadow"; }
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
4
|
import { Host, h, writeTask } from "@stencil/core";
|
|
5
|
+
import { win } from "../../utils/browser/index";
|
|
5
6
|
import { findIonContent, printIonContentErrorMsg } from "../../utils/content/index";
|
|
6
7
|
import { CoreDelegate, attachComponent, detachComponent } from "../../utils/framework-delegate";
|
|
7
8
|
import { raf, inheritAttributes, hasLazyBuild, getElementRoot } from "../../utils/helpers";
|
|
@@ -262,6 +263,8 @@ export class Modal {
|
|
|
262
263
|
this.triggerController.removeClickListener();
|
|
263
264
|
this.cleanupViewTransitionListener();
|
|
264
265
|
this.cleanupParentRemovalObserver();
|
|
266
|
+
// Reset safe-area state to handle removal without dismiss (e.g., framework unmount)
|
|
267
|
+
this.resetSafeAreaState();
|
|
265
268
|
}
|
|
266
269
|
componentWillLoad() {
|
|
267
270
|
var _a;
|
|
@@ -698,7 +701,9 @@ export class Modal {
|
|
|
698
701
|
this.skipSafeAreaCoordinateDetection = true;
|
|
699
702
|
this.updateFooterPadding();
|
|
700
703
|
// Watch for dynamic footer additions/removals (e.g., async data loading)
|
|
701
|
-
|
|
704
|
+
// Use subtree:true to support wrapped footers in framework components
|
|
705
|
+
// (e.g., <my-footer><ion-footer>...</ion-footer></my-footer>)
|
|
706
|
+
if (!this.footerObserver && win !== undefined && 'MutationObserver' in win) {
|
|
702
707
|
this.footerObserver = new MutationObserver(() => this.updateFooterPadding());
|
|
703
708
|
this.footerObserver.observe(this.el, { childList: true, subtree: true });
|
|
704
709
|
}
|
|
@@ -731,6 +736,30 @@ export class Modal {
|
|
|
731
736
|
style.setProperty('--ion-safe-area-left', '0px');
|
|
732
737
|
style.setProperty('--ion-safe-area-right', '0px');
|
|
733
738
|
}
|
|
739
|
+
/**
|
|
740
|
+
* Resets all safe-area related state and styles.
|
|
741
|
+
* Called during dismiss and disconnectedCallback to ensure clean state
|
|
742
|
+
* for re-presentation of inline modals.
|
|
743
|
+
*/
|
|
744
|
+
resetSafeAreaState() {
|
|
745
|
+
var _a;
|
|
746
|
+
this.skipSafeAreaCoordinateDetection = false;
|
|
747
|
+
this.cachedSafeAreas = undefined;
|
|
748
|
+
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
749
|
+
(_a = this.footerObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
750
|
+
this.footerObserver = undefined;
|
|
751
|
+
// Clear wrapper styles that may have been set for safe-area handling
|
|
752
|
+
if (this.wrapperEl) {
|
|
753
|
+
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
754
|
+
this.wrapperEl.style.removeProperty('box-sizing');
|
|
755
|
+
}
|
|
756
|
+
// Clear safe-area CSS variable overrides
|
|
757
|
+
const style = this.el.style;
|
|
758
|
+
style.removeProperty('--ion-safe-area-top');
|
|
759
|
+
style.removeProperty('--ion-safe-area-bottom');
|
|
760
|
+
style.removeProperty('--ion-safe-area-left');
|
|
761
|
+
style.removeProperty('--ion-safe-area-right');
|
|
762
|
+
}
|
|
734
763
|
/**
|
|
735
764
|
* Gets the root safe-area values from the document element.
|
|
736
765
|
* Uses cached values during gestures to avoid getComputedStyle calls.
|
|
@@ -822,7 +851,7 @@ export class Modal {
|
|
|
822
851
|
* For example, `cancel` or `backdrop`.
|
|
823
852
|
*/
|
|
824
853
|
async dismiss(data, role) {
|
|
825
|
-
var _a
|
|
854
|
+
var _a;
|
|
826
855
|
if (this.gestureAnimationDismissing && role !== GESTURE) {
|
|
827
856
|
return false;
|
|
828
857
|
}
|
|
@@ -885,22 +914,7 @@ export class Modal {
|
|
|
885
914
|
this.currentBreakpoint = undefined;
|
|
886
915
|
this.animation = undefined;
|
|
887
916
|
// Reset safe-area state for potential re-presentation
|
|
888
|
-
this.
|
|
889
|
-
this.cachedSafeAreas = undefined;
|
|
890
|
-
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
891
|
-
(_b = this.footerObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
892
|
-
this.footerObserver = undefined;
|
|
893
|
-
// Clear styles that may have been set for safe-area handling
|
|
894
|
-
if (this.wrapperEl) {
|
|
895
|
-
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
896
|
-
this.wrapperEl.style.removeProperty('box-sizing');
|
|
897
|
-
}
|
|
898
|
-
// Clear safe-area CSS variable overrides
|
|
899
|
-
const style = this.el.style;
|
|
900
|
-
style.removeProperty('--ion-safe-area-top');
|
|
901
|
-
style.removeProperty('--ion-safe-area-bottom');
|
|
902
|
-
style.removeProperty('--ion-safe-area-left');
|
|
903
|
-
style.removeProperty('--ion-safe-area-right');
|
|
917
|
+
this.resetSafeAreaState();
|
|
904
918
|
unlock();
|
|
905
919
|
return dismissed;
|
|
906
920
|
}
|
|
@@ -1158,20 +1172,20 @@ export class Modal {
|
|
|
1158
1172
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
1159
1173
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
1160
1174
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
1161
|
-
return (h(Host, Object.assign({ key: '
|
|
1175
|
+
return (h(Host, Object.assign({ key: '44022099fcaf047b97d1c2cb45b9b51c930e707c', "no-router": true,
|
|
1162
1176
|
// Allow the modal to be navigable when the handle is focusable
|
|
1163
1177
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
1164
1178
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
1165
|
-
}, 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: '
|
|
1179
|
+
}, 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: 'ddd7e4f6eef51ac1f62ac70e0af10fb01e707f07', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '58620980e3e4ec273c6787bde026e1c010b904b7', class: "modal-shadow" }), h("div", Object.assign({ key: '3fb7f6218644ba898fc504467775593eb89426a0',
|
|
1166
1180
|
/*
|
|
1167
1181
|
role and aria-modal must be used on the
|
|
1168
1182
|
same element. They must also be set inside the
|
|
1169
1183
|
shadow DOM otherwise ion-button will not be highlighted
|
|
1170
1184
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
1171
1185
|
*/
|
|
1172
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '
|
|
1186
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '9745cd590fdaa9d023a14b487ec2c87ddbafd7f7', class: "modal-handle",
|
|
1173
1187
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
1174
|
-
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: '
|
|
1188
|
+
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: 'b9a8b5d2d3d3c9b06f99179f496c9f08907d0bad', onSlotchange: this.onSlotChange }))));
|
|
1175
1189
|
}
|
|
1176
1190
|
static get is() { return "ion-modal"; }
|
|
1177
1191
|
static get encapsulation() { return "shadow"; }
|
|
@@ -28,7 +28,7 @@ export const mdEnterAnimation = (baseEl, opts) => {
|
|
|
28
28
|
};
|
|
29
29
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
|
|
30
30
|
const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
|
|
31
|
-
const { originX, originY, top, left, bottom, checkSafeAreaTop, checkSafeAreaBottom } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
|
|
31
|
+
const { originX, originY, top, left, bottom, checkSafeAreaTop, checkSafeAreaBottom, checkSafeAreaLeft, checkSafeAreaRight, } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
|
|
32
32
|
/**
|
|
33
33
|
* Safe area CSS variable adjustments.
|
|
34
34
|
* When the popover is positioned near an edge, we add the corresponding
|
|
@@ -37,14 +37,23 @@ export const mdEnterAnimation = (baseEl, opts) => {
|
|
|
37
37
|
*/
|
|
38
38
|
const safeAreaTop = ' + var(--ion-safe-area-top, 0)';
|
|
39
39
|
const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0)';
|
|
40
|
+
const safeAreaLeft = ' + var(--ion-safe-area-left, 0)';
|
|
41
|
+
const safeAreaRight = ' - var(--ion-safe-area-right, 0)';
|
|
40
42
|
let topValue = `${top}px`;
|
|
41
43
|
let bottomValue = bottom !== undefined ? `${bottom}px` : undefined;
|
|
44
|
+
let leftValue = `${left}px`;
|
|
42
45
|
if (checkSafeAreaTop) {
|
|
43
46
|
topValue = `${top}px${safeAreaTop}`;
|
|
44
47
|
}
|
|
45
48
|
if (checkSafeAreaBottom && bottomValue !== undefined) {
|
|
46
49
|
bottomValue = `${bottom}px${safeAreaBottom}`;
|
|
47
50
|
}
|
|
51
|
+
if (checkSafeAreaLeft) {
|
|
52
|
+
leftValue = `${left}px${safeAreaLeft}`;
|
|
53
|
+
}
|
|
54
|
+
if (checkSafeAreaRight) {
|
|
55
|
+
leftValue = `${left}px${safeAreaRight}`;
|
|
56
|
+
}
|
|
48
57
|
const baseAnimation = createAnimation();
|
|
49
58
|
const backdropAnimation = createAnimation();
|
|
50
59
|
const wrapperAnimation = createAnimation();
|
|
@@ -62,7 +71,7 @@ export const mdEnterAnimation = (baseEl, opts) => {
|
|
|
62
71
|
.addElement(contentEl)
|
|
63
72
|
.beforeStyles({
|
|
64
73
|
top: `calc(${topValue} + var(--offset-y, 0px))`,
|
|
65
|
-
left: `calc(${
|
|
74
|
+
left: `calc(${leftValue} + var(--offset-x, 0px))`,
|
|
66
75
|
'transform-origin': `${originY} ${originX}`,
|
|
67
76
|
})
|
|
68
77
|
.beforeAddWrite(() => {
|
package/dist/docs.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { r as registerInstance, h, e as config, d as Host, g as getElement, f as printIonWarning, c as createEvent, i as forceUpdate, a as readTask, w as writeTask, j as printIonError } from './index-C8IsBmNU.js';
|
|
5
5
|
import { shouldUseCloseWatcher } from './hardware-back-button-CPLxO-Ev.js';
|
|
6
6
|
import { b as getIonMode, a as isPlatform } from './ionic-global-CDrldh-5.js';
|
|
7
|
+
import { w as win } from './index-ZjP4CjeZ.js';
|
|
7
8
|
import { i as inheritAriaAttributes, h as hasLazyBuild, c as componentOnReady, e as clamp, s as shallowEqualStringMap } from './helpers-DEn3pfjm.js';
|
|
8
9
|
import { i as isRTL } from './dir-C53feagD.js';
|
|
9
10
|
import { c as createColorClasses, h as hostContext } from './theme-DiVJyqlX.js';
|
|
@@ -13,7 +14,6 @@ import { g as getTimeGivenProgression } from './cubic-bezier-hHmYLOfE.js';
|
|
|
13
14
|
import { a as attachComponent, d as detachComponent } from './framework-delegate-BYawdMXj.js';
|
|
14
15
|
import { c as createLockController } from './lock-controller-B-hirT0v.js';
|
|
15
16
|
import { t as transition } from './index-r2D9DEro.js';
|
|
16
|
-
import './index-ZjP4CjeZ.js';
|
|
17
17
|
import './keyboard-CUw4ekVy.js';
|
|
18
18
|
import './capacitor-CFERIeaU.js';
|
|
19
19
|
|
|
@@ -229,7 +229,11 @@ const Content = class {
|
|
|
229
229
|
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
|
230
230
|
}
|
|
231
231
|
connectedCallback() {
|
|
232
|
-
|
|
232
|
+
var _a;
|
|
233
|
+
// Content is "main" if not inside menu/popover/modal and not nested in another ion-content
|
|
234
|
+
this.isMainContent =
|
|
235
|
+
this.el.closest('ion-menu, ion-popover, ion-modal') === null &&
|
|
236
|
+
((_a = this.el.parentElement) === null || _a === void 0 ? void 0 : _a.closest('ion-content')) === null;
|
|
233
237
|
// Detect sibling header/footer for safe-area handling
|
|
234
238
|
this.detectSiblingElements();
|
|
235
239
|
/**
|
|
@@ -262,7 +266,12 @@ const Content = class {
|
|
|
262
266
|
* bubbles, we can catch any instances of child tab bars loading by listening
|
|
263
267
|
* on IonTabs.
|
|
264
268
|
*/
|
|
265
|
-
this.tabsLoadCallback = () =>
|
|
269
|
+
this.tabsLoadCallback = () => {
|
|
270
|
+
this.resize();
|
|
271
|
+
// Re-detect footer when tab bar loads (it may not exist during initial detection)
|
|
272
|
+
this.updateSiblingDetection();
|
|
273
|
+
forceUpdate(this);
|
|
274
|
+
};
|
|
266
275
|
closestTabs.addEventListener('ionTabBarLoaded', this.tabsLoadCallback);
|
|
267
276
|
}
|
|
268
277
|
}
|
|
@@ -275,10 +284,15 @@ const Content = class {
|
|
|
275
284
|
this.updateSiblingDetection();
|
|
276
285
|
// Watch for dynamic header/footer changes (common in React conditional rendering)
|
|
277
286
|
const parent = this.el.parentElement;
|
|
278
|
-
if (parent && !this.parentMutationObserver) {
|
|
287
|
+
if (parent && !this.parentMutationObserver && win !== undefined && 'MutationObserver' in win) {
|
|
279
288
|
this.parentMutationObserver = new MutationObserver(() => {
|
|
289
|
+
const prevHasHeader = this.hasHeader;
|
|
290
|
+
const prevHasFooter = this.hasFooter;
|
|
280
291
|
this.updateSiblingDetection();
|
|
281
|
-
|
|
292
|
+
// Only trigger re-render if header/footer detection actually changed
|
|
293
|
+
if (prevHasHeader !== this.hasHeader || prevHasFooter !== this.hasFooter) {
|
|
294
|
+
forceUpdate(this);
|
|
295
|
+
}
|
|
282
296
|
});
|
|
283
297
|
this.parentMutationObserver.observe(parent, { childList: true });
|
|
284
298
|
}
|
|
@@ -584,7 +598,7 @@ const Content = class {
|
|
|
584
598
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
585
599
|
const transitionShadow = mode === 'ios';
|
|
586
600
|
this.resize();
|
|
587
|
-
return (h(Host, Object.assign({ key: '
|
|
601
|
+
return (h(Host, Object.assign({ key: 'f7218f733e4022a30875441bd949747537d28aa1', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
588
602
|
[mode]: true,
|
|
589
603
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
590
604
|
overscroll: forceOverscroll,
|
|
@@ -594,12 +608,12 @@ const Content = class {
|
|
|
594
608
|
}), style: {
|
|
595
609
|
'--offset-top': `${this.cTop}px`,
|
|
596
610
|
'--offset-bottom': `${this.cBottom}px`,
|
|
597
|
-
} }, inheritedAttributes), h("div", { key: '
|
|
611
|
+
} }, inheritedAttributes), h("div", { key: 'b735ec68c18c0b99c3595bb194029830e6542cde', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: 'e76c00d030342d44ade6648c3f9e32ca990787ba', class: {
|
|
598
612
|
'inner-scroll': true,
|
|
599
613
|
'scroll-x': scrollX,
|
|
600
614
|
'scroll-y': scrollY,
|
|
601
615
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
602
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '
|
|
616
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '9049be4cea9b5da5ec1e1012248b05286fddeb7a' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
|
|
603
617
|
}
|
|
604
618
|
get el() { return getElement(this); }
|
|
605
619
|
};
|
|
@@ -2,6 +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, w as writeTask, e as config, h, d as Host, g as getElement } from './index-C8IsBmNU.js';
|
|
5
|
+
import { w as win } from './index-ZjP4CjeZ.js';
|
|
5
6
|
import { f as findClosestIonContent, i as isIonContent, d as disableContentScrollY, r as resetContentScrollY, a as findIonContent, p as printIonContentErrorMsg } from './index-Bs3kT4bc.js';
|
|
6
7
|
import { C as CoreDelegate, a as attachComponent, d as detachComponent } from './framework-delegate-BYawdMXj.js';
|
|
7
8
|
import { e as clamp, g as getElementRoot, r as raf, b as inheritAttributes, h as hasLazyBuild } from './helpers-DEn3pfjm.js';
|
|
@@ -15,7 +16,6 @@ import { KEYBOARD_DID_OPEN } from './keyboard-ywgs5efA.js';
|
|
|
15
16
|
import { c as createAnimation } from './animation-Dt8bGnA-.js';
|
|
16
17
|
import { g as getTimeGivenProgression } from './cubic-bezier-hHmYLOfE.js';
|
|
17
18
|
import { createGesture } from './index-CfgBF1SE.js';
|
|
18
|
-
import { w as win } from './index-ZjP4CjeZ.js';
|
|
19
19
|
import './hardware-back-button-CPLxO-Ev.js';
|
|
20
20
|
import './gesture-controller-BTEOs1at.js';
|
|
21
21
|
import './keyboard-CUw4ekVy.js';
|
|
@@ -1721,6 +1721,8 @@ const Modal = class {
|
|
|
1721
1721
|
this.triggerController.removeClickListener();
|
|
1722
1722
|
this.cleanupViewTransitionListener();
|
|
1723
1723
|
this.cleanupParentRemovalObserver();
|
|
1724
|
+
// Reset safe-area state to handle removal without dismiss (e.g., framework unmount)
|
|
1725
|
+
this.resetSafeAreaState();
|
|
1724
1726
|
}
|
|
1725
1727
|
componentWillLoad() {
|
|
1726
1728
|
var _a;
|
|
@@ -2157,7 +2159,9 @@ const Modal = class {
|
|
|
2157
2159
|
this.skipSafeAreaCoordinateDetection = true;
|
|
2158
2160
|
this.updateFooterPadding();
|
|
2159
2161
|
// Watch for dynamic footer additions/removals (e.g., async data loading)
|
|
2160
|
-
|
|
2162
|
+
// Use subtree:true to support wrapped footers in framework components
|
|
2163
|
+
// (e.g., <my-footer><ion-footer>...</ion-footer></my-footer>)
|
|
2164
|
+
if (!this.footerObserver && win !== undefined && 'MutationObserver' in win) {
|
|
2161
2165
|
this.footerObserver = new MutationObserver(() => this.updateFooterPadding());
|
|
2162
2166
|
this.footerObserver.observe(this.el, { childList: true, subtree: true });
|
|
2163
2167
|
}
|
|
@@ -2190,6 +2194,30 @@ const Modal = class {
|
|
|
2190
2194
|
style.setProperty('--ion-safe-area-left', '0px');
|
|
2191
2195
|
style.setProperty('--ion-safe-area-right', '0px');
|
|
2192
2196
|
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Resets all safe-area related state and styles.
|
|
2199
|
+
* Called during dismiss and disconnectedCallback to ensure clean state
|
|
2200
|
+
* for re-presentation of inline modals.
|
|
2201
|
+
*/
|
|
2202
|
+
resetSafeAreaState() {
|
|
2203
|
+
var _a;
|
|
2204
|
+
this.skipSafeAreaCoordinateDetection = false;
|
|
2205
|
+
this.cachedSafeAreas = undefined;
|
|
2206
|
+
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
2207
|
+
(_a = this.footerObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
2208
|
+
this.footerObserver = undefined;
|
|
2209
|
+
// Clear wrapper styles that may have been set for safe-area handling
|
|
2210
|
+
if (this.wrapperEl) {
|
|
2211
|
+
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
2212
|
+
this.wrapperEl.style.removeProperty('box-sizing');
|
|
2213
|
+
}
|
|
2214
|
+
// Clear safe-area CSS variable overrides
|
|
2215
|
+
const style = this.el.style;
|
|
2216
|
+
style.removeProperty('--ion-safe-area-top');
|
|
2217
|
+
style.removeProperty('--ion-safe-area-bottom');
|
|
2218
|
+
style.removeProperty('--ion-safe-area-left');
|
|
2219
|
+
style.removeProperty('--ion-safe-area-right');
|
|
2220
|
+
}
|
|
2193
2221
|
/**
|
|
2194
2222
|
* Gets the root safe-area values from the document element.
|
|
2195
2223
|
* Uses cached values during gestures to avoid getComputedStyle calls.
|
|
@@ -2281,7 +2309,7 @@ const Modal = class {
|
|
|
2281
2309
|
* For example, `cancel` or `backdrop`.
|
|
2282
2310
|
*/
|
|
2283
2311
|
async dismiss(data, role) {
|
|
2284
|
-
var _a
|
|
2312
|
+
var _a;
|
|
2285
2313
|
if (this.gestureAnimationDismissing && role !== GESTURE) {
|
|
2286
2314
|
return false;
|
|
2287
2315
|
}
|
|
@@ -2344,22 +2372,7 @@ const Modal = class {
|
|
|
2344
2372
|
this.currentBreakpoint = undefined;
|
|
2345
2373
|
this.animation = undefined;
|
|
2346
2374
|
// Reset safe-area state for potential re-presentation
|
|
2347
|
-
this.
|
|
2348
|
-
this.cachedSafeAreas = undefined;
|
|
2349
|
-
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
2350
|
-
(_b = this.footerObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
2351
|
-
this.footerObserver = undefined;
|
|
2352
|
-
// Clear styles that may have been set for safe-area handling
|
|
2353
|
-
if (this.wrapperEl) {
|
|
2354
|
-
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
2355
|
-
this.wrapperEl.style.removeProperty('box-sizing');
|
|
2356
|
-
}
|
|
2357
|
-
// Clear safe-area CSS variable overrides
|
|
2358
|
-
const style = this.el.style;
|
|
2359
|
-
style.removeProperty('--ion-safe-area-top');
|
|
2360
|
-
style.removeProperty('--ion-safe-area-bottom');
|
|
2361
|
-
style.removeProperty('--ion-safe-area-left');
|
|
2362
|
-
style.removeProperty('--ion-safe-area-right');
|
|
2375
|
+
this.resetSafeAreaState();
|
|
2363
2376
|
unlock();
|
|
2364
2377
|
return dismissed;
|
|
2365
2378
|
}
|
|
@@ -2609,20 +2622,20 @@ const Modal = class {
|
|
|
2609
2622
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
2610
2623
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
2611
2624
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
2612
|
-
return (h(Host, Object.assign({ key: '
|
|
2625
|
+
return (h(Host, Object.assign({ key: '44022099fcaf047b97d1c2cb45b9b51c930e707c', "no-router": true,
|
|
2613
2626
|
// Allow the modal to be navigable when the handle is focusable
|
|
2614
2627
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
2615
2628
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
2616
|
-
}, 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: '
|
|
2629
|
+
}, 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: 'ddd7e4f6eef51ac1f62ac70e0af10fb01e707f07', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '58620980e3e4ec273c6787bde026e1c010b904b7', class: "modal-shadow" }), h("div", Object.assign({ key: '3fb7f6218644ba898fc504467775593eb89426a0',
|
|
2617
2630
|
/*
|
|
2618
2631
|
role and aria-modal must be used on the
|
|
2619
2632
|
same element. They must also be set inside the
|
|
2620
2633
|
shadow DOM otherwise ion-button will not be highlighted
|
|
2621
2634
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
2622
2635
|
*/
|
|
2623
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '
|
|
2636
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '9745cd590fdaa9d023a14b487ec2c87ddbafd7f7', class: "modal-handle",
|
|
2624
2637
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
2625
|
-
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: '
|
|
2638
|
+
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: 'b9a8b5d2d3d3c9b06f99179f496c9f08907d0bad', onSlotchange: this.onSlotChange }))));
|
|
2626
2639
|
}
|
|
2627
2640
|
get el() { return getElement(this); }
|
|
2628
2641
|
static get watchers() { return {
|
|
@@ -946,7 +946,7 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
946
946
|
};
|
|
947
947
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
|
|
948
948
|
const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
|
|
949
|
-
const { originX, originY, top, left, bottom, checkSafeAreaTop, checkSafeAreaBottom } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
|
|
949
|
+
const { originX, originY, top, left, bottom, checkSafeAreaTop, checkSafeAreaBottom, checkSafeAreaLeft, checkSafeAreaRight, } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
|
|
950
950
|
/**
|
|
951
951
|
* Safe area CSS variable adjustments.
|
|
952
952
|
* When the popover is positioned near an edge, we add the corresponding
|
|
@@ -955,14 +955,23 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
955
955
|
*/
|
|
956
956
|
const safeAreaTop = ' + var(--ion-safe-area-top, 0)';
|
|
957
957
|
const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0)';
|
|
958
|
+
const safeAreaLeft = ' + var(--ion-safe-area-left, 0)';
|
|
959
|
+
const safeAreaRight = ' - var(--ion-safe-area-right, 0)';
|
|
958
960
|
let topValue = `${top}px`;
|
|
959
961
|
let bottomValue = bottom !== undefined ? `${bottom}px` : undefined;
|
|
962
|
+
let leftValue = `${left}px`;
|
|
960
963
|
if (checkSafeAreaTop) {
|
|
961
964
|
topValue = `${top}px${safeAreaTop}`;
|
|
962
965
|
}
|
|
963
966
|
if (checkSafeAreaBottom && bottomValue !== undefined) {
|
|
964
967
|
bottomValue = `${bottom}px${safeAreaBottom}`;
|
|
965
968
|
}
|
|
969
|
+
if (checkSafeAreaLeft) {
|
|
970
|
+
leftValue = `${left}px${safeAreaLeft}`;
|
|
971
|
+
}
|
|
972
|
+
if (checkSafeAreaRight) {
|
|
973
|
+
leftValue = `${left}px${safeAreaRight}`;
|
|
974
|
+
}
|
|
966
975
|
const baseAnimation = createAnimation();
|
|
967
976
|
const backdropAnimation = createAnimation();
|
|
968
977
|
const wrapperAnimation = createAnimation();
|
|
@@ -980,7 +989,7 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
980
989
|
.addElement(contentEl)
|
|
981
990
|
.beforeStyles({
|
|
982
991
|
top: `calc(${topValue} + var(--offset-y, 0px))`,
|
|
983
|
-
left: `calc(${
|
|
992
|
+
left: `calc(${leftValue} + var(--offset-x, 0px))`,
|
|
984
993
|
'transform-origin': `${originY} ${originX}`,
|
|
985
994
|
})
|
|
986
995
|
.beforeAddWrite(() => {
|