@ionic/core 8.7.18-dev.11769790854.11895f8f → 8.7.18-dev.11770316329.126ef4af

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 (38) hide show
  1. package/components/ion-refresher.js +32 -3
  2. package/components/modal.js +12 -220
  3. package/components/popover.js +11 -83
  4. package/dist/cjs/ion-modal.cjs.entry.js +12 -220
  5. package/dist/cjs/ion-popover.cjs.entry.js +11 -83
  6. package/dist/cjs/ion-refresher_2.cjs.entry.js +32 -3
  7. package/dist/collection/components/modal/gestures/sheet.js +1 -3
  8. package/dist/collection/components/modal/gestures/swipe-to-close.js +1 -3
  9. package/dist/collection/components/modal/modal.ios.css +4 -0
  10. package/dist/collection/components/modal/modal.js +7 -215
  11. package/dist/collection/components/modal/modal.md.css +4 -0
  12. package/dist/collection/components/popover/animations/ios.enter.js +5 -21
  13. package/dist/collection/components/popover/animations/md.enter.js +5 -30
  14. package/dist/collection/components/popover/utils.js +1 -32
  15. package/dist/collection/components/refresher/refresher.js +70 -4
  16. package/dist/docs.json +49 -4
  17. package/dist/esm/ion-modal.entry.js +12 -220
  18. package/dist/esm/ion-popover.entry.js +11 -83
  19. package/dist/esm/ion-refresher_2.entry.js +32 -3
  20. package/dist/html.html-data.json +1 -1
  21. package/dist/ionic/ionic.esm.js +1 -1
  22. package/dist/ionic/p-90f2d3ff.entry.js +4 -0
  23. package/dist/ionic/p-91840a80.entry.js +4 -0
  24. package/dist/ionic/p-f9061316.entry.js +4 -0
  25. package/dist/types/components/modal/gestures/sheet.d.ts +1 -1
  26. package/dist/types/components/modal/gestures/swipe-to-close.d.ts +1 -1
  27. package/dist/types/components/modal/modal.d.ts +0 -47
  28. package/dist/types/components/popover/utils.d.ts +0 -2
  29. package/dist/types/components/refresher/refresher-interface.d.ts +7 -0
  30. package/dist/types/components/refresher/refresher.d.ts +16 -3
  31. package/dist/types/components.d.ts +16 -5
  32. package/dist/types/interface.d.ts +1 -1
  33. package/hydrate/index.js +54 -305
  34. package/hydrate/index.mjs +54 -305
  35. package/package.json +2 -4
  36. package/dist/ionic/p-639dd543.entry.js +0 -4
  37. package/dist/ionic/p-ec9ca3fe.entry.js +0 -4
  38. package/dist/ionic/p-ef4256eb.entry.js +0 -4
@@ -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)');
@@ -4,7 +4,6 @@
4
4
  'use strict';
5
5
 
6
6
  var index$3 = require('./index-D6Wc6v08.js');
7
- var index = require('./index-DkNv4J_i.js');
8
7
  var index$2 = require('./index-CO6eryBo.js');
9
8
  var frameworkDelegate = require('./framework-delegate-DMJRBuDi.js');
10
9
  var helpers = require('./helpers-DrTqNghc.js');
@@ -18,6 +17,7 @@ var keyboard = require('./keyboard-hHzlEQpk.js');
18
17
  var animation = require('./animation-Bt3H9L1C.js');
19
18
  var cubicBezier = require('./cubic-bezier-DAjy1V-e.js');
20
19
  var index$1 = require('./index-CAvQ7Tka.js');
20
+ var index = require('./index-DkNv4J_i.js');
21
21
  require('./hardware-back-button-VCK4V3mG.js');
22
22
  require('./gesture-controller-dtqlP_q4.js');
23
23
  require('./keyboard-UuAS4D_9.js');
