@ionic/core 8.7.17-dev.11767984108.1f9159e1 → 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 -113
- package/dist/cjs/ion-app_8.cjs.entry.js +20 -124
- package/dist/collection/components/content/content.css +0 -20
- package/dist/collection/components/content/content.js +6 -111
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +9 -113
- 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 -99
- package/hydrate/index.mjs +7 -99
- package/package.json +1 -1
- package/dist/ionic/p-6c6933fe.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,30 +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
|
-
'safe-area-left': isMainContent,
|
|
484
|
-
'safe-area-right': isMainContent,
|
|
485
380
|
}), style: {
|
|
486
381
|
'--offset-top': `${this.cTop}px`,
|
|
487
382
|
'--offset-bottom': `${this.cBottom}px`,
|
|
488
|
-
} }, 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: {
|
|
489
384
|
'inner-scroll': true,
|
|
490
385
|
'scroll-x': scrollX,
|
|
491
386
|
'scroll-y': scrollY,
|
|
492
387
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
493
|
-
}, 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));
|
|
494
389
|
}
|
|
495
390
|
get el() { return this; }
|
|
496
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,30 +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
|
-
'safe-area-left': isMainContent,
|
|
626
|
-
'safe-area-right': isMainContent,
|
|
627
523
|
}), style: {
|
|
628
524
|
'--offset-top': `${this.cTop}px`,
|
|
629
525
|
'--offset-bottom': `${this.cBottom}px`,
|
|
630
|
-
} }, 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: {
|
|
631
527
|
'inner-scroll': true,
|
|
632
528
|
'scroll-x': scrollX,
|
|
633
529
|
'scroll-y': scrollY,
|
|
634
530
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
635
|
-
}, 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));
|
|
636
532
|
}
|
|
637
533
|
get el() { return index.getElement(this); }
|
|
638
534
|
};
|
|
@@ -750,16 +646,16 @@ const Footer = class {
|
|
|
750
646
|
this.destroyCollapsibleFooter();
|
|
751
647
|
if (hasFade) {
|
|
752
648
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
753
|
-
const contentEl = pageEl ? index$
|
|
649
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
754
650
|
if (!contentEl) {
|
|
755
|
-
index$
|
|
651
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
756
652
|
return;
|
|
757
653
|
}
|
|
758
654
|
this.setupFadeFooter(contentEl);
|
|
759
655
|
}
|
|
760
656
|
};
|
|
761
657
|
this.setupFadeFooter = async (contentEl) => {
|
|
762
|
-
const scrollEl = (this.scrollEl = await index$
|
|
658
|
+
const scrollEl = (this.scrollEl = await index$1.getScrollElement(contentEl));
|
|
763
659
|
/**
|
|
764
660
|
* Handle fading of toolbars on scroll
|
|
765
661
|
*/
|
|
@@ -1072,7 +968,7 @@ const Header = class {
|
|
|
1072
968
|
*/
|
|
1073
969
|
this.translucent = false;
|
|
1074
970
|
this.setupFadeHeader = async (contentEl, condenseHeader) => {
|
|
1075
|
-
const scrollEl = (this.scrollEl = await index$
|
|
971
|
+
const scrollEl = (this.scrollEl = await index$1.getScrollElement(contentEl));
|
|
1076
972
|
/**
|
|
1077
973
|
* Handle fading of toolbars on scroll
|
|
1078
974
|
*/
|
|
@@ -1106,7 +1002,7 @@ const Header = class {
|
|
|
1106
1002
|
this.destroyCollapsibleHeader();
|
|
1107
1003
|
if (hasCondense) {
|
|
1108
1004
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
1109
|
-
const contentEl = pageEl ? index$
|
|
1005
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
1110
1006
|
// Cloned elements are always needed in iOS transition
|
|
1111
1007
|
index.writeTask(() => {
|
|
1112
1008
|
const title = cloneElement('ion-title');
|
|
@@ -1117,9 +1013,9 @@ const Header = class {
|
|
|
1117
1013
|
}
|
|
1118
1014
|
else if (hasFade) {
|
|
1119
1015
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
1120
|
-
const contentEl = pageEl ? index$
|
|
1016
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
1121
1017
|
if (!contentEl) {
|
|
1122
|
-
index$
|
|
1018
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
1123
1019
|
return;
|
|
1124
1020
|
}
|
|
1125
1021
|
const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"]');
|
|
@@ -1142,13 +1038,13 @@ const Header = class {
|
|
|
1142
1038
|
}
|
|
1143
1039
|
async setupCondenseHeader(contentEl, pageEl) {
|
|
1144
1040
|
if (!contentEl || !pageEl) {
|
|
1145
|
-
index$
|
|
1041
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
1146
1042
|
return;
|
|
1147
1043
|
}
|
|
1148
1044
|
if (typeof IntersectionObserver === 'undefined') {
|
|
1149
1045
|
return;
|
|
1150
1046
|
}
|
|
1151
|
-
this.scrollEl = await index$
|
|
1047
|
+
this.scrollEl = await index$1.getScrollElement(contentEl);
|
|
1152
1048
|
const headers = pageEl.querySelectorAll('ion-header');
|
|
1153
1049
|
this.collapsibleMainHeader = Array.from(headers).find((header) => header.collapse !== 'condense');
|
|
1154
1050
|
if (!this.collapsibleMainHeader) {
|
|
@@ -1346,7 +1242,7 @@ const RouterOutlet = class {
|
|
|
1346
1242
|
const { el, mode } = this;
|
|
1347
1243
|
const animated = this.animated && index.config.getBoolean('animated', true);
|
|
1348
1244
|
const animationBuilder = opts.animationBuilder || this.animation || index.config.get('navAnimation');
|
|
1349
|
-
await index$
|
|
1245
|
+
await index$2.transition(Object.assign(Object.assign({ mode,
|
|
1350
1246
|
animated,
|
|
1351
1247
|
enteringEl,
|
|
1352
1248
|
leavingEl, baseEl: el,
|
|
@@ -263,26 +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
|
-
:host(.safe-area-left) #background-content,
|
|
277
|
-
:host(.safe-area-left) .inner-scroll {
|
|
278
|
-
left: var(--ion-safe-area-left, 0px);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
:host(.safe-area-right) #background-content,
|
|
282
|
-
:host(.safe-area-right) .inner-scroll {
|
|
283
|
-
right: var(--ion-safe-area-right, 0px);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
266
|
::slotted([slot=fixed]) {
|
|
287
267
|
position: absolute;
|
|
288
268
|
/**
|