@ionic/core 8.7.17-dev.11767980394.1d9266a9 → 8.7.17-dev.11768239180.18ee1069
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 +8 -111
- package/dist/cjs/ion-app_8.cjs.entry.js +20 -122
- package/dist/collection/components/content/content.css +0 -10
- package/dist/collection/components/content/content.js +6 -109
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +9 -111
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-732b2fd6.entry.js +4 -0
- package/dist/types/components/content/content.d.ts +0 -26
- package/hydrate/index.js +7 -97
- package/hydrate/index.mjs +7 -97
- package/package.json +1 -1
- package/dist/ionic/p-b55c44c8.entry.js +0 -4
package/components/content.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { proxyCustomElement, HTMLElement, createEvent,
|
|
5
|
-
import { w as win } from './index9.js';
|
|
4
|
+
import { proxyCustomElement, HTMLElement, createEvent, Build, readTask, forceUpdate, h, Host } from '@stencil/core/internal/client';
|
|
6
5
|
import { i as inheritAriaAttributes, k as hasLazyBuild, c as componentOnReady } from './helpers.js';
|
|
7
6
|
import { b as getIonMode, a as isPlatform } from './ionic-global.js';
|
|
8
7
|
import { i as isRTL } from './dir.js';
|
|
9
8
|
import { c as createColorClasses, h as hostContext } from './theme.js';
|
|
10
9
|
|
|
11
|
-
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)}";
|
|
12
11
|
|
|
13
12
|
const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLElement {
|
|
14
13
|
constructor(registerHost) {
|
|
@@ -29,12 +28,6 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
29
28
|
this.isMainContent = true;
|
|
30
29
|
this.resizeTimeout = null;
|
|
31
30
|
this.inheritedAttributes = {};
|
|
32
|
-
/**
|
|
33
|
-
* Track whether this content has sibling header/footer elements.
|
|
34
|
-
* When absent, we need to apply safe-area padding directly.
|
|
35
|
-
*/
|
|
36
|
-
this.hasHeader = false;
|
|
37
|
-
this.hasFooter = false;
|
|
38
31
|
this.tabsElement = null;
|
|
39
32
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
40
33
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -89,13 +82,7 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
89
82
|
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
|
90
83
|
}
|
|
91
84
|
connectedCallback() {
|
|
92
|
-
|
|
93
|
-
// Content is "main" if not inside menu/popover/modal and not nested in another ion-content
|
|
94
|
-
this.isMainContent =
|
|
95
|
-
this.el.closest('ion-menu, ion-popover, ion-modal') === null &&
|
|
96
|
-
((_a = this.el.parentElement) === null || _a === void 0 ? void 0 : _a.closest('ion-content')) === null;
|
|
97
|
-
// Detect sibling header/footer for safe-area handling
|
|
98
|
-
this.detectSiblingElements();
|
|
85
|
+
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
99
86
|
/**
|
|
100
87
|
* The fullscreen content offsets need to be
|
|
101
88
|
* computed after the tab bar has loaded. Since
|
|
@@ -126,101 +113,13 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
126
113
|
* bubbles, we can catch any instances of child tab bars loading by listening
|
|
127
114
|
* on IonTabs.
|
|
128
115
|
*/
|
|
129
|
-
this.tabsLoadCallback = () =>
|
|
130
|
-
this.resize();
|
|
131
|
-
// Re-detect footer when tab bar loads (it may not exist during initial detection)
|
|
132
|
-
this.updateSiblingDetection();
|
|
133
|
-
forceUpdate(this);
|
|
134
|
-
};
|
|
116
|
+
this.tabsLoadCallback = () => this.resize();
|
|
135
117
|
closestTabs.addEventListener('ionTabBarLoaded', this.tabsLoadCallback);
|
|
136
118
|
}
|
|
137
119
|
}
|
|
138
120
|
}
|
|
139
|
-
/**
|
|
140
|
-
* Detects sibling ion-header and ion-footer elements and sets up
|
|
141
|
-
* a mutation observer to handle dynamic changes (e.g., conditional rendering).
|
|
142
|
-
*/
|
|
143
|
-
detectSiblingElements() {
|
|
144
|
-
this.updateSiblingDetection();
|
|
145
|
-
// Watch for dynamic header/footer changes (common in React conditional rendering)
|
|
146
|
-
const parent = this.el.parentElement;
|
|
147
|
-
if (parent && !this.parentMutationObserver && win !== undefined && 'MutationObserver' in win) {
|
|
148
|
-
this.parentMutationObserver = new MutationObserver(() => {
|
|
149
|
-
const prevHasHeader = this.hasHeader;
|
|
150
|
-
const prevHasFooter = this.hasFooter;
|
|
151
|
-
this.updateSiblingDetection();
|
|
152
|
-
// Only trigger re-render if header/footer detection actually changed
|
|
153
|
-
if (prevHasHeader !== this.hasHeader || prevHasFooter !== this.hasFooter) {
|
|
154
|
-
forceUpdate(this);
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
this.parentMutationObserver.observe(parent, { childList: true });
|
|
158
|
-
}
|
|
159
|
-
// Watch for dynamic tab bar changes in ion-tabs (common in Angular conditional rendering)
|
|
160
|
-
const tabs = this.el.closest('ion-tabs');
|
|
161
|
-
if (tabs && !this.tabsMutationObserver && win !== undefined && 'MutationObserver' in win) {
|
|
162
|
-
this.tabsMutationObserver = new MutationObserver(() => {
|
|
163
|
-
const prevHasFooter = this.hasFooter;
|
|
164
|
-
this.updateSiblingDetection();
|
|
165
|
-
// Only trigger re-render if footer detection actually changed
|
|
166
|
-
if (prevHasFooter !== this.hasFooter) {
|
|
167
|
-
forceUpdate(this);
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
this.tabsMutationObserver.observe(tabs, { childList: true });
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Updates hasHeader/hasFooter based on current DOM state.
|
|
175
|
-
* Checks both direct siblings and elements wrapped in custom components
|
|
176
|
-
* (e.g., <my-header><ion-header>...</ion-header></my-header>).
|
|
177
|
-
*/
|
|
178
|
-
updateSiblingDetection() {
|
|
179
|
-
const parent = this.el.parentElement;
|
|
180
|
-
if (parent) {
|
|
181
|
-
// First check for direct ion-header/ion-footer siblings
|
|
182
|
-
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
183
|
-
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
184
|
-
// If not found, check if any sibling contains them (wrapped components)
|
|
185
|
-
if (!this.hasHeader) {
|
|
186
|
-
this.hasHeader = this.siblingContainsElement(parent, 'ion-header');
|
|
187
|
-
}
|
|
188
|
-
if (!this.hasFooter) {
|
|
189
|
-
this.hasFooter = this.siblingContainsElement(parent, 'ion-footer');
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
193
|
-
if (!this.hasFooter) {
|
|
194
|
-
const tabs = this.el.closest('ion-tabs');
|
|
195
|
-
if (tabs) {
|
|
196
|
-
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Checks if any sibling element of ion-content contains the specified element.
|
|
202
|
-
* Only searches one level deep to avoid finding elements in nested pages.
|
|
203
|
-
*/
|
|
204
|
-
siblingContainsElement(parent, tagName) {
|
|
205
|
-
for (const sibling of parent.children) {
|
|
206
|
-
// Skip ion-content itself
|
|
207
|
-
if (sibling === this.el)
|
|
208
|
-
continue;
|
|
209
|
-
// Check if this sibling contains the target element as an immediate child
|
|
210
|
-
if (sibling.querySelector(`:scope > ${tagName}`) !== null) {
|
|
211
|
-
return true;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
121
|
disconnectedCallback() {
|
|
217
|
-
var _a, _b;
|
|
218
122
|
this.onScrollEnd();
|
|
219
|
-
// Clean up mutation observers to prevent memory leaks
|
|
220
|
-
(_a = this.parentMutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
221
|
-
this.parentMutationObserver = undefined;
|
|
222
|
-
(_b = this.tabsMutationObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
223
|
-
this.tabsMutationObserver = undefined;
|
|
224
123
|
if (hasLazyBuild(this.el)) {
|
|
225
124
|
/**
|
|
226
125
|
* The event listener and tabs caches need to
|
|
@@ -467,28 +366,26 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
|
|
|
467
366
|
}
|
|
468
367
|
}
|
|
469
368
|
render() {
|
|
470
|
-
const { fixedSlotPlacement,
|
|
369
|
+
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
471
370
|
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
|
472
371
|
const mode = getIonMode(this);
|
|
473
372
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
474
373
|
const transitionShadow = mode === 'ios';
|
|
475
374
|
this.resize();
|
|
476
|
-
return (h(Host, Object.assign({ key: '
|
|
375
|
+
return (h(Host, Object.assign({ key: 'cd8781f848d8dc926fe66f43d43c49564425a507', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
477
376
|
[mode]: true,
|
|
478
377
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
479
378
|
overscroll: forceOverscroll,
|
|
480
379
|
[`content-${rtl}`]: true,
|
|
481
|
-
'safe-area-top': isMainContent && !hasHeader,
|
|
482
|
-
'safe-area-bottom': isMainContent && !hasFooter,
|
|
483
380
|
}), style: {
|
|
484
381
|
'--offset-top': `${this.cTop}px`,
|
|
485
382
|
'--offset-bottom': `${this.cBottom}px`,
|
|
486
|
-
} }, 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: {
|
|
487
384
|
'inner-scroll': true,
|
|
488
385
|
'scroll-x': scrollX,
|
|
489
386
|
'scroll-y': scrollY,
|
|
490
387
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
491
|
-
}, 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));
|
|
492
389
|
}
|
|
493
390
|
get el() { return this; }
|
|
494
391
|
static get style() { return contentCss; }
|
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
var index = require('./index-D6Wc6v08.js');
|
|
7
7
|
var hardwareBackButton = require('./hardware-back-button-VCK4V3mG.js');
|
|
8
8
|
var ionicGlobal = require('./ionic-global-HMVqOFGO.js');
|
|
9
|
-
var index$1 = require('./index-DkNv4J_i.js');
|
|
10
9
|
var helpers = require('./helpers-DrTqNghc.js');
|
|
11
10
|
var dir = require('./dir-Cn0z1rJH.js');
|
|
12
11
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
13
|
-
var index$
|
|
12
|
+
var index$1 = require('./index-CO6eryBo.js');
|
|
14
13
|
var keyboardController = require('./keyboard-controller-GXBiBRKS.js');
|
|
15
14
|
var cubicBezier = require('./cubic-bezier-DAjy1V-e.js');
|
|
16
15
|
var frameworkDelegate = require('./framework-delegate-DMJRBuDi.js');
|
|
17
16
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
18
|
-
var index$
|
|
17
|
+
var index$2 = require('./index-094mMFB-.js');
|
|
18
|
+
require('./index-DkNv4J_i.js');
|
|
19
19
|
require('./keyboard-UuAS4D_9.js');
|
|
20
20
|
require('./capacitor-DmA66EwP.js');
|
|
21
21
|
|
|
@@ -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)}
|
|
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)}";
|
|
158
158
|
|
|
159
159
|
const Content = class {
|
|
160
160
|
constructor(hostRef) {
|
|
@@ -171,12 +171,6 @@ 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;
|
|
180
174
|
this.tabsElement = null;
|
|
181
175
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
182
176
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -231,13 +225,7 @@ const Content = class {
|
|
|
231
225
|
this.inheritedAttributes = helpers.inheritAriaAttributes(this.el);
|
|
232
226
|
}
|
|
233
227
|
connectedCallback() {
|
|
234
|
-
|
|
235
|
-
// Content is "main" if not inside menu/popover/modal and not nested in another ion-content
|
|
236
|
-
this.isMainContent =
|
|
237
|
-
this.el.closest('ion-menu, ion-popover, ion-modal') === null &&
|
|
238
|
-
((_a = this.el.parentElement) === null || _a === void 0 ? void 0 : _a.closest('ion-content')) === null;
|
|
239
|
-
// Detect sibling header/footer for safe-area handling
|
|
240
|
-
this.detectSiblingElements();
|
|
228
|
+
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
241
229
|
/**
|
|
242
230
|
* The fullscreen content offsets need to be
|
|
243
231
|
* computed after the tab bar has loaded. Since
|
|
@@ -268,101 +256,13 @@ const Content = class {
|
|
|
268
256
|
* bubbles, we can catch any instances of child tab bars loading by listening
|
|
269
257
|
* on IonTabs.
|
|
270
258
|
*/
|
|
271
|
-
this.tabsLoadCallback = () =>
|
|
272
|
-
this.resize();
|
|
273
|
-
// Re-detect footer when tab bar loads (it may not exist during initial detection)
|
|
274
|
-
this.updateSiblingDetection();
|
|
275
|
-
index.forceUpdate(this);
|
|
276
|
-
};
|
|
259
|
+
this.tabsLoadCallback = () => this.resize();
|
|
277
260
|
closestTabs.addEventListener('ionTabBarLoaded', this.tabsLoadCallback);
|
|
278
261
|
}
|
|
279
262
|
}
|
|
280
263
|
}
|
|
281
|
-
/**
|
|
282
|
-
* Detects sibling ion-header and ion-footer elements and sets up
|
|
283
|
-
* a mutation observer to handle dynamic changes (e.g., conditional rendering).
|
|
284
|
-
*/
|
|
285
|
-
detectSiblingElements() {
|
|
286
|
-
this.updateSiblingDetection();
|
|
287
|
-
// Watch for dynamic header/footer changes (common in React conditional rendering)
|
|
288
|
-
const parent = this.el.parentElement;
|
|
289
|
-
if (parent && !this.parentMutationObserver && index$1.win !== undefined && 'MutationObserver' in index$1.win) {
|
|
290
|
-
this.parentMutationObserver = new MutationObserver(() => {
|
|
291
|
-
const prevHasHeader = this.hasHeader;
|
|
292
|
-
const prevHasFooter = this.hasFooter;
|
|
293
|
-
this.updateSiblingDetection();
|
|
294
|
-
// Only trigger re-render if header/footer detection actually changed
|
|
295
|
-
if (prevHasHeader !== this.hasHeader || prevHasFooter !== this.hasFooter) {
|
|
296
|
-
index.forceUpdate(this);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
this.parentMutationObserver.observe(parent, { childList: true });
|
|
300
|
-
}
|
|
301
|
-
// Watch for dynamic tab bar changes in ion-tabs (common in Angular conditional rendering)
|
|
302
|
-
const tabs = this.el.closest('ion-tabs');
|
|
303
|
-
if (tabs && !this.tabsMutationObserver && index$1.win !== undefined && 'MutationObserver' in index$1.win) {
|
|
304
|
-
this.tabsMutationObserver = new MutationObserver(() => {
|
|
305
|
-
const prevHasFooter = this.hasFooter;
|
|
306
|
-
this.updateSiblingDetection();
|
|
307
|
-
// Only trigger re-render if footer detection actually changed
|
|
308
|
-
if (prevHasFooter !== this.hasFooter) {
|
|
309
|
-
index.forceUpdate(this);
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
this.tabsMutationObserver.observe(tabs, { childList: true });
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Updates hasHeader/hasFooter based on current DOM state.
|
|
317
|
-
* Checks both direct siblings and elements wrapped in custom components
|
|
318
|
-
* (e.g., <my-header><ion-header>...</ion-header></my-header>).
|
|
319
|
-
*/
|
|
320
|
-
updateSiblingDetection() {
|
|
321
|
-
const parent = this.el.parentElement;
|
|
322
|
-
if (parent) {
|
|
323
|
-
// First check for direct ion-header/ion-footer siblings
|
|
324
|
-
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
325
|
-
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
326
|
-
// If not found, check if any sibling contains them (wrapped components)
|
|
327
|
-
if (!this.hasHeader) {
|
|
328
|
-
this.hasHeader = this.siblingContainsElement(parent, 'ion-header');
|
|
329
|
-
}
|
|
330
|
-
if (!this.hasFooter) {
|
|
331
|
-
this.hasFooter = this.siblingContainsElement(parent, 'ion-footer');
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
335
|
-
if (!this.hasFooter) {
|
|
336
|
-
const tabs = this.el.closest('ion-tabs');
|
|
337
|
-
if (tabs) {
|
|
338
|
-
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Checks if any sibling element of ion-content contains the specified element.
|
|
344
|
-
* Only searches one level deep to avoid finding elements in nested pages.
|
|
345
|
-
*/
|
|
346
|
-
siblingContainsElement(parent, tagName) {
|
|
347
|
-
for (const sibling of parent.children) {
|
|
348
|
-
// Skip ion-content itself
|
|
349
|
-
if (sibling === this.el)
|
|
350
|
-
continue;
|
|
351
|
-
// Check if this sibling contains the target element as an immediate child
|
|
352
|
-
if (sibling.querySelector(`:scope > ${tagName}`) !== null) {
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
return false;
|
|
357
|
-
}
|
|
358
264
|
disconnectedCallback() {
|
|
359
|
-
var _a, _b;
|
|
360
265
|
this.onScrollEnd();
|
|
361
|
-
// Clean up mutation observers to prevent memory leaks
|
|
362
|
-
(_a = this.parentMutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
363
|
-
this.parentMutationObserver = undefined;
|
|
364
|
-
(_b = this.tabsMutationObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
365
|
-
this.tabsMutationObserver = undefined;
|
|
366
266
|
if (helpers.hasLazyBuild(this.el)) {
|
|
367
267
|
/**
|
|
368
268
|
* The event listener and tabs caches need to
|
|
@@ -609,28 +509,26 @@ const Content = class {
|
|
|
609
509
|
}
|
|
610
510
|
}
|
|
611
511
|
render() {
|
|
612
|
-
const { fixedSlotPlacement,
|
|
512
|
+
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
613
513
|
const rtl = dir.isRTL(el) ? 'rtl' : 'ltr';
|
|
614
514
|
const mode = ionicGlobal.getIonMode(this);
|
|
615
515
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
616
516
|
const transitionShadow = mode === 'ios';
|
|
617
517
|
this.resize();
|
|
618
|
-
return (index.h(index.Host, Object.assign({ key: '
|
|
518
|
+
return (index.h(index.Host, Object.assign({ key: 'cd8781f848d8dc926fe66f43d43c49564425a507', role: isMainContent ? 'main' : undefined, class: theme.createColorClasses(this.color, {
|
|
619
519
|
[mode]: true,
|
|
620
520
|
'content-sizing': theme.hostContext('ion-popover', this.el),
|
|
621
521
|
overscroll: forceOverscroll,
|
|
622
522
|
[`content-${rtl}`]: true,
|
|
623
|
-
'safe-area-top': isMainContent && !hasHeader,
|
|
624
|
-
'safe-area-bottom': isMainContent && !hasFooter,
|
|
625
523
|
}), style: {
|
|
626
524
|
'--offset-top': `${this.cTop}px`,
|
|
627
525
|
'--offset-bottom': `${this.cBottom}px`,
|
|
628
|
-
} }, inheritedAttributes), index.h("div", { key: '
|
|
526
|
+
} }, inheritedAttributes), index.h("div", { key: '95b112d7cae30f22ef778ceffb88edb4d941c170', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? index.h("slot", { name: "fixed" }) : null, index.h("div", { key: '2fdfcbc39fb66f11b6191911f2941c660f4c12e5', class: {
|
|
629
527
|
'inner-scroll': true,
|
|
630
528
|
'scroll-x': scrollX,
|
|
631
529
|
'scroll-y': scrollY,
|
|
632
530
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
633
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, index.h("slot", { key: '
|
|
531
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, index.h("slot", { key: '6bc77e0054ec8e21635a7f2abfe0ca46e0962e03' })), 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));
|
|
634
532
|
}
|
|
635
533
|
get el() { return index.getElement(this); }
|
|
636
534
|
};
|
|
@@ -748,16 +646,16 @@ const Footer = class {
|
|
|
748
646
|
this.destroyCollapsibleFooter();
|
|
749
647
|
if (hasFade) {
|
|
750
648
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
751
|
-
const contentEl = pageEl ? index$
|
|
649
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
752
650
|
if (!contentEl) {
|
|
753
|
-
index$
|
|
651
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
754
652
|
return;
|
|
755
653
|
}
|
|
756
654
|
this.setupFadeFooter(contentEl);
|
|
757
655
|
}
|
|
758
656
|
};
|
|
759
657
|
this.setupFadeFooter = async (contentEl) => {
|
|
760
|
-
const scrollEl = (this.scrollEl = await index$
|
|
658
|
+
const scrollEl = (this.scrollEl = await index$1.getScrollElement(contentEl));
|
|
761
659
|
/**
|
|
762
660
|
* Handle fading of toolbars on scroll
|
|
763
661
|
*/
|
|
@@ -1070,7 +968,7 @@ const Header = class {
|
|
|
1070
968
|
*/
|
|
1071
969
|
this.translucent = false;
|
|
1072
970
|
this.setupFadeHeader = async (contentEl, condenseHeader) => {
|
|
1073
|
-
const scrollEl = (this.scrollEl = await index$
|
|
971
|
+
const scrollEl = (this.scrollEl = await index$1.getScrollElement(contentEl));
|
|
1074
972
|
/**
|
|
1075
973
|
* Handle fading of toolbars on scroll
|
|
1076
974
|
*/
|
|
@@ -1104,7 +1002,7 @@ const Header = class {
|
|
|
1104
1002
|
this.destroyCollapsibleHeader();
|
|
1105
1003
|
if (hasCondense) {
|
|
1106
1004
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
1107
|
-
const contentEl = pageEl ? index$
|
|
1005
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
1108
1006
|
// Cloned elements are always needed in iOS transition
|
|
1109
1007
|
index.writeTask(() => {
|
|
1110
1008
|
const title = cloneElement('ion-title');
|
|
@@ -1115,9 +1013,9 @@ const Header = class {
|
|
|
1115
1013
|
}
|
|
1116
1014
|
else if (hasFade) {
|
|
1117
1015
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
1118
|
-
const contentEl = pageEl ? index$
|
|
1016
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
1119
1017
|
if (!contentEl) {
|
|
1120
|
-
index$
|
|
1018
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
1121
1019
|
return;
|
|
1122
1020
|
}
|
|
1123
1021
|
const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"]');
|
|
@@ -1140,13 +1038,13 @@ const Header = class {
|
|
|
1140
1038
|
}
|
|
1141
1039
|
async setupCondenseHeader(contentEl, pageEl) {
|
|
1142
1040
|
if (!contentEl || !pageEl) {
|
|
1143
|
-
index$
|
|
1041
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
1144
1042
|
return;
|
|
1145
1043
|
}
|
|
1146
1044
|
if (typeof IntersectionObserver === 'undefined') {
|
|
1147
1045
|
return;
|
|
1148
1046
|
}
|
|
1149
|
-
this.scrollEl = await index$
|
|
1047
|
+
this.scrollEl = await index$1.getScrollElement(contentEl);
|
|
1150
1048
|
const headers = pageEl.querySelectorAll('ion-header');
|
|
1151
1049
|
this.collapsibleMainHeader = Array.from(headers).find((header) => header.collapse !== 'condense');
|
|
1152
1050
|
if (!this.collapsibleMainHeader) {
|
|
@@ -1344,7 +1242,7 @@ const RouterOutlet = class {
|
|
|
1344
1242
|
const { el, mode } = this;
|
|
1345
1243
|
const animated = this.animated && index.config.getBoolean('animated', true);
|
|
1346
1244
|
const animationBuilder = opts.animationBuilder || this.animation || index.config.get('navAnimation');
|
|
1347
|
-
await index$
|
|
1245
|
+
await index$2.transition(Object.assign(Object.assign({ mode,
|
|
1348
1246
|
animated,
|
|
1349
1247
|
enteringEl,
|
|
1350
1248
|
leavingEl, baseEl: el,
|
|
@@ -263,16 +263,6 @@
|
|
|
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
|
-
|
|
276
266
|
::slotted([slot=fixed]) {
|
|
277
267
|
position: absolute;
|
|
278
268
|
/**
|