@@ -249,7 +249,7 @@ const calculateSpringStep = (t) => {
249
249
  const SwipeToCloseDefaults = {
250
250
  MIN_PRESENTING_SCALE: 0.915,
251
251
  };
252
- const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onGestureMove) => {
252
+ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
253
253
  /**
254
254
  * The step value at which a card modal
255
255
  * is eligible for dismissing via gesture.
@@ -406,8 +406,6 @@ const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss, onG
406
406
  const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
407
407
  const clampedStep = helpers.clamp(0.0001, processedStep, maxStep);
408
408
  animation.progressStep(clampedStep);
409
- // Notify modal of position change for safe-area updates
410
- onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
411
409
  /**
412
410
  * When swiping down half way, the status bar style
413
411
  * should be reset to its default value.
@@ -951,7 +949,7 @@ const mdLeaveAnimation = (baseEl, opts) => {
951
949
  return baseAnimation;
952
950
  };
953
951
 
954
- const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange, onGestureMove) => {
952
+ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
955
953
  // Defaults for the sheet swipe animation
956
954
  const defaultBackdrop = [
957
955
  { offset: 0, opacity: 'var(--backdrop-opacity)' },
@@ -1282,8 +1280,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1282
1280
  : step;
1283
1281
  offset = helpers.clamp(0.0001, processedStep, maxStep);
1284
1282
  animation.progressStep(offset);
1285
- // Notify modal of position change for safe-area updates
1286
- onGestureMove === null || onGestureMove === void 0 ? void 0 : onGestureMove();
1287
1283
  };
1288
1284
  const onEnd = (detail) => {
1289
1285
  /**
@@ -1478,9 +1474,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1478
1474
  };
1479
1475
  };
1480
1476
 
1481
- 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}";
1477
+ 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}";
1482
1478
 
1483
- 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}";
1479
+ 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}";
1484
1480
 
1485
1481
  const Modal = class {
1486
1482
  constructor(hostRef) {
@@ -1503,10 +1499,6 @@ const Modal = class {
1503
1499
  this.inline = false;
1504
1500
  // Whether or not modal is being dismissed via gesture
1505
1501
  this.gestureAnimationDismissing = false;
1506
- // Whether to skip coordinate-based safe-area detection (for fullscreen phone modals)
1507
- this.skipSafeAreaCoordinateDetection = false;
1508
- // Track previous safe-area state to avoid redundant DOM writes
1509
- this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
1510
1502
  this.presented = false;
1511
1503
  /** @internal */
1512
1504
  this.hasController = false;
@@ -1697,10 +1689,7 @@ const Modal = class {
1697
1689
  }
1698
1690
  }
