@ionic/core 8.7.17-dev.11768239180.18ee1069 → 8.7.17-dev.11769628168.11eca7cd

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.
Files changed (39) hide show
  1. package/components/content.js +4 -3
  2. package/components/ion-range.js +12 -4
  3. package/components/modal.js +12 -213
  4. package/components/popover.js +11 -83
  5. package/dist/cjs/ion-app_8.cjs.entry.js +4 -3
  6. package/dist/cjs/ion-modal.cjs.entry.js +12 -213
  7. package/dist/cjs/ion-popover.cjs.entry.js +11 -83
  8. package/dist/cjs/ion-range.cjs.entry.js +12 -4
  9. package/dist/collection/components/content/content.js +4 -3
  10. package/dist/collection/components/modal/gestures/sheet.js +1 -3
  11. package/dist/collection/components/modal/gestures/swipe-to-close.js +1 -3
  12. package/dist/collection/components/modal/modal.ios.css +4 -0
  13. package/dist/collection/components/modal/modal.js +7 -205
  14. package/dist/collection/components/modal/modal.md.css +4 -0
  15. package/dist/collection/components/popover/animations/ios.enter.js +5 -21
  16. package/dist/collection/components/popover/animations/md.enter.js +5 -30
  17. package/dist/collection/components/popover/utils.js +1 -32
  18. package/dist/collection/components/range/range.js +12 -4
  19. package/dist/docs.json +1 -1
  20. package/dist/esm/ion-app_8.entry.js +4 -3
  21. package/dist/esm/ion-modal.entry.js +12 -213
  22. package/dist/esm/ion-popover.entry.js +11 -83
  23. package/dist/esm/ion-range.entry.js +12 -4
  24. package/dist/ionic/ionic.esm.js +1 -1
  25. package/dist/ionic/p-012212e4.entry.js +4 -0
  26. package/dist/ionic/p-91840a80.entry.js +4 -0
  27. package/dist/ionic/p-c73627c8.entry.js +4 -0
  28. package/dist/ionic/p-f9061316.entry.js +4 -0
  29. package/dist/types/components/modal/gestures/sheet.d.ts +1 -1
  30. package/dist/types/components/modal/gestures/swipe-to-close.d.ts +1 -1
  31. package/dist/types/components/modal/modal.d.ts +0 -45
  32. package/dist/types/components/popover/utils.d.ts +0 -2
  33. package/hydrate/index.js +38 -302
  34. package/hydrate/index.mjs +38 -302
  35. package/package.json +1 -1
  36. package/dist/ionic/p-1647c46c.entry.js +0 -4
  37. package/dist/ionic/p-732b2fd6.entry.js +0 -4
  38. package/dist/ionic/p-968a55d1.entry.js +0 -4
  39. package/dist/ionic/p-ec9ca3fe.entry.js +0 -4
