@ionic/core 8.7.17-dev.11767796972.148e4bc4 → 8.7.17-dev.11767895575.16ea7cef
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/content.js +6 -79
- package/components/ion-tab-bar.js +23 -3
- package/components/modal.js +12 -200
- package/components/popover.js +10 -73
- package/dist/cjs/ion-app_8.cjs.entry.js +5 -78
- package/dist/cjs/ion-modal.cjs.entry.js +12 -200
- package/dist/cjs/ion-popover.cjs.entry.js +10 -73
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +23 -3
- package/dist/collection/components/content/content.css +0 -10
- package/dist/collection/components/content/content.js +4 -77
- package/dist/collection/components/modal/gestures/sheet.js +1 -3
- package/dist/collection/components/modal/gestures/swipe-to-close.js +1 -3
- package/dist/collection/components/modal/modal.ios.css +4 -0
- package/dist/collection/components/modal/modal.js +8 -192
- package/dist/collection/components/modal/modal.md.css +4 -0
- package/dist/collection/components/popover/animations/ios.enter.js +5 -21
- package/dist/collection/components/popover/animations/md.enter.js +4 -20
- package/dist/collection/components/popover/utils.js +1 -32
- package/dist/collection/components/tab-bar/tab-bar.js +23 -3
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +6 -79
- package/dist/esm/ion-modal.entry.js +12 -200
- package/dist/esm/ion-popover.entry.js +10 -73
- package/dist/esm/ion-tab-bar_2.entry.js +23 -3
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-172a579f.entry.js +4 -0
- package/dist/ionic/p-732b2fd6.entry.js +4 -0
- package/dist/ionic/p-91840a80.entry.js +4 -0
- package/dist/ionic/p-f9061316.entry.js +4 -0
- package/dist/types/components/content/content.d.ts +0 -24
- package/dist/types/components/modal/gestures/sheet.d.ts +1 -1
- package/dist/types/components/modal/gestures/swipe-to-close.d.ts +1 -1
- package/dist/types/components/modal/modal.d.ts +0 -39
- package/dist/types/components/popover/utils.d.ts +0 -2
- package/dist/types/components/tab-bar/tab-bar.d.ts +1 -0
- package/hydrate/index.js +50 -353
- package/hydrate/index.mjs +50 -353
- package/package.json +1 -1
- package/dist/ionic/p-3830217a.entry.js +0 -4
- package/dist/ionic/p-7268efa5.entry.js +0 -4
- package/dist/ionic/p-a4827773.entry.js +0 -4
- package/dist/ionic/p-cecd141b.entry.js +0 -4
package/hydrate/index.mjs
CHANGED
|
@@ -10497,7 +10497,7 @@ const isRTL$1 = (hostEl) => {
|
|
|
10497
10497
|
return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
|
|
10498
10498
|
};
|
|
10499
10499
|
|
|
10500
|
-
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)}
|
|
10500
|
+
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)}";
|
|
10501
10501
|
|
|
10502
10502
|
/**
|
|
10503
10503
|
* @slot - Content is placed in the scrollable area if provided without a slot.
|
|
@@ -10521,12 +10521,6 @@ class Content {
|
|
|
10521
10521
|
this.isMainContent = true;
|
|
10522
10522
|
this.resizeTimeout = null;
|
|
10523
10523
|
this.inheritedAttributes = {};
|
|
10524
|
-
/**
|
|
10525
|
-
* Track whether this content has sibling header/footer elements.
|
|
10526
|
-
* When absent, we need to apply safe-area padding directly.
|
|
10527
|
-
*/
|
|
10528
|
-
this.hasHeader = false;
|
|
10529
|
-
this.hasFooter = false;
|
|
10530
10524
|
this.tabsElement = null;
|
|
10531
10525
|
// Detail is used in a hot loop in the scroll event, by allocating it here
|
|
10532
10526
|
// V8 will be able to inline any read/write to it since it's a monomorphic class.
|
|
@@ -10582,8 +10576,6 @@ class Content {
|
|
|
10582
10576
|
}
|
|
10583
10577
|
connectedCallback() {
|
|
10584
10578
|
this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
|
|
10585
|
-
// Detect sibling header/footer for safe-area handling
|
|
10586
|
-
this.detectSiblingElements();
|
|
10587
10579
|
/**
|
|
10588
10580
|
* The fullscreen content offsets need to be
|
|
10589
10581
|
* computed after the tab bar has loaded. Since
|
|
@@ -10619,70 +10611,8 @@ class Content {
|
|
|
10619
10611
|
}
|
|
10620
10612
|
}
|
|
10621
10613
|
}
|
|
10622
|
-
/**
|
|
10623
|
-
* Detects sibling ion-header and ion-footer elements and sets up
|
|
10624
|
-
* a mutation observer to handle dynamic changes (e.g., conditional rendering).
|
|
10625
|
-
*/
|
|
10626
|
-
detectSiblingElements() {
|
|
10627
|
-
this.updateSiblingDetection();
|
|
10628
|
-
// Watch for dynamic header/footer changes (common in React conditional rendering)
|
|
10629
|
-
const parent = this.el.parentElement;
|
|
10630
|
-
if (parent && !this.parentMutationObserver) {
|
|
10631
|
-
this.parentMutationObserver = new MutationObserver(() => {
|
|
10632
|
-
this.updateSiblingDetection();
|
|
10633
|
-
});
|
|
10634
|
-
this.parentMutationObserver.observe(parent, { childList: true });
|
|
10635
|
-
}
|
|
10636
|
-
}
|
|
10637
|
-
/**
|
|
10638
|
-
* Updates hasHeader/hasFooter based on current DOM state.
|
|
10639
|
-
* Checks both direct siblings and elements wrapped in custom components
|
|
10640
|
-
* (e.g., <my-header><ion-header>...</ion-header></my-header>).
|
|
10641
|
-
*/
|
|
10642
|
-
updateSiblingDetection() {
|
|
10643
|
-
const parent = this.el.parentElement;
|
|
10644
|
-
if (parent) {
|
|
10645
|
-
// First check for direct ion-header/ion-footer siblings
|
|
10646
|
-
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
|
|
10647
|
-
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
|
|
10648
|
-
// If not found, check if any sibling contains them (wrapped components)
|
|
10649
|
-
if (!this.hasHeader) {
|
|
10650
|
-
this.hasHeader = this.siblingContainsElement(parent, 'ion-header');
|
|
10651
|
-
}
|
|
10652
|
-
if (!this.hasFooter) {
|
|
10653
|
-
this.hasFooter = this.siblingContainsElement(parent, 'ion-footer');
|
|
10654
|
-
}
|
|
10655
|
-
}
|
|
10656
|
-
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
|
|
10657
|
-
if (!this.hasFooter) {
|
|
10658
|
-
const tabs = this.el.closest('ion-tabs');
|
|
10659
|
-
if (tabs) {
|
|
10660
|
-
this.hasFooter = tabs.querySelector(':scope > ion-tab-bar') !== null;
|
|
10661
|
-
}
|
|
10662
|
-
}
|
|
10663
|
-
}
|
|
10664
|
-
/**
|
|
10665
|
-
* Checks if any sibling element of ion-content contains the specified element.
|
|
10666
|
-
* Only searches one level deep to avoid finding elements in nested pages.
|
|
10667
|
-
*/
|
|
10668
|
-
siblingContainsElement(parent, tagName) {
|
|
10669
|
-
for (const sibling of parent.children) {
|
|
10670
|
-
// Skip ion-content itself
|
|
10671
|
-
if (sibling === this.el)
|
|
10672
|
-
continue;
|
|
10673
|
-
// Check if this sibling contains the target element as an immediate child
|
|
10674
|
-
if (sibling.querySelector(`:scope > ${tagName}`) !== null) {
|
|
10675
|
-
return true;
|
|
10676
|
-
}
|
|
10677
|
-
}
|
|
10678
|
-
return false;
|
|
10679
|
-
}
|
|
10680
10614
|
disconnectedCallback() {
|
|
10681
|
-
var _a;
|
|
10682
10615
|
this.onScrollEnd();
|
|
10683
|
-
// Clean up mutation observer to prevent memory leaks
|
|
10684
|
-
(_a = this.parentMutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
10685
|
-
this.parentMutationObserver = undefined;
|
|
10686
10616
|
if (hasLazyBuild(this.el)) {
|
|
10687
10617
|
/**
|
|
10688
10618
|
* The event listener and tabs caches need to
|
|
@@ -10911,28 +10841,26 @@ class Content {
|
|
|
10911
10841
|
}
|
|
10912
10842
|
}
|
|
10913
10843
|
render() {
|
|
10914
|
-
const { fixedSlotPlacement,
|
|
10844
|
+
const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
|
|
10915
10845
|
const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
|
|
10916
10846
|
const mode = getIonMode$1(this);
|
|
10917
10847
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
10918
10848
|
const transitionShadow = mode === 'ios';
|
|
10919
10849
|
this.resize();
|
|
10920
|
-
return (hAsync(Host, Object.assign({ key: '
|
|
10850
|
+
return (hAsync(Host, Object.assign({ key: 'cd8781f848d8dc926fe66f43d43c49564425a507', role: isMainContent ? 'main' : undefined, class: createColorClasses$1(this.color, {
|
|
10921
10851
|
[mode]: true,
|
|
10922
10852
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
10923
10853
|
overscroll: forceOverscroll,
|
|
10924
10854
|
[`content-${rtl}`]: true,
|
|
10925
|
-
'safe-area-top': isMainContent && !hasHeader,
|
|
10926
|
-
'safe-area-bottom': isMainContent && !hasFooter,
|
|
10927
10855
|
}), style: {
|
|
10928
10856
|
'--offset-top': `${this.cTop}px`,
|
|
10929
10857
|
'--offset-bottom': `${this.cBottom}px`,
|
|
10930
|
-
} }, inheritedAttributes), hAsync("div", { key: '
|
|
10858
|
+
} }, inheritedAttributes), hAsync("div", { key: '95b112d7cae30f22ef778ceffb88edb4d941c170', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? hAsync("slot", { name: "fixed" }) : null, hAsync("div", { key: '2fdfcbc39fb66f11b6191911f2941c660f4c12e5', class: {
|
|
10931
10859
|
'inner-scroll': true,
|
|
10932
10860
|
'scroll-x': scrollX,
|
|
10933
10861
|
'scroll-y': scrollY,
|
|
10934
10862
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
10935
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, hAsync("slot", { key: '
|
|
10863
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, hAsync("slot", { key: '6bc77e0054ec8e21635a7f2abfe0ca46e0962e03' })), transitionShadow ? (hAsync("div", { class: "transition-effect" }, hAsync("div", { class: "transition-cover" }), hAsync("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? hAsync("slot", { name: "fixed" }) : null));
|
|
10936
10864
|
}
|
|
10937
10865
|
get el() { return getElement(this); }
|
|
10938
10866
|
static get style() { return contentCss; }
|
|
@@ -21603,7 +21531,7 @@ const calculateSpringStep = (t) => {
|
|
|
21603
21531
|
const SwipeToCloseDefaults = {
|
|
21604
21532
|
MIN_PRESENTING_SCALE: 0.915,
|
|
21605
21533
|
};
|
|
21606
|
-
const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss
|
|
21534
|
+
const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
|
|
21607
21535
|
/**
|
|
21608
21536
|
* The step value at which a card modal
|
|
21609
21537
|
* is eligible for dismissing via gesture.
|
|
@@ -21760,8 +21688,6 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onG
|
|
|
21760
21688
|
const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
|
|
21761
21689
|
const clampedStep = clamp(0.0001, processedStep, maxStep);
|
|
21762
21690
|
animation.progressStep(clampedStep);
|
|
21763
|
-
// Notify modal of position change for safe-area updates
|
|
21764
|
-
onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
|
|
21765
21691
|
/**
|
|
21766
21692
|
* When swiping down half way, the status bar style
|
|
21767
21693
|
* should be reset to its default value.
|
|
@@ -22305,7 +22231,7 @@ const mdLeaveAnimation$2 = (baseEl, opts) => {
|
|
|
22305
22231
|
return baseAnimation;
|
|
22306
22232
|
};
|
|
22307
22233
|
|
|
22308
|
-
const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange
|
|
22234
|
+
const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
|
|
22309
22235
|
// Defaults for the sheet swipe animation
|
|
22310
22236
|
const defaultBackdrop = [
|
|
22311
22237
|
{ offset: 0, opacity: 'var(--backdrop-opacity)' },
|
|
@@ -22636,8 +22562,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
22636
22562
|
: step;
|
|
22637
22563
|
offset = clamp(0.0001, processedStep, maxStep);
|
|
22638
22564
|
animation.progressStep(offset);
|
|
22639
|
-
// Notify modal of position change for safe-area updates
|
|
22640
|
-
onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
|
|
22641
22565
|
};
|
|
22642
22566
|
const onEnd = (detail) => {
|
|
22643
22567
|
/**
|
|
@@ -22832,9 +22756,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
22832
22756
|
};
|
|
22833
22757
|
};
|
|
22834
22758
|
|
|
22835
|
-
const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
|
|
22759
|
+
const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}";
|
|
22836
22760
|
|
|
22837
|
-
const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
|
|
22761
|
+
const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
|
|
22838
22762
|
|
|
22839
22763
|
// TODO(FW-2832): types
|
|
22840
22764
|
/**
|
|
@@ -22867,10 +22791,6 @@ class Modal {
|
|
|
22867
22791
|
this.inline = false;
|
|
22868
22792
|
// Whether or not modal is being dismissed via gesture
|
|
22869
22793
|
this.gestureAnimationDismissing = false;
|
|
22870
|
-
// Whether to skip coordinate-based safe-area detection (for fullscreen phone modals)
|
|
22871
|
-
this.skipSafeAreaCoordinateDetection = false;
|
|
22872
|
-
// Track previous safe-area state to avoid redundant DOM writes
|
|
22873
|
-
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
22874
22794
|
this.presented = false;
|
|
22875
22795
|
/** @internal */
|
|
22876
22796
|
this.hasController = false;
|
|
@@ -23061,10 +22981,7 @@ class Modal {
|
|
|
23061
22981
|
}
|
|
23062
22982
|
}
|
|
23063
22983
|
onWindowResize() {
|
|
23064
|
-
//
|
|
23065
|
-
this.cachedSafeAreas = undefined;
|
|
23066
|
-
this.updateSafeAreaOverrides();
|
|
23067
|
-
// Only handle view transition for iOS card modals when no custom animations are provided
|
|
22984
|
+
// Only handle resize for iOS card modals when no custom animations are provided
|
|
23068
22985
|
if (getIonMode$1(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
|
|
23069
22986
|
return;
|
|
23070
22987
|
}
|
|
@@ -23246,8 +23163,6 @@ class Modal {
|
|
|
23246
23163
|
else if (!this.keepContentsMounted) {
|
|
23247
23164
|
await waitForMount();
|
|
23248
23165
|
}
|
|
23249
|
-
// Predict safe-area needs based on modal configuration to avoid visual snap
|
|
23250
|
-
this.setInitialSafeAreaOverrides(presentingElement);
|
|
23251
23166
|
writeTask(() => this.el.classList.add('show-modal'));
|
|
23252
23167
|
const hasCardModal = presentingElement !== undefined;
|
|
23253
23168
|
/**
|
|
@@ -23309,8 +23224,6 @@ class Modal {
|
|
|
23309
23224
|
else if (hasCardModal) {
|
|
23310
23225
|
this.initSwipeToClose();
|
|
23311
23226
|
}
|
|
23312
|
-
// Now that animation is complete, update safe-area based on actual position
|
|
23313
|
-
this.updateSafeAreaOverrides();
|
|
23314
23227
|
// Initialize view transition listener for iOS card modals
|
|
23315
23228
|
this.initViewTransitionListener();
|
|
23316
23229
|
// Initialize parent removal observer
|
|
@@ -23362,7 +23275,7 @@ class Modal {
|
|
|
23362
23275
|
await this.dismiss(undefined, GESTURE);
|
|
23363
23276
|
this.gestureAnimationDismissing = false;
|
|
23364
23277
|
});
|
|
23365
|
-
}
|
|
23278
|
+
});
|
|
23366
23279
|
this.gesture.enable(true);
|
|
23367
23280
|
}
|
|
23368
23281
|
initSheetGesture() {
|
|
@@ -23383,8 +23296,7 @@ class Modal {
|
|
|
23383
23296
|
this.currentBreakpoint = breakpoint;
|
|
23384
23297
|
this.ionBreakpointDidChange.emit({ breakpoint });
|
|
23385
23298
|
}
|
|
23386
|
-
|
|
23387
|
-
}, () => this.updateSafeAreaOverrides());
|
|
23299
|
+
});
|
|
23388
23300
|
this.gesture = gesture;
|
|
23389
23301
|
this.moveSheetToBreakpoint = moveSheetToBreakpoint;
|
|
23390
23302
|
this.gesture.enable(true);
|
|
@@ -23462,161 +23374,6 @@ class Modal {
|
|
|
23462
23374
|
// Clear the cached reference
|
|
23463
23375
|
this.cachedPageParent = undefined;
|
|
23464
23376
|
}
|
|
23465
|
-
/**
|
|
23466
|
-
* Sets initial safe-area overrides based on modal configuration before
|
|
23467
|
-
* the modal becomes visible. This predicts whether the modal will touch
|
|
23468
|
-
* screen edges to avoid a visual snap after animation completes.
|
|
23469
|
-
*/
|
|
23470
|
-
setInitialSafeAreaOverrides(presentingElement) {
|
|
23471
|
-
const style = this.el.style;
|
|
23472
|
-
const mode = getIonMode$1(this);
|
|
23473
|
-
const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
|
|
23474
|
-
// Card modals only exist in iOS mode - in MD mode, presentingElement is ignored
|
|
23475
|
-
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
23476
|
-
const isTablet = window.innerWidth >= 768;
|
|
23477
|
-
// Sheet modals always touch bottom edge, never top/left/right
|
|
23478
|
-
if (isSheetModal) {
|
|
23479
|
-
style.setProperty('--ion-safe-area-top', '0px');
|
|
23480
|
-
style.setProperty('--ion-safe-area-left', '0px');
|
|
23481
|
-
style.setProperty('--ion-safe-area-right', '0px');
|
|
23482
|
-
return;
|
|
23483
|
-
}
|
|
23484
|
-
// Card modals have rounded top corners
|
|
23485
|
-
if (isCardModal) {
|
|
23486
|
-
style.setProperty('--ion-safe-area-top', '0px');
|
|
23487
|
-
if (isTablet) {
|
|
23488
|
-
// On tablets, card modals are inset from all edges
|
|
23489
|
-
this.zeroAllSafeAreas();
|
|
23490
|
-
}
|
|
23491
|
-
else {
|
|
23492
|
-
// On phones, card modals still extend to the bottom edge
|
|
23493
|
-
style.setProperty('--ion-safe-area-left', '0px');
|
|
23494
|
-
style.setProperty('--ion-safe-area-right', '0px');
|
|
23495
|
-
this.applyFullscreenSafeArea();
|
|
23496
|
-
}
|
|
23497
|
-
return;
|
|
23498
|
-
}
|
|
23499
|
-
// Phone-sized fullscreen modals inherit safe areas and use wrapper padding
|
|
23500
|
-
if (!isTablet) {
|
|
23501
|
-
this.applyFullscreenSafeArea();
|
|
23502
|
-
return;
|
|
23503
|
-
}
|
|
23504
|
-
// Check if tablet modal is fullscreen via CSS custom properties
|
|
23505
|
-
const computedStyle = getComputedStyle(this.el);
|
|
23506
|
-
const width = computedStyle.getPropertyValue('--width').trim();
|
|
23507
|
-
const height = computedStyle.getPropertyValue('--height').trim();
|
|
23508
|
-
const isFullscreen = width === '100%' && height === '100%';
|
|
23509
|
-
if (isFullscreen) {
|
|
23510
|
-
this.applyFullscreenSafeArea();
|
|
23511
|
-
}
|
|
23512
|
-
else {
|
|
23513
|
-
// Centered dialog doesn't touch edges
|
|
23514
|
-
this.zeroAllSafeAreas();
|
|
23515
|
-
}
|
|
23516
|
-
}
|
|
23517
|
-
/**
|
|
23518
|
-
* Applies safe-area handling for fullscreen modals.
|
|
23519
|
-
* Adds wrapper padding when no footer is present to prevent
|
|
23520
|
-
* content from overlapping system navigation areas.
|
|
23521
|
-
*/
|
|
23522
|
-
applyFullscreenSafeArea() {
|
|
23523
|
-
this.skipSafeAreaCoordinateDetection = true;
|
|
23524
|
-
this.updateFooterPadding();
|
|
23525
|
-
// Watch for dynamic footer additions/removals (e.g., async data loading)
|
|
23526
|
-
if (!this.footerObserver) {
|
|
23527
|
-
this.footerObserver = new MutationObserver(() => this.updateFooterPadding());
|
|
23528
|
-
this.footerObserver.observe(this.el, { childList: true, subtree: true });
|
|
23529
|
-
}
|
|
23530
|
-
}
|
|
23531
|
-
/**
|
|
23532
|
-
* Updates wrapper padding based on footer presence.
|
|
23533
|
-
* Called initially and when footer is dynamically added/removed.
|
|
23534
|
-
*/
|
|
23535
|
-
updateFooterPadding() {
|
|
23536
|
-
if (!this.wrapperEl)
|
|
23537
|
-
return;
|
|
23538
|
-
const hasFooter = this.el.querySelector('ion-footer') !== null;
|
|
23539
|
-
if (hasFooter) {
|
|
23540
|
-
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
23541
|
-
this.wrapperEl.style.removeProperty('box-sizing');
|
|
23542
|
-
}
|
|
23543
|
-
else {
|
|
23544
|
-
this.wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
|
|
23545
|
-
this.wrapperEl.style.setProperty('box-sizing', 'border-box');
|
|
23546
|
-
}
|
|
23547
|
-
}
|
|
23548
|
-
/**
|
|
23549
|
-
* Sets all safe-area CSS variables to 0px for modals that
|
|
23550
|
-
* don't touch screen edges.
|
|
23551
|
-
*/
|
|
23552
|
-
zeroAllSafeAreas() {
|
|
23553
|
-
const style = this.el.style;
|
|
23554
|
-
style.setProperty('--ion-safe-area-top', '0px');
|
|
23555
|
-
style.setProperty('--ion-safe-area-bottom', '0px');
|
|
23556
|
-
style.setProperty('--ion-safe-area-left', '0px');
|
|
23557
|
-
style.setProperty('--ion-safe-area-right', '0px');
|
|
23558
|
-
}
|
|
23559
|
-
/**
|
|
23560
|
-
* Gets the root safe-area values from the document element.
|
|
23561
|
-
* Uses cached values during gestures to avoid getComputedStyle calls.
|
|
23562
|
-
*/
|
|
23563
|
-
getSafeAreaValues() {
|
|
23564
|
-
if (!this.cachedSafeAreas) {
|
|
23565
|
-
const rootStyle = getComputedStyle(document.documentElement);
|
|
23566
|
-
this.cachedSafeAreas = {
|
|
23567
|
-
top: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-top')) || 0,
|
|
23568
|
-
bottom: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-bottom')) || 0,
|
|
23569
|
-
left: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-left')) || 0,
|
|
23570
|
-
right: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-right')) || 0,
|
|
23571
|
-
};
|
|
23572
|
-
}
|
|
23573
|
-
return this.cachedSafeAreas;
|
|
23574
|
-
}
|
|
23575
|
-
/**
|
|
23576
|
-
* Updates safe-area CSS variable overrides based on whether the modal
|
|
23577
|
-
* extends into each safe-area region. Called after animation
|
|
23578
|
-
* and during gestures to handle dynamic position changes.
|
|
23579
|
-
*
|
|
23580
|
-
* Optimized to avoid redundant DOM writes by tracking previous state.
|
|
23581
|
-
*/
|
|
23582
|
-
updateSafeAreaOverrides() {
|
|
23583
|
-
if (this.skipSafeAreaCoordinateDetection) {
|
|
23584
|
-
return;
|
|
23585
|
-
}
|
|
23586
|
-
const wrapper = this.wrapperEl;
|
|
23587
|
-
if (!wrapper) {
|
|
23588
|
-
return;
|
|
23589
|
-
}
|
|
23590
|
-
const rect = wrapper.getBoundingClientRect();
|
|
23591
|
-
const safeAreas = this.getSafeAreaValues();
|
|
23592
|
-
const extendsIntoTop = rect.top < safeAreas.top;
|
|
23593
|
-
const extendsIntoBottom = rect.bottom > window.innerHeight - safeAreas.bottom;
|
|
23594
|
-
const extendsIntoLeft = rect.left < safeAreas.left;
|
|
23595
|
-
const extendsIntoRight = rect.right > window.innerWidth - safeAreas.right;
|
|
23596
|
-
// Only update DOM when state actually changes
|
|
23597
|
-
const prev = this.prevSafeAreaState;
|
|
23598
|
-
const style = this.el.style;
|
|
23599
|
-
if (extendsIntoTop !== prev.top) {
|
|
23600
|
-
extendsIntoTop ? style.removeProperty('--ion-safe-area-top') : style.setProperty('--ion-safe-area-top', '0px');
|
|
23601
|
-
prev.top = extendsIntoTop;
|
|
23602
|
-
}
|
|
23603
|
-
if (extendsIntoBottom !== prev.bottom) {
|
|
23604
|
-
extendsIntoBottom
|
|
23605
|
-
? style.removeProperty('--ion-safe-area-bottom')
|
|
23606
|
-
: style.setProperty('--ion-safe-area-bottom', '0px');
|
|
23607
|
-
prev.bottom = extendsIntoBottom;
|
|
23608
|
-
}
|
|
23609
|
-
if (extendsIntoLeft !== prev.left) {
|
|
23610
|
-
extendsIntoLeft ? style.removeProperty('--ion-safe-area-left') : style.setProperty('--ion-safe-area-left', '0px');
|
|
23611
|
-
prev.left = extendsIntoLeft;
|
|
23612
|
-
}
|
|
23613
|
-
if (extendsIntoRight !== prev.right) {
|
|
23614
|
-
extendsIntoRight
|
|
23615
|
-
? style.removeProperty('--ion-safe-area-right')
|
|
23616
|
-
: style.setProperty('--ion-safe-area-right', '0px');
|
|
23617
|
-
prev.right = extendsIntoRight;
|
|
23618
|
-
}
|
|
23619
|
-
}
|
|
23620
23377
|
sheetOnDismiss() {
|
|
23621
23378
|
/**
|
|
23622
23379
|
* While the gesture animation is finishing
|
|
@@ -23647,7 +23404,7 @@ class Modal {
|
|
|
23647
23404
|
* For example, `cancel` or `backdrop`.
|
|
23648
23405
|
*/
|
|
23649
23406
|
async dismiss(data, role) {
|
|
23650
|
-
var _a
|
|
23407
|
+
var _a;
|
|
23651
23408
|
if (this.gestureAnimationDismissing && role !== GESTURE) {
|
|
23652
23409
|
return false;
|
|
23653
23410
|
}
|
|
@@ -23709,23 +23466,6 @@ class Modal {
|
|
|
23709
23466
|
}
|
|
23710
23467
|
this.currentBreakpoint = undefined;
|
|
23711
23468
|
this.animation = undefined;
|
|
23712
|
-
// Reset safe-area state for potential re-presentation
|
|
23713
|
-
this.skipSafeAreaCoordinateDetection = false;
|
|
23714
|
-
this.cachedSafeAreas = undefined;
|
|
23715
|
-
this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
|
|
23716
|
-
(_b = this.footerObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
23717
|
-
this.footerObserver = undefined;
|
|
23718
|
-
// Clear styles that may have been set for safe-area handling
|
|
23719
|
-
if (this.wrapperEl) {
|
|
23720
|
-
this.wrapperEl.style.removeProperty('padding-bottom');
|
|
23721
|
-
this.wrapperEl.style.removeProperty('box-sizing');
|
|
23722
|
-
}
|
|
23723
|
-
// Clear safe-area CSS variable overrides
|
|
23724
|
-
const style = this.el.style;
|
|
23725
|
-
style.removeProperty('--ion-safe-area-top');
|
|
23726
|
-
style.removeProperty('--ion-safe-area-bottom');
|
|
23727
|
-
style.removeProperty('--ion-safe-area-left');
|
|
23728
|
-
style.removeProperty('--ion-safe-area-right');
|
|
23729
23469
|
unlock();
|
|
23730
23470
|
return dismissed;
|
|
23731
23471
|
}
|
|
@@ -23975,20 +23715,20 @@ class Modal {
|
|
|
23975
23715
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
23976
23716
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
23977
23717
|
const isSheetModalWithHandle = isSheetModal && showHandle;
|
|
23978
|
-
return (hAsync(Host, Object.assign({ key: '
|
|
23718
|
+
return (hAsync(Host, Object.assign({ key: '87328006ea6c75ebc518ace300438492a567223e', "no-router": true,
|
|
23979
23719
|
// Allow the modal to be navigable when the handle is focusable
|
|
23980
23720
|
tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
|
|
23981
23721
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
23982
|
-
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), hAsync("ion-backdrop", { key: '
|
|
23722
|
+
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), hAsync("ion-backdrop", { key: 'ee94ff8e09b691dd4ad4e4db1720f06bc3c5a469', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: 'bffd69b4635c22d9f249725bd952c1e93d5615c7', class: "modal-shadow" }), hAsync("div", Object.assign({ key: '1d394d3c68916e464ff1fbf5242419f4a3d3cca1',
|
|
23983
23723
|
/*
|
|
23984
23724
|
role and aria-modal must be used on the
|
|
23985
23725
|
same element. They must also be set inside the
|
|
23986
23726
|
shadow DOM otherwise ion-button will not be highlighted
|
|
23987
23727
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
23988
23728
|
*/
|
|
23989
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '
|
|
23729
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '2dcf58792018e557e0c323baad2d672bc99c0bb1', class: "modal-handle",
|
|
23990
23730
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
23991
|
-
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), hAsync("slot", { key: '
|
|
23731
|
+
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), hAsync("slot", { key: '44164b1e8710c3895400ad9f44ecd99873874ad5', onSlotchange: this.onSlotChange }))));
|
|
23992
23732
|
}
|
|
23993
23733
|
get el() { return getElement(this); }
|
|
23994
23734
|
static get watchers() { return {
|
|
@@ -27566,8 +27306,6 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
27566
27306
|
let bottom;
|
|
27567
27307
|
let originX = contentOriginX;
|
|
27568
27308
|
let originY = contentOriginY;
|
|
27569
|
-
let checkSafeAreaTop = false;
|
|
27570
|
-
let checkSafeAreaBottom = false;
|
|
27571
27309
|
let checkSafeAreaLeft = false;
|
|
27572
27310
|
let checkSafeAreaRight = false;
|
|
27573
27311
|
const triggerTop = triggerCoordinates
|
|
@@ -27612,18 +27350,10 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
27612
27350
|
* We chose 12 here so that the popover position looks a bit nicer as
|
|
27613
27351
|
* it is not right up against the edge of the screen.
|
|
27614
27352
|
*/
|
|
27615
|
-
top = Math.max(
|
|
27353
|
+
top = Math.max(12, triggerTop - contentHeight - triggerHeight - (arrowHeight - 1));
|
|
27616
27354
|
arrowTop = top + contentHeight;
|
|
27617
27355
|
originY = 'bottom';
|
|
27618
27356
|
addPopoverBottomClass = true;
|
|
27619
|
-
/**
|
|
27620
|
-
* If the popover is positioned near the top edge, account for safe area.
|
|
27621
|
-
* This ensures the popover doesn't overlap with status bars or notches.
|
|
27622
|
-
*/
|
|
27623
|
-
if (top <= bodyPadding + safeAreaMargin) {
|
|
27624
|
-
checkSafeAreaTop = true;
|
|
27625
|
-
top = bodyPadding;
|
|
27626
|
-
}
|
|
27627
27357
|
/**
|
|
27628
27358
|
* If not enough room for popover to appear
|
|
27629
27359
|
* above trigger, then cut it off.
|
|
@@ -27631,35 +27361,14 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
27631
27361
|
}
|
|
27632
27362
|
else {
|
|
27633
27363
|
bottom = bodyPadding;
|
|
27634
|
-
/**
|
|
27635
|
-
* When the popover is pinned to the bottom, account for safe area.
|
|
27636
|
-
* This ensures the popover doesn't overlap with home indicators
|
|
27637
|
-
* or navigation bars (e.g., Android API 36+ edge-to-edge).
|
|
27638
|
-
*/
|
|
27639
|
-
checkSafeAreaBottom = true;
|
|
27640
27364
|
}
|
|
27641
27365
|
}
|
|
27642
|
-
/**
|
|
27643
|
-
* Final check: If the popover extends into any safe-area region,
|
|
27644
|
-
* ensure the corresponding flag is set regardless of side.
|
|
27645
|
-
* This handles cases where a side-positioned popover (left/right)
|
|
27646
|
-
* still needs bottom safe-area padding because it extends into that region.
|
|
27647
|
-
*/
|
|
27648
|
-
const popoverBottom = bottom !== undefined ? bodyHeight - bottom : top + contentHeight;
|
|
27649
|
-
if (popoverBottom + safeAreaMargin > bodyHeight) {
|
|
27650
|
-
checkSafeAreaBottom = true;
|
|
27651
|
-
}
|
|
27652
|
-
if (top < safeAreaMargin) {
|
|
27653
|
-
checkSafeAreaTop = true;
|
|
27654
|
-
}
|
|
27655
27366
|
return {
|
|
27656
27367
|
top,
|
|
27657
27368
|
left,
|
|
27658
27369
|
bottom,
|
|
27659
27370
|
originX,
|
|
27660
27371
|
originY,
|
|
27661
|
-
checkSafeAreaTop,
|
|
27662
|
-
checkSafeAreaBottom,
|
|
27663
27372
|
checkSafeAreaLeft,
|
|
27664
27373
|
checkSafeAreaRight,
|
|
27665
27374
|
arrowTop,
|
|
@@ -27720,7 +27429,7 @@ const iosEnterAnimation$1 = (baseEl, opts) => {
|
|
|
27720
27429
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, trigger, ev);
|
|
27721
27430
|
const padding = size === 'cover' ? 0 : POPOVER_IOS_BODY_PADDING;
|
|
27722
27431
|
const margin = size === 'cover' ? 0 : 25;
|
|
27723
|
-
const { originX, originY, top, left, bottom,
|
|
27432
|
+
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);
|
|
27724
27433
|
const baseAnimation = createAnimation();
|
|
27725
27434
|
const backdropAnimation = createAnimation();
|
|
27726
27435
|
const contentAnimation = createAnimation();
|
|
@@ -27750,35 +27459,19 @@ const iosEnterAnimation$1 = (baseEl, opts) => {
|
|
|
27750
27459
|
if (addPopoverBottomClass) {
|
|
27751
27460
|
baseEl.classList.add('popover-bottom');
|
|
27752
27461
|
}
|
|
27753
|
-
|
|
27754
|
-
|
|
27755
|
-
|
|
27756
|
-
* safe-area inset to ensure the popover doesn't overlap with system UI
|
|
27757
|
-
* (status bars, home indicators, navigation bars on Android API 36+, etc.)
|
|
27758
|
-
*/
|
|
27759
|
-
const safeAreaTop = ' + var(--ion-safe-area-top, 0)';
|
|
27760
|
-
const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0)';
|
|
27462
|
+
if (bottom !== undefined) {
|
|
27463
|
+
contentEl.style.setProperty('bottom', `${bottom}px`);
|
|
27464
|
+
}
|
|
27761
27465
|
const safeAreaLeft = ' + var(--ion-safe-area-left, 0)';
|
|
27762
27466
|
const safeAreaRight = ' - var(--ion-safe-area-right, 0)';
|
|
27763
|
-
let topValue = `${top}px`;
|
|
27764
|
-
let bottomValue = bottom !== undefined ? `${bottom}px` : undefined;
|
|
27765
27467
|
let leftValue = `${left}px`;
|
|
27766
|
-
if (checkSafeAreaTop) {
|
|
27767
|
-
topValue = `${top}px${safeAreaTop}`;
|
|
27768
|
-
}
|
|
27769
|
-
if (checkSafeAreaBottom && bottomValue !== undefined) {
|
|
27770
|
-
bottomValue = `${bottom}px${safeAreaBottom}`;
|
|
27771
|
-
}
|
|
27772
27468
|
if (checkSafeAreaLeft) {
|
|
27773
27469
|
leftValue = `${left}px${safeAreaLeft}`;
|
|
27774
27470
|
}
|
|
27775
27471
|
if (checkSafeAreaRight) {
|
|
27776
27472
|
leftValue = `${left}px${safeAreaRight}`;
|
|
27777
27473
|
}
|
|
27778
|
-
|
|
27779
|
-
contentEl.style.setProperty('bottom', `calc(${bottomValue})`);
|
|
27780
|
-
}
|
|
27781
|
-
contentEl.style.setProperty('top', `calc(${topValue} + var(--offset-y, 0))`);
|
|
27474
|
+
contentEl.style.setProperty('top', `calc(${top}px + var(--offset-y, 0))`);
|
|
27782
27475
|
contentEl.style.setProperty('left', `calc(${leftValue} + var(--offset-x, 0))`);
|
|
27783
27476
|
contentEl.style.setProperty('transform-origin', `${originY} ${originX}`);
|
|
27784
27477
|
if (arrowEl !== null) {
|
|
@@ -27854,23 +27547,7 @@ const mdEnterAnimation$1 = (baseEl, opts) => {
|
|
|
27854
27547
|
};
|
|
27855
27548
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
|
|
27856
27549
|
const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
|
|
27857
|
-
const { originX, originY, top, left, bottom
|
|
27858
|
-
/**
|
|
27859
|
-
* Safe area CSS variable adjustments.
|
|
27860
|
-
* When the popover is positioned near an edge, we add the corresponding
|
|
27861
|
-
* safe-area inset to ensure the popover doesn't overlap with system UI
|
|
27862
|
-
* (status bars, home indicators, navigation bars on Android API 36+, etc.)
|
|
27863
|
-
*/
|
|
27864
|
-
const safeAreaTop = ' + var(--ion-safe-area-top, 0)';
|
|
27865
|
-
const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0)';
|
|
27866
|
-
let topValue = `${top}px`;
|
|
27867
|
-
let bottomValue = bottom !== undefined ? `${bottom}px` : undefined;
|
|
27868
|
-
if (checkSafeAreaTop) {
|
|
27869
|
-
topValue = `${top}px${safeAreaTop}`;
|
|
27870
|
-
}
|
|
27871
|
-
if (checkSafeAreaBottom && bottomValue !== undefined) {
|
|
27872
|
-
bottomValue = `${bottom}px${safeAreaBottom}`;
|
|
27873
|
-
}
|
|
27550
|
+
const { originX, originY, top, left, bottom } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
|
|
27874
27551
|
const baseAnimation = createAnimation();
|
|
27875
27552
|
const backdropAnimation = createAnimation();
|
|
27876
27553
|
const wrapperAnimation = createAnimation();
|
|
@@ -27887,13 +27564,13 @@ const mdEnterAnimation$1 = (baseEl, opts) => {
|
|
|
27887
27564
|
contentAnimation
|
|
27888
27565
|
.addElement(contentEl)
|
|
27889
27566
|
.beforeStyles({
|
|
27890
|
-
top: `calc(${
|
|
27567
|
+
top: `calc(${top}px + var(--offset-y, 0px))`,
|
|
27891
27568
|
left: `calc(${left}px + var(--offset-x, 0px))`,
|
|
27892
27569
|
'transform-origin': `${originY} ${originX}`,
|
|
27893
27570
|
})
|
|
27894
27571
|
.beforeAddWrite(() => {
|
|
27895
|
-
if (
|
|
27896
|
-
contentEl.style.setProperty('bottom',
|
|
27572
|
+
if (bottom !== undefined) {
|
|
27573
|
+
contentEl.style.setProperty('bottom', `${bottom}px`);
|
|
27897
27574
|
}
|
|
27898
27575
|
})
|
|
27899
27576
|
.fromTo('transform', 'scale(0.8)', 'scale(1)');
|
|
@@ -35311,6 +34988,7 @@ class TabBar {
|
|
|
35311
34988
|
this.ionTabBarChanged = createEvent(this, "ionTabBarChanged", 7);
|
|
35312
34989
|
this.ionTabBarLoaded = createEvent(this, "ionTabBarLoaded", 7);
|
|
35313
34990
|
this.keyboardCtrl = null;
|
|
34991
|
+
this.keyboardCtrlPromise = null;
|
|
35314
34992
|
this.didLoad = false;
|
|
35315
34993
|
this.keyboardVisible = false;
|
|
35316
34994
|
/**
|
|
@@ -35346,7 +35024,7 @@ class TabBar {
|
|
|
35346
35024
|
}
|
|
35347
35025
|
}
|
|
35348
35026
|
async connectedCallback() {
|
|
35349
|
-
|
|
35027
|
+
const promise = createKeyboardController(async (keyboardOpen, waitForResize) => {
|
|
35350
35028
|
/**
|
|
35351
35029
|
* If the keyboard is hiding, then we need to wait
|
|
35352
35030
|
* for the webview to resize. Otherwise, the tab bar
|
|
@@ -35357,21 +35035,40 @@ class TabBar {
|
|
|
35357
35035
|
}
|
|
35358
35036
|
this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
|
|
35359
35037
|
});
|
|
35038
|
+
this.keyboardCtrlPromise = promise;
|
|
35039
|
+
const keyboardCtrl = await promise;
|
|
35040
|
+
/**
|
|
35041
|
+
* Only assign if this is still the current promise.
|
|
35042
|
+
* Otherwise, a new connectedCallback has started or
|
|
35043
|
+
* disconnectedCallback was called, so destroy this instance.
|
|
35044
|
+
*/
|
|
35045
|
+
if (this.keyboardCtrlPromise === promise) {
|
|
35046
|
+
this.keyboardCtrl = keyboardCtrl;
|
|
35047
|
+
this.keyboardCtrlPromise = null;
|
|
35048
|
+
}
|
|
35049
|
+
else {
|
|
35050
|
+
keyboardCtrl.destroy();
|
|
35051
|
+
}
|
|
35360
35052
|
}
|
|
35361
35053
|
disconnectedCallback() {
|
|
35054
|
+
if (this.keyboardCtrlPromise) {
|
|
35055
|
+
this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
|
|
35056
|
+
this.keyboardCtrlPromise = null;
|
|
35057
|
+
}
|
|
35362
35058
|
if (this.keyboardCtrl) {
|
|
35363
35059
|
this.keyboardCtrl.destroy();
|
|
35060
|
+
this.keyboardCtrl = null;
|
|
35364
35061
|
}
|
|
35365
35062
|
}
|
|
35366
35063
|
render() {
|
|
35367
35064
|
const { color, translucent, keyboardVisible } = this;
|
|
35368
35065
|
const mode = getIonMode$1(this);
|
|
35369
35066
|
const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
|
|
35370
|
-
return (hAsync(Host, { key: '
|
|
35067
|
+
return (hAsync(Host, { key: '9daf4e2acaff6e3ce3878cf9dd5109fb1afbbebe', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: createColorClasses$1(color, {
|
|
35371
35068
|
[mode]: true,
|
|
35372
35069
|
'tab-bar-translucent': translucent,
|
|
35373
35070
|
'tab-bar-hidden': shouldHide,
|
|
35374
|
-
}) }, hAsync("slot", { key: '
|
|
35071
|
+
}) }, hAsync("slot", { key: '1d15aa2da8501e8e7eff11ad4a491478be845c43' })));
|
|
35375
35072
|
}
|
|
35376
35073
|
get el() { return getElement(this); }
|
|
35377
35074
|
static get watchers() { return {
|