@ionic/core 8.7.18-dev.11771365900.125bf49c → 8.7.18-dev.11772217280.122eed89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ion-app.js +17 -12
- package/components/ion-checkbox.js +1 -1
- package/components/ion-content.js +1 -1
- package/components/ion-datetime.js +7 -4
- package/components/ion-fab-list.js +10 -3
- package/components/ion-img.js +11 -2
- package/components/ion-label.js +1 -1
- package/components/ion-modal.js +1 -1
- package/components/ion-popover.js +1 -1
- package/components/ion-radio-group.js +1 -1
- package/components/ion-searchbar.js +17 -6
- package/components/ion-select-modal.js +1 -1
- package/components/ion-select-popover.js +1 -1
- package/components/ion-select.js +8 -8
- package/components/{p-CJrGvZ1Z.js → p-51c2oSfC.js} +3 -3
- package/components/{p-BnpDIASH.js → p-BANeLH_G.js} +2 -2
- package/components/{p-D3KEyQ8e.js → p-BRLve2EP.js} +3 -3
- package/components/{p-DRHwNkVo.js → p-C6dkQWq2.js} +152 -30
- package/components/{p-CUfY9DTD.js → p-Cdm3dKWf.js} +8 -3
- package/components/{p-DyFBFrV7.js → p-D--b4514.js} +4 -4
- package/components/{p-DPm73mCi.js → p-DGOrLIyS.js} +7 -3
- package/components/{p-IHgAGzvW.js → p-iyo0Toaz.js} +326 -17
- package/dist/cjs/ion-app_8.cjs.entry.js +22 -13
- package/dist/cjs/ion-checkbox.cjs.entry.js +3 -3
- package/dist/cjs/ion-datetime_3.cjs.entry.js +6 -3
- package/dist/cjs/ion-fab_3.cjs.entry.js +10 -3
- package/dist/cjs/ion-img.cjs.entry.js +11 -2
- package/dist/cjs/ion-item_8.cjs.entry.js +8 -3
- package/dist/cjs/ion-modal.cjs.entry.js +326 -17
- package/dist/cjs/ion-popover.cjs.entry.js +152 -30
- package/dist/cjs/ion-radio_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-searchbar.cjs.entry.js +17 -6
- package/dist/collection/components/app/app.js +15 -10
- package/dist/collection/components/checkbox/checkbox.js +4 -4
- package/dist/collection/components/content/content.js +7 -3
- package/dist/collection/components/datetime/datetime.js +6 -3
- package/dist/collection/components/fab-list/fab-list.js +10 -3
- package/dist/collection/components/img/img.js +11 -2
- package/dist/collection/components/label/label.js +8 -3
- package/dist/collection/components/modal/modal.ios.css +6 -5
- package/dist/collection/components/modal/modal.js +164 -15
- package/dist/collection/components/modal/modal.md.css +6 -5
- package/dist/collection/components/modal/safe-area-utils.js +165 -0
- package/dist/collection/components/popover/animations/ios.enter.js +33 -8
- package/dist/collection/components/popover/animations/md.enter.js +26 -6
- package/dist/collection/components/popover/utils.js +96 -19
- package/dist/collection/components/radio-group/radio-group.ios.css +0 -4
- package/dist/collection/components/radio-group/radio-group.md.css +0 -4
- package/dist/collection/components/searchbar/searchbar.js +17 -6
- package/dist/docs.json +1 -1
- package/dist/esm/ion-app_8.entry.js +24 -15
- package/dist/esm/ion-checkbox.entry.js +4 -4
- package/dist/esm/ion-datetime_3.entry.js +6 -3
- package/dist/esm/ion-fab_3.entry.js +10 -3
- package/dist/esm/ion-img.entry.js +11 -2
- package/dist/esm/ion-item_8.entry.js +8 -3
- package/dist/esm/ion-modal.entry.js +326 -17
- package/dist/esm/ion-popover.entry.js +152 -30
- package/dist/esm/ion-radio_2.entry.js +2 -2
- package/dist/esm/ion-searchbar.entry.js +17 -6
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-72af946b.entry.js → p-2ac254dc.entry.js} +1 -1
- package/dist/ionic/p-7cad388a.entry.js +4 -0
- package/dist/ionic/p-7d218555.entry.js +4 -0
- package/dist/ionic/p-8303e3fc.entry.js +4 -0
- package/dist/ionic/p-915b3e3d.entry.js +4 -0
- package/dist/ionic/{p-eaf3f5ff.entry.js → p-b0ebf9f8.entry.js} +1 -1
- package/dist/ionic/p-e4c57008.entry.js +4 -0
- package/dist/ionic/p-e5d6d0f0.entry.js +4 -0
- package/dist/ionic/p-f1dfee25.entry.js +4 -0
- package/dist/ionic/{p-6444c606.entry.js → p-f9f7b9db.entry.js} +1 -1
- package/dist/types/components/app/app.d.ts +3 -0
- package/dist/types/components/datetime/datetime.d.ts +1 -0
- package/dist/types/components/fab-list/fab-list.d.ts +2 -0
- package/dist/types/components/img/img.d.ts +2 -0
- package/dist/types/components/label/label.d.ts +2 -0
- package/dist/types/components/modal/modal.d.ts +35 -0
- package/dist/types/components/modal/safe-area-utils.d.ts +66 -0
- package/dist/types/components/popover/utils.d.ts +23 -1
- package/dist/types/components/searchbar/searchbar.d.ts +3 -0
- package/hydrate/index.js +556 -73
- package/hydrate/index.mjs +556 -73
- package/package.json +1 -1
- package/dist/ionic/p-01e27965.entry.js +0 -4
- package/dist/ionic/p-3ec563c1.entry.js +0 -4
- package/dist/ionic/p-42db6404.entry.js +0 -4
- package/dist/ionic/p-46d74291.entry.js +0 -4
- package/dist/ionic/p-bc293244.entry.js +0 -4
- package/dist/ionic/p-d1f54e28.entry.js +0 -4
- package/dist/ionic/p-e338f669.entry.js +0 -4
|
@@ -16,6 +16,58 @@ require('./index-DkNv4J_i.js');
|
|
|
16
16
|
require('./hardware-back-button-VCK4V3mG.js');
|
|
17
17
|
require('./gesture-controller-dtqlP_q4.js');
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Shared per-frame cache for safe-area insets. Avoids creating a temporary
|
|
21
|
+
* DOM element and forcing a synchronous reflow on every call within the same
|
|
22
|
+
* frame (e.g., multiple popovers presenting simultaneously). Invalidated
|
|
23
|
+
* after the next animation frame so values stay fresh across orientation
|
|
24
|
+
* changes and viewport resizes.
|
|
25
|
+
*/
|
|
26
|
+
let cachedInsets = null;
|
|
27
|
+
let cacheInvalidationScheduled = false;
|
|
28
|
+
/**
|
|
29
|
+
* Resolves the current --ion-safe-area-* CSS custom property values
|
|
30
|
+
* to actual pixel numbers. A temporary element is needed because
|
|
31
|
+
* getComputedStyle on :root returns the declared value of custom
|
|
32
|
+
* properties (e.g. "env(safe-area-inset-top)") rather than a
|
|
33
|
+
* resolved number. By assigning them to standard padding properties,
|
|
34
|
+
* the browser resolves the value.
|
|
35
|
+
*
|
|
36
|
+
* Results are cached for the current frame to avoid repeated reflows.
|
|
37
|
+
*/
|
|
38
|
+
const getSafeAreaInsets = (doc) => {
|
|
39
|
+
if (cachedInsets !== null) {
|
|
40
|
+
return cachedInsets;
|
|
41
|
+
}
|
|
42
|
+
if (doc.body === null) {
|
|
43
|
+
return { top: 0, bottom: 0, left: 0, right: 0 };
|
|
44
|
+
}
|
|
45
|
+
const el = doc.createElement('div');
|
|
46
|
+
el.style.cssText =
|
|
47
|
+
'position:fixed;visibility:hidden;pointer-events:none;top:0;left:0;' +
|
|
48
|
+
'padding-top:var(--ion-safe-area-top,0px);' +
|
|
49
|
+
'padding-bottom:var(--ion-safe-area-bottom,0px);' +
|
|
50
|
+
'padding-left:var(--ion-safe-area-left,0px);' +
|
|
51
|
+
'padding-right:var(--ion-safe-area-right,0px);';
|
|
52
|
+
doc.body.appendChild(el);
|
|
53
|
+
const style = getComputedStyle(el);
|
|
54
|
+
const insets = {
|
|
55
|
+
top: parseFloat(style.paddingTop) || 0,
|
|
56
|
+
bottom: parseFloat(style.paddingBottom) || 0,
|
|
57
|
+
left: parseFloat(style.paddingLeft) || 0,
|
|
58
|
+
right: parseFloat(style.paddingRight) || 0,
|
|
59
|
+
};
|
|
60
|
+
el.remove();
|
|
61
|
+
cachedInsets = insets;
|
|
62
|
+
if (!cacheInvalidationScheduled) {
|
|
63
|
+
cacheInvalidationScheduled = true;
|
|
64
|
+
helpers.raf(() => {
|
|
65
|
+
cachedInsets = null;
|
|
66
|
+
cacheInvalidationScheduled = false;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return insets;
|
|
70
|
+
};
|
|
19
71
|
/**
|
|
20
72
|
* Returns the dimensions of the popover
|
|
21
73
|
* arrow on `ios` mode. If arrow is disabled
|
|
@@ -651,8 +703,10 @@ const calculatePopoverCenterAlign = (side, triggerBoundingBox, contentWidth, con
|
|
|
651
703
|
* Adjusts popover positioning coordinates
|
|
652
704
|
* such that popover does not appear offscreen
|
|
653
705
|
* or overlapping safe area bounds.
|
|
706
|
+
*
|
|
707
|
+
* @internal - This is not part of the public API.
|
|
654
708
|
*/
|
|
655
|
-
const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyWidth, bodyHeight, contentWidth, contentHeight,
|
|
709
|
+
const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyWidth, bodyHeight, contentWidth, contentHeight, safeArea, contentOriginX, contentOriginY, triggerCoordinates, coordArrowTop = 0, coordArrowLeft = 0, arrowHeight = 0) => {
|
|
656
710
|
let arrowTop = coordArrowTop;
|
|
657
711
|
const arrowLeft = coordArrowLeft;
|
|
658
712
|
let left = coordLeft;
|
|
@@ -662,16 +716,19 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
662
716
|
let originY = contentOriginY;
|
|
663
717
|
let checkSafeAreaLeft = false;
|
|
664
718
|
let checkSafeAreaRight = false;
|
|
719
|
+
let checkSafeAreaTop = false;
|
|
720
|
+
let checkSafeAreaBottom = false;
|
|
665
721
|
const triggerTop = triggerCoordinates
|
|
666
722
|
? triggerCoordinates.top + triggerCoordinates.height
|
|
667
723
|
: bodyHeight / 2 - contentHeight / 2;
|
|
668
724
|
const triggerHeight = triggerCoordinates ? triggerCoordinates.height : 0;
|
|
669
725
|
let addPopoverBottomClass = false;
|
|
726
|
+
const hideArrow = false;
|
|
670
727
|
/**
|
|
671
728
|
* Adjust popover so it does not
|
|
672
729
|
* go off the left of the screen.
|
|
673
730
|
*/
|
|
674
|
-
if (left < bodyPadding +
|
|
731
|
+
if (left < bodyPadding + safeArea.left) {
|
|
675
732
|
left = bodyPadding;
|
|
676
733
|
checkSafeAreaLeft = true;
|
|
677
734
|
originX = 'left';
|
|
@@ -680,41 +737,58 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
680
737
|
* go off the right of the screen.
|
|
681
738
|
*/
|
|
682
739
|
}
|
|
683
|
-
else if (contentWidth + bodyPadding + left +
|
|
740
|
+
else if (contentWidth + bodyPadding + left + safeArea.right > bodyWidth) {
|
|
684
741
|
checkSafeAreaRight = true;
|
|
685
742
|
left = bodyWidth - contentWidth - bodyPadding;
|
|
686
743
|
originX = 'right';
|
|
687
744
|
}
|
|
688
745
|
/**
|
|
689
746
|
* Adjust popover so it does not
|
|
690
|
-
* go off the
|
|
747
|
+
* go off the bottom of the screen
|
|
748
|
+
* or overlap the bottom safe area.
|
|
691
749
|
* If popover is on the left or the right of
|
|
692
750
|
* the trigger, then we should not adjust top
|
|
693
751
|
* margins.
|
|
694
752
|
*/
|
|
695
|
-
if (triggerTop + triggerHeight + contentHeight > bodyHeight
|
|
696
|
-
|
|
753
|
+
if (triggerTop + triggerHeight + contentHeight > bodyHeight - safeArea.bottom &&
|
|
754
|
+
(side === 'top' || side === 'bottom')) {
|
|
755
|
+
/**
|
|
756
|
+
* Calculate where the popover top would be if flipped
|
|
757
|
+
* above the trigger. Check whether that position clears
|
|
758
|
+
* the top safe area with room for bodyPadding.
|
|
759
|
+
*/
|
|
760
|
+
const idealFlipTop = triggerTop - contentHeight - triggerHeight - (arrowHeight - 1);
|
|
761
|
+
if (idealFlipTop >= safeArea.top + bodyPadding) {
|
|
697
762
|
/**
|
|
698
|
-
*
|
|
699
|
-
*
|
|
700
|
-
*
|
|
701
|
-
* off the bottom of the screen. However, we do not want to move
|
|
702
|
-
* the popover up so much that it goes off the top of the screen.
|
|
703
|
-
*
|
|
704
|
-
* We chose 12 here so that the popover position looks a bit nicer as
|
|
705
|
-
* it is not right up against the edge of the screen.
|
|
763
|
+
* Popover fits above the trigger without overlapping
|
|
764
|
+
* the top safe area. Use the ideal position directly —
|
|
765
|
+
* no safe-area CSS vars needed since it clears both edges.
|
|
706
766
|
*/
|
|
707
|
-
top =
|
|
767
|
+
top = idealFlipTop;
|
|
708
768
|
arrowTop = top + contentHeight;
|
|
709
769
|
originY = 'bottom';
|
|
710
770
|
addPopoverBottomClass = true;
|
|
711
|
-
/**
|
|
712
|
-
* If not enough room for popover to appear
|
|
713
|
-
* above trigger, then cut it off.
|
|
714
|
-
*/
|
|
715
771
|
}
|
|
716
772
|
else {
|
|
773
|
+
/**
|
|
774
|
+
* Can't flip above the trigger. Constrain the bottom
|
|
775
|
+
* edge while keeping the top near the trigger. This
|
|
776
|
+
* creates a scrollable area anchored to the trigger.
|
|
777
|
+
*/
|
|
717
778
|
bottom = bodyPadding;
|
|
779
|
+
checkSafeAreaBottom = true;
|
|
780
|
+
/**
|
|
781
|
+
* When the trigger is near the bottom of the screen,
|
|
782
|
+
* the calculated top may be at or past the bottom
|
|
783
|
+
* constraint, leaving zero visible height. In that
|
|
784
|
+
* case, pull top up to the top safe area so the
|
|
785
|
+
* popover fills the available space between safe areas.
|
|
786
|
+
*/
|
|
787
|
+
const bottomEdge = bodyHeight - safeArea.bottom - bodyPadding;
|
|
788
|
+
if (top >= bottomEdge) {
|
|
789
|
+
top = safeArea.top + bodyPadding;
|
|
790
|
+
checkSafeAreaTop = true;
|
|
791
|
+
}
|
|
718
792
|
}
|
|
719
793
|
}
|
|
720
794
|
return {
|
|
@@ -725,9 +799,12 @@ const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyW
|
|
|
725
799
|
originY,
|
|
726
800
|
checkSafeAreaLeft,
|
|
727
801
|
checkSafeAreaRight,
|
|
802
|
+
checkSafeAreaTop,
|
|
803
|
+
checkSafeAreaBottom,
|
|
728
804
|
arrowTop,
|
|
729
805
|
arrowLeft,
|
|
730
806
|
addPopoverBottomClass,
|
|
807
|
+
hideArrow,
|
|
731
808
|
};
|
|
732
809
|
};
|
|
733
810
|
const shouldShowArrow = (side, didAdjustBounds = false, ev, trigger) => {
|
|
@@ -757,6 +834,15 @@ const shouldShowArrow = (side, didAdjustBounds = false, ev, trigger) => {
|
|
|
757
834
|
};
|
|
758
835
|
|
|
759
836
|
const POPOVER_IOS_BODY_PADDING = 5;
|
|
837
|
+
/**
|
|
838
|
+
* Minimum edge margin for iOS popovers ensures visual spacing from screen
|
|
839
|
+
* edges on devices without safe areas (e.g., older iPhones without notches).
|
|
840
|
+
* Previously this was a hardcoded `safeAreaMargin = 25` that served dual
|
|
841
|
+
* purpose: safe-area avoidance AND visual spacing. Now that actual safe-area
|
|
842
|
+
* insets are read dynamically, this floor preserves the visual spacing when
|
|
843
|
+
* safe-area values are 0.
|
|
844
|
+
*/
|
|
845
|
+
const POPOVER_IOS_MIN_EDGE_MARGIN = 25;
|
|
760
846
|
/**
|
|
761
847
|
* iOS Popover Enter Animation
|
|
762
848
|
*/
|
|
@@ -782,8 +868,16 @@ const iosEnterAnimation = (baseEl, opts) => {
|
|
|
782
868
|
};
|
|
783
869
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, trigger, ev);
|
|
784
870
|
const padding = size === 'cover' ? 0 : POPOVER_IOS_BODY_PADDING;
|
|
785
|
-
const
|
|
786
|
-
const
|
|
871
|
+
const rawSafeArea = getSafeAreaInsets(doc);
|
|
872
|
+
const safeArea = size === 'cover'
|
|
873
|
+
? { top: 0, bottom: 0, left: 0, right: 0 }
|
|
874
|
+
: {
|
|
875
|
+
top: Math.max(rawSafeArea.top, POPOVER_IOS_MIN_EDGE_MARGIN),
|
|
876
|
+
bottom: Math.max(rawSafeArea.bottom, POPOVER_IOS_MIN_EDGE_MARGIN),
|
|
877
|
+
left: Math.max(rawSafeArea.left, POPOVER_IOS_MIN_EDGE_MARGIN),
|
|
878
|
+
right: Math.max(rawSafeArea.right, POPOVER_IOS_MIN_EDGE_MARGIN),
|
|
879
|
+
};
|
|
880
|
+
const { originX, originY, top, left, bottom, checkSafeAreaLeft, checkSafeAreaRight, checkSafeAreaTop, checkSafeAreaBottom, arrowTop, arrowLeft, addPopoverBottomClass} = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, safeArea, results.originX, results.originY, results.referenceCoordinates, results.arrowTop, results.arrowLeft, arrowHeight);
|
|
787
881
|
const baseAnimation = animation.createAnimation();
|
|
788
882
|
const backdropAnimation = animation.createAnimation();
|
|
789
883
|
const contentAnimation = animation.createAnimation();
|
|
@@ -814,10 +908,14 @@ const iosEnterAnimation = (baseEl, opts) => {
|
|
|
814
908
|
baseEl.classList.add('popover-bottom');
|
|
815
909
|
}
|
|
816
910
|
if (bottom !== undefined) {
|
|
817
|
-
|
|
911
|
+
let bottomValue = `${bottom}px`;
|
|
912
|
+
if (checkSafeAreaBottom) {
|
|
913
|
+
bottomValue = `${bottom}px + var(--ion-safe-area-bottom, 0px)`;
|
|
914
|
+
}
|
|
915
|
+
contentEl.style.setProperty('bottom', `calc(${bottomValue})`);
|
|
818
916
|
}
|
|
819
|
-
const safeAreaLeft = ' + var(--ion-safe-area-left,
|
|
820
|
-
const safeAreaRight = ' - var(--ion-safe-area-right,
|
|
917
|
+
const safeAreaLeft = ' + var(--ion-safe-area-left, 0px)';
|
|
918
|
+
const safeAreaRight = ' - var(--ion-safe-area-right, 0px)';
|
|
821
919
|
let leftValue = `${left}px`;
|
|
822
920
|
if (checkSafeAreaLeft) {
|
|
823
921
|
leftValue = `${left}px${safeAreaLeft}`;
|
|
@@ -825,7 +923,11 @@ const iosEnterAnimation = (baseEl, opts) => {
|
|
|
825
923
|
if (checkSafeAreaRight) {
|
|
826
924
|
leftValue = `${left}px${safeAreaRight}`;
|
|
827
925
|
}
|
|
828
|
-
|
|
926
|
+
let topValue = `${top}px`;
|
|
927
|
+
if (checkSafeAreaTop) {
|
|
928
|
+
topValue = `${top}px + var(--ion-safe-area-top, 0px)`;
|
|
929
|
+
}
|
|
930
|
+
contentEl.style.setProperty('top', `calc(${topValue} + var(--offset-y, 0))`);
|
|
829
931
|
contentEl.style.setProperty('left', `calc(${leftValue} + var(--offset-x, 0))`);
|
|
830
932
|
contentEl.style.setProperty('transform-origin', `${originY} ${originX}`);
|
|
831
933
|
if (arrowEl !== null) {
|
|
@@ -901,7 +1003,23 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
901
1003
|
};
|
|
902
1004
|
const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
|
|
903
1005
|
const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
|
|
904
|
-
|
|
1006
|
+
// MD mode now applies safe-area insets (previously passed 0, ignoring all safe areas).
|
|
1007
|
+
// This is needed for Android edge-to-edge (API 36+) where system bars overlap content.
|
|
1008
|
+
const safeArea = size === 'cover' ? { top: 0, bottom: 0, left: 0, right: 0 } : getSafeAreaInsets(doc);
|
|
1009
|
+
const { originX, originY, top, left, bottom, checkSafeAreaLeft, checkSafeAreaRight, checkSafeAreaTop, checkSafeAreaBottom, addPopoverBottomClass, } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, safeArea, results.originX, results.originY, results.referenceCoordinates);
|
|
1010
|
+
const safeAreaLeftCalc = ' + var(--ion-safe-area-left, 0px)';
|
|
1011
|
+
const safeAreaRightCalc = ' - var(--ion-safe-area-right, 0px)';
|
|
1012
|
+
let leftValue = `${left}px`;
|
|
1013
|
+
if (checkSafeAreaLeft) {
|
|
1014
|
+
leftValue = `${left}px${safeAreaLeftCalc}`;
|
|
1015
|
+
}
|
|
1016
|
+
if (checkSafeAreaRight) {
|
|
1017
|
+
leftValue = `${left}px${safeAreaRightCalc}`;
|
|
1018
|
+
}
|
|
1019
|
+
let topValue = `${top}px`;
|
|
1020
|
+
if (checkSafeAreaTop) {
|
|
1021
|
+
topValue = `${top}px + var(--ion-safe-area-top, 0px)`;
|
|
1022
|
+
}
|
|
905
1023
|
const baseAnimation = animation.createAnimation();
|
|
906
1024
|
const backdropAnimation = animation.createAnimation();
|
|
907
1025
|
const wrapperAnimation = animation.createAnimation();
|
|
@@ -918,13 +1036,17 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
918
1036
|
contentAnimation
|
|
919
1037
|
.addElement(contentEl)
|
|
920
1038
|
.beforeStyles({
|
|
921
|
-
top: `calc(${
|
|
922
|
-
left: `calc(${
|
|
1039
|
+
top: `calc(${topValue} + var(--offset-y, 0px))`,
|
|
1040
|
+
left: `calc(${leftValue} + var(--offset-x, 0px))`,
|
|
923
1041
|
'transform-origin': `${originY} ${originX}`,
|
|
924
1042
|
})
|
|
925
1043
|
.beforeAddWrite(() => {
|
|
926
1044
|
if (bottom !== undefined) {
|
|
927
|
-
|
|
1045
|
+
let bottomValue = `${bottom}px`;
|
|
1046
|
+
if (checkSafeAreaBottom) {
|
|
1047
|
+
bottomValue = `${bottom}px + var(--ion-safe-area-bottom, 0px)`;
|
|
1048
|
+
}
|
|
1049
|
+
contentEl.style.setProperty('bottom', `calc(${bottomValue})`);
|
|
928
1050
|
}
|
|
929
1051
|
})
|
|
930
1052
|
.fromTo('transform', 'scale(0.8)', 'scale(1)');
|
|
@@ -936,7 +1058,7 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
936
1058
|
if (size === 'cover') {
|
|
937
1059
|
baseEl.style.setProperty('--width', `${contentWidth}px`);
|
|
938
1060
|
}
|
|
939
|
-
if (
|
|
1061
|
+
if (addPopoverBottomClass) {
|
|
940
1062
|
baseEl.classList.add('popover-bottom');
|
|
941
1063
|
}
|
|
942
1064
|
})
|
|
@@ -165,9 +165,9 @@ Radio.style = {
|
|
|
165
165
|
md: radioMdCss
|
|
166
166
|
};
|
|
167
167
|
|
|
168
|
-
const radioGroupIosCss = "ion-radio-group{vertical-align:top}.radio-group-
|
|
168
|
+
const radioGroupIosCss = "ion-radio-group{vertical-align:top}.radio-group-top{line-height:1.5}.radio-group-top .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.radio-group-top .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid .radio-group-top .error-text{display:block}.ion-touched.ion-invalid .radio-group-top .helper-text{display:none}ion-list .radio-group-top{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}";
|
|
169
169
|
|
|
170
|
-
const radioGroupMdCss = "ion-radio-group{vertical-align:top}.radio-group-
|
|
170
|
+
const radioGroupMdCss = "ion-radio-group{vertical-align:top}.radio-group-top{line-height:1.5}.radio-group-top .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.radio-group-top .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid .radio-group-top .error-text{display:block}.ion-touched.ion-invalid .radio-group-top .helper-text{display:none}ion-list .radio-group-top{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}";
|
|
171
171
|
|
|
172
172
|
const RadioGroup = class {
|
|
173
173
|
constructor(hostRef) {
|
|
@@ -107,11 +107,14 @@ const Searchbar = class {
|
|
|
107
107
|
* Clears the input field and triggers the control change.
|
|
108
108
|
*/
|
|
109
109
|
this.onClearInput = async (shouldFocus) => {
|
|
110
|
+
if (this.clearTimeout) {
|
|
111
|
+
clearTimeout(this.clearTimeout);
|
|
112
|
+
}
|
|
110
113
|
this.ionClear.emit();
|
|
111
114
|
return new Promise((resolve) => {
|
|
112
115
|
// setTimeout() fixes https://github.com/ionic-team/ionic-framework/issues/7527
|
|
113
116
|
// wait for 4 frames
|
|
114
|
-
setTimeout(() => {
|
|
117
|
+
this.clearTimeout = setTimeout(() => {
|
|
115
118
|
const value = this.getValue();
|
|
116
119
|
if (value !== '') {
|
|
117
120
|
this.value = '';
|
|
@@ -246,10 +249,18 @@ const Searchbar = class {
|
|
|
246
249
|
this.originalIonInput = this.ionInput;
|
|
247
250
|
this.positionElements();
|
|
248
251
|
this.debounceChanged();
|
|
249
|
-
setTimeout(() => {
|
|
252
|
+
this.loadTimeout = setTimeout(() => {
|
|
250
253
|
this.noAnimate = false;
|
|
251
254
|
}, 300);
|
|
252
255
|
}
|
|
256
|
+
disconnectedCallback() {
|
|
257
|
+
if (this.loadTimeout) {
|
|
258
|
+
clearTimeout(this.loadTimeout);
|
|
259
|
+
}
|
|
260
|
+
if (this.clearTimeout) {
|
|
261
|
+
clearTimeout(this.clearTimeout);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
253
264
|
emitStyle() {
|
|
254
265
|
this.ionStyle.emit({
|
|
255
266
|
searchbar: true,
|
|
@@ -438,8 +449,8 @@ const Searchbar = class {
|
|
|
438
449
|
const clearIcon = this.clearIcon || (mode === 'ios' ? index$1.closeCircle : index$1.closeSharp);
|
|
439
450
|
const searchIcon = this.searchIcon || (mode === 'ios' ? index$1.searchOutline : index$1.searchSharp);
|
|
440
451
|
const shouldShowCancelButton = this.shouldShowCancelButton();
|
|
441
|
-
const cancelButton = this.showCancelButton !== 'never' && (index.h("button", { key: '
|
|
442
|
-
return (index.h(index.Host, { key: '
|
|
452
|
+
const cancelButton = this.showCancelButton !== 'never' && (index.h("button", { key: '9e9f3a7f6ee66140181f8c3cfa42bbeee75adafc', "aria-label": cancelButtonText, "aria-hidden": shouldShowCancelButton ? undefined : 'true', type: "button", tabIndex: mode === 'ios' && !shouldShowCancelButton ? -1 : undefined, onMouseDown: this.onCancelSearchbar, onTouchStart: this.onCancelSearchbar, class: "searchbar-cancel-button" }, index.h("div", { key: '5f83fbcc0708830637815e8c0b69356cad381870', "aria-hidden": "true" }, mode === 'md' ? (index.h("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
|
|
453
|
+
return (index.h(index.Host, { key: '219c263c1f3cc63e18bc2d2ba5d672b7806eddd0', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: theme.createColorClasses(this.color, {
|
|
443
454
|
[mode]: true,
|
|
444
455
|
'searchbar-animated': animated,
|
|
445
456
|
'searchbar-disabled': this.disabled,
|
|
@@ -449,14 +460,14 @@ const Searchbar = class {
|
|
|
449
460
|
'searchbar-has-focus': this.focused,
|
|
450
461
|
'searchbar-should-show-clear': this.shouldShowClearButton(),
|
|
451
462
|
'searchbar-should-show-cancel': this.shouldShowCancelButton(),
|
|
452
|
-
}) }, index.h("div", { key: '
|
|
463
|
+
}) }, index.h("div", { key: '3f1c25442d6d87c0df67f79482a925b80dcc403d', class: "searchbar-input-container" }, index.h("input", Object.assign({ key: 'a386fecafda0fab449ea1488906ba6cfc55e2b5c', "aria-label": "search text", disabled: this.disabled, ref: (el) => (this.nativeInput = el), class: "searchbar-input", inputMode: this.inputmode, enterKeyHint: this.enterkeyhint, name: this.name, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, minLength: this.minlength, maxLength: this.maxlength, placeholder: this.placeholder, type: this.type, value: this.getValue(), autoCapitalize: autocapitalize === 'default' ? undefined : autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, spellcheck: this.spellcheck }, this.inheritedAttributes)), mode === 'md' && cancelButton, index.h("ion-icon", { key: '5f81642628335def39a14f0726e0fafdc7203776', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), index.h("button", { key: 'da3073646f2d7f639261b556517fbadabc3c10e9', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
|
|
453
464
|
/**
|
|
454
465
|
* This prevents mobile browsers from
|
|
455
466
|
* blurring the input when the clear
|
|
456
467
|
* button is activated.
|
|
457
468
|
*/
|
|
458
469
|
ev.preventDefault();
|
|
459
|
-
}, onClick: () => this.onClearInput(true) }, index.h("ion-icon", { key: '
|
|
470
|
+
}, onClick: () => this.onClearInput(true) }, index.h("ion-icon", { key: '065cd6c707ae462c0767df1bab04ce8045f340a4', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
|
|
460
471
|
}
|
|
461
472
|
get el() { return index.getElement(this); }
|
|
462
473
|
static get watchers() { return {
|
|
@@ -10,7 +10,7 @@ import { getIonMode } from "../../global/ionic-global";
|
|
|
10
10
|
export class App {
|
|
11
11
|
componentDidLoad() {
|
|
12
12
|
if (Build.isBrowser) {
|
|
13
|
-
rIC(async () => {
|
|
13
|
+
this.rIC(async () => {
|
|
14
14
|
const isHybrid = isPlatform(window, 'hybrid');
|
|
15
15
|
if (!config.getBoolean('_testing')) {
|
|
16
16
|
import('../../utils/tap-click').then((module) => module.startTapClick(config));
|
|
@@ -48,6 +48,11 @@ export class App {
|
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
disconnectedCallback() {
|
|
52
|
+
if (this.loadTimeout) {
|
|
53
|
+
clearTimeout(this.loadTimeout);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
51
56
|
/**
|
|
52
57
|
* Used to set focus on an element that uses `ion-focusable`.
|
|
53
58
|
* Do not use this if focusing the element as a result of a keyboard
|
|
@@ -64,9 +69,17 @@ export class App {
|
|
|
64
69
|
this.focusVisible.setFocus(elements);
|
|
65
70
|
}
|
|
66
71
|
}
|
|
72
|
+
rIC(callback) {
|
|
73
|
+
if ('requestIdleCallback' in window) {
|
|
74
|
+
window.requestIdleCallback(callback);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.loadTimeout = setTimeout(callback, 32);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
67
80
|
render() {
|
|
68
81
|
const mode = getIonMode(this);
|
|
69
|
-
return (h(Host, { key: '
|
|
82
|
+
return (h(Host, { key: '77a7459d3e42b3715a5a7e1cf468e2ebc99e54bb', class: {
|
|
70
83
|
[mode]: true,
|
|
71
84
|
'ion-page': true,
|
|
72
85
|
'force-statusbar-padding': config.getBoolean('_forceStatusbarPadding'),
|
|
@@ -136,11 +149,3 @@ const needInputShims = () => {
|
|
|
136
149
|
}
|
|
137
150
|
return false;
|
|
138
151
|
};
|
|
139
|
-
const rIC = (callback) => {
|
|
140
|
-
if ('requestIdleCallback' in window) {
|
|
141
|
-
window.requestIdleCallback(callback);
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
setTimeout(callback, 32);
|
|
145
|
-
}
|
|
146
|
-
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { Build, Host, h } from "@stencil/core";
|
|
4
|
+
import { Build, Host, h, forceUpdate } from "@stencil/core";
|
|
5
5
|
import { checkInvalidState } from "../../utils/forms/index";
|
|
6
6
|
import { inheritAriaAttributes, renderHiddenInput } from "../../utils/helpers";
|
|
7
7
|
import { createColorClasses, hostContext } from "../../utils/theme";
|
|
@@ -201,7 +201,7 @@ export class Checkbox {
|
|
|
201
201
|
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
|
202
202
|
// The host element must have a checkbox role to ensure proper VoiceOver
|
|
203
203
|
// support in Safari for accessibility.
|
|
204
|
-
return (h(Host, { key: '
|
|
204
|
+
return (h(Host, { key: 'fca2e80987d5e2e7f9138eeac3314d883ea1252b', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, "aria-required": required ? 'true' : undefined, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses(color, {
|
|
205
205
|
[mode]: true,
|
|
206
206
|
'in-item': hostContext('ion-item', el),
|
|
207
207
|
'checkbox-checked': checked,
|
|
@@ -211,10 +211,10 @@ export class Checkbox {
|
|
|
211
211
|
[`checkbox-justify-${justify}`]: justify !== undefined,
|
|
212
212
|
[`checkbox-alignment-${alignment}`]: alignment !== undefined,
|
|
213
213
|
[`checkbox-label-placement-${labelPlacement}`]: true,
|
|
214
|
-
}) }, h("label", { key: '
|
|
214
|
+
}) }, h("label", { key: '5cf50b6abdb9a3ae1f846f18bd8d5345de0ea2e9', class: "checkbox-wrapper", htmlFor: inputId }, h("input", Object.assign({ key: 'b8c3c6b01f65ff1b723c0de4b5d6f1b62940f481', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), h("div", { key: '7b29b18b97b8151f454760d73aca1543c8325e41', class: {
|
|
215
215
|
'label-text-wrapper': true,
|
|
216
216
|
'label-text-wrapper-hidden': !hasLabelContent,
|
|
217
|
-
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: '
|
|
217
|
+
}, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, h("slot", { key: 'ffbce8010274a68b8e67f9c0f19ec012944df484', onSlotchange: () => forceUpdate(this) }), this.renderHintText()), h("div", { key: '8e21fb89c72fbd52df70fa1916367ab5a543f281', class: "native-wrapper" }, h("svg", { key: 'c2519ff1a5c7f69e03ab26197ccfa8718b0951c6', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
|
|
218
218
|
}
|
|
219
219
|
getSVGPath(mode, indeterminate) {
|
|
220
220
|
let path = indeterminate ? (h("path", { d: "M6 12L18 12", part: "mark" })) : (h("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
|
|
@@ -131,6 +131,10 @@ export class Content {
|
|
|
131
131
|
this.tabsElement = null;
|
|
132
132
|
this.tabsLoadCallback = undefined;
|
|
133
133
|
}
|
|
134
|
+
if (this.resizeTimeout) {
|
|
135
|
+
clearTimeout(this.resizeTimeout);
|
|
136
|
+
this.resizeTimeout = null;
|
|
137
|
+
}
|
|
134
138
|
}
|
|
135
139
|
/**
|
|
136
140
|
* Rotating certain devices can update
|
|
@@ -369,7 +373,7 @@ export class Content {
|
|
|
369
373
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
370
374
|
const transitionShadow = mode === 'ios';
|
|
371
375
|
this.resize();
|
|
372
|
-
return (h(Host, Object.assign({ key: '
|
|
376
|
+
return (h(Host, Object.assign({ key: '287f5bb78888b0f66394a35ba2a3ad636d8f3412', role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
373
377
|
[mode]: true,
|
|
374
378
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
375
379
|
overscroll: forceOverscroll,
|
|
@@ -377,12 +381,12 @@ export class Content {
|
|
|
377
381
|
}), style: {
|
|
378
382
|
'--offset-top': `${this.cTop}px`,
|
|
379
383
|
'--offset-bottom': `${this.cBottom}px`,
|
|
380
|
-
} }, inheritedAttributes), h("div", { key: '
|
|
384
|
+
} }, inheritedAttributes), h("div", { key: '2e70e5e0ab4209478ea711a630058fa0e83af7f8', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? h("slot", { name: "fixed" }) : null, h("div", { key: '018a83406173ec7f7725f09b4bd1c0d964874ee4', class: {
|
|
381
385
|
'inner-scroll': true,
|
|
382
386
|
'scroll-x': scrollX,
|
|
383
387
|
'scroll-y': scrollY,
|
|
384
388
|
overscroll: (scrollX || scrollY) && forceOverscroll,
|
|
385
|
-
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '
|
|
389
|
+
}, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, h("slot", { key: '6f028eeb7c9dc7e1b82a8e549e1dd8aaf1d15fca' })), transitionShadow ? (h("div", { class: "transition-effect" }, h("div", { class: "transition-cover" }), h("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? h("slot", { name: "fixed" }) : null));
|
|
386
390
|
}
|
|
387
391
|
static get is() { return "ion-content"; }
|
|
388
392
|
static get encapsulation() { return "shadow"; }
|
|
@@ -884,6 +884,9 @@ export class Datetime {
|
|
|
884
884
|
this.clearFocusVisible();
|
|
885
885
|
this.clearFocusVisible = undefined;
|
|
886
886
|
}
|
|
887
|
+
if (this.loadTimeout) {
|
|
888
|
+
clearTimeout(this.loadTimeout);
|
|
889
|
+
}
|
|
887
890
|
}
|
|
888
891
|
initializeListeners() {
|
|
889
892
|
this.initializeCalendarListener();
|
|
@@ -932,7 +935,7 @@ export class Datetime {
|
|
|
932
935
|
*
|
|
933
936
|
* We schedule this after everything has had a chance to run.
|
|
934
937
|
*/
|
|
935
|
-
setTimeout(() => {
|
|
938
|
+
this.loadTimeout = setTimeout(() => {
|
|
936
939
|
this.ensureReadyIfVisible();
|
|
937
940
|
}, 100);
|
|
938
941
|
/**
|
|
@@ -1690,7 +1693,7 @@ export class Datetime {
|
|
|
1690
1693
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1691
1694
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1692
1695
|
renderHiddenInput(true, el, name, formatValue(value), disabled);
|
|
1693
|
-
return (h(Host, { key: '
|
|
1696
|
+
return (h(Host, { key: 'b81c3531f4654be3f6948df5f790c0f6ab488000', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
|
|
1694
1697
|
[mode]: true,
|
|
1695
1698
|
['datetime-readonly']: readonly,
|
|
1696
1699
|
['datetime-disabled']: disabled,
|
|
@@ -1700,7 +1703,7 @@ export class Datetime {
|
|
|
1700
1703
|
[`datetime-size-${size}`]: true,
|
|
1701
1704
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1702
1705
|
[`datetime-grid`]: isGridStyle,
|
|
1703
|
-
})) }, h("div", { key: '
|
|
1706
|
+
})) }, h("div", { key: 'f7f39f8e56146186210d0ab70ae95e829573e549', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1704
1707
|
}
|
|
1705
1708
|
static get is() { return "ion-datetime"; }
|
|
1706
1709
|
static get encapsulation() { return "shadow"; }
|
|
@@ -5,6 +5,7 @@ import { Host, h } from "@stencil/core";
|
|
|
5
5
|
import { getIonMode } from "../../global/ionic-global";
|
|
6
6
|
export class FabList {
|
|
7
7
|
constructor() {
|
|
8
|
+
this.activateTimeouts = [];
|
|
8
9
|
/**
|
|
9
10
|
* If `true`, the fab list will show all fab buttons in the list.
|
|
10
11
|
*/
|
|
@@ -15,20 +16,26 @@ export class FabList {
|
|
|
15
16
|
this.side = 'bottom';
|
|
16
17
|
}
|
|
17
18
|
activatedChanged(activated) {
|
|
19
|
+
this.activateTimeouts.forEach(clearTimeout);
|
|
20
|
+
this.activateTimeouts = [];
|
|
18
21
|
const fabs = Array.from(this.el.querySelectorAll('ion-fab-button'));
|
|
19
22
|
// if showing the fabs add a timeout, else show immediately
|
|
20
23
|
const timeout = activated ? 30 : 0;
|
|
21
24
|
fabs.forEach((fab, i) => {
|
|
22
|
-
setTimeout(() => (fab.show = activated), i * timeout);
|
|
25
|
+
this.activateTimeouts.push(setTimeout(() => (fab.show = activated), i * timeout));
|
|
23
26
|
});
|
|
24
27
|
}
|
|
28
|
+
disconnectedCallback() {
|
|
29
|
+
this.activateTimeouts.forEach(clearTimeout);
|
|
30
|
+
this.activateTimeouts = [];
|
|
31
|
+
}
|
|
25
32
|
render() {
|
|
26
33
|
const mode = getIonMode(this);
|
|
27
|
-
return (h(Host, { key: '
|
|
34
|
+
return (h(Host, { key: '03a8920c29a93c6df4bab14753a78a8a30722ce8', class: {
|
|
28
35
|
[mode]: true,
|
|
29
36
|
'fab-list-active': this.activated,
|
|
30
37
|
[`fab-list-side-${this.side}`]: true,
|
|
31
|
-
} }, h("slot", { key: '
|
|
38
|
+
} }, h("slot", { key: 'd9e1541cb044e209bc2dff14080f3b938a2b84ae' })));
|
|
32
39
|
}
|
|
33
40
|
static get is() { return "ion-fab-list"; }
|
|
34
41
|
static get encapsulation() { return "shadow"; }
|
|
@@ -26,7 +26,16 @@ export class Img {
|
|
|
26
26
|
componentDidLoad() {
|
|
27
27
|
this.addIO();
|
|
28
28
|
}
|
|
29
|
+
disconnectedCallback() {
|
|
30
|
+
if (this.loadTimeout) {
|
|
31
|
+
clearTimeout(this.loadTimeout);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
29
34
|
addIO() {
|
|
35
|
+
if (this.loadTimeout) {
|
|
36
|
+
clearTimeout(this.loadTimeout);
|
|
37
|
+
this.loadTimeout = undefined;
|
|
38
|
+
}
|
|
30
39
|
if (this.src === undefined) {
|
|
31
40
|
return;
|
|
32
41
|
}
|
|
@@ -50,7 +59,7 @@ export class Img {
|
|
|
50
59
|
}
|
|
51
60
|
else {
|
|
52
61
|
// fall back to setTimeout for Safari and IE
|
|
53
|
-
setTimeout(() => this.load(), 200);
|
|
62
|
+
this.loadTimeout = setTimeout(() => this.load(), 200);
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
load() {
|
|
@@ -67,7 +76,7 @@ export class Img {
|
|
|
67
76
|
render() {
|
|
68
77
|
const { loadSrc, alt, onLoad, loadError, inheritedAttributes } = this;
|
|
69
78
|
const { draggable } = inheritedAttributes;
|
|
70
|
-
return (h(Host, { key: '
|
|
79
|
+
return (h(Host, { key: '9bfaa659b0680189fd29f3acb2fdce7f70be6060', class: getIonMode(this) }, h("img", { key: 'd484beae0d5cbe0406958bfad40cdd6c05625340', decoding: "async", src: loadSrc, alt: alt, onLoad: onLoad, onError: loadError, part: "image", draggable: isDraggable(draggable) })));
|
|
71
80
|
}
|
|
72
81
|
static get is() { return "ion-img"; }
|
|
73
82
|
static get encapsulation() { return "shadow"; }
|