@ionic/core 8.7.17-dev.11767796972.148e4bc4 → 8.7.17-dev.11767895575.16ea7cef
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 +6 -79
- package/components/ion-tab-bar.js +23 -3
- package/components/modal.js +12 -200
- package/components/popover.js +10 -73
- package/dist/cjs/ion-app_8.cjs.entry.js +5 -78
- package/dist/cjs/ion-modal.cjs.entry.js +12 -200
- package/dist/cjs/ion-popover.cjs.entry.js +10 -73
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +23 -3
- package/dist/collection/components/content/content.css +0 -10
- package/dist/collection/components/content/content.js +4 -77
- package/dist/collection/components/modal/gestures/sheet.js +1 -3
- package/dist/collection/components/modal/gestures/swipe-to-close.js +1 -3
- package/dist/collection/components/modal/modal.ios.css +4 -0
- package/dist/collection/components/modal/modal.js +8 -192
- package/dist/collection/components/modal/modal.md.css +4 -0
- package/dist/collection/components/popover/animations/ios.enter.js +5 -21
- package/dist/collection/components/popover/animations/md.enter.js +4 -20
- package/dist/collection/components/popover/utils.js +1 -32
- package/dist/collection/components/tab-bar/tab-bar.js +23 -3
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +6 -79
- package/dist/esm/ion-modal.entry.js +12 -200
- package/dist/esm/ion-popover.entry.js +10 -73
- package/dist/esm/ion-tab-bar_2.entry.js +23 -3
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-172a579f.entry.js +4 -0
- package/dist/ionic/p-732b2fd6.entry.js +4 -0
- package/dist/ionic/p-91840a80.entry.js +4 -0
- package/dist/ionic/p-f9061316.entry.js +4 -0
- package/dist/types/components/content/content.d.ts +0 -24
- package/dist/types/components/modal/gestures/sheet.d.ts +1 -1
- package/dist/types/components/modal/gestures/swipe-to-close.d.ts +1 -1
- package/dist/types/components/modal/modal.d.ts +0 -39
- package/dist/types/components/popover/utils.d.ts +0 -2
- package/dist/types/components/tab-bar/tab-bar.d.ts +1 -0
- package/hydrate/index.js +50 -353
- package/hydrate/index.mjs +50 -353
- package/package.json +1 -1
- package/dist/ionic/p-3830217a.entry.js +0 -4
- package/dist/ionic/p-7268efa5.entry.js +0 -4
- package/dist/ionic/p-a4827773.entry.js +0 -4
- package/dist/ionic/p-cecd141b.entry.js +0 -4
package/components/content.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { proxyCustomElement, HTMLElement, createEvent,
|
|
4
|
+
import { proxyCustomElement, HTMLElement, createEvent, Build, readTask, forceUpdate, h, Host } from '@stencil/core/internal/client';
|
|
5
5
|
import { i as inheritAriaAttributes, k as hasLazyBuild, c as componentOnReady } from './helpers.js';
|
|
6
6
|
import { b as getIonMode, a as isPlatform } from './ionic-global.js';
|
|
7
7
|
import { i as isRTL } from './dir.js';
|
|
8
8
|
import { c as createColorClasses, h as hostContext } from './theme.js';
|
|
9
9
|
|
|
10
|
-
const contentCss = ":host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:\"\"}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}
|
|
10
|
+
const contentCss = ":host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:\"\"}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}";
|
|
11
11
|
|
|
12
12
|
const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLElement {
|
|
13
13
|
constructor(registerHost) {
|
|
@@ -28,12 +28,6 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
28
28
|
this.isMainContent = true;
|
|
29
29
|
this.resizeTimeout = null;
|
|
30
30
|
this.inheritedAttributes = {};
|
|
31
|
-
/**
|
|
32
|
-
* Track whether this content has sibling header/footer elements.
|
|
33
|
-
* When absent, we need to apply safe-area padding directly.
|
|
34
|
-
*/
|
|
35
|
-
this.hasHeader = false;
|
|
36
|
-
this.hasFooter = false;
|
|
37
31
|
this.tabsElement = null;
|
|
38
32
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
39
33
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -89,8 +83,6 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
89
83
|
}
|
|
90
84
|
connectedCallback() {
|
|
91
85
|
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
92
|
-
// Detect sibling header/footer for safe-area handling
|
|
93
|
-
this.detectSiblingElements();
|
|
94
86
|
/**
|
|
95
87
|
* The fullscreen content offsets need to be
|
|
96
88
|
* computed after the tab bar has loaded. Since
|
|
@@ -126,71 +118,8 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
126
118
|
}
|
|
127
119
|
}
|
|
128
120
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Detects sibling ion-header and ion-footer elements and sets up
|
|
131
|
-
* a mutation observer to handle dynamic changes (e.g., conditional rendering).
|
|
132
|
-
*/
|
|
133
|
-
detectSiblingElements() {
|
|
134
|
-
this.updateSiblingDetection();
|
|
135
|
-
// Watch for dynamic header/footer changes (common in React conditional rendering)
|
|
136
|
-
const parent = this.el.parentElement;
|
|
137
|
-
if (parent && !this.parentMutationObserver) {
|
|
138
|
-
this.parentMutationObserver = new MutationObserver(() => {
|
|
139
|
-
this.updateSiblingDetection();
|
|
140
|
-
forceUpdate(this);
|
|
141
|
-
});
|
|
142
|
-
this.parentMutationObserver.observe(parent, { childList: true });
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Updates hasHeader/hasFooter based on current DOM state.
|
|
147
|
-
* Checks both direct siblings and elements wrapped in custom components
|
|
148
|
-
* (e.g., <my-header><ion-header>...</ion-header></my-header>).
|
|
149
|
-
*/
|
|
150
|
-
updateSiblingDetection() {
|
|
151
|
-
const parent = this.el.parentElement;
|
|
152
|
-
if (parent) {
|
|
153
|
-
// First check for direct ion-header/ion-footer siblings
|
|
154
|
-
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
155
|
-
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
156
|
-
// If not found, check if any sibling contains them (wrapped components)
|
|
157
|
-
if (!this.hasHeader) {
|
|
158
|
-
this.hasHeader = this.siblingContainsElement(parent, 'ion-header');
|
|
159
|
-
}
|
|
160
|
-
if (!this.hasFooter) {
|
|
161
|
-
this.hasFooter = this.siblingContainsElement(parent, 'ion-footer');
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
165
|
-
if (!this.hasFooter) {
|
|
166
|
-
const tabs = this.el.closest('ion-tabs');
|
|
167
|
-
if (tabs) {
|
|
168
|
-
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Checks if any sibling element of ion-content contains the specified element.
|
|
174
|
-
* Only searches one level deep to avoid finding elements in nested pages.
|
|
175
|
-
*/
|
|
176
|
-
siblingContainsElement(parent, tagName) {
|
|
177
|
-
for (const sibling of parent.children) {
|
|
178
|
-
// Skip ion-content itself
|
|
179
|
-
if (sibling === this.el)
|
|
180
|
-
continue;
|
|
181
|
-
// Check if this sibling contains the target element as an immediate child
|
|
182
|
-
if (sibling.querySelector(`:scope > ${tagName}`) !== null) {
|
|
183
|
-
return true;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
121
|
disconnectedCallback() {
|
|
189
|
-
var _a;
|
|
190
122
|
this.onScrollEnd();
|
|
191
|
-
// Clean up mutation observer to prevent memory leaks
|
|
192
|
-
(_a = this.parentMutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
193
|
-
this.parentMutationObserver = undefined;
|
|
194
123
|
if (hasLazyBuild(this.el)) {
|
|
195
124
|
/**
|
|
196
125
|
* The event listener and tabs caches need to
|
|
@@ -437,28 +366,26 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
437
366
|
}
|
|
438
367
|
}
|
|
439
368
|
render() {
|
|
440
|
-
const { fixedSlotPlacement,
|
|
369
|
+
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
441
370
|
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
|
442
371
|
const mode = getIonMode(this);
|
|
443
372
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
444
373
|
const transitionShadow = mode === 'ios';
|
|
445
374
|
this.resize();
|
|
446
|
-
return (h(Host, Object.assign({ key: '
|
|
375
|
+
return (h(Host, Object.assign({ key: 'cd8781f848d8dc926fe66f43d43c49564425a507', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
447
376
|
[mode]: true,
|
|
448
377
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
449
378
|
overscroll: forceOverscroll,
|
|
450
379
|
[`content-${rtl}`]: true,
|
|
451
|
-
'safe-area-top': isMainContent && !hasHeader,
|
|
452
|
-
'safe-area-bottom': isMainContent && !hasFooter,
|
|
453
380
|
}), style: {
|
|
454
381
|
'--offset-top': `${this.cTop}px`,
|
|
455
382
|
'--offset-bottom': `${this.cBottom}px`,
|
|
456
|
-
} }, inheritedAttributes), h("div", { key: '
|
|
383
|
+
} }, inheritedAttributes), h("div", { key: '95b112d7cae30f22ef778ceffb88edb4d941c170', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: '2fdfcbc39fb66f11b6191911f2941c660f4c12e5', class: {
|
|
457
384
|
'inner-scroll': true,
|
|
458
385
|
'scroll-x': scrollX,
|
|
459
386
|
'scroll-y': scrollY,
|
|
460
387
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
461
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '
|
|
388
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '6bc77e0054ec8e21635a7f2abfe0ca46e0962e03' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
|
|
462
389
|
}
|
|
463
390
|
get el() { return this; }
|
|
464
391
|
static get style() { return contentCss; }
|
|
@@ -20,6 +20,7 @@ const TabBar = /*@__PURE__*/ proxyCustomElement(class TabBar extends HTMLElement
|
|
|
20
20
|
this.ionTabBarChanged = createEvent(this, "ionTabBarChanged", 7);
|
|
21
21
|
this.ionTabBarLoaded = createEvent(this, "ionTabBarLoaded", 7);
|
|
22
22
|
this.keyboardCtrl = null;
|
|
23
|
+
this.keyboardCtrlPromise = null;
|
|
23
24
|
this.didLoad = false;
|
|
24
25
|
this.keyboardVisible = false;
|
|
25
26
|
/**
|
|
@@ -55,7 +56,7 @@ const TabBar = /*@__PURE__*/ proxyCustomElement(class TabBar extends HTMLElement
|
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
async connectedCallback() {
|
|
58
|
-
|
|
59
|
+
const promise = createKeyboardController(async (keyboardOpen, waitForResize) => {
|
|
59
60
|
/**
|
|
60
61
|
* If the keyboard is hiding, then we need to wait
|
|
61
62
|
* for the webview to resize. Otherwise, the tab bar
|
|
@@ -66,21 +67,40 @@ const TabBar = /*@__PURE__*/ proxyCustomElement(class TabBar extends HTMLElement
|
|
|
66
67
|
}
|
|
67
68
|
this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
|
|
68
69
|
});
|
|
70
|
+
this.keyboardCtrlPromise = promise;
|
|
71
|
+
const keyboardCtrl = await promise;
|
|
72
|
+
/**
|
|
73
|
+
* Only assign if this is still the current promise.
|
|
74
|
+
* Otherwise, a new connectedCallback has started or
|
|
75
|
+
* disconnectedCallback was called, so destroy this instance.
|
|
76
|
+
*/
|
|
77
|
+
if (this.keyboardCtrlPromise === promise) {
|
|
78
|
+
this.keyboardCtrl = keyboardCtrl;
|
|
79
|
+
this.keyboardCtrlPromise = null;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
keyboardCtrl.destroy();
|
|
83
|
+
}
|
|
69
84
|
}
|
|
70
85
|
disconnectedCallback() {
|
|
86
|
+
if (this.keyboardCtrlPromise) {
|
|
87
|
+
this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
|
|
88
|
+
this.keyboardCtrlPromise = null;
|
|
89
|
+
}
|
|
71
90
|
if (this.keyboardCtrl) {
|
|
72
91
|
this.keyboardCtrl.destroy();
|
|
92
|
+
this.keyboardCtrl = null;
|
|
73
93
|
}
|
|
74
94
|
}
|
|
75
95
|
render() {
|
|
76
96
|
const { color, translucent, keyboardVisible } = this;
|
|
77
97
|
const mode = getIonMode(this);
|
|
78
98
|
const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
|
|
79
|
-
return (h(Host, { key: '
|
|
99
|
+
return (h(Host, { key: '9daf4e2acaff6e3ce3878cf9dd5109fb1afbbebe', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: createColorClasses(color, {
|
|
80
100
|
[mode]: true,
|
|
81
101
|
'tab-bar-translucent': translucent,
|
|
82
102
|
'tab-bar-hidden': shouldHide,
|
|
83
|
-
}) }, h("slot", { key: '
|
|
103
|
+
}) }, h("slot", { key: '1d15aa2da8501e8e7eff11ad4a491478be845c43' })));
|
|
84
104
|
}
|
|
85
105
|
get el() { return this; }
|
|
86
106
|
static get watchers() { return {
|
package/components/modal.js
CHANGED
|
@@ -246,7 +246,7 @@ const calculateSpringStep = (t) => {
|
|
|
246
246
|
const SwipeToCloseDefaults = {
|
|
247
247
|
MIN_PRESENTING_SCALE: 0.915,
|
|
248
248
|
};
|
|
249
|
-
const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss
|
|
249
|
+
const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
|
|
250
250
|
/**
|
|
251
251
|
* The step value at which a card modal
|
|
252
252
|
* is eligible for dismissing via gesture.
|
|
@@ -403,8 +403,6 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onG
|
|
|
403
403
|
const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
|
|
404
404
|
const clampedStep = clamp(0.0001, processedStep, maxStep);
|
|
405
405
|
animation.progressStep(clampedStep);
|
|
406
|
-
// Notify modal of position change for safe-area updates
|
|
407
|
-
onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
|
|
408
406
|
/**
|
|
409
407
|
* When swiping down half way, the status bar style
|
|
410
408
|
* should be reset to its default value.
|
|
@@ -948,7 +946,7 @@ const mdLeaveAnimation = (baseEl, opts) => {
|
|
|
948
946
|
return baseAnimation;
|
|
949
947
|
};
|
|
950
948
|
|
|
951
|
-
const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange
|
|
949
|
+
const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
|
|
952
950
|
// Defaults for the sheet swipe animation
|
|
953
951
|
const defaultBackdrop = [
|
|
954
952
|
{ offset: 0, opacity: 'var(--backdrop-opacity)' },
|
|
@@ -1279,8 +1277,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1279
1277
|
: step;
|
|
1280
1278
|
offset = clamp(0.0001, processedStep, maxStep);
|
|
1281
1279
|
animation.progressStep(offset);
|
|
1282
|
-
// Notify modal of position change for safe-area updates
|
|
1283
|
-
onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
|
|
1284
1280
|
};
|
|
1285
1281
|
const onEnd = (detail) => {
|
|
1286
1282
|
/**
|
|
@@ -1475,9 +1471,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1475
1471
|
};
|
|
1476
1472
|
};
|
|
1477
1473
|
|
|
1478
|
-
const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
|
|
1474
|
+
const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
|
|
1479
1475
|
|
|
1480
|
-
const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
|
|
1476
|
+
const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
|
|
1481
1477
|
|
|
1482
1478
|
const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
1483
1479
|
constructor(registerHost) {
|
|
@@ -1504,10 +1500,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
1504
1500
|
this.inline = false;
|
|
1505
1501
|
// Whether or not modal is being dismissed via gesture
|
|
1506
1502
|
this.gestureAnimationDismissing = false;
|
|
1507
|
-
// Whether to skip coordinate-based safe-area detection (for fullscreen phone modals)
|
|
1508
|
-
this.skipSafeAreaCoordinateDetection = false;
|
|
1509
|
-
// Track previous safe-area state to avoid redundant DOM writes
|
|
1510
|
-
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
1511
1503
|
this.presented = false;
|
|
1512
1504
|
/** @internal */
|
|
1513
1505
|
this.hasController = false;
|
|
@@ -1698,10 +1690,7 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
1698
1690
|
}
|
|
1699
1691
|
}
|
|
1700
1692
|
onWindowResize() {
|
|
1701
|
-
//
|
|
1702
|
-
this.cachedSafeAreas = undefined;
|
|
1703
|
-
this.updateSafeAreaOverrides();
|
|
1704
|
-
// Only handle view transition for iOS card modals when no custom animations are provided
|
|
1693
|
+
// Only handle resize for iOS card modals when no custom animations are provided
|
|
1705
1694
|
if (getIonMode(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
|
|
1706
1695
|
return;
|
|
1707
1696
|
}
|
|
@@ -1883,8 +1872,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
1883
1872
|
else if (!this.keepContentsMounted) {
|
|
1884
1873
|
await waitForMount();
|
|
1885
1874
|
}
|
|
1886
|
-
// Predict safe-area needs based on modal configuration to avoid visual snap
|
|
1887
|
-
this.setInitialSafeAreaOverrides(presentingElement);
|
|
1888
1875
|
writeTask(() => this.el.classList.add('show-modal'));
|
|
1889
1876
|
const hasCardModal = presentingElement !== undefined;
|
|
1890
1877
|
/**
|
|
@@ -1946,8 +1933,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
1946
1933
|
else if (hasCardModal) {
|
|
1947
1934
|
this.initSwipeToClose();
|
|
1948
1935
|
}
|
|
1949
|
-
// Now that animation is complete, update safe-area based on actual position
|
|
1950
|
-
this.updateSafeAreaOverrides();
|
|
1951
1936
|
// Initialize view transition listener for iOS card modals
|
|
1952
1937
|
this.initViewTransitionListener();
|
|
1953
1938
|
// Initialize parent removal observer
|
|
@@ -1999,7 +1984,7 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
1999
1984
|
await this.dismiss(undefined, GESTURE);
|
|
2000
1985
|
this.gestureAnimationDismissing = false;
|
|
2001
1986
|
});
|
|
2002
|
-
}
|
|
1987
|
+
});
|
|
2003
1988
|
this.gesture.enable(true);
|
|
2004
1989
|
}
|
|
2005
1990
|
initSheetGesture() {
|
|
@@ -2020,8 +2005,7 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
2020
2005
|
this.currentBreakpoint = breakpoint;
|
|
2021
2006
|
this.ionBreakpointDidChange.emit({ breakpoint });
|
|
2022
2007
|
}
|
|
2023
|
-
|
|
2024
|
-
}, () => this.updateSafeAreaOverrides());
|
|
2008
|
+
});
|
|
2025
2009
|
this.gesture = gesture;
|
|
2026
2010
|
this.moveSheetToBreakpoint = moveSheetToBreakpoint;
|
|
2027
2011
|
this.gesture.enable(true);
|
|
@@ -2099,161 +2083,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
2099
2083
|
// Clear the cached reference
|
|
2100
2084
|
this.cachedPageParent = undefined;
|
|
2101
2085
|
}
|
|
2102
|
-
/**
|
|
2103
|
-
* Sets initial safe-area overrides based on modal configuration before
|
|
2104
|
-
* the modal becomes visible. This predicts whether the modal will touch
|
|
2105
|
-
* screen edges to avoid a visual snap after animation completes.
|
|
2106
|
-
*/
|
|
2107
|
-
setInitialSafeAreaOverrides(presentingElement) {
|
|
2108
|
-
const style = this.el.style;
|
|
2109
|
-
const mode = getIonMode(this);
|
|
2110
|
-
const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
|
|
2111
|
-
// Card modals only exist in iOS mode - in MD mode, presentingElement is ignored
|
|
2112
|
-
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
2113
|
-
const isTablet = window.innerWidth >= 768;
|
|
2114
|
-
// Sheet modals always touch bottom edge, never top/left/right
|
|
2115
|
-
if (isSheetModal) {
|
|
2116
|
-
style.setProperty('--ion-safe-area-top', '0px');
|
|
2117
|
-
style.setProperty('--ion-safe-area-left', '0px');
|
|
2118
|
-
style.setProperty('--ion-safe-area-right', '0px');
|
|
2119
|
-
return;
|
|
2120
|
-
}
|
|
2121
|
-
// Card modals have rounded top corners
|
|
2122
|
-
if (isCardModal) {
|
|
2123
|
-
style.setProperty('--ion-safe-area-top', '0px');
|
|
2124
|
-
if (isTablet) {
|
|
2125
|
-
// On tablets, card modals are inset from all edges
|
|
2126
|
-
this.zeroAllSafeAreas();
|
|
2127
|
-
}
|
|
2128
|
-
else {
|
|
2129
|
-
// On phones, card modals still extend to the bottom edge
|
|
2130
|
-
style.setProperty('--ion-safe-area-left', '0px');
|
|
2131
|
-
style.setProperty('--ion-safe-area-right', '0px');
|
|
2132
|
-
this.applyFullscreenSafeArea();
|
|
2133
|
-
}
|
|
2134
|
-
return;
|
|
2135
|
-
}
|
|
2136
|
-
// Phone-sized fullscreen modals inherit safe areas and use wrapper padding
|
|
2137
|
-
if (!isTablet) {
|
|
2138
|
-
this.applyFullscreenSafeArea();
|
|
2139
|
-
return;
|
|
2140
|
-
}
|
|
2141
|
-
// Check if tablet modal is fullscreen via CSS custom properties
|
|
2142
|
-
const computedStyle = getComputedStyle(this.el);
|
|
2143
|
-
const width = computedStyle.getPropertyValue('--width').trim();
|
|
2144
|
-
const height = computedStyle.getPropertyValue('--height').trim();
|
|
2145
|
-
const isFullscreen = width === '100%' && height === '100%';
|
|
2146
|
-
if (isFullscreen) {
|
|
2147
|
-
this.applyFullscreenSafeArea();
|
|
2148
|
-
}
|
|
2149
|
-
else {
|
|
2150
|
-
// Centered dialog doesn't touch edges
|
|
2151
|
-
this.zeroAllSafeAreas();
|
|
2152
|
-
}
|
|
2153
|
-
}
|
|
2154
|
-
/**
|
|
2155
|
-
* Applies safe-area handling for fullscreen modals.
|
|
2156
|
-
* Adds wrapper padding when no footer is present to prevent
|
|
2157
|
-
* content from overlapping system navigation areas.
|
|
2158
|
-
*/
|
|
2159
|
-
applyFullscreenSafeArea() {
|
|
2160
|
-
this.skipSafeAreaCoordinateDetection = true;
|
|
2161
|
-
this.updateFooterPadding();
|
|
2162
|
-
// Watch for dynamic footer additions/removals (e.g., async data loading)
|
|
2163
|
-
if (!this.footerObserver) {
|
|
2164
|
-
this.footerObserver = new MutationObserver(() => this.updateFooterPadding());
|
|
2165
|
-
this.footerObserver.observe(this.el, { childList: true, subtree: true });
|
|
2166
|
-
}
|
|
2167
|
-
}
|
|
2168
|
-
/**
|
|
2169
|
-
* Updates wrapper padding based on footer presence.
|
|
2170
|
-
* Called initially and when footer is dynamically added/removed.
|
|
2171
|
-
*/
|
|
2172
|
-
updateFooterPadding() {
|
|
2173
|
-
if (!this.wrapperEl)
|
|
2174
|
-
return;
|
|
2175
|
-
const hasFooter = this.el.querySelector('ion-footer') !== null;
|
|
2176
|
-
if (hasFooter) {
|
|
2177
|
-
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
2178
|
-
this.wrapperEl.style.removeProperty('box-sizing');
|
|
2179
|
-
}
|
|
2180
|
-
else {
|
|
2181
|
-
this.wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
|
|
2182
|
-
this.wrapperEl.style.setProperty('box-sizing', 'border-box');
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
/**
|
|
2186
|
-
* Sets all safe-area CSS variables to 0px for modals that
|
|
2187
|
-
* don't touch screen edges.
|
|
2188
|
-
*/
|
|
2189
|
-
zeroAllSafeAreas() {
|
|
2190
|
-
const style = this.el.style;
|
|
2191
|
-
style.setProperty('--ion-safe-area-top', '0px');
|
|
2192
|
-
style.setProperty('--ion-safe-area-bottom', '0px');
|
|
2193
|
-
style.setProperty('--ion-safe-area-left', '0px');
|
|
2194
|
-
style.setProperty('--ion-safe-area-right', '0px');
|
|
2195
|
-
}
|
|
2196
|
-
/**
|
|
2197
|
-
* Gets the root safe-area values from the document element.
|
|
2198
|
-
* Uses cached values during gestures to avoid getComputedStyle calls.
|
|
2199
|
-
*/
|
|
2200
|
-
getSafeAreaValues() {
|
|
2201
|
-
if (!this.cachedSafeAreas) {
|
|
2202
|
-
const rootStyle = getComputedStyle(document.documentElement);
|
|
2203
|
-
this.cachedSafeAreas = {
|
|
2204
|
-
top: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-top')) || 0,
|
|
2205
|
-
bottom: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-bottom')) || 0,
|
|
2206
|
-
left: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-left')) || 0,
|
|
2207
|
-
right: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-right')) || 0,
|
|
2208
|
-
};
|
|
2209
|
-
}
|
|
2210
|
-
return this.cachedSafeAreas;
|
|
2211
|
-
}
|
|
2212
|
-
/**
|
|
2213
|
-
* Updates safe-area CSS variable overrides based on whether the modal
|
|
2214
|
-
* extends into each safe-area region. Called after animation
|
|
2215
|
-
* and during gestures to handle dynamic position changes.
|
|
2216
|
-
*
|
|
2217
|
-
* Optimized to avoid redundant DOM writes by tracking previous state.
|
|
2218
|
-
*/
|
|
2219
|
-
updateSafeAreaOverrides() {
|
|
2220
|
-
if (this.skipSafeAreaCoordinateDetection) {
|
|
2221
|
-
return;
|
|
2222
|
-
}
|
|
2223
|
-
const wrapper = this.wrapperEl;
|
|
2224
|
-
if (!wrapper) {
|
|
2225
|
-
return;
|
|
2226
|
-
}
|
|
2227
|
-
const rect = wrapper.getBoundingClientRect();
|
|
2228
|
-
const safeAreas = this.getSafeAreaValues();
|
|
2229
|
-
const extendsIntoTop = rect.top < safeAreas.top;
|
|
2230
|
-
const extendsIntoBottom = rect.bottom > window.innerHeight - safeAreas.bottom;
|
|
2231
|
-
const extendsIntoLeft = rect.left < safeAreas.left;
|
|
2232
|
-
const extendsIntoRight = rect.right > window.innerWidth - safeAreas.right;
|
|
2233
|
-
// Only update DOM when state actually changes
|
|
2234
|
-
const prev = this.prevSafeAreaState;
|
|
2235
|
-
const style = this.el.style;
|
|
2236
|
-
if (extendsIntoTop !== prev.top) {
|
|
2237
|
-
extendsIntoTop ? style.removeProperty('--ion-safe-area-top') : style.setProperty('--ion-safe-area-top', '0px');
|
|
2238
|
-
prev.top = extendsIntoTop;
|
|
2239
|
-
}
|
|
2240
|
-
if (extendsIntoBottom !== prev.bottom) {
|
|
2241
|
-
extendsIntoBottom
|
|
2242
|
-
? style.removeProperty('--ion-safe-area-bottom')
|
|
2243
|
-
: style.setProperty('--ion-safe-area-bottom', '0px');
|
|
2244
|
-
prev.bottom = extendsIntoBottom;
|
|
2245
|
-
}
|
|
2246
|
-
if (extendsIntoLeft !== prev.left) {
|
|
2247
|
-
extendsIntoLeft ? style.removeProperty('--ion-safe-area-left') : style.setProperty('--ion-safe-area-left', '0px');
|
|
2248
|
-
prev.left = extendsIntoLeft;
|
|
2249
|
-
}
|
|
2250
|
-
if (extendsIntoRight !== prev.right) {
|
|
2251
|
-
extendsIntoRight
|
|
2252
|
-
? style.removeProperty('--ion-safe-area-right')
|
|
2253
|
-
: style.setProperty('--ion-safe-area-right', '0px');
|
|
2254
|
-
prev.right = extendsIntoRight;
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2257
2086
|
sheetOnDismiss() {
|
|
2258
2087
|
/**
|
|
2259
2088
|
* While the gesture animation is finishing
|
|
@@ -2284,7 +2113,7 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
2284
2113
|
* For example, `cancel` or `backdrop`.
|
|
2285
2114
|
*/
|
|
2286
2115
|
async dismiss(data, role) {
|
|
2287
|
-
var _a
|
|
2116
|
+
var _a;
|
|
2288
2117
|
if (this.gestureAnimationDismissing && role !== GESTURE) {
|
|
2289
2118
|
return false;
|
|
2290
2119
|
}
|
|
@@ -2346,23 +2175,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
2346
2175
|
}
|
|
2347
2176
|
this.currentBreakpoint = undefined;
|
|
2348
2177
|
this.animation = undefined;
|
|
2349
|
-
// Reset safe-area state for potential re-presentation
|
|
2350
|
-
this.skipSafeAreaCoordinateDetection = false;
|
|
2351
|
-
this.cachedSafeAreas = undefined;
|
|
2352
|
-
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
2353
|
-
(_b = this.footerObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
2354
|
-
this.footerObserver = undefined;
|
|
2355
|
-
// Clear styles that may have been set for safe-area handling
|
|
2356
|
-
if (this.wrapperEl) {
|
|
2357
|
-
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
2358
|
-
this.wrapperEl.style.removeProperty('box-sizing');
|
|
2359
|
-
}
|
|
2360
|
-
// Clear safe-area CSS variable overrides
|
|
2361
|
-
const style = this.el.style;
|
|
2362
|
-
style.removeProperty('--ion-safe-area-top');
|
|
2363
|
-
style.removeProperty('--ion-safe-area-bottom');
|
|
2364
|
-
style.removeProperty('--ion-safe-area-left');
|
|
2365
|
-
style.removeProperty('--ion-safe-area-right');
|
|
2366
2178
|
unlock();
|
|
2367
2179
|
return dismissed;
|
|
2368
2180
|
}
|
|
@@ -2612,20 +2424,20 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
|
|
|
2612
2424
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
2613
2425
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
2614
2426
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
2615
|
-
return (h(Host, Object.assign({ key: '
|
|
2427
|
+
return (h(Host, Object.assign({ key: '87328006ea6c75ebc518ace300438492a567223e', "no-router": true,
|
|
2616
2428
|
// Allow the modal to be navigable when the handle is focusable
|
|
2617
2429
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
2618
2430
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
2619
|
-
}, 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: '
|
|
2431
|
+
}, 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: 'ee94ff8e09b691dd4ad4e4db1720f06bc3c5a469', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'bffd69b4635c22d9f249725bd952c1e93d5615c7', class: "modal-shadow" }), h("div", Object.assign({ key: '1d394d3c68916e464ff1fbf5242419f4a3d3cca1',
|
|
2620
2432
|
/*
|
|
2621
2433
|
role and aria-modal must be used on the
|
|
2622
2434
|
same element. They must also be set inside the
|
|
2623
2435
|
shadow DOM otherwise ion-button will not be highlighted
|
|
2624
2436
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
2625
2437
|
*/
|
|
2626
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '
|
|
2438
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '2dcf58792018e557e0c323baad2d672bc99c0bb1', class: "modal-handle",
|
|
2627
2439
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
2628
|
-
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: '
|
|
2440
|
+
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: '44164b1e8710c3895400ad9f44ecd99873874ad5', onSlotchange: this.onSlotChange }))));
|
|
2629
2441
|
}
|
|
2630
2442
|
get el() { return this; }
|
|
2631
2443
|
static get watchers() { return {
|