@@ -372,20 +372,21 @@ const Content = /*@__PURE__*/ proxyCustomElement(class Content extends HTMLEleme
372
372
  const forceOverscroll = this.shouldForceOverscroll();
373
373
  const transitionShadow = mode === 'ios';
374
374
  this.resize();
375
- return (h(Host, Object.assign({ key: 'cd8781f848d8dc926fe66f43d43c49564425a507', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
375
+ return (h(Host, Object.assign({ key: '212b1438f044061887984e02e1c8943ee1d33c20', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
376
376
  [mode]: true,
377
+ 'content-fullscreen': this.fullscreen,
377
378
  'content-sizing': hostContext('ion-popover', this.el),
378
379
  overscroll: forceOverscroll,
379
380
  [`content-${rtl}`]: true,
380
381
  }), style: {
381
382
  '--offset-top': `${this.cTop}px`,
382
383
  '--offset-bottom': `${this.cBottom}px`,
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: {
384
+ } }, inheritedAttributes), h("div", { key: 'ea46641492eef8cc7b08fc398d0285115b5a7100', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: 'dc9096f0b97ab6145fb46cf065cd244f4af1cab5', class: {
384
385
  'inner-scroll': true,
385
386
  'scroll-x': scrollX,
386
387
  'scroll-y': scrollY,
387
388
  overscroll: (scrollX || scrollY) && forceOverscroll,
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));
389
+ }, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '4b13fd5b7e124353d43b47a30e975400ae2a0341' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
389
390
  }
390
391
  get el() { return this; }
391
392
  static get style() { return contentCss; }
@@ -710,7 +710,7 @@ const Range = /*@__PURE__*/ proxyCustomElement(class Range extends HTMLElement {
710
710
  })));
711
711
  }
712
712
  render() {
713
- const { disabled, el, hasLabel, rangeId, pin, pressedKnob, labelPlacement, label } = this;
713
+ const { disabled, el, hasLabel, rangeId, pin, pressedKnob, labelPlacement, label, dualKnobs, min, max } = this;
714
714
  const inItem = hostContext('ion-item', el);
715
715
  /**
716
716
  * If there is no start content then the knob at
@@ -725,8 +725,14 @@ const Range = /*@__PURE__*/ proxyCustomElement(class Range extends HTMLElement {
725
725
  const hasEndContent = (hasLabel && labelPlacement === 'end') || this.hasEndSlotContent;
726
726
  const needsEndAdjustment = inItem && !hasEndContent;
727
727
  const mode = getIonMode(this);
728
+ /**
729
+ * Determine if any knob is at the min or max value to
730
+ * apply Host classes for styling.
731
+ */
732
+ const valueAtMin = dualKnobs ? this.valA === min || this.valB === min : this.valA === min;
733
+ const valueAtMax = dualKnobs ? this.valA === max || this.valB === max : this.valA === max;
728
734
  renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
729
- return (h(Host, { key: 'ef7b01f80515bcaeb2983934ad7f10a6bd5d13ec', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses(this.color, {
735
+ return (h(Host, { key: 'ed646a42d51b8fe22012198c354cbcf5a389c108', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses(this.color, {
730
736
  [mode]: true,
731
737
  'in-item': inItem,
732
738
  'range-disabled': disabled,
@@ -735,10 +741,12 @@ const Range = /*@__PURE__*/ proxyCustomElement(class Range extends HTMLElement {
735
741
  [`range-label-placement-${labelPlacement}`]: true,
736
742
  'range-item-start-adjustment': needsStartAdjustment,
737
743
  'range-item-end-adjustment': needsEndAdjustment,
738
- }) }, h("label", { key: 'fd8aa90a9d52be9da024b907e68858dae424449d', class: "range-wrapper", id: "range-label" }, h("div", { key: '2172b4f329c22017dd23475c80aac25ba6e753eb', class: {
744
+ 'range-value-min': valueAtMin,
745
+ 'range-value-max': valueAtMax,
746
+ }) }, h("label", { key: '3083e4f2a624e3b268396acb4415f7c6ac44d851', class: "range-wrapper", id: "range-label" }, h("div", { key: '47b92f94d2a0381dd7c5cd3dda54ed2942096715', class: {
739
747
  'label-text-wrapper': true,
740
748
  'label-text-wrapper-hidden': !hasLabel,
741
- }, part: "label" }, label !== undefined ? h("div", { class: "label-text" }, label) : h("slot", { name: "label" })), h("div", { key: '3c318bf2ea0576646d4c010bf44573fd0f483186', class: "native-wrapper" }, h("slot", { key: '6586fd6fc96271e73f8a86c202d1913ad1a26f96', name: "start" }), this.renderRangeSlider(), h("slot", { key: '74ac0bc2d2cb66ef708bb729f88b6ecbc1b2155d', name: "end" })))));
749
+ }, part: "label" }, label !== undefined ? h("div", { class: "label-text" }, label) : h("slot", { name: "label" })), h("div", { key: '5341da8d19eb29091df680978a0e20cc8f2eec65', class: "native-wrapper" }, h("slot", { key: '09f1437078032676695442d8c827a16faa7dffe2', name: "start" }), this.renderRangeSlider(), h("slot", { key: '02b7781970ea4d44f10b5f4627a2ca36eca45f85', name: "end" })))));
742
750
  }
743
751
  get el() { return this; }
744
752
  static get watchers() { return {
@@ -2,7 +2,6 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { proxyCustomElement, HTMLElement, createEvent, writeTask, h, Host } from '@stencil/core/internal/client';
5
- import { w as win } from './index9.js';
6
5
  import { a as findClosestIonContent, i as isIonContent, d as disableContentScrollY, r as resetContentScrollY, f as findIonContent, p as printIonContentErrorMsg } from './index8.js';
7
6
  import { C as CoreDelegate, a as attachComponent, d as detachComponent } from './framework-delegate.js';
8
7
  import { f as clamp, g as getElementRoot, r as raf, d as inheritAttributes, k as hasLazyBuild } from './helpers.js';
@@ -17,6 +16,7 @@ import { KEYBOARD_DID_OPEN } from './keyboard.js';
17
16
  import { c as createAnimation } from './animation.js';
18
17
  import { g as getTimeGivenProgression } from './cubic-bezier.js';
19
18
  import { createGesture } from './index3.js';
19
+ import { w as win } from './index9.js';
20
20
  import { d as defineCustomElement$1 } from './backdrop.js';
21
21
 
22
22
  var Style;
@@ -246,7 +246,7 @@ const calculateSpringStep = (t) => {
246
246
  const SwipeToCloseDefaults = {
247
247
  MIN_PRESENTING_SCALE: 0.915,
248
248
  };
249
- const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onGestureMove) => {
249
+ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
250
250
  /**
251
251
  * The step value at which a card modal
252
252
  * is eligible for dismissing via gesture.
@@ -403,8 +403,6 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onG
403
403
  const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
404
404
  const clampedStep = clamp(0.0001, processedStep, maxStep);
405
405
  animation.progressStep(clampedStep);
406
- // Notify modal of position change for safe-area updates
407
- onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
408
406
  /**
409
407
  * When swiping down half way, the status bar style
410
408
  * should be reset to its default value.
@@ -948,7 +946,7 @@ const mdLeaveAnimation = (baseEl, opts) => {
948
946
  return baseAnimation;
949
947
  };
950
948
 
951
- const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange, onGestureMove) => {
949
+ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
952
950
  // Defaults for the sheet swipe animation
953
951
  const defaultBackdrop = [
954
952
  { offset: 0, opacity: 'var(--backdrop-opacity)' },
@@ -1279,8 +1277,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1279
1277
  : step;
1280
1278
  offset = clamp(0.0001, processedStep, maxStep);
1281
1279
  animation.progressStep(offset);
1282
- // Notify modal of position change for safe-area updates
1283
- onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
1284
1280
  };
1285
1281
  const onEnd = (detail) => {
1286
1282
  /**
@@ -1475,9 +1471,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1475
1471
  };
1476
1472
  };
1477
1473
 
1478
- 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}";
1474
+ 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}";
1479
1475
 
1480
- 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}";
1476
+ 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}";
1481
1477
 
1482
1478
  const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
1483
1479
  constructor(registerHost) {
@@ -1504,10 +1500,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
1504
1500
  this.inline = false;
1505
1501
  // Whether or not modal is being dismissed via gesture
1506
1502
  this.gestureAnimationDismissing = false;
1507
- // Whether to skip coordinate-based safe-area detection (for fullscreen phone modals)
1508
- this.skipSafeAreaCoordinateDetection = false;
1509
- // Track previous safe-area state to avoid redundant DOM writes
1510
- this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
1511
1503
  this.presented = false;
1512
1504
  /** @internal */
1513
1505
  this.hasController = false;
@@ -1698,10 +1690,7 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
1698
1690
  }
1699
1691
  }
1700
1692
  onWindowResize() {
1701
- // Invalidate safe-area cache on resize (device rotation may change values)
1702
- this.cachedSafeAreas = undefined;
1703
- this.updateSafeAreaOverrides();
1704
- // Only handle view transition for iOS card modals when no custom animations are provided
1693
+ // Only handle resize for iOS card modals when no custom animations are provided
1705
1694
  if (getIonMode(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
1706
1695
  return;
1707
1696
  }
@@ -1724,8 +1713,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
1724
1713
  this.triggerController.removeClickListener();
1725
1714
  this.cleanupViewTransitionListener();
1726
1715
  this.cleanupParentRemovalObserver();
1727
- // Reset safe-area state to handle removal without dismiss (e.g., framework unmount)
1728
- this.resetSafeAreaState();
1729
1716
  }
1730
1717
  componentWillLoad() {
1731
1718
  var _a;
@@ -1885,8 +1872,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
1885
1872
  else if (!this.keepContentsMounted) {
1886
1873
  await waitForMount();
1887
1874
  }
1888
- // Predict safe-area needs based on modal configuration to avoid visual snap
1889
- this.setInitialSafeAreaOverrides(presentingElement);
1890
1875
  writeTask(() => this.el.classList.add('show-modal'));
1891
1876
  const hasCardModal = presentingElement !== undefined;
1892
1877
  /**
@@ -1948,8 +1933,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
1948
1933
  else if (hasCardModal) {
1949
1934
  this.initSwipeToClose();
1950
1935
  }
1951
- // Now that animation is complete, update safe-area based on actual position
1952
- this.updateSafeAreaOverrides();
1953
1936
  // Initialize view transition listener for iOS card modals
1954
1937
  this.initViewTransitionListener();
1955
1938
  // Initialize parent removal observer
@@ -2001,7 +1984,7 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
2001
1984
  await this.dismiss(undefined, GESTURE);
2002
1985
  this.gestureAnimationDismissing = false;
2003
1986
  });
2004
- }, () => this.updateSafeAreaOverrides());
1987
+ });
2005
1988
  this.gesture.enable(true);
2006
1989
  }
2007
1990
  initSheetGesture() {
@@ -2022,8 +2005,7 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
2022
2005
  this.currentBreakpoint = breakpoint;
2023
2006
  this.ionBreakpointDidChange.emit({ breakpoint });
2024
2007
  }
2025
- this.updateSafeAreaOverrides();
2026
- }, () => this.updateSafeAreaOverrides());
2008
+ });
2027
2009
  this.gesture = gesture;
2028
2010
  this.moveSheetToBreakpoint = moveSheetToBreakpoint;
2029
2011
  this.gesture.enable(true);
@@ -2101,187 +2083,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
2101
2083
  // Clear the cached reference
2102
2084
  this.cachedPageParent = undefined;
2103
2085
  }
2104
- /**
2105
- * Sets initial safe-area overrides based on modal configuration before
2106
- * the modal becomes visible. This predicts whether the modal will touch
2107
- * screen edges to avoid a visual snap after animation completes.
2108
- */
2109
- setInitialSafeAreaOverrides(presentingElement) {
2110
- const style = this.el.style;
2111
- const mode = getIonMode(this);
2112
- const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
2113
- // Card modals only exist in iOS mode - in MD mode, presentingElement is ignored
2114
- const isCardModal = presentingElement !== undefined && mode === 'ios';
2115
- const isTablet = window.innerWidth >= 768;
2116
- // Sheet modals always touch bottom edge, never top/left/right
2117
- if (isSheetModal) {
2118
- style.setProperty('--ion-safe-area-top', '0px');
2119
- style.setProperty('--ion-safe-area-left', '0px');
2120
- style.setProperty('--ion-safe-area-right', '0px');
2121
- return;
2122
- }
2123
- // Card modals have rounded top corners
2124
- if (isCardModal) {
2125
- style.setProperty('--ion-safe-area-top', '0px');
2126
- if (isTablet) {
2127
- // On tablets, card modals are inset from all edges
2128
- this.zeroAllSafeAreas();
2129
- }
2130
- else {
2131
- // On phones, card modals still extend to the bottom edge
2132
- style.setProperty('--ion-safe-area-left', '0px');
2133
- style.setProperty('--ion-safe-area-right', '0px');
2134
- this.applyFullscreenSafeArea();
2135
- }
2136
- return;
2137
- }
2138
- // Phone-sized fullscreen modals inherit safe areas and use wrapper padding
2139
- if (!isTablet) {
2140
- this.applyFullscreenSafeArea();
2141
- return;
2142
- }
2143
- // Check if tablet modal is fullscreen via CSS custom properties
2144
- const computedStyle = getComputedStyle(this.el);
2145
- const width = computedStyle.getPropertyValue('--width').trim();
2146
- const height = computedStyle.getPropertyValue('--height').trim();
2147
- const isFullscreen = width === '100%' && height === '100%';
2148
- if (isFullscreen) {
2149
- this.applyFullscreenSafeArea();
2150
- }
2151
- else {
2152
- // Centered dialog doesn't touch edges
2153
- this.zeroAllSafeAreas();
2154
- }
2155
- }
2156
- /**
2157
- * Applies safe-area handling for fullscreen modals.
2158
- * Adds wrapper padding when no footer is present to prevent
2159
- * content from overlapping system navigation areas.
2160
- */
2161
- applyFullscreenSafeArea() {
2162
- this.skipSafeAreaCoordinateDetection = true;
2163
- this.updateFooterPadding();
2164
- // Watch for dynamic footer additions/removals (e.g., async data loading)
2165
- // Use subtree:true to support wrapped footers in framework components
2166
- // (e.g., <my-footer><ion-footer>...</ion-footer></my-footer>)
2167
- if (!this.footerObserver && win !== undefined && 'MutationObserver' in win) {
2168
- this.footerObserver = new MutationObserver(() => this.updateFooterPadding());
2169
- this.footerObserver.observe(this.el, { childList: true, subtree: true });
2170
- }
2171
- }
2172
- /**
2173
- * Updates wrapper padding based on footer presence.
2174
- * Called initially and when footer is dynamically added/removed.
2175
- */
2176
- updateFooterPadding() {
2177
- if (!this.wrapperEl)
2178
- return;
2179
- const hasFooter = this.el.querySelector('ion-footer') !== null;
2180
- if (hasFooter) {
2181
- this.wrapperEl.style.removeProperty('padding-bottom');
2182
- this.wrapperEl.style.removeProperty('box-sizing');
2183
- }
2184
- else {
2185
- this.wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
2186
- this.wrapperEl.style.setProperty('box-sizing', 'border-box');
2187
- }
2188
- }
2189
- /**
2190
- * Sets all safe-area CSS variables to 0px for modals that
2191
- * don't touch screen edges.
2192
- */
2193
- zeroAllSafeAreas() {
2194
- const style = this.el.style;
2195
- style.setProperty('--ion-safe-area-top', '0px');
2196
- style.setProperty('--ion-safe-area-bottom', '0px');
2197
- style.setProperty('--ion-safe-area-left', '0px');
2198
- style.setProperty('--ion-safe-area-right', '0px');
2199
- }
2200
- /**
2201
- * Resets all safe-area related state and styles.
2202
- * Called during dismiss and disconnectedCallback to ensure clean state
2203
- * for re-presentation of inline modals.
2204
- */
2205
- resetSafeAreaState() {
2206
- var _a;
2207
- this.skipSafeAreaCoordinateDetection = false;
2208
- this.cachedSafeAreas = undefined;
2209
- this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
2210
- (_a = this.footerObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
2211
- this.footerObserver = undefined;
2212
- // Clear wrapper styles that may have been set for safe-area handling
2213
- if (this.wrapperEl) {
2214
- this.wrapperEl.style.removeProperty('padding-bottom');
2215
- this.wrapperEl.style.removeProperty('box-sizing');
2216
- }
2217
- // Clear safe-area CSS variable overrides
2218
- const style = this.el.style;
2219
- style.removeProperty('--ion-safe-area-top');
2220
- style.removeProperty('--ion-safe-area-bottom');
2221
- style.removeProperty('--ion-safe-area-left');
2222
- style.removeProperty('--ion-safe-area-right');
2223
- }
2224
- /**
2225
- * Gets the root safe-area values from the document element.
2226
- * Uses cached values during gestures to avoid getComputedStyle calls.
2227
- */
2228
- getSafeAreaValues() {
2229
- if (!this.cachedSafeAreas) {
2230
- const rootStyle = getComputedStyle(document.documentElement);
2231
- this.cachedSafeAreas = {
2232
- top: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-top')) || 0,
2233
- bottom: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-bottom')) || 0,
2234
- left: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-left')) || 0,
2235
- right: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-right')) || 0,
2236
- };
2237
- }
2238
- return this.cachedSafeAreas;
2239
- }
2240
- /**
2241
- * Updates safe-area CSS variable overrides based on whether the modal
2242
- * extends into each safe-area region. Called after animation
2243
- * and during gestures to handle dynamic position changes.
2244
- *
2245
- * Optimized to avoid redundant DOM writes by tracking previous state.
2246
- */
2247
- updateSafeAreaOverrides() {
2248
- if (this.skipSafeAreaCoordinateDetection) {
2249
- return;
2250
- }
2251
- const wrapper = this.wrapperEl;
2252
- if (!wrapper) {
2253
- return;
2254
- }
2255
- const rect = wrapper.getBoundingClientRect();
2256
- const safeAreas = this.getSafeAreaValues();
2257
- const extendsIntoTop = rect.top < safeAreas.top;
2258
- const extendsIntoBottom = rect.bottom > window.innerHeight - safeAreas.bottom;
2259
- const extendsIntoLeft = rect.left < safeAreas.left;
2260
- const extendsIntoRight = rect.right > window.innerWidth - safeAreas.right;
2261
- // Only update DOM when state actually changes
2262
- const prev = this.prevSafeAreaState;
2263
- const style = this.el.style;
2264
- if (extendsIntoTop !== prev.top) {
2265
- extendsIntoTop ? style.removeProperty('--ion-safe-area-top') : style.setProperty('--ion-safe-area-top', '0px');
2266
- prev.top = extendsIntoTop;
2267
- }
2268
- if (extendsIntoBottom !== prev.bottom) {
2269
- extendsIntoBottom
2270
- ? style.removeProperty('--ion-safe-area-bottom')
2271
- : style.setProperty('--ion-safe-area-bottom', '0px');
2272
- prev.bottom = extendsIntoBottom;
2273
- }
2274
- if (extendsIntoLeft !== prev.left) {
2275
- extendsIntoLeft ? style.removeProperty('--ion-safe-area-left') : style.setProperty('--ion-safe-area-left', '0px');
2276
- prev.left = extendsIntoLeft;
2277
- }
2278
- if (extendsIntoRight !== prev.right) {
2279
- extendsIntoRight
2280
- ? style.removeProperty('--ion-safe-area-right')
2281
- : style.setProperty('--ion-safe-area-right', '0px');
2282
- prev.right = extendsIntoRight;
2283
- }
2284
- }
2285
2086
  sheetOnDismiss() {
2286
2087
  /**
2287
2088
  * While the gesture animation is finishing
@@ -2374,8 +2175,6 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
2374
2175
  }
2375
2176
  this.currentBreakpoint = undefined;
2376
2177
  this.animation = undefined;
2377
- // Reset safe-area state for potential re-presentation
2378
- this.resetSafeAreaState();
2379
2178
  unlock();
2380
2179
  return dismissed;
2381
2180
  }
@@ -2625,20 +2424,20 @@ const Modal = /*@__PURE__*/ proxyCustomElement(class Modal extends HTMLElement {
2625
2424
  const isCardModal = presentingElement !== undefined && mode === 'ios';
2626
2425
  const isHandleCycle = handleBehavior === 'cycle';
2627
2426
  const isSheetModalWithHandle = isSheetModal && showHandle;
2628
- return (h(Host, Object.assign({ key: '44022099fcaf047b97d1c2cb45b9b51c930e707c', "no-router": true,
2427
+ return (h(Host, Object.assign({ key: '87328006ea6c75ebc518ace300438492a567223e', "no-router": true,
2629
2428
  // Allow the modal to be navigable when the handle is focusable
2630
2429
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
2631
2430
  zIndex: `${20000 + this.overlayIndex}`,
2632
- }, 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 }), h("ion-backdrop", { key: 'ddd7e4f6eef51ac1f62ac70e0af10fb01e707f07', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '58620980e3e4ec273c6787bde026e1c010b904b7', class: "modal-shadow" }), h("div", Object.assign({ key: '3fb7f6218644ba898fc504467775593eb89426a0',
2431
+ }, 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 }), h("ion-backdrop", { key: 'ee94ff8e09b691dd4ad4e4db1720f06bc3c5a469', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: 'bffd69b4635c22d9f249725bd952c1e93d5615c7', class: "modal-shadow" }), h("div", Object.assign({ key: '1d394d3c68916e464ff1fbf5242419f4a3d3cca1',
2633
2432
  /*
2634
2433
  role and aria-modal must be used on the
2635
2434
  same element. They must also be set inside the
2636
2435
  shadow DOM otherwise ion-button will not be highlighted
2637
2436
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
2638
2437
  */
2639
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '9745cd590fdaa9d023a14b487ec2c87ddbafd7f7', class: "modal-handle",
2438
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '2dcf58792018e557e0c323baad2d672bc99c0bb1', class: "modal-handle",
2640
2439
  // Prevents the handle from receiving keyboard focus when it does not cycle
2641
- 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) })), h("slot", { key: 'b9a8b5d2d3d3c9b06f99179f496c9f08907d0bad', onSlotchange: this.onSlotChange }))));
2440
+ 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) })), h("slot", { key: '44164b1e8710c3895400ad9f44ecd99873874ad5', onSlotchange: this.onSlotChange }))));
2642
2441
  }
2643
2442
  get el() { return this; }
2644
2443
  static get watchers() { return {
@@ -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(bodyPadding, triggerTop - contentHeight - triggerHeight - (arrowHeight - 1));
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, checkSafeAreaTop, checkSafeAreaBottom, 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);
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
- * Safe area CSS variable adjustments.
846
- * When the popover is positioned near an edge, we add the corresponding
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
- if (bottomValue !== undefined) {
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, checkSafeAreaTop, checkSafeAreaBottom, checkSafeAreaLeft, checkSafeAreaRight, } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
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(${topValue} + var(--offset-y, 0px))`,
991
- left: `calc(${leftValue} + var(--offset-x, 0px))`,
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 (bottomValue !== undefined) {
996
- contentEl.style.setProperty('bottom', `calc(${bottomValue})`);
923
+ if (bottom !== undefined) {
924
+ contentEl.style.setProperty('bottom', `${bottom}px`);
997
925
  }
998
926
  })
999
927
  .fromTo('transform', 'scale(0.8)', 'scale(1)');
@@ -515,20 +515,21 @@ const Content = class {
515
515
  const forceOverscroll = this.shouldForceOverscroll();
516
516
  const transitionShadow = mode === 'ios';
517
517
  this.resize();
518
- return (index.h(index.Host, Object.assign({ key: 'cd8781f848d8dc926fe66f43d43c49564425a507', role: isMainContent ? 'main' : undefined, class: theme.createColorClasses(this.color, {
518
+ return (index.h(index.Host, Object.assign({ key: '212b1438f044061887984e02e1c8943ee1d33c20', role: isMainContent ? 'main' : undefined, class: theme.createColorClasses(this.color, {
519
519
  [mode]: true,
520
+ 'content-fullscreen': this.fullscreen,
520
521
  'content-sizing': theme.hostContext('ion-popover', this.el),
521
522
  overscroll: forceOverscroll,
522
523
  [`content-${rtl}`]: true,
523
524
  }), style: {
524
525
  '--offset-top': `${this.cTop}px`,
525
526
  '--offset-bottom': `${this.cBottom}px`,
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: {
527
+ } }, inheritedAttributes), index.h("div", { key: 'ea46641492eef8cc7b08fc398d0285115b5a7100', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? index.h("slot", { name: "fixed" }) : null, index.h("div", { key: 'dc9096f0b97ab6145fb46cf065cd244f4af1cab5', class: {
527
528
  'inner-scroll': true,
528
529
  'scroll-x': scrollX,
529
530
  'scroll-y': scrollY,
530
531
  overscroll: (scrollX || scrollY) && forceOverscroll,
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));
532
+ }, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, index.h("slot", { key: '4b13fd5b7e124353d43b47a30e975400ae2a0341' })), transitionShadow ? (index.h("div", { class: "transition-effect" }, index.h("div", { class: "transition-cover" }), index.h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? index.h("slot", { name: "fixed" }) : null));
532
533
  }
533
534
  get el() { return index.getElement(this); }
534
535
  };