@ionic/core 9.0.9-nightly.20261020 → 9.0.9-nightly.20261021
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-action-sheet.js +1 -1
- package/components/ion-alert.js +1 -1
- package/components/ion-backdrop.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/ion-loading.js +1 -1
- package/components/ion-menu.js +1 -1
- package/components/ion-modal.js +1 -1
- package/components/ion-popover.js +1 -1
- package/components/ion-select.js +1 -1
- package/components/{p-DhfJAkyd.js → p-CKTjkpAq.js} +1 -1
- package/components/{p-DnGlmM4u.js → p-CONpe3oX.js} +1 -1
- package/components/p-CVrOcN5N.js +4 -0
- package/components/{p-DMPsc_0r.js → p-CW84OFQa.js} +1 -1
- package/components/{p-CQKWzUsE.js → p-CYctYy9B.js} +1 -1
- package/dist/cjs/ion-backdrop.cjs.entry.js +5 -1
- package/dist/cjs/ion-datetime.cjs.entry.js +55 -9
- package/dist/collection/components/backdrop/backdrop.js +6 -2
- package/dist/collection/components/datetime/datetime.js +56 -10
- package/dist/docs.json +3 -3
- package/dist/esm/ion-backdrop.entry.js +5 -1
- package/dist/esm/ion-datetime.entry.js +55 -9
- package/dist/html.html-data.json +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-230f510c.entry.js → p-76c189e7.entry.js} +1 -1
- package/dist/ionic/p-94f1f7df.entry.js +4 -0
- package/dist/types/components/backdrop/backdrop.d.ts +4 -0
- package/dist/types/components/datetime/datetime.d.ts +20 -3
- package/dist/types/components.d.ts +3 -3
- package/hydrate/index.js +60 -10
- package/hydrate/index.mjs +60 -10
- package/package.json +1 -1
- package/components/p-CQnEg-p2.js +0 -4
- package/dist/ionic/p-d9a3dfd1.entry.js +0 -4
|
@@ -767,6 +767,13 @@ const Datetime = class {
|
|
|
767
767
|
this.ionStyle = index.createEvent(this, "ionStyle", 7);
|
|
768
768
|
this.ionRender = index.createEvent(this, "ionRender", 7);
|
|
769
769
|
this.inputId = `ion-dt-${datetimeIds++}`;
|
|
770
|
+
/**
|
|
771
|
+
* Set when the user selects a value, cleared when it's confirmed
|
|
772
|
+
* or `processValue` runs (`reset()`, or `value` being set to a
|
|
773
|
+
* non-empty value). The overlay present listener only discards a
|
|
774
|
+
* selection while this is set.
|
|
775
|
+
*/
|
|
776
|
+
this.hasUnconfirmedSelection = false;
|
|
770
777
|
this.prevPresentation = null;
|
|
771
778
|
this.showMonthAndYear = false;
|
|
772
779
|
this.activeParts = [];
|
|
@@ -930,6 +937,7 @@ const Datetime = class {
|
|
|
930
937
|
if (popoverOrModal) {
|
|
931
938
|
popoverOrModal.dismiss(undefined, role);
|
|
932
939
|
}
|
|
940
|
+
return popoverOrModal !== null;
|
|
933
941
|
};
|
|
934
942
|
this.setWorkingParts = (parts) => {
|
|
935
943
|
this.workingParts = {
|
|
@@ -944,6 +952,7 @@ const Datetime = class {
|
|
|
944
952
|
if (this.readonly) {
|
|
945
953
|
return;
|
|
946
954
|
}
|
|
955
|
+
this.hasUnconfirmedSelection = true;
|
|
947
956
|
const { multiple, minParts, maxParts, activeParts } = this;
|
|
948
957
|
/**
|
|
949
958
|
* When setting the active parts, it is possible
|
|
@@ -1364,7 +1373,8 @@ const Datetime = class {
|
|
|
1364
1373
|
this.loadTimeout = undefined;
|
|
1365
1374
|
}
|
|
1366
1375
|
};
|
|
1367
|
-
this.processValue = (value) => {
|
|
1376
|
+
this.processValue = (value, animated = true) => {
|
|
1377
|
+
this.hasUnconfirmedSelection = false;
|
|
1368
1378
|
const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
|
|
1369
1379
|
const valueToProcess = hasValue ? format.parseDate(value) : this.defaultParts;
|
|
1370
1380
|
const { minParts, maxParts, workingParts, el } = this;
|
|
@@ -1427,13 +1437,14 @@ const Datetime = class {
|
|
|
1427
1437
|
const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
|
|
1428
1438
|
const bodyIsVisible = el.classList.contains('datetime-ready');
|
|
1429
1439
|
const { isGridStyle, showMonthAndYear } = this;
|
|
1430
|
-
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
|
|
1440
|
+
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear && animated) {
|
|
1431
1441
|
/**
|
|
1432
1442
|
* Only animate if:
|
|
1433
1443
|
* 1. We're using grid style (wheel style pickers should just jump to new value)
|
|
1434
1444
|
* 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
|
|
1435
1445
|
* 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
|
|
1436
1446
|
* 4. The month/year picker is not open (since you wouldn't see the animation anyway)
|
|
1447
|
+
* 5. The caller did not opt out (e.g. the parent overlay is still hidden)
|
|
1437
1448
|
*/
|
|
1438
1449
|
this.animateToDate(targetValue);
|
|
1439
1450
|
}
|
|
@@ -1604,6 +1615,7 @@ const Datetime = class {
|
|
|
1604
1615
|
this.setValue(format.convertDataToISO(activeParts));
|
|
1605
1616
|
}
|
|
1606
1617
|
}
|
|
1618
|
+
this.hasUnconfirmedSelection = false;
|
|
1607
1619
|
if (closeOverlay) {
|
|
1608
1620
|
this.closeParentOverlay(CONFIRM_ROLE);
|
|
1609
1621
|
}
|
|
@@ -1619,17 +1631,22 @@ const Datetime = class {
|
|
|
1619
1631
|
this.processValue(startDate);
|
|
1620
1632
|
}
|
|
1621
1633
|
/**
|
|
1622
|
-
* Emits the ionCancel event
|
|
1623
|
-
*
|
|
1624
|
-
*
|
|
1634
|
+
* Emits the ionCancel event, discards
|
|
1635
|
+
* any unconfirmed selection, and
|
|
1636
|
+
* optionally closes the popover or
|
|
1637
|
+
* modal that the datetime was
|
|
1625
1638
|
* presented in.
|
|
1626
1639
|
*
|
|
1627
1640
|
* @param closeOverlay If `true`, closes the parent overlay. Defaults to `false`.
|
|
1628
1641
|
*/
|
|
1629
1642
|
async cancel(closeOverlay = false) {
|
|
1630
1643
|
this.ionCancel.emit();
|
|
1631
|
-
|
|
1632
|
-
|
|
1644
|
+
/**
|
|
1645
|
+
* When a parent overlay closes, the present listener discards
|
|
1646
|
+
* the selection on the next open. Otherwise discard it now.
|
|
1647
|
+
*/
|
|
1648
|
+
if (!closeOverlay || !this.closeParentOverlay(CANCEL_ROLE)) {
|
|
1649
|
+
this.processValue(this.value);
|
|
1633
1650
|
}
|
|
1634
1651
|
}
|
|
1635
1652
|
/**
|
|
@@ -1651,6 +1668,7 @@ const Datetime = class {
|
|
|
1651
1668
|
this.loadTimeout = setTimeout(() => {
|
|
1652
1669
|
this.ensureReadyIfVisible();
|
|
1653
1670
|
}, 100);
|
|
1671
|
+
this.initializeOverlayPresentListener();
|
|
1654
1672
|
}
|
|
1655
1673
|
disconnectedCallback() {
|
|
1656
1674
|
if (this.clearFocusVisible) {
|
|
@@ -1658,6 +1676,34 @@ const Datetime = class {
|
|
|
1658
1676
|
this.clearFocusVisible = undefined;
|
|
1659
1677
|
}
|
|
1660
1678
|
this.loadTimeoutCleanup();
|
|
1679
|
+
if (this.destroyOverlayPresentListener) {
|
|
1680
|
+
this.destroyOverlayPresentListener();
|
|
1681
|
+
this.destroyOverlayPresentListener = undefined;
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* A datetime in a modal or popover stays mounted between
|
|
1686
|
+
* presentations, so an unconfirmed selection would still show when
|
|
1687
|
+
* it reopens. Discarding on present rather than dismiss lets app
|
|
1688
|
+
* code that runs on dismiss still confirm or reset the selection,
|
|
1689
|
+
* whatever order its listeners were added in.
|
|
1690
|
+
*/
|
|
1691
|
+
initializeOverlayPresentListener() {
|
|
1692
|
+
const overlay = this.el.closest('ion-modal, ion-popover');
|
|
1693
|
+
if (!overlay) {
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
const eventName = overlay.tagName === 'ION-MODAL' ? 'ionModalWillPresent' : 'ionPopoverWillPresent';
|
|
1697
|
+
const onPresent = (ev) => {
|
|
1698
|
+
// Ignore nested overlays and skip when there's nothing to discard.
|
|
1699
|
+
if (ev.target !== overlay || !this.hasUnconfirmedSelection) {
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1702
|
+
// The overlay is still hidden, so skip the month animation.
|
|
1703
|
+
this.processValue(this.value, false);
|
|
1704
|
+
};
|
|
1705
|
+
overlay.addEventListener(eventName, onPresent);
|
|
1706
|
+
this.destroyOverlayPresentListener = () => overlay.removeEventListener(eventName, onPresent);
|
|
1661
1707
|
}
|
|
1662
1708
|
initializeListeners() {
|
|
1663
1709
|
this.initializeCalendarListener();
|
|
@@ -2540,7 +2586,7 @@ const Datetime = class {
|
|
|
2540
2586
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
2541
2587
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
2542
2588
|
helpers.renderHiddenInput(true, el, name, format.formatValue(value), disabled);
|
|
2543
|
-
return (index.h(index.Host, { key: '
|
|
2589
|
+
return (index.h(index.Host, { key: 'e9b99bb5610fc7fe879200a56dcc865c6e2f1404', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: {
|
|
2544
2590
|
...theme.createColorClasses(color, {
|
|
2545
2591
|
[mode]: true,
|
|
2546
2592
|
['datetime-readonly']: readonly,
|
|
@@ -2552,7 +2598,7 @@ const Datetime = class {
|
|
|
2552
2598
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
2553
2599
|
[`datetime-grid`]: isGridStyle,
|
|
2554
2600
|
}),
|
|
2555
|
-
} }, index.h("div", { key: '
|
|
2601
|
+
} }, index.h("div", { key: 'a5e61be2989468dc24ec8fb394116d9339b7824c', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
2556
2602
|
}
|
|
2557
2603
|
get el() { return index.getElement(this); }
|
|
2558
2604
|
static get watchers() { return {
|
|
@@ -7,6 +7,10 @@ export class Backdrop {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
/**
|
|
9
9
|
* If `true`, the backdrop will be visible.
|
|
10
|
+
* This property controls whether or not the backdrop's
|
|
11
|
+
* default background is shown. It does not control whether
|
|
12
|
+
* or not the backdrop blocks interaction, and it does not
|
|
13
|
+
* override a custom background set on `ion-backdrop`.
|
|
10
14
|
*/
|
|
11
15
|
this.visible = true;
|
|
12
16
|
/**
|
|
@@ -32,7 +36,7 @@ export class Backdrop {
|
|
|
32
36
|
}
|
|
33
37
|
render() {
|
|
34
38
|
const mode = getIonMode(this);
|
|
35
|
-
return (h(Host, { key: '
|
|
39
|
+
return (h(Host, { key: '14141148f4a22371b8ad7cb9dcdc32398ec109aa', "aria-hidden": "true", class: {
|
|
36
40
|
[mode]: true,
|
|
37
41
|
'backdrop-hide': !this.visible,
|
|
38
42
|
'backdrop-no-tappable': !this.tappable,
|
|
@@ -66,7 +70,7 @@ export class Backdrop {
|
|
|
66
70
|
"optional": false,
|
|
67
71
|
"docs": {
|
|
68
72
|
"tags": [],
|
|
69
|
-
"text": "If `true`, the backdrop will be visible."
|
|
73
|
+
"text": "If `true`, the backdrop will be visible.\nThis property controls whether or not the backdrop's\ndefault background is shown. It does not control whether\nor not the backdrop blocks interaction, and it does not\noverride a custom background set on `ion-backdrop`."
|
|
70
74
|
},
|
|
71
75
|
"getter": false,
|
|
72
76
|
"setter": false,
|
|
@@ -56,6 +56,13 @@ import { checkForPresentationFormatMismatch, warnIfTimeZoneProvided } from "./ut
|
|
|
56
56
|
export class Datetime {
|
|
57
57
|
constructor() {
|
|
58
58
|
this.inputId = `ion-dt-${datetimeIds++}`;
|
|
59
|
+
/**
|
|
60
|
+
* Set when the user selects a value, cleared when it's confirmed
|
|
61
|
+
* or `processValue` runs (`reset()`, or `value` being set to a
|
|
62
|
+
* non-empty value). The overlay present listener only discards a
|
|
63
|
+
* selection while this is set.
|
|
64
|
+
*/
|
|
65
|
+
this.hasUnconfirmedSelection = false;
|
|
59
66
|
this.prevPresentation = null;
|
|
60
67
|
this.showMonthAndYear = false;
|
|
61
68
|
this.activeParts = [];
|
|
@@ -219,6 +226,7 @@ export class Datetime {
|
|
|
219
226
|
if (popoverOrModal) {
|
|
220
227
|
popoverOrModal.dismiss(undefined, role);
|
|
221
228
|
}
|
|
229
|
+
return popoverOrModal !== null;
|
|
222
230
|
};
|
|
223
231
|
this.setWorkingParts = (parts) => {
|
|
224
232
|
this.workingParts = {
|
|
@@ -233,6 +241,7 @@ export class Datetime {
|
|
|
233
241
|
if (this.readonly) {
|
|
234
242
|
return;
|
|
235
243
|
}
|
|
244
|
+
this.hasUnconfirmedSelection = true;
|
|
236
245
|
const { multiple, minParts, maxParts, activeParts } = this;
|
|
237
246
|
/**
|
|
238
247
|
* When setting the active parts, it is possible
|
|
@@ -653,7 +662,8 @@ export class Datetime {
|
|
|
653
662
|
this.loadTimeout = undefined;
|
|
654
663
|
}
|
|
655
664
|
};
|
|
656
|
-
this.processValue = (value) => {
|
|
665
|
+
this.processValue = (value, animated = true) => {
|
|
666
|
+
this.hasUnconfirmedSelection = false;
|
|
657
667
|
const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
|
|
658
668
|
const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
|
|
659
669
|
const { minParts, maxParts, workingParts, el } = this;
|
|
@@ -716,13 +726,14 @@ export class Datetime {
|
|
|
716
726
|
const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
|
|
717
727
|
const bodyIsVisible = el.classList.contains('datetime-ready');
|
|
718
728
|
const { isGridStyle, showMonthAndYear } = this;
|
|
719
|
-
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
|
|
729
|
+
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear && animated) {
|
|
720
730
|
/**
|
|
721
731
|
* Only animate if:
|
|
722
732
|
* 1. We're using grid style (wheel style pickers should just jump to new value)
|
|
723
733
|
* 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
|
|
724
734
|
* 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
|
|
725
735
|
* 4. The month/year picker is not open (since you wouldn't see the animation anyway)
|
|
736
|
+
* 5. The caller did not opt out (e.g. the parent overlay is still hidden)
|
|
726
737
|
*/
|
|
727
738
|
this.animateToDate(targetValue);
|
|
728
739
|
}
|
|
@@ -893,6 +904,7 @@ export class Datetime {
|
|
|
893
904
|
this.setValue(convertDataToISO(activeParts));
|
|
894
905
|
}
|
|
895
906
|
}
|
|
907
|
+
this.hasUnconfirmedSelection = false;
|
|
896
908
|
if (closeOverlay) {
|
|
897
909
|
this.closeParentOverlay(CONFIRM_ROLE);
|
|
898
910
|
}
|
|
@@ -908,17 +920,22 @@ export class Datetime {
|
|
|
908
920
|
this.processValue(startDate);
|
|
909
921
|
}
|
|
910
922
|
/**
|
|
911
|
-
* Emits the ionCancel event
|
|
912
|
-
*
|
|
913
|
-
*
|
|
923
|
+
* Emits the ionCancel event, discards
|
|
924
|
+
* any unconfirmed selection, and
|
|
925
|
+
* optionally closes the popover or
|
|
926
|
+
* modal that the datetime was
|
|
914
927
|
* presented in.
|
|
915
928
|
*
|
|
916
929
|
* @param closeOverlay If `true`, closes the parent overlay. Defaults to `false`.
|
|
917
930
|
*/
|
|
918
931
|
async cancel(closeOverlay = false) {
|
|
919
932
|
this.ionCancel.emit();
|
|
920
|
-
|
|
921
|
-
|
|
933
|
+
/**
|
|
934
|
+
* When a parent overlay closes, the present listener discards
|
|
935
|
+
* the selection on the next open. Otherwise discard it now.
|
|
936
|
+
*/
|
|
937
|
+
if (!closeOverlay || !this.closeParentOverlay(CANCEL_ROLE)) {
|
|
938
|
+
this.processValue(this.value);
|
|
922
939
|
}
|
|
923
940
|
}
|
|
924
941
|
/**
|
|
@@ -940,6 +957,7 @@ export class Datetime {
|
|
|
940
957
|
this.loadTimeout = setTimeout(() => {
|
|
941
958
|
this.ensureReadyIfVisible();
|
|
942
959
|
}, 100);
|
|
960
|
+
this.initializeOverlayPresentListener();
|
|
943
961
|
}
|
|
944
962
|
disconnectedCallback() {
|
|
945
963
|
if (this.clearFocusVisible) {
|
|
@@ -947,6 +965,34 @@ export class Datetime {
|
|
|
947
965
|
this.clearFocusVisible = undefined;
|
|
948
966
|
}
|
|
949
967
|
this.loadTimeoutCleanup();
|
|
968
|
+
if (this.destroyOverlayPresentListener) {
|
|
969
|
+
this.destroyOverlayPresentListener();
|
|
970
|
+
this.destroyOverlayPresentListener = undefined;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* A datetime in a modal or popover stays mounted between
|
|
975
|
+
* presentations, so an unconfirmed selection would still show when
|
|
976
|
+
* it reopens. Discarding on present rather than dismiss lets app
|
|
977
|
+
* code that runs on dismiss still confirm or reset the selection,
|
|
978
|
+
* whatever order its listeners were added in.
|
|
979
|
+
*/
|
|
980
|
+
initializeOverlayPresentListener() {
|
|
981
|
+
const overlay = this.el.closest('ion-modal, ion-popover');
|
|
982
|
+
if (!overlay) {
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
const eventName = overlay.tagName === 'ION-MODAL' ? 'ionModalWillPresent' : 'ionPopoverWillPresent';
|
|
986
|
+
const onPresent = (ev) => {
|
|
987
|
+
// Ignore nested overlays and skip when there's nothing to discard.
|
|
988
|
+
if (ev.target !== overlay || !this.hasUnconfirmedSelection) {
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
// The overlay is still hidden, so skip the month animation.
|
|
992
|
+
this.processValue(this.value, false);
|
|
993
|
+
};
|
|
994
|
+
overlay.addEventListener(eventName, onPresent);
|
|
995
|
+
this.destroyOverlayPresentListener = () => overlay.removeEventListener(eventName, onPresent);
|
|
950
996
|
}
|
|
951
997
|
initializeListeners() {
|
|
952
998
|
this.initializeCalendarListener();
|
|
@@ -1829,7 +1875,7 @@ export class Datetime {
|
|
|
1829
1875
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1830
1876
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1831
1877
|
renderHiddenInput(true, el, name, formatValue(value), disabled);
|
|
1832
|
-
return (h(Host, { key: '
|
|
1878
|
+
return (h(Host, { key: 'e9b99bb5610fc7fe879200a56dcc865c6e2f1404', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: {
|
|
1833
1879
|
...createColorClasses(color, {
|
|
1834
1880
|
[mode]: true,
|
|
1835
1881
|
['datetime-readonly']: readonly,
|
|
@@ -1841,7 +1887,7 @@ export class Datetime {
|
|
|
1841
1887
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1842
1888
|
[`datetime-grid`]: isGridStyle,
|
|
1843
1889
|
}),
|
|
1844
|
-
} }, h("div", { key: '
|
|
1890
|
+
} }, h("div", { key: 'a5e61be2989468dc24ec8fb394116d9339b7824c', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1845
1891
|
}
|
|
1846
1892
|
static get is() { return "ion-datetime"; }
|
|
1847
1893
|
static get encapsulation() { return "shadow"; }
|
|
@@ -2721,7 +2767,7 @@ export class Datetime {
|
|
|
2721
2767
|
"return": "Promise<void>"
|
|
2722
2768
|
},
|
|
2723
2769
|
"docs": {
|
|
2724
|
-
"text": "Emits the ionCancel event and\noptionally closes the popover\
|
|
2770
|
+
"text": "Emits the ionCancel event, discards\nany unconfirmed selection, and\noptionally closes the popover or\nmodal that the datetime was\npresented in.",
|
|
2725
2771
|
"tags": [{
|
|
2726
2772
|
"name": "param",
|
|
2727
2773
|
"text": "closeOverlay If `true`, closes the parent overlay. Defaults to `false`."
|
package/dist/docs.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2026-10-
|
|
2
|
+
"timestamp": "2026-10-21T06:17:54",
|
|
3
3
|
"compiler": {
|
|
4
4
|
"name": "@stencil/core",
|
|
5
5
|
"version": "4.45.2",
|
|
@@ -3315,7 +3315,7 @@
|
|
|
3315
3315
|
"mutable": false,
|
|
3316
3316
|
"attr": "visible",
|
|
3317
3317
|
"reflectToAttr": false,
|
|
3318
|
-
"docs": "If `true`, the backdrop will be visible.",
|
|
3318
|
+
"docs": "If `true`, the backdrop will be visible.\nThis property controls whether or not the backdrop's\ndefault background is shown. It does not control whether\nor not the backdrop blocks interaction, and it does not\noverride a custom background set on `ion-backdrop`.",
|
|
3319
3319
|
"docsTags": [
|
|
3320
3320
|
{
|
|
3321
3321
|
"name": "default",
|
|
@@ -9696,7 +9696,7 @@
|
|
|
9696
9696
|
"docs": "If `true`, closes the parent overlay. Defaults to `false`."
|
|
9697
9697
|
}
|
|
9698
9698
|
],
|
|
9699
|
-
"docs": "Emits the ionCancel event and\noptionally closes the popover\
|
|
9699
|
+
"docs": "Emits the ionCancel event, discards\nany unconfirmed selection, and\noptionally closes the popover or\nmodal that the datetime was\npresented in.",
|
|
9700
9700
|
"docsTags": [
|
|
9701
9701
|
{
|
|
9702
9702
|
"name": "param",
|
|
@@ -14,6 +14,10 @@ const Backdrop = class {
|
|
|
14
14
|
this.ionBackdropTap = createEvent(this, "ionBackdropTap", 7);
|
|
15
15
|
/**
|
|
16
16
|
* If `true`, the backdrop will be visible.
|
|
17
|
+
* This property controls whether or not the backdrop's
|
|
18
|
+
* default background is shown. It does not control whether
|
|
19
|
+
* or not the backdrop blocks interaction, and it does not
|
|
20
|
+
* override a custom background set on `ion-backdrop`.
|
|
17
21
|
*/
|
|
18
22
|
this.visible = true;
|
|
19
23
|
/**
|
|
@@ -39,7 +43,7 @@ const Backdrop = class {
|
|
|
39
43
|
}
|
|
40
44
|
render() {
|
|
41
45
|
const mode = getIonMode(this);
|
|
42
|
-
return (h(Host, { key: '
|
|
46
|
+
return (h(Host, { key: '14141148f4a22371b8ad7cb9dcdc32398ec109aa', "aria-hidden": "true", class: {
|
|
43
47
|
[mode]: true,
|
|
44
48
|
'backdrop-hide': !this.visible,
|
|
45
49
|
'backdrop-no-tappable': !this.tappable,
|
|
@@ -765,6 +765,13 @@ const Datetime = class {
|
|
|
765
765
|
this.ionStyle = createEvent(this, "ionStyle", 7);
|
|
766
766
|
this.ionRender = createEvent(this, "ionRender", 7);
|
|
767
767
|
this.inputId = `ion-dt-${datetimeIds++}`;
|
|
768
|
+
/**
|
|
769
|
+
* Set when the user selects a value, cleared when it's confirmed
|
|
770
|
+
* or `processValue` runs (`reset()`, or `value` being set to a
|
|
771
|
+
* non-empty value). The overlay present listener only discards a
|
|
772
|
+
* selection while this is set.
|
|
773
|
+
*/
|
|
774
|
+
this.hasUnconfirmedSelection = false;
|
|
768
775
|
this.prevPresentation = null;
|
|
769
776
|
this.showMonthAndYear = false;
|
|
770
777
|
this.activeParts = [];
|
|
@@ -928,6 +935,7 @@ const Datetime = class {
|
|
|
928
935
|
if (popoverOrModal) {
|
|
929
936
|
popoverOrModal.dismiss(undefined, role);
|
|
930
937
|
}
|
|
938
|
+
return popoverOrModal !== null;
|
|
931
939
|
};
|
|
932
940
|
this.setWorkingParts = (parts) => {
|
|
933
941
|
this.workingParts = {
|
|
@@ -942,6 +950,7 @@ const Datetime = class {
|
|
|
942
950
|
if (this.readonly) {
|
|
943
951
|
return;
|
|
944
952
|
}
|
|
953
|
+
this.hasUnconfirmedSelection = true;
|
|
945
954
|
const { multiple, minParts, maxParts, activeParts } = this;
|
|
946
955
|
/**
|
|
947
956
|
* When setting the active parts, it is possible
|
|
@@ -1362,7 +1371,8 @@ const Datetime = class {
|
|
|
1362
1371
|
this.loadTimeout = undefined;
|
|
1363
1372
|
}
|
|
1364
1373
|
};
|
|
1365
|
-
this.processValue = (value) => {
|
|
1374
|
+
this.processValue = (value, animated = true) => {
|
|
1375
|
+
this.hasUnconfirmedSelection = false;
|
|
1366
1376
|
const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
|
|
1367
1377
|
const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
|
|
1368
1378
|
const { minParts, maxParts, workingParts, el } = this;
|
|
@@ -1425,13 +1435,14 @@ const Datetime = class {
|
|
|
1425
1435
|
const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
|
|
1426
1436
|
const bodyIsVisible = el.classList.contains('datetime-ready');
|
|
1427
1437
|
const { isGridStyle, showMonthAndYear } = this;
|
|
1428
|
-
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
|
|
1438
|
+
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear && animated) {
|
|
1429
1439
|
/**
|
|
1430
1440
|
* Only animate if:
|
|
1431
1441
|
* 1. We're using grid style (wheel style pickers should just jump to new value)
|
|
1432
1442
|
* 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
|
|
1433
1443
|
* 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
|
|
1434
1444
|
* 4. The month/year picker is not open (since you wouldn't see the animation anyway)
|
|
1445
|
+
* 5. The caller did not opt out (e.g. the parent overlay is still hidden)
|
|
1435
1446
|
*/
|
|
1436
1447
|
this.animateToDate(targetValue);
|
|
1437
1448
|
}
|
|
@@ -1602,6 +1613,7 @@ const Datetime = class {
|
|
|
1602
1613
|
this.setValue(convertDataToISO(activeParts));
|
|
1603
1614
|
}
|
|
1604
1615
|
}
|
|
1616
|
+
this.hasUnconfirmedSelection = false;
|
|
1605
1617
|
if (closeOverlay) {
|
|
1606
1618
|
this.closeParentOverlay(CONFIRM_ROLE);
|
|
1607
1619
|
}
|
|
@@ -1617,17 +1629,22 @@ const Datetime = class {
|
|
|
1617
1629
|
this.processValue(startDate);
|
|
1618
1630
|
}
|
|
1619
1631
|
/**
|
|
1620
|
-
* Emits the ionCancel event
|
|
1621
|
-
*
|
|
1622
|
-
*
|
|
1632
|
+
* Emits the ionCancel event, discards
|
|
1633
|
+
* any unconfirmed selection, and
|
|
1634
|
+
* optionally closes the popover or
|
|
1635
|
+
* modal that the datetime was
|
|
1623
1636
|
* presented in.
|
|
1624
1637
|
*
|
|
1625
1638
|
* @param closeOverlay If `true`, closes the parent overlay. Defaults to `false`.
|
|
1626
1639
|
*/
|
|
1627
1640
|
async cancel(closeOverlay = false) {
|
|
1628
1641
|
this.ionCancel.emit();
|
|
1629
|
-
|
|
1630
|
-
|
|
1642
|
+
/**
|
|
1643
|
+
* When a parent overlay closes, the present listener discards
|
|
1644
|
+
* the selection on the next open. Otherwise discard it now.
|
|
1645
|
+
*/
|
|
1646
|
+
if (!closeOverlay || !this.closeParentOverlay(CANCEL_ROLE)) {
|
|
1647
|
+
this.processValue(this.value);
|
|
1631
1648
|
}
|
|
1632
1649
|
}
|
|
1633
1650
|
/**
|
|
@@ -1649,6 +1666,7 @@ const Datetime = class {
|
|
|
1649
1666
|
this.loadTimeout = setTimeout(() => {
|
|
1650
1667
|
this.ensureReadyIfVisible();
|
|
1651
1668
|
}, 100);
|
|
1669
|
+
this.initializeOverlayPresentListener();
|
|
1652
1670
|
}
|
|
1653
1671
|
disconnectedCallback() {
|
|
1654
1672
|
if (this.clearFocusVisible) {
|
|
@@ -1656,6 +1674,34 @@ const Datetime = class {
|
|
|
1656
1674
|
this.clearFocusVisible = undefined;
|
|
1657
1675
|
}
|
|
1658
1676
|
this.loadTimeoutCleanup();
|
|
1677
|
+
if (this.destroyOverlayPresentListener) {
|
|
1678
|
+
this.destroyOverlayPresentListener();
|
|
1679
|
+
this.destroyOverlayPresentListener = undefined;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* A datetime in a modal or popover stays mounted between
|
|
1684
|
+
* presentations, so an unconfirmed selection would still show when
|
|
1685
|
+
* it reopens. Discarding on present rather than dismiss lets app
|
|
1686
|
+
* code that runs on dismiss still confirm or reset the selection,
|
|
1687
|
+
* whatever order its listeners were added in.
|
|
1688
|
+
*/
|
|
1689
|
+
initializeOverlayPresentListener() {
|
|
1690
|
+
const overlay = this.el.closest('ion-modal, ion-popover');
|
|
1691
|
+
if (!overlay) {
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
const eventName = overlay.tagName === 'ION-MODAL' ? 'ionModalWillPresent' : 'ionPopoverWillPresent';
|
|
1695
|
+
const onPresent = (ev) => {
|
|
1696
|
+
// Ignore nested overlays and skip when there's nothing to discard.
|
|
1697
|
+
if (ev.target !== overlay || !this.hasUnconfirmedSelection) {
|
|
1698
|
+
return;
|
|
1699
|
+
}
|
|
1700
|
+
// The overlay is still hidden, so skip the month animation.
|
|
1701
|
+
this.processValue(this.value, false);
|
|
1702
|
+
};
|
|
1703
|
+
overlay.addEventListener(eventName, onPresent);
|
|
1704
|
+
this.destroyOverlayPresentListener = () => overlay.removeEventListener(eventName, onPresent);
|
|
1659
1705
|
}
|
|
1660
1706
|
initializeListeners() {
|
|
1661
1707
|
this.initializeCalendarListener();
|
|
@@ -2538,7 +2584,7 @@ const Datetime = class {
|
|
|
2538
2584
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
2539
2585
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
2540
2586
|
renderHiddenInput(true, el, name, formatValue(value), disabled);
|
|
2541
|
-
return (h(Host, { key: '
|
|
2587
|
+
return (h(Host, { key: 'e9b99bb5610fc7fe879200a56dcc865c6e2f1404', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: {
|
|
2542
2588
|
...createColorClasses(color, {
|
|
2543
2589
|
[mode]: true,
|
|
2544
2590
|
['datetime-readonly']: readonly,
|
|
@@ -2550,7 +2596,7 @@ const Datetime = class {
|
|
|
2550
2596
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
2551
2597
|
[`datetime-grid`]: isGridStyle,
|
|
2552
2598
|
}),
|
|
2553
|
-
} }, h("div", { key: '
|
|
2599
|
+
} }, h("div", { key: 'a5e61be2989468dc24ec8fb394116d9339b7824c', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
2554
2600
|
}
|
|
2555
2601
|
get el() { return getElement(this); }
|
|
2556
2602
|
static get watchers() { return {
|
package/dist/html.html-data.json
CHANGED
|
@@ -381,7 +381,7 @@
|
|
|
381
381
|
},
|
|
382
382
|
{
|
|
383
383
|
"name": "visible",
|
|
384
|
-
"description": "If `true`, the backdrop will be visible."
|
|
384
|
+
"description": "If `true`, the backdrop will be visible.\nThis property controls whether or not the backdrop's\ndefault background is shown. It does not control whether\nor not the backdrop blocks interaction, and it does not\noverride a custom background set on `ion-backdrop`."
|
|
385
385
|
}
|
|
386
386
|
],
|
|
387
387
|
"references": [
|