@ionic/core 8.7.17-dev.11767641184.14a165bc → 8.7.17-dev.11767717752.14fe98a4
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 +34 -5
- package/components/popover.js +13 -0
- package/dist/cjs/ion-app_8.cjs.entry.js +34 -5
- package/dist/cjs/ion-popover.cjs.entry.js +13 -0
- package/dist/collection/components/content/content.css +10 -0
- package/dist/collection/components/content/content.js +33 -4
- package/dist/collection/components/popover/utils.js +13 -0
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +34 -5
- package/dist/esm/ion-popover.entry.js +13 -0
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-34cdcd15.entry.js +4 -0
- package/dist/ionic/p-a4827773.entry.js +4 -0
- package/dist/types/components/content/content.d.ts +11 -0
- package/hydrate/index.js +47 -5
- package/hydrate/index.mjs +47 -5
- package/package.json +1 -1
- package/dist/ionic/p-301ad219.entry.js +0 -4
- package/dist/ionic/p-732b2fd6.entry.js +0 -4
package/components/content.js
CHANGED
|
@@ -7,7 +7,7 @@ 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)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}";
|
|
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)}:host(.safe-area-top) #background-content,:host(.safe-area-top) .inner-scroll{top:var(--ion-safe-area-top, 0px)}:host(.safe-area-bottom) #background-content,:host(.safe-area-bottom) .inner-scroll{bottom:var(--ion-safe-area-bottom, 0px)}::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,6 +28,12 @@ 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;
|
|
31
37
|
this.tabsElement = null;
|
|
32
38
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
33
39
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -83,6 +89,8 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
83
89
|
}
|
|
84
90
|
connectedCallback() {
|
|
85
91
|
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
92
|
+
// Detect sibling header/footer for safe-area handling
|
|
93
|
+
this.detectSiblingElements();
|
|
86
94
|
/**
|
|
87
95
|
* The fullscreen content offsets need to be
|
|
88
96
|
* computed after the tab bar has loaded. Since
|
|
@@ -118,6 +126,25 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Detects sibling ion-header and ion-footer elements.
|
|
131
|
+
* When these are absent, content needs to handle safe-area padding directly.
|
|
132
|
+
*/
|
|
133
|
+
detectSiblingElements() {
|
|
134
|
+
// Check parent element for sibling header/footer.
|
|
135
|
+
const parent = this.el.parentElement;
|
|
136
|
+
if (parent) {
|
|
137
|
+
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
138
|
+
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
139
|
+
}
|
|
140
|
+
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
141
|
+
if (!this.hasFooter) {
|
|
142
|
+
const tabs = this.el.closest('ion-tabs');
|
|
143
|
+
if (tabs) {
|
|
144
|
+
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
121
148
|
disconnectedCallback() {
|
|
122
149
|
this.onScrollEnd();
|
|
123
150
|
if (hasLazyBuild(this.el)) {
|
|
@@ -366,26 +393,28 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
366
393
|
}
|
|
367
394
|
}
|
|
368
395
|
render() {
|
|
369
|
-
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
396
|
+
const { fixedSlotPlacement, hasFooter, hasHeader, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
370
397
|
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
|
371
398
|
const mode = getIonMode(this);
|
|
372
399
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
373
400
|
const transitionShadow = mode === 'ios';
|
|
374
401
|
this.resize();
|
|
375
|
-
return (h(Host, Object.assign({ key: '
|
|
402
|
+
return (h(Host, Object.assign({ key: '83665c0e35e4f4117709606e47d27ad36e343458', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
376
403
|
[mode]: true,
|
|
377
404
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
378
405
|
overscroll: forceOverscroll,
|
|
379
406
|
[`content-${rtl}`]: true,
|
|
407
|
+
'safe-area-top': isMainContent && !hasHeader,
|
|
408
|
+
'safe-area-bottom': isMainContent && !hasFooter,
|
|
380
409
|
}), style: {
|
|
381
410
|
'--offset-top': `${this.cTop}px`,
|
|
382
411
|
'--offset-bottom': `${this.cBottom}px`,
|
|
383
|
-
} }, inheritedAttributes), h("div", { key: '
|
|
412
|
+
} }, inheritedAttributes), h("div", { key: '75d7cf9315bc8dfb150c3b5bcc356a1f9c793b5a', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: 'f68bc5843c93ed6f32e998b80c5edc553c77a2d7', class: {
|
|
384
413
|
'inner-scroll': true,
|
|
385
414
|
'scroll-x': scrollX,
|
|
386
415
|
'scroll-y': scrollY,
|
|
387
416
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
388
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '
|
|
417
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '8d4b2be00f036f6a24bfa65e6324ca715dd93b60' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
|
|
389
418
|
}
|
|
390
419
|
get el() { return this; }
|
|
391
420
|
static get style() { return contentCss; }
|
package/components/popover.js
CHANGED
|
@@ -730,6 +730,19 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
730
730
|
checkSafeAreaBottom = true;
|
|
731
731
|
}
|
|
732
732
|
}
|
|
733
|
+
/**
|
|
734
|
+
* Final check: If the popover extends into any safe-area region,
|
|
735
|
+
* ensure the corresponding flag is set regardless of side.
|
|
736
|
+
* This handles cases where a side-positioned popover (left/right)
|
|
737
|
+
* still needs bottom safe-area padding because it extends into that region.
|
|
738
|
+
*/
|
|
739
|
+
const popoverBottom = bottom !== undefined ? bodyHeight - bottom : top + contentHeight;
|
|
740
|
+
if (popoverBottom + safeAreaMargin > bodyHeight) {
|
|
741
|
+
checkSafeAreaBottom = true;
|
|
742
|
+
}
|
|
743
|
+
if (top < safeAreaMargin) {
|
|
744
|
+
checkSafeAreaTop = true;
|
|
745
|
+
}
|
|
733
746
|
return {
|
|
734
747
|
top,
|
|
735
748
|
left,
|
|
@@ -154,7 +154,7 @@ Buttons.style = {
|
|
|
154
154
|
md: buttonsMdCss
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
-
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)}";
|
|
157
|
+
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)}:host(.safe-area-top) #background-content,:host(.safe-area-top) .inner-scroll{top:var(--ion-safe-area-top, 0px)}:host(.safe-area-bottom) #background-content,:host(.safe-area-bottom) .inner-scroll{bottom:var(--ion-safe-area-bottom, 0px)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}";
|
|
158
158
|
|
|
159
159
|
const Content = class {
|
|
160
160
|
constructor(hostRef) {
|
|
@@ -171,6 +171,12 @@ const Content = class {
|
|
|
171
171
|
this.isMainContent = true;
|
|
172
172
|
this.resizeTimeout = null;
|
|
173
173
|
this.inheritedAttributes = {};
|
|
174
|
+
/**
|
|
175
|
+
* Track whether this content has sibling header/footer elements.
|
|
176
|
+
* When absent, we need to apply safe-area padding directly.
|
|
177
|
+
*/
|
|
178
|
+
this.hasHeader = false;
|
|
179
|
+
this.hasFooter = false;
|
|
174
180
|
this.tabsElement = null;
|
|
175
181
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
176
182
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -226,6 +232,8 @@ const Content = class {
|
|
|
226
232
|
}
|
|
227
233
|
connectedCallback() {
|
|
228
234
|
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
235
|
+
// Detect sibling header/footer for safe-area handling
|
|
236
|
+
this.detectSiblingElements();
|
|
229
237
|
/**
|
|
230
238
|
* The fullscreen content offsets need to be
|
|
231
239
|
* computed after the tab bar has loaded. Since
|
|
@@ -261,6 +269,25 @@ const Content = class {
|
|
|
261
269
|
}
|
|
262
270
|
}
|
|
263
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Detects sibling ion-header and ion-footer elements.
|
|
274
|
+
* When these are absent, content needs to handle safe-area padding directly.
|
|
275
|
+
*/
|
|
276
|
+
detectSiblingElements() {
|
|
277
|
+
// Check parent element for sibling header/footer.
|
|
278
|
+
const parent = this.el.parentElement;
|
|
279
|
+
if (parent) {
|
|
280
|
+
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
281
|
+
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
282
|
+
}
|
|
283
|
+
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
284
|
+
if (!this.hasFooter) {
|
|
285
|
+
const tabs = this.el.closest('ion-tabs');
|
|
286
|
+
if (tabs) {
|
|
287
|
+
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
264
291
|
disconnectedCallback() {
|
|
265
292
|
this.onScrollEnd();
|
|
266
293
|
if (helpers.hasLazyBuild(this.el)) {
|
|
@@ -509,26 +536,28 @@ const Content = class {
|
|
|
509
536
|
}
|
|
510
537
|
}
|
|
511
538
|
render() {
|
|
512
|
-
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
539
|
+
const { fixedSlotPlacement, hasFooter, hasHeader, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
513
540
|
const rtl = dir.isRTL(el) ? 'rtl' : 'ltr';
|
|
514
541
|
const mode = ionicGlobal.getIonMode(this);
|
|
515
542
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
516
543
|
const transitionShadow = mode === 'ios';
|
|
517
544
|
this.resize();
|
|
518
|
-
return (index.h(index.Host, Object.assign({ key: '
|
|
545
|
+
return (index.h(index.Host, Object.assign({ key: '83665c0e35e4f4117709606e47d27ad36e343458', role: isMainContent ? 'main' : undefined, class: theme.createColorClasses(this.color, {
|
|
519
546
|
[mode]: true,
|
|
520
547
|
'content-sizing': theme.hostContext('ion-popover', this.el),
|
|
521
548
|
overscroll: forceOverscroll,
|
|
522
549
|
[`content-${rtl}`]: true,
|
|
550
|
+
'safe-area-top': isMainContent && !hasHeader,
|
|
551
|
+
'safe-area-bottom': isMainContent && !hasFooter,
|
|
523
552
|
}), style: {
|
|
524
553
|
'--offset-top': `${this.cTop}px`,
|
|
525
554
|
'--offset-bottom': `${this.cBottom}px`,
|
|
526
|
-
} }, inheritedAttributes), index.h("div", { key: '
|
|
555
|
+
} }, inheritedAttributes), index.h("div", { key: '75d7cf9315bc8dfb150c3b5bcc356a1f9c793b5a', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? index.h("slot", { name: "fixed" }) : null, index.h("div", { key: 'f68bc5843c93ed6f32e998b80c5edc553c77a2d7', class: {
|
|
527
556
|
'inner-scroll': true,
|
|
528
557
|
'scroll-x': scrollX,
|
|
529
558
|
'scroll-y': scrollY,
|
|
530
559
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
531
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, index.h("slot", { key: '
|
|
560
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, index.h("slot", { key: '8d4b2be00f036f6a24bfa65e6324ca715dd93b60' })), transitionShadow ? (index.h("div", { class: "transition-effect" }, index.h("div", { class: "transition-cover" }), index.h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? index.h("slot", { name: "fixed" }) : null));
|
|
532
561
|
}
|
|
533
562
|
get el() { return index.getElement(this); }
|
|
534
563
|
};
|
|
@@ -733,6 +733,19 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
733
733
|
checkSafeAreaBottom = true;
|
|
734
734
|
}
|
|
735
735
|
}
|
|
736
|
+
/**
|
|
737
|
+
* Final check: If the popover extends into any safe-area region,
|
|
738
|
+
* ensure the corresponding flag is set regardless of side.
|
|
739
|
+
* This handles cases where a side-positioned popover (left/right)
|
|
740
|
+
* still needs bottom safe-area padding because it extends into that region.
|
|
741
|
+
*/
|
|
742
|
+
const popoverBottom = bottom !== undefined ? bodyHeight - bottom : top + contentHeight;
|
|
743
|
+
if (popoverBottom + safeAreaMargin > bodyHeight) {
|
|
744
|
+
checkSafeAreaBottom = true;
|
|
745
|
+
}
|
|
746
|
+
if (top < safeAreaMargin) {
|
|
747
|
+
checkSafeAreaTop = true;
|
|
748
|
+
}
|
|
736
749
|
return {
|
|
737
750
|
top,
|
|
738
751
|
left,
|
|
@@ -263,6 +263,16 @@
|
|
|
263
263
|
transform: scaleX(-1);
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
:host(.safe-area-top) #background-content,
|
|
267
|
+
:host(.safe-area-top) .inner-scroll {
|
|
268
|
+
top: var(--ion-safe-area-top, 0px);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
:host(.safe-area-bottom) #background-content,
|
|
272
|
+
:host(.safe-area-bottom) .inner-scroll {
|
|
273
|
+
bottom: var(--ion-safe-area-bottom, 0px);
|
|
274
|
+
}
|
|
275
|
+
|
|
266
276
|
::slotted([slot=fixed]) {
|
|
267
277
|
position: absolute;
|
|
268
278
|
/**
|
|
@@ -25,6 +25,12 @@ export class Content {
|
|
|
25
25
|
this.isMainContent = true;
|
|
26
26
|
this.resizeTimeout = null;
|
|
27
27
|
this.inheritedAttributes = {};
|
|
28
|
+
/**
|
|
29
|
+
* Track whether this content has sibling header/footer elements.
|
|
30
|
+
* When absent, we need to apply safe-area padding directly.
|
|
31
|
+
*/
|
|
32
|
+
this.hasHeader = false;
|
|
33
|
+
this.hasFooter = false;
|
|
28
34
|
this.tabsElement = null;
|
|
29
35
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
30
36
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -80,6 +86,8 @@ export class Content {
|
|
|
80
86
|
}
|
|
81
87
|
connectedCallback() {
|
|
82
88
|
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
89
|
+
// Detect sibling header/footer for safe-area handling
|
|
90
|
+
this.detectSiblingElements();
|
|
83
91
|
/**
|
|
84
92
|
* The fullscreen content offsets need to be
|
|
85
93
|
* computed after the tab bar has loaded. Since
|
|
@@ -115,6 +123,25 @@ export class Content {
|
|
|
115
123
|
}
|
|
116
124
|
}
|
|
117
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Detects sibling ion-header and ion-footer elements.
|
|
128
|
+
* When these are absent, content needs to handle safe-area padding directly.
|
|
129
|
+
*/
|
|
130
|
+
detectSiblingElements() {
|
|
131
|
+
// Check parent element for sibling header/footer.
|
|
132
|
+
const parent = this.el.parentElement;
|
|
133
|
+
if (parent) {
|
|
134
|
+
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
135
|
+
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
136
|
+
}
|
|
137
|
+
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
138
|
+
if (!this.hasFooter) {
|
|
139
|
+
const tabs = this.el.closest('ion-tabs');
|
|
140
|
+
if (tabs) {
|
|
141
|
+
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
118
145
|
disconnectedCallback() {
|
|
119
146
|
this.onScrollEnd();
|
|
120
147
|
if (hasLazyBuild(this.el)) {
|
|
@@ -363,26 +390,28 @@ export class Content {
|
|
|
363
390
|
}
|
|
364
391
|
}
|
|
365
392
|
render() {
|
|
366
|
-
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
393
|
+
const { fixedSlotPlacement, hasFooter, hasHeader, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
367
394
|
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
|
368
395
|
const mode = getIonMode(this);
|
|
369
396
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
370
397
|
const transitionShadow = mode === 'ios';
|
|
371
398
|
this.resize();
|
|
372
|
-
return (h(Host, Object.assign({ key: '
|
|
399
|
+
return (h(Host, Object.assign({ key: '83665c0e35e4f4117709606e47d27ad36e343458', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
373
400
|
[mode]: true,
|
|
374
401
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
375
402
|
overscroll: forceOverscroll,
|
|
376
403
|
[`content-${rtl}`]: true,
|
|
404
|
+
'safe-area-top': isMainContent && !hasHeader,
|
|
405
|
+
'safe-area-bottom': isMainContent && !hasFooter,
|
|
377
406
|
}), style: {
|
|
378
407
|
'--offset-top': `${this.cTop}px`,
|
|
379
408
|
'--offset-bottom': `${this.cBottom}px`,
|
|
380
|
-
} }, inheritedAttributes), h("div", { key: '
|
|
409
|
+
} }, inheritedAttributes), h("div", { key: '75d7cf9315bc8dfb150c3b5bcc356a1f9c793b5a', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: 'f68bc5843c93ed6f32e998b80c5edc553c77a2d7', class: {
|
|
381
410
|
'inner-scroll': true,
|
|
382
411
|
'scroll-x': scrollX,
|
|
383
412
|
'scroll-y': scrollY,
|
|
384
413
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
385
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '
|
|
414
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '8d4b2be00f036f6a24bfa65e6324ca715dd93b60' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
|
|
386
415
|
}
|
|
387
416
|
static get is() { return "ion-content"; }
|
|
388
417
|
static get encapsulation() { return "shadow"; }
|
|
@@ -721,6 +721,19 @@ export const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding
|
|
|
721
721
|
checkSafeAreaBottom = true;
|
|
722
722
|
}
|
|
723
723
|
}
|
|
724
|
+
/**
|
|
725
|
+
* Final check: If the popover extends into any safe-area region,
|
|
726
|
+
* ensure the corresponding flag is set regardless of side.
|
|
727
|
+
* This handles cases where a side-positioned popover (left/right)
|
|
728
|
+
* still needs bottom safe-area padding because it extends into that region.
|
|
729
|
+
*/
|
|
730
|
+
const popoverBottom = bottom !== undefined ? bodyHeight - bottom : top + contentHeight;
|
|
731
|
+
if (popoverBottom + safeAreaMargin > bodyHeight) {
|
|
732
|
+
checkSafeAreaBottom = true;
|
|
733
|
+
}
|
|
734
|
+
if (top < safeAreaMargin) {
|
|
735
|
+
checkSafeAreaTop = true;
|
|
736
|
+
}
|
|
724
737
|
return {
|
|
725
738
|
top,
|
|
726
739
|
left,
|
package/dist/docs.json
CHANGED
|
@@ -152,7 +152,7 @@ Buttons.style = {
|
|
|
152
152
|
md: buttonsMdCss
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
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)}";
|
|
155
|
+
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)}:host(.safe-area-top) #background-content,:host(.safe-area-top) .inner-scroll{top:var(--ion-safe-area-top, 0px)}:host(.safe-area-bottom) #background-content,:host(.safe-area-bottom) .inner-scroll{bottom:var(--ion-safe-area-bottom, 0px)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}";
|
|
156
156
|
|
|
157
157
|
const Content = class {
|
|
158
158
|
constructor(hostRef) {
|
|
@@ -169,6 +169,12 @@ const Content = class {
|
|
|
169
169
|
this.isMainContent = true;
|
|
170
170
|
this.resizeTimeout = null;
|
|
171
171
|
this.inheritedAttributes = {};
|
|
172
|
+
/**
|
|
173
|
+
* Track whether this content has sibling header/footer elements.
|
|
174
|
+
* When absent, we need to apply safe-area padding directly.
|
|
175
|
+
*/
|
|
176
|
+
this.hasHeader = false;
|
|
177
|
+
this.hasFooter = false;
|
|
172
178
|
this.tabsElement = null;
|
|
173
179
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
174
180
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -224,6 +230,8 @@ const Content = class {
|
|
|
224
230
|
}
|
|
225
231
|
connectedCallback() {
|
|
226
232
|
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
233
|
+
// Detect sibling header/footer for safe-area handling
|
|
234
|
+
this.detectSiblingElements();
|
|
227
235
|
/**
|
|
228
236
|
* The fullscreen content offsets need to be
|
|
229
237
|
* computed after the tab bar has loaded. Since
|
|
@@ -259,6 +267,25 @@ const Content = class {
|
|
|
259
267
|
}
|
|
260
268
|
}
|
|
261
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Detects sibling ion-header and ion-footer elements.
|
|
272
|
+
* When these are absent, content needs to handle safe-area padding directly.
|
|
273
|
+
*/
|
|
274
|
+
detectSiblingElements() {
|
|
275
|
+
// Check parent element for sibling header/footer.
|
|
276
|
+
const parent = this.el.parentElement;
|
|
277
|
+
if (parent) {
|
|
278
|
+
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
279
|
+
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
280
|
+
}
|
|
281
|
+
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
282
|
+
if (!this.hasFooter) {
|
|
283
|
+
const tabs = this.el.closest('ion-tabs');
|
|
284
|
+
if (tabs) {
|
|
285
|
+
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
262
289
|
disconnectedCallback() {
|
|
263
290
|
this.onScrollEnd();
|
|
264
291
|
if (hasLazyBuild(this.el)) {
|
|
@@ -507,26 +534,28 @@ const Content = class {
|
|
|
507
534
|
}
|
|
508
535
|
}
|
|
509
536
|
render() {
|
|
510
|
-
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
537
|
+
const { fixedSlotPlacement, hasFooter, hasHeader, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
511
538
|
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
|
512
539
|
const mode = getIonMode(this);
|
|
513
540
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
514
541
|
const transitionShadow = mode === 'ios';
|
|
515
542
|
this.resize();
|
|
516
|
-
return (h(Host, Object.assign({ key: '
|
|
543
|
+
return (h(Host, Object.assign({ key: '83665c0e35e4f4117709606e47d27ad36e343458', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
517
544
|
[mode]: true,
|
|
518
545
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
519
546
|
overscroll: forceOverscroll,
|
|
520
547
|
[`content-${rtl}`]: true,
|
|
548
|
+
'safe-area-top': isMainContent && !hasHeader,
|
|
549
|
+
'safe-area-bottom': isMainContent && !hasFooter,
|
|
521
550
|
}), style: {
|
|
522
551
|
'--offset-top': `${this.cTop}px`,
|
|
523
552
|
'--offset-bottom': `${this.cBottom}px`,
|
|
524
|
-
} }, inheritedAttributes), h("div", { key: '
|
|
553
|
+
} }, inheritedAttributes), h("div", { key: '75d7cf9315bc8dfb150c3b5bcc356a1f9c793b5a', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: 'f68bc5843c93ed6f32e998b80c5edc553c77a2d7', class: {
|
|
525
554
|
'inner-scroll': true,
|
|
526
555
|
'scroll-x': scrollX,
|
|
527
556
|
'scroll-y': scrollY,
|
|
528
557
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
529
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '
|
|
558
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '8d4b2be00f036f6a24bfa65e6324ca715dd93b60' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
|
|
530
559
|
}
|
|
531
560
|
get el() { return getElement(this); }
|
|
532
561
|
};
|
|
@@ -731,6 +731,19 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
731
731
|
checkSafeAreaBottom = true;
|
|
732
732
|
}
|
|
733
733
|
}
|
|
734
|
+
/**
|
|
735
|
+
* Final check: If the popover extends into any safe-area region,
|
|
736
|
+
* ensure the corresponding flag is set regardless of side.
|
|
737
|
+
* This handles cases where a side-positioned popover (left/right)
|
|
738
|
+
* still needs bottom safe-area padding because it extends into that region.
|
|
739
|
+
*/
|
|
740
|
+
const popoverBottom = bottom !== undefined ? bodyHeight - bottom : top + contentHeight;
|
|
741
|
+
if (popoverBottom + safeAreaMargin > bodyHeight) {
|
|
742
|
+
checkSafeAreaBottom = true;
|
|
743
|
+
}
|
|
744
|
+
if (top < safeAreaMargin) {
|
|
745
|
+
checkSafeAreaTop = true;
|
|
746
|
+
}
|
|
734
747
|
return {
|
|
735
748
|
top,
|
|
736
749
|
left,
|