@ionic/core 8.7.17-dev.11767891829.1a63afa3 → 8.7.17-dev.11767895575.16ea7cef
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/content.js +8 -96
- package/components/ion-tab-bar.js +23 -3
- package/components/modal.js +12 -213
- package/components/popover.js +11 -83
- package/dist/cjs/ion-app_8.cjs.entry.js +20 -107
- package/dist/cjs/ion-modal.cjs.entry.js +12 -213
- package/dist/cjs/ion-popover.cjs.entry.js +11 -83
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +23 -3
- package/dist/collection/components/content/content.css +0 -10
- package/dist/collection/components/content/content.js +6 -94
- package/dist/collection/components/modal/gestures/sheet.js +1 -3
- package/dist/collection/components/modal/gestures/swipe-to-close.js +1 -3
- package/dist/collection/components/modal/modal.ios.css +4 -0
- package/dist/collection/components/modal/modal.js +7 -205
- package/dist/collection/components/modal/modal.md.css +4 -0
- package/dist/collection/components/popover/animations/ios.enter.js +5 -21
- package/dist/collection/components/popover/animations/md.enter.js +5 -30
- package/dist/collection/components/popover/utils.js +1 -32
- package/dist/collection/components/tab-bar/tab-bar.js +23 -3
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +9 -96
- package/dist/esm/ion-modal.entry.js +12 -213
- package/dist/esm/ion-popover.entry.js +11 -83
- package/dist/esm/ion-tab-bar_2.entry.js +23 -3
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-172a579f.entry.js +4 -0
- package/dist/ionic/p-732b2fd6.entry.js +4 -0
- package/dist/ionic/p-91840a80.entry.js +4 -0
- package/dist/ionic/p-f9061316.entry.js +4 -0
- package/dist/types/components/content/content.d.ts +0 -24
- package/dist/types/components/modal/gestures/sheet.d.ts +1 -1
- package/dist/types/components/modal/gestures/swipe-to-close.d.ts +1 -1
- package/dist/types/components/modal/modal.d.ts +0 -45
- package/dist/types/components/popover/utils.d.ts +0 -2
- package/dist/types/components/tab-bar/tab-bar.d.ts +1 -0
- package/hydrate/index.js +52 -385
- package/hydrate/index.mjs +52 -385
- package/package.json +1 -1
- package/dist/ionic/p-7268efa5.entry.js +0 -4
- package/dist/ionic/p-968a55d1.entry.js +0 -4
- package/dist/ionic/p-d9fd799f.entry.js +0 -4
- package/dist/ionic/p-ec9ca3fe.entry.js +0 -4
package/components/popover.js
CHANGED
|
@@ -657,8 +657,6 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
657
657
|
let bottom;
|
|
658
658
|
let originX = contentOriginX;
|
|
659
659
|
let originY = contentOriginY;
|
|
660
|
-
let checkSafeAreaTop = false;
|
|
661
|
-
let checkSafeAreaBottom = false;
|
|
662
660
|
let checkSafeAreaLeft = false;
|
|
663
661
|
let checkSafeAreaRight = false;
|
|
664
662
|
const triggerTop = triggerCoordinates
|
|
@@ -703,18 +701,10 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
703
701
|
* We chose 12 here so that the popover position looks a bit nicer as
|
|
704
702
|
* it is not right up against the edge of the screen.
|
|
705
703
|
*/
|
|
706
|
-
top = Math.max(
|
|
704
|
+
top = Math.max(12, triggerTop - contentHeight - triggerHeight - (arrowHeight - 1));
|
|
707
705
|
arrowTop = top + contentHeight;
|
|
708
706
|
originY = 'bottom';
|
|
709
707
|
addPopoverBottomClass = true;
|
|
710
|
-
/**
|
|
711
|
-
* If the popover is positioned near the top edge, account for safe area.
|
|
712
|
-
* This ensures the popover doesn't overlap with status bars or notches.
|
|
713
|
-
*/
|
|
714
|
-
if (top <= bodyPadding + safeAreaMargin) {
|
|
715
|
-
checkSafeAreaTop = true;
|
|
716
|
-
top = bodyPadding;
|
|
717
|
-
}
|
|
718
708
|
/**
|
|
719
709
|
* If not enough room for popover to appear
|
|
720
710
|
* above trigger, then cut it off.
|
|
@@ -722,35 +712,14 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
722
712
|
}
|
|
723
713
|
else {
|
|
724
714
|
bottom = bodyPadding;
|
|
725
|
-
/**
|
|
726
|
-
* When the popover is pinned to the bottom, account for safe area.
|
|
727
|
-
* This ensures the popover doesn't overlap with home indicators
|
|
728
|
-
* or navigation bars (e.g., Android API 36+ edge-to-edge).
|
|
729
|
-
*/
|
|
730
|
-
checkSafeAreaBottom = true;
|
|
731
715
|
}
|
|
732
716
|
}
|
|
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
|
-
}
|
|
746
717
|
return {
|
|
747
718
|
top,
|
|
748
719
|
left,
|
|
749
720
|
bottom,
|
|
750
721
|
originX,
|
|
751
722
|
originY,
|
|
752
|
-
checkSafeAreaTop,
|
|
753
|
-
checkSafeAreaBottom,
|
|
754
723
|
checkSafeAreaLeft,
|
|
755
724
|
checkSafeAreaRight,
|
|
756
725
|
arrowTop,
|
|
@@ -811,7 +780,7 @@ const iosEnterAnimation = (baseEl, opts) => {
|
|
|
811
780
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, trigger, ev);
|
|
812
781
|
const padding = size === 'cover' ? 0 : POPOVER_IOS_BODY_PADDING;
|
|
813
782
|
const margin = size === 'cover' ? 0 : 25;
|
|
814
|
-
const { originX, originY, top, left, bottom,
|
|
783
|
+
const { originX, originY, top, left, bottom, checkSafeAreaLeft, checkSafeAreaRight, arrowTop, arrowLeft, addPopoverBottomClass, } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, margin, results.originX, results.originY, results.referenceCoordinates, results.arrowTop, results.arrowLeft, arrowHeight);
|
|
815
784
|
const baseAnimation = createAnimation();
|
|
816
785
|
const backdropAnimation = createAnimation();
|
|
817
786
|
const contentAnimation = createAnimation();
|
|
@@ -841,35 +810,19 @@ const iosEnterAnimation = (baseEl, opts) => {
|
|
|
841
810
|
if (addPopoverBottomClass) {
|
|
842
811
|
baseEl.classList.add('popover-bottom');
|
|
843
812
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
* safe-area inset to ensure the popover doesn't overlap with system UI
|
|
848
|
-
* (status bars, home indicators, navigation bars on Android API 36+, etc.)
|
|
849
|
-
*/
|
|
850
|
-
const safeAreaTop = ' + var(--ion-safe-area-top, 0)';
|
|
851
|
-
const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0)';
|
|
813
|
+
if (bottom !== undefined) {
|
|
814
|
+
contentEl.style.setProperty('bottom', `${bottom}px`);
|
|
815
|
+
}
|
|
852
816
|
const safeAreaLeft = ' + var(--ion-safe-area-left, 0)';
|
|
853
817
|
const safeAreaRight = ' - var(--ion-safe-area-right, 0)';
|
|
854
|
-
let topValue = `${top}px`;
|
|
855
|
-
let bottomValue = bottom !== undefined ? `${bottom}px` : undefined;
|
|
856
818
|
let leftValue = `${left}px`;
|
|
857
|
-
if (checkSafeAreaTop) {
|
|
858
|
-
topValue = `${top}px${safeAreaTop}`;
|
|
859
|
-
}
|
|
860
|
-
if (checkSafeAreaBottom && bottomValue !== undefined) {
|
|
861
|
-
bottomValue = `${bottom}px${safeAreaBottom}`;
|
|
862
|
-
}
|
|
863
819
|
if (checkSafeAreaLeft) {
|
|
864
820
|
leftValue = `${left}px${safeAreaLeft}`;
|
|
865
821
|
}
|
|
866
822
|
if (checkSafeAreaRight) {
|
|
867
823
|
leftValue = `${left}px${safeAreaRight}`;
|
|
868
824
|
}
|
|
869
|
-
|
|
870
|
-
contentEl.style.setProperty('bottom', `calc(${bottomValue})`);
|
|
871
|
-
}
|
|
872
|
-
contentEl.style.setProperty('top', `calc(${topValue} + var(--offset-y, 0))`);
|
|
825
|
+
contentEl.style.setProperty('top', `calc(${top}px + var(--offset-y, 0))`);
|
|
873
826
|
contentEl.style.setProperty('left', `calc(${leftValue} + var(--offset-x, 0))`);
|
|
874
827
|
contentEl.style.setProperty('transform-origin', `${originY} ${originX}`);
|
|
875
828
|
if (arrowEl !== null) {
|
|
@@ -945,32 +898,7 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
945
898
|
};
|
|
946
899
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
|
|
947
900
|
const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
|
|
948
|
-
const { originX, originY, top, left, bottom
|
|
949
|
-
/**
|
|
950
|
-
* Safe area CSS variable adjustments.
|
|
951
|
-
* When the popover is positioned near an edge, we add the corresponding
|
|
952
|
-
* safe-area inset to ensure the popover doesn't overlap with system UI
|
|
953
|
-
* (status bars, home indicators, navigation bars on Android API 36+, etc.)
|
|
954
|
-
*/
|
|
955
|
-
const safeAreaTop = ' + var(--ion-safe-area-top, 0)';
|
|
956
|
-
const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0)';
|
|
957
|
-
const safeAreaLeft = ' + var(--ion-safe-area-left, 0)';
|
|
958
|
-
const safeAreaRight = ' - var(--ion-safe-area-right, 0)';
|
|
959
|
-
let topValue = `${top}px`;
|
|
960
|
-
let bottomValue = bottom !== undefined ? `${bottom}px` : undefined;
|
|
961
|
-
let leftValue = `${left}px`;
|
|
962
|
-
if (checkSafeAreaTop) {
|
|
963
|
-
topValue = `${top}px${safeAreaTop}`;
|
|
964
|
-
}
|
|
965
|
-
if (checkSafeAreaBottom && bottomValue !== undefined) {
|
|
966
|
-
bottomValue = `${bottom}px${safeAreaBottom}`;
|
|
967
|
-
}
|
|
968
|
-
if (checkSafeAreaLeft) {
|
|
969
|
-
leftValue = `${left}px${safeAreaLeft}`;
|
|
970
|
-
}
|
|
971
|
-
if (checkSafeAreaRight) {
|
|
972
|
-
leftValue = `${left}px${safeAreaRight}`;
|
|
973
|
-
}
|
|
901
|
+
const { originX, originY, top, left, bottom } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
|
|
974
902
|
const baseAnimation = createAnimation();
|
|
975
903
|
const backdropAnimation = createAnimation();
|
|
976
904
|
const wrapperAnimation = createAnimation();
|
|
@@ -987,13 +915,13 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
987
915
|
contentAnimation
|
|
988
916
|
.addElement(contentEl)
|
|
989
917
|
.beforeStyles({
|
|
990
|
-
top: `calc(${
|
|
991
|
-
left: `calc(${
|
|
918
|
+
top: `calc(${top}px + var(--offset-y, 0px))`,
|
|
919
|
+
left: `calc(${left}px + var(--offset-x, 0px))`,
|
|
992
920
|
'transform-origin': `${originY} ${originX}`,
|
|
993
921
|
})
|
|
994
922
|
.beforeAddWrite(() => {
|
|
995
|
-
if (
|
|
996
|
-
contentEl.style.setProperty('bottom',
|
|
923
|
+
if (bottom !== undefined) {
|
|
924
|
+
contentEl.style.setProperty('bottom', `${bottom}px`);
|
|
997
925
|
}
|
|
998
926
|
})
|
|
999
927
|
.fromTo('transform', 'scale(0.8)', 'scale(1)');
|
|
@@ -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,86 +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
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Updates hasHeader/hasFooter based on current DOM state.
|
|
304
|
-
* Checks both direct siblings and elements wrapped in custom components
|
|
305
|
-
* (e.g., <my-header><ion-header>...</ion-header></my-header>).
|
|
306
|
-
*/
|
|
307
|
-
updateSiblingDetection() {
|
|
308
|
-
const parent = this.el.parentElement;
|
|
309
|
-
if (parent) {
|
|
310
|
-
// First check for direct ion-header/ion-footer siblings
|
|
311
|
-
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
312
|
-
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
313
|
-
// If not found, check if any sibling contains them (wrapped components)
|
|
314
|
-
if (!this.hasHeader) {
|
|
315
|
-
this.hasHeader = this.siblingContainsElement(parent, 'ion-header');
|
|
316
|
-
}
|
|
317
|
-
if (!this.hasFooter) {
|
|
318
|
-
this.hasFooter = this.siblingContainsElement(parent, 'ion-footer');
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
322
|
-
if (!this.hasFooter) {
|
|
323
|
-
const tabs = this.el.closest('ion-tabs');
|
|
324
|
-
if (tabs) {
|
|
325
|
-
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Checks if any sibling element of ion-content contains the specified element.
|
|
331
|
-
* Only searches one level deep to avoid finding elements in nested pages.
|
|
332
|
-
*/
|
|
333
|
-
siblingContainsElement(parent, tagName) {
|
|
334
|
-
for (const sibling of parent.children) {
|
|
335
|
-
// Skip ion-content itself
|
|
336
|
-
if (sibling === this.el)
|
|
337
|
-
continue;
|
|
338
|
-
// Check if this sibling contains the target element as an immediate child
|
|
339
|
-
if (sibling.querySelector(`:scope > ${tagName}`) !== null) {
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
return false;
|
|
344
|
-
}
|
|
345
264
|
disconnectedCallback() {
|
|
346
|
-
var _a;
|
|
347
265
|
this.onScrollEnd();
|
|
348
|
-
// Clean up mutation observer to prevent memory leaks
|
|
349
|
-
(_a = this.parentMutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
350
|
-
this.parentMutationObserver = undefined;
|
|
351
266
|
if (helpers.hasLazyBuild(this.el)) {
|
|
352
267
|
/**
|
|
353
268
|
* The event listener and tabs caches need to
|
|
@@ -594,28 +509,26 @@ const Content = class {
|
|
|
594
509
|
}
|
|
595
510
|
}
|
|
596
511
|
render() {
|
|
597
|
-
const { fixedSlotPlacement,
|
|
512
|
+
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
598
513
|
const rtl = dir.isRTL(el) ? 'rtl' : 'ltr';
|
|
599
514
|
const mode = ionicGlobal.getIonMode(this);
|
|
600
515
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
601
516
|
const transitionShadow = mode === 'ios';
|
|
602
517
|
this.resize();
|
|
603
|
-
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, {
|
|
604
519
|
[mode]: true,
|
|
605
520
|
'content-sizing': theme.hostContext('ion-popover', this.el),
|
|
606
521
|
overscroll: forceOverscroll,
|
|
607
522
|
[`content-${rtl}`]: true,
|
|
608
|
-
'safe-area-top': isMainContent && !hasHeader,
|
|
609
|
-
'safe-area-bottom': isMainContent && !hasFooter,
|
|
610
523
|
}), style: {
|
|
611
524
|
'--offset-top': `${this.cTop}px`,
|
|
612
525
|
'--offset-bottom': `${this.cBottom}px`,
|
|
613
|
-
} }, 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: {
|
|
614
527
|
'inner-scroll': true,
|
|
615
528
|
'scroll-x': scrollX,
|
|
616
529
|
'scroll-y': scrollY,
|
|
617
530
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
618
|
-
}, 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));
|
|
619
532
|
}
|
|
620
533
|
get el() { return index.getElement(this); }
|
|
621
534
|
};
|
|
@@ -733,16 +646,16 @@ const Footer = class {
|
|
|
733
646
|
this.destroyCollapsibleFooter();
|
|
734
647
|
if (hasFade) {
|
|
735
648
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
736
|
-
const contentEl = pageEl ? index$
|
|
649
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
737
650
|
if (!contentEl) {
|
|
738
|
-
index$
|
|
651
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
739
652
|
return;
|
|
740
653
|
}
|
|
741
654
|
this.setupFadeFooter(contentEl);
|
|
742
655
|
}
|
|
743
656
|
};
|
|
744
657
|
this.setupFadeFooter = async (contentEl) => {
|
|
745
|
-
const scrollEl = (this.scrollEl = await index$
|
|
658
|
+
const scrollEl = (this.scrollEl = await index$1.getScrollElement(contentEl));
|
|
746
659
|
/**
|
|
747
660
|
* Handle fading of toolbars on scroll
|
|
748
661
|
*/
|
|
@@ -1055,7 +968,7 @@ const Header = class {
|
|
|
1055
968
|
*/
|
|
1056
969
|
this.translucent = false;
|
|
1057
970
|
this.setupFadeHeader = async (contentEl, condenseHeader) => {
|
|
1058
|
-
const scrollEl = (this.scrollEl = await index$
|
|
971
|
+
const scrollEl = (this.scrollEl = await index$1.getScrollElement(contentEl));
|
|
1059
972
|
/**
|
|
1060
973
|
* Handle fading of toolbars on scroll
|
|
1061
974
|
*/
|
|
@@ -1089,7 +1002,7 @@ const Header = class {
|
|
|
1089
1002
|
this.destroyCollapsibleHeader();
|
|
1090
1003
|
if (hasCondense) {
|
|
1091
1004
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
1092
|
-
const contentEl = pageEl ? index$
|
|
1005
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
1093
1006
|
// Cloned elements are always needed in iOS transition
|
|
1094
1007
|
index.writeTask(() => {
|
|
1095
1008
|
const title = cloneElement('ion-title');
|
|
@@ -1100,9 +1013,9 @@ const Header = class {
|
|
|
1100
1013
|
}
|
|
1101
1014
|
else if (hasFade) {
|
|
1102
1015
|
const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
|
|
1103
|
-
const contentEl = pageEl ? index$
|
|
1016
|
+
const contentEl = pageEl ? index$1.findIonContent(pageEl) : null;
|
|
1104
1017
|
if (!contentEl) {
|
|
1105
|
-
index$
|
|
1018
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
1106
1019
|
return;
|
|
1107
1020
|
}
|
|
1108
1021
|
const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"]');
|
|
@@ -1125,13 +1038,13 @@ const Header = class {
|
|
|
1125
1038
|
}
|
|
1126
1039
|
async setupCondenseHeader(contentEl, pageEl) {
|
|
1127
1040
|
if (!contentEl || !pageEl) {
|
|
1128
|
-
index$
|
|
1041
|
+
index$1.printIonContentErrorMsg(this.el);
|
|
1129
1042
|
return;
|
|
1130
1043
|
}
|
|
1131
1044
|
if (typeof IntersectionObserver === 'undefined') {
|
|
1132
1045
|
return;
|
|
1133
1046
|
}
|
|
1134
|
-
this.scrollEl = await index$
|
|
1047
|
+
this.scrollEl = await index$1.getScrollElement(contentEl);
|
|
1135
1048
|
const headers = pageEl.querySelectorAll('ion-header');
|
|
1136
1049
|
this.collapsibleMainHeader = Array.from(headers).find((header) => header.collapse !== 'condense');
|
|
1137
1050
|
if (!this.collapsibleMainHeader) {
|
|
@@ -1329,7 +1242,7 @@ const RouterOutlet = class {
|
|
|
1329
1242
|
const { el, mode } = this;
|
|
1330
1243
|
const animated = this.animated && index.config.getBoolean('animated', true);
|
|
1331
1244
|
const animationBuilder = opts.animationBuilder || this.animation || index.config.get('navAnimation');
|
|
1332
|
-
await index$
|
|
1245
|
+
await index$2.transition(Object.assign(Object.assign({ mode,
|
|
1333
1246
|
animated,
|
|
1334
1247
|
enteringEl,
|
|
1335
1248
|
leavingEl, baseEl: el,
|