1699
1691
  onWindowResize() {
1700
- // Invalidate safe-area cache on resize (device rotation may change values)
1701
- this.cachedSafeAreas = undefined;
1702
- this.updateSafeAreaOverrides();
1703
- // Only handle view transition for iOS card modals when no custom animations are provided
1692
+ // Only handle resize for iOS card modals when no custom animations are provided
1704
1693
  if (ionicGlobal.getIonMode(this) !== 'ios' || !this.presentingElement || this.enterAnimation || this.leaveAnimation) {
1705
1694
  return;
1706
1695
  }
@@ -1723,8 +1712,6 @@ const Modal = class {
1723
1712
  this.triggerController.removeClickListener();
1724
1713
  this.cleanupViewTransitionListener();
1725
1714
  this.cleanupParentRemovalObserver();
1726
- // Reset safe-area state to handle removal without dismiss (e.g., framework unmount)
1727
- this.resetSafeAreaState();
1728
1715
  }
1729
1716
  componentWillLoad() {
1730
1717
  var _a;
@@ -1884,8 +1871,6 @@ const Modal = class {
1884
1871
  else if (!this.keepContentsMounted) {
1885
1872
  await index$4.waitForMount();
1886
1873
  }
1887
- // Predict safe-area needs based on modal configuration to avoid visual snap
1888
- this.setInitialSafeAreaOverrides(presentingElement);
1889
1874
  index$3.writeTask(() => this.el.classList.add('show-modal'));
1890
1875
  const hasCardModal = presentingElement !== undefined;
1891
1876
  /**
@@ -1947,8 +1932,6 @@ const Modal = class {
1947
1932
  else if (hasCardModal) {
1948
1933
  this.initSwipeToClose();
1949
1934
  }
1950
- // Now that animation is complete, update safe-area based on actual position
1951
- this.updateSafeAreaOverrides();
1952
1935
  // Initialize view transition listener for iOS card modals
1953
1936
  this.initViewTransitionListener();
1954
1937
  // Initialize parent removal observer
@@ -2000,7 +1983,7 @@ const Modal = class {
2000
1983
  await this.dismiss(undefined, overlays.GESTURE);
2001
1984
  this.gestureAnimationDismissing = false;
2002
1985
  });
2003
- }, () => this.updateSafeAreaOverrides());
1986
+ });
2004
1987
  this.gesture.enable(true);
2005
1988
  }
2006
1989
  initSheetGesture() {
@@ -2021,8 +2004,7 @@ const Modal = class {
2021
2004
  this.currentBreakpoint = breakpoint;
2022
2005
  this.ionBreakpointDidChange.emit({ breakpoint });
2023
2006
  }
2024
- this.updateSafeAreaOverrides();
2025
- }, () => this.updateSafeAreaOverrides());
2007
+ });
2026
2008
  this.gesture = gesture;
2027
2009
  this.moveSheetToBreakpoint = moveSheetToBreakpoint;
2028
2010
  this.gesture.enable(true);
@@ -2100,194 +2082,6 @@ const Modal = class {
2100
2082
  // Clear the cached reference
2101
2083
  this.cachedPageParent = undefined;
2102
2084
  }
2103
- /**
2104
- * Sets initial safe-area overrides based on modal configuration before
2105
- * the modal becomes visible. This predicts whether the modal will touch
2106
- * screen edges to avoid a visual snap after animation completes.
2107
- */
2108
- setInitialSafeAreaOverrides(presentingElement) {
2109
- const style = this.el.style;
2110
- const mode = ionicGlobal.getIonMode(this);
2111
- const isSheetModal = this.breakpoints !== undefined && this.initialBreakpoint !== undefined;
2112
- // Card modals only exist in iOS mode - in MD mode, presentingElement is ignored
2113
- const isCardModal = presentingElement !== undefined && mode === 'ios';
2114
- const isTablet = window.innerWidth >= 768;
2115
- // Sheet modals always touch bottom edge, never top/left/right
2116
- if (isSheetModal) {
2117
- style.setProperty('--ion-safe-area-top', '0px');
2118
- style.setProperty('--ion-safe-area-left', '0px');
2119
- style.setProperty('--ion-safe-area-right', '0px');
2120
- return;
2121
- }
2122
- // Card modals have rounded top corners
2123
- if (isCardModal) {
2124
- style.setProperty('--ion-safe-area-top', '0px');
2125
- if (isTablet) {
2126
- // On tablets, card modals are inset from all edges
2127
- this.zeroAllSafeAreas();
2128
- }
2129
- else {
2130
- // On phones, card modals still extend to the bottom edge
2131
- style.setProperty('--ion-safe-area-left', '0px');
2132
- style.setProperty('--ion-safe-area-right', '0px');
2133
- this.applyFullscreenSafeArea();
2134
- }
2135
- return;
2136
- }
2137
- // Check if modal is fullscreen via CSS custom properties
2138
- // This applies to both phone and tablet sizes - custom modals may have
2139
- // non-fullscreen dimensions even on phones (e.g., --height: 70%)
2140
- const computedStyle = getComputedStyle(this.el);
2141
- const width = computedStyle.getPropertyValue('--width').trim();
2142
- const height = computedStyle.getPropertyValue('--height').trim();
2143
- const isFullscreen = width === '100%' && height === '100%';
2144
- if (isFullscreen) {
2145
- this.applyFullscreenSafeArea();
2146
- }
2147
- else if (isTablet) {
2148
- // Centered dialog on tablet doesn't touch edges
2149
- this.zeroAllSafeAreas();
2150
- }
2151
- else ;
2152
- }
2153
- /**
2154
- * Applies safe-area handling for fullscreen modals.
2155
- * Adds wrapper padding when no footer is present to prevent
2156
- * content from overlapping system navigation areas.
2157
- */
2158
- applyFullscreenSafeArea() {
2159
- this.skipSafeAreaCoordinateDetection = true;
2160
- this.updateFooterPadding();
2161
- // Watch for dynamic footer additions/removals (e.g., async data loading)
2162
- // Use subtree:true to support wrapped footers in framework components
2163
- // (e.g., <my-footer><ion-footer>...</ion-footer></my-footer>)
2164
- if (!this.footerObserver && index.win !== undefined && 'MutationObserver' in index.win) {
2165
- this.footerObserver = new MutationObserver(() => this.updateFooterPadding());
2166
- this.footerObserver.observe(this.el, { childList: true, subtree: true });
2167
- }
2168
- }
2169
- /**
2170
- * Updates wrapper and shadow padding based on footer presence.
2171
- * Called initially and when footer is dynamically added/removed.
2172
- * Both elements must be styled identically to prevent visual mismatches.
2173
- */
2174
- updateFooterPadding() {
2175
- if (!this.wrapperEl)
2176
- return;
2177
- const hasFooter = this.el.querySelector('ion-footer') !== null;
2178
- // Apply to both wrapper and shadow to keep them in sync
2179
- const elements = [this.wrapperEl, this.shadowEl].filter(Boolean);
2180
- if (hasFooter) {
2181
- elements.forEach((el) => {
2182
- el.style.removeProperty('padding-bottom');
2183
- el.style.removeProperty('box-sizing');
2184
- });
2185
- }
2186
- else {
2187
- elements.forEach((el) => {
2188
- el.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
2189
- el.style.setProperty('box-sizing', 'border-box');
2190
- });
2191
- }
2192
- }
2193
- /**
2194
- * Sets all safe-area CSS variables to 0px for modals that
2195
- * don't touch screen edges.
2196
- */
2197
- zeroAllSafeAreas() {
2198
- const style = this.el.style;
2199
- style.setProperty('--ion-safe-area-top', '0px');
2200
- style.setProperty('--ion-safe-area-bottom', '0px');
2201
- style.setProperty('--ion-safe-area-left', '0px');
2202
- style.setProperty('--ion-safe-area-right', '0px');
2203
- }
2204
- /**
2205
- * Resets all safe-area related state and styles.
2206
- * Called during dismiss and disconnectedCallback to ensure clean state
2207
- * for re-presentation of inline modals.
2208
- */
2209
- resetSafeAreaState() {
2210
- var _a;
2211
- this.skipSafeAreaCoordinateDetection = false;
2212
- this.cachedSafeAreas = undefined;
2213
- this.prevSafeAreaState = { top: false, bottom: false, left: false, right: false };
2214
- (_a = this.footerObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
2215
- this.footerObserver = undefined;
2216
- // Clear wrapper and shadow styles that may have been set for safe-area handling
2217
- [this.wrapperEl, this.shadowEl].forEach((el) => {
2218
- if (el) {
2219
- el.style.removeProperty('padding-bottom');
2220
- el.style.removeProperty('box-sizing');
2221
- }
2222
- });
2223
- // Clear safe-area CSS variable overrides
2224
- const style = this.el.style;
2225
- style.removeProperty('--ion-safe-area-top');
2226
- style.removeProperty('--ion-safe-area-bottom');
2227
- style.removeProperty('--ion-safe-area-left');
2228
- style.removeProperty('--ion-safe-area-right');
2229
- }
2230
- /**
2231
- * Gets the root safe-area values from the document element.
2232
- * Uses cached values during gestures to avoid getComputedStyle calls.
2233
- */
2234
- getSafeAreaValues() {
2235
- if (!this.cachedSafeAreas) {
2236
- const rootStyle = getComputedStyle(document.documentElement);
2237
- this.cachedSafeAreas = {
2238
- top: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-top')) || 0,
2239
- bottom: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-bottom')) || 0,
2240
- left: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-left')) || 0,
2241
- right: parseFloat(rootStyle.getPropertyValue('--ion-safe-area-right')) || 0,
2242
- };
2243
- }
2244
- return this.cachedSafeAreas;
2245
- }
2246
- /**
2247
- * Updates safe-area CSS variable overrides based on whether the modal
2248
- * extends into each safe-area region. Called after animation
2249
- * and during gestures to handle dynamic position changes.
2250
- *
2251
- * Optimized to avoid redundant DOM writes by tracking previous state.
2252
- */
2253
- updateSafeAreaOverrides() {
2254
- if (this.skipSafeAreaCoordinateDetection) {
2255
- return;
2256
- }
2257
- const wrapper = this.wrapperEl;
2258
- if (!wrapper) {
2259
- return;
2260
- }
2261
- const rect = wrapper.getBoundingClientRect();
2262
- const safeAreas = this.getSafeAreaValues();
2263
- const extendsIntoTop = rect.top < safeAreas.top;
2264
- const extendsIntoBottom = rect.bottom > window.innerHeight - safeAreas.bottom;
2265
- const extendsIntoLeft = rect.left < safeAreas.left;
2266
- const extendsIntoRight = rect.right > window.innerWidth - safeAreas.right;
2267
- // Only update DOM when state actually changes
2268
- const prev = this.prevSafeAreaState;
2269
- const style = this.el.style;
2270
- if (extendsIntoTop !== prev.top) {
2271
- extendsIntoTop ? style.removeProperty('--ion-safe-area-top') : style.setProperty('--ion-safe-area-top', '0px');
2272
- prev.top = extendsIntoTop;
2273
- }
2274
- if (extendsIntoBottom !== prev.bottom) {
2275
- extendsIntoBottom
2276
- ? style.removeProperty('--ion-safe-area-bottom')
2277
- : style.setProperty('--ion-safe-area-bottom', '0px');
2278
- prev.bottom = extendsIntoBottom;
2279
- }
2280
- if (extendsIntoLeft !== prev.left) {
2281
- extendsIntoLeft ? style.removeProperty('--ion-safe-area-left') : style.setProperty('--ion-safe-area-left', '0px');
2282
- prev.left = extendsIntoLeft;
2283
- }
2284
- if (extendsIntoRight !== prev.right) {
2285
- extendsIntoRight
2286
- ? style.removeProperty('--ion-safe-area-right')
2287
- : style.setProperty('--ion-safe-area-right', '0px');
2288
- prev.right = extendsIntoRight;
2289
- }
2290
- }
2291
2085
  sheetOnDismiss() {
2292
2086
  /**
2293
2087
  * While the gesture animation is finishing
@@ -2380,8 +2174,6 @@ const Modal = class {
2380
2174
  }
2381
2175
  this.currentBreakpoint = undefined;
2382
2176
  this.animation = undefined;
2383
- // Reset safe-area state for potential re-presentation
2384
- this.resetSafeAreaState();
2385
2177
  unlock();
2386
2178
  return dismissed;
2387
2179
  }
@@ -2631,20 +2423,20 @@ const Modal = class {
2631
2423
  const isCardModal = presentingElement !== undefined && mode === 'ios';
2632
2424
  const isHandleCycle = handleBehavior === 'cycle';
2633
2425
  const isSheetModalWithHandle = isSheetModal && showHandle;
2634
- return (index$3.h(index$3.Host, Object.assign({ key: '8f42c71ec9c9270b4218ca7eec57ca998871ac07', "no-router": true,
2426
+ return (index$3.h(index$3.Host, Object.assign({ key: '87328006ea6c75ebc518ace300438492a567223e', "no-router": true,
2635
2427
  // Allow the modal to be navigable when the handle is focusable
2636
2428
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
2637
2429
  zIndex: `${20000 + this.overlayIndex}`,
2638
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: '2f7b08b019c66cbfceacafa9a68b91f8da1f4084', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && index$3.h("div", { key: '6b0d1ae90e8483332f74371be5dcbd0a7b2661ba', class: "modal-shadow", ref: (el) => (this.shadowEl = el) }), index$3.h("div", Object.assign({ key: 'c96f671fb25e5de45231ea65ac52500547b2e262',
2430
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [overlays.FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, theme.getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), index$3.h("ion-backdrop", { key: 'ee94ff8e09b691dd4ad4e4db1720f06bc3c5a469', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && index$3.h("div", { key: 'bffd69b4635c22d9f249725bd952c1e93d5615c7', class: "modal-shadow" }), index$3.h("div", Object.assign({ key: '1d394d3c68916e464ff1fbf5242419f4a3d3cca1',
2639
2431
  /*
2640
2432
  role and aria-modal must be used on the
2641
2433
  same element. They must also be set inside the
2642
2434
  shadow DOM otherwise ion-button will not be highlighted
2643
2435
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
2644
2436
  */
2645
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: 'e07419b01a588c0ba62ed9607c843cac7bd26337', class: "modal-handle",
2437
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (index$3.h("button", { key: '2dcf58792018e557e0c323baad2d672bc99c0bb1', class: "modal-handle",
2646
2438
  // Prevents the handle from receiving keyboard focus when it does not cycle
2647
- 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) })), index$3.h("slot", { key: '65f35079df8eb8b6cd262e3a08297866715ce7ea', onSlotchange: this.onSlotChange }))));
2439
+ 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) })), index$3.h("slot", { key: '44164b1e8710c3895400ad9f44ecd99873874ad5', onSlotchange: this.onSlotChange }))));
2648
2440
  }
2649
2441
  get el() { return index$3.getElement(this); }
2650
2442
  static get watchers() { return {