voyager-ionic-core 9.0.7 → 9.0.9
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/index.js +1 -1
- 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-input.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-nav.js +1 -1
- package/components/ion-popover.js +1 -1
- package/components/ion-router-outlet.js +1 -1
- package/components/ion-select.js +1 -1
- package/components/ion-textarea.js +1 -1
- package/components/p-Bd8hg9FK.js +4 -0
- package/components/{p-DhfJAkyd.js → p-CKTjkpAq.js} +1 -1
- package/components/{p-DnGlmM4u.js → p-CONpe3oX.js} +1 -1
- package/components/{p-DMPsc_0r.js → p-CW84OFQa.js} +1 -1
- package/components/{p-D64Tyi-z.js → p-CYctYy9B.js} +1 -1
- package/components/{p-Dvyv9SMk.js → p-D0nwlsl_.js} +1 -1
- package/components/p-DfDIY2oP.js +4 -0
- package/components/p-SHHIB5F0.js +4 -0
- package/components/p-zQi7R3tS.js +4 -0
- package/css/core.css.map +1 -1
- package/css/ionic.bundle.css.map +1 -1
- package/dist/cjs/{index-DUiuw_fH.js → index-DCfr5hz-.js} +14 -2
- package/dist/cjs/index.cjs.js +3 -3
- package/dist/cjs/ion-app_8.cjs.entry.js +31 -3
- package/dist/cjs/ion-backdrop.cjs.entry.js +5 -1
- package/dist/cjs/ion-datetime.cjs.entry.js +55 -9
- package/dist/cjs/ion-input.cjs.entry.js +13 -13
- package/dist/cjs/ion-modal.cjs.entry.js +31 -81
- package/dist/cjs/ion-nav_2.cjs.entry.js +24 -2
- package/dist/cjs/ion-popover.cjs.entry.js +1 -1
- package/dist/cjs/ion-select_3.cjs.entry.js +12 -12
- package/dist/cjs/ion-textarea.cjs.entry.js +12 -12
- package/dist/cjs/{ios.transition-D85_rHf5.js → ios.transition-Ca6XODo9.js} +1 -1
- package/dist/cjs/{md.transition-Ce9X1WXr.js → md.transition-D8SfNYEp.js} +1 -1
- package/dist/cjs/{slot-mutation-controller-ClDxh3EK.js → slot-mutation-controller-B2OfJEBH.js} +67 -33
- package/dist/collection/components/backdrop/backdrop.js +6 -2
- package/dist/collection/components/datetime/datetime.js +56 -10
- package/dist/collection/components/input/input.ios.css +7 -3
- package/dist/collection/components/input/input.js +11 -11
- package/dist/collection/components/input/input.md.css +28 -15
- package/dist/collection/components/modal/gestures/sheet.js +30 -80
- package/dist/collection/components/nav/nav.js +24 -2
- package/dist/collection/components/router-outlet/router-outlet.js +31 -3
- package/dist/collection/components/select/select.ios.css +7 -3
- package/dist/collection/components/select/select.js +10 -10
- package/dist/collection/components/select/select.md.css +28 -15
- package/dist/collection/components/textarea/textarea.ios.css +7 -3
- package/dist/collection/components/textarea/textarea.js +10 -10
- package/dist/collection/components/textarea/textarea.md.css +28 -17
- package/dist/collection/utils/forms/index.js +1 -1
- package/dist/collection/utils/forms/{start-container-controller.js → start-end-container-controller.js} +66 -32
- package/dist/collection/utils/transition/index.js +11 -0
- package/dist/docs.json +3 -3
- package/dist/esm/{index-BBASprVu.js → index-z9vdZN7I.js} +14 -3
- package/dist/esm/index.js +3 -3
- package/dist/esm/ion-app_8.entry.js +31 -3
- package/dist/esm/ion-backdrop.entry.js +5 -1
- package/dist/esm/ion-datetime.entry.js +55 -9
- package/dist/esm/ion-input.entry.js +13 -13
- package/dist/esm/ion-modal.entry.js +31 -81
- package/dist/esm/ion-nav_2.entry.js +24 -2
- package/dist/esm/ion-popover.entry.js +1 -1
- package/dist/esm/ion-select_3.entry.js +12 -12
- package/dist/esm/ion-textarea.entry.js +12 -12
- package/dist/esm/{ios.transition-B8netzsb.js → ios.transition-BkUGiDUz.js} +1 -1
- package/dist/esm/{md.transition-DNCSSiXk.js → md.transition-B6hlrWjR.js} +1 -1
- package/dist/esm/{slot-mutation-controller-hAS2uJ7c.js → slot-mutation-controller-Btpr9-9O.js} +67 -33
- package/dist/html.html-data.json +1 -1
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-293cb1d5.entry.js +4 -0
- package/dist/ionic/p-61321cfa.entry.js +4 -0
- package/dist/ionic/p-657239f5.entry.js +4 -0
- package/dist/ionic/p-67f004eb.entry.js +4 -0
- package/dist/ionic/{p-230f510c.entry.js → p-76c189e7.entry.js} +1 -1
- package/dist/ionic/p-94f1f7df.entry.js +4 -0
- package/dist/ionic/{p-Bppj2PE0.js → p-BZTgGzGK.js} +1 -1
- package/dist/ionic/p-BpED_ep_.js +4 -0
- package/dist/ionic/{p-Bnc1L7Rk.js → p-CgcGX08t.js} +1 -1
- package/dist/ionic/p-Dk4Mdaru.js +4 -0
- package/dist/ionic/{p-4ed3c460.entry.js → p-a7d368b5.entry.js} +1 -1
- package/dist/ionic/p-e8e69c21.entry.js +4 -0
- package/dist/ionic/{p-af56702e.entry.js → p-f2116a54.entry.js} +1 -1
- package/dist/types/components/backdrop/backdrop.d.ts +4 -0
- package/dist/types/components/datetime/datetime.d.ts +20 -3
- package/dist/types/components/input/input.d.ts +2 -1
- package/dist/types/components/nav/nav.d.ts +1 -0
- package/dist/types/components/router-outlet/router-outlet.d.ts +1 -0
- package/dist/types/components/select/select.d.ts +2 -1
- package/dist/types/components/textarea/textarea.d.ts +2 -1
- package/dist/types/components.d.ts +3 -3
- package/dist/types/utils/forms/index.d.ts +1 -1
- package/dist/types/utils/forms/start-end-container-controller.d.ts +44 -0
- package/dist/types/utils/transition/index.d.ts +6 -0
- package/hydrate/index.js +254 -159
- package/hydrate/index.mjs +254 -159
- package/package.json +4 -4
- package/components/p-C7r5Gja6.js +0 -4
- package/components/p-CtiO6_sC.js +0 -4
- package/components/p-TLtgwTFF.js +0 -4
- package/components/p-Uk13YgEc.js +0 -4
- package/dist/ionic/p-27d96a9b.entry.js +0 -4
- package/dist/ionic/p-4d785062.entry.js +0 -4
- package/dist/ionic/p-6317d620.entry.js +0 -4
- package/dist/ionic/p-8b79061e.entry.js +0 -4
- package/dist/ionic/p-B8IuTu_r.js +0 -4
- package/dist/ionic/p-DQXtveHv.js +0 -4
- package/dist/ionic/p-c81ec0e8.entry.js +0 -4
- package/dist/ionic/p-d9a3dfd1.entry.js +0 -4
- package/dist/types/utils/forms/start-container-controller.d.ts +0 -34
|
@@ -453,7 +453,11 @@
|
|
|
453
453
|
* would not be able to see what they are typing.
|
|
454
454
|
*/
|
|
455
455
|
max-width: 200px;
|
|
456
|
-
|
|
456
|
+
/**
|
|
457
|
+
* The max-width animates with the transform so the label does not
|
|
458
|
+
* reveal its full floating width while it is still at full size.
|
|
459
|
+
*/
|
|
460
|
+
transition: color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), max-width 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
457
461
|
/**
|
|
458
462
|
* This ensures that double tapping this text
|
|
459
463
|
* clicks the <label> and focuses the textarea
|
|
@@ -467,8 +471,8 @@
|
|
|
467
471
|
* disable the label transition to prevent the floating label
|
|
468
472
|
* from animating as its position is adjusted.
|
|
469
473
|
*
|
|
470
|
-
* This class is applied by the start container controller,
|
|
471
|
-
* renaming it here requires renaming it there too.
|
|
474
|
+
* This class is applied by the start and end container controller,
|
|
475
|
+
* so renaming it here requires renaming it there too.
|
|
472
476
|
*/
|
|
473
477
|
:host(.skip-label-transition) .label-text-wrapper {
|
|
474
478
|
transition: none;
|
|
@@ -1060,12 +1064,20 @@
|
|
|
1060
1064
|
--padding-end: 16px;
|
|
1061
1065
|
/**
|
|
1062
1066
|
* The measured width of the start container, as a negative offset
|
|
1063
|
-
* in LTR and a positive one in RTL. Written to the host by the
|
|
1064
|
-
*
|
|
1067
|
+
* in LTR and a positive one in RTL. Written to the host by the start
|
|
1068
|
+
* and end container controller, so renaming it here requires renaming
|
|
1065
1069
|
* it there too. Declared with a default so the label is positioned
|
|
1066
1070
|
* correctly before the first measurement runs.
|
|
1067
1071
|
*/
|
|
1068
1072
|
--internal-start-container-adjustment: 0px;
|
|
1073
|
+
/**
|
|
1074
|
+
* The measured combined width of the start and end containers.
|
|
1075
|
+
* Written to the host by the start and end container controller, so
|
|
1076
|
+
* renaming it here requires renaming it there too. Declared with a
|
|
1077
|
+
* default so the floating label falls back to the width of the
|
|
1078
|
+
* control before the first measurement runs.
|
|
1079
|
+
*/
|
|
1080
|
+
--internal-start-end-container-width: 0px;
|
|
1069
1081
|
}
|
|
1070
1082
|
|
|
1071
1083
|
:host(.textarea-fill-outline.textarea-shape-round) {
|
|
@@ -1120,11 +1132,12 @@
|
|
|
1120
1132
|
}
|
|
1121
1133
|
|
|
1122
1134
|
/**
|
|
1123
|
-
* The
|
|
1124
|
-
* the
|
|
1125
|
-
*
|
|
1135
|
+
* The label is positioned relative to the control whether it is resting
|
|
1136
|
+
* over the textarea or floating in the notch, so its max-width always resolves
|
|
1137
|
+
* against the same width. This lets the max-width animate between the
|
|
1138
|
+
* resting and floating values without jumping.
|
|
1126
1139
|
*/
|
|
1127
|
-
:host(.textarea-fill-outline
|
|
1140
|
+
:host(.textarea-fill-outline) .textarea-control {
|
|
1128
1141
|
position: relative;
|
|
1129
1142
|
}
|
|
1130
1143
|
|
|
@@ -1133,9 +1146,8 @@
|
|
|
1133
1146
|
transform-origin: left top;
|
|
1134
1147
|
position: absolute;
|
|
1135
1148
|
/**
|
|
1136
|
-
*
|
|
1137
|
-
* excludes the start and end slots.
|
|
1138
|
-
* containing block becomes the wrapper and the rule below takes over.
|
|
1149
|
+
* This is the width of the textarea, which already
|
|
1150
|
+
* excludes the start and end slots.
|
|
1139
1151
|
*/
|
|
1140
1152
|
max-width: 100%;
|
|
1141
1153
|
}
|
|
@@ -1168,12 +1180,11 @@
|
|
|
1168
1180
|
margin-top: 0;
|
|
1169
1181
|
margin-bottom: 0;
|
|
1170
1182
|
/**
|
|
1171
|
-
* Label text should not extend
|
|
1172
|
-
*
|
|
1183
|
+
* Label text should not extend beyond the bounds of the textarea.
|
|
1184
|
+
* The control excludes the start and end slots, but the notch spans
|
|
1185
|
+
* the full width of the outline, so their width is added back.
|
|
1173
1186
|
*/
|
|
1174
|
-
max-width: calc(
|
|
1175
|
-
(100% - var(--padding-start) - var(--padding-end) - 8px) / 0.75
|
|
1176
|
-
);
|
|
1187
|
+
max-width: calc((100% + var(--internal-start-end-container-width) - 8px) / 0.75);
|
|
1177
1188
|
}
|
|
1178
1189
|
|
|
1179
1190
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
4
|
export * from './notch-controller';
|
|
5
|
-
export * from './start-container-controller';
|
|
5
|
+
export * from './start-end-container-controller';
|
|
6
6
|
export * from './compare-with-utils';
|
|
7
7
|
export * from './item-multiple-inputs';
|
|
8
8
|
export * from './click-controller';
|
|
@@ -18,10 +18,19 @@ export const SKIP_LABEL_TRANSITION_CLASS = 'skip-label-transition';
|
|
|
18
18
|
*/
|
|
19
19
|
export const START_CONTAINER_ADJUSTMENT_VAR = '--internal-start-container-adjustment';
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
21
|
+
* Set on the host as an inline style. The component stylesheets declare
|
|
22
|
+
* this property and read it with `var()`, so it must stay in sync with
|
|
23
|
+
* the `--internal-start-end-container-width` references in those files.
|
|
24
|
+
* Renaming it here requires renaming it there too.
|
|
25
|
+
*/
|
|
26
|
+
export const START_END_CONTAINER_WIDTH_VAR = '--internal-start-end-container-width';
|
|
27
|
+
/**
|
|
28
|
+
* A utility to measure the start and end containers of form components
|
|
29
|
+
* (input, textarea, select) with `fill="outline"` and write the results
|
|
30
|
+
* to the host. The start container width offsets floating/stacked labels
|
|
31
|
+
* so they line up with the outline border. The combined start and end
|
|
32
|
+
* container width lets the floating label size itself to the full width
|
|
33
|
+
* of the outline while still being positioned relative to the control.
|
|
25
34
|
*
|
|
26
35
|
* Measurement is deferred with raf() to avoid forcing layout during
|
|
27
36
|
* component updates, and a ResizeObserver watches for dynamic width
|
|
@@ -30,29 +39,36 @@ export const START_CONTAINER_ADJUSTMENT_VAR = '--internal-start-container-adjust
|
|
|
30
39
|
* @internal
|
|
31
40
|
* @param el - The host element (ion-input, ion-textarea, or ion-select).
|
|
32
41
|
* @param getStartContainer - A callback that returns the start container element.
|
|
33
|
-
* @param
|
|
42
|
+
* @param getEndContainer - A callback that returns the end container element.
|
|
43
|
+
* @param shouldMeasure - A callback that determines whether the containers should be measured.
|
|
34
44
|
*/
|
|
35
|
-
export const
|
|
45
|
+
export const createStartEndContainerController = (el, getStartContainer, getEndContainer, shouldMeasure) => {
|
|
36
46
|
let resizeObserver;
|
|
37
|
-
let
|
|
47
|
+
let observedStartContainer;
|
|
48
|
+
let observedEndContainer;
|
|
38
49
|
let measurementRaf;
|
|
39
50
|
let transitionRaf;
|
|
40
51
|
let appliedAdjustment;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
let appliedStartEndWidth;
|
|
53
|
+
/*
|
|
54
|
+
* Round to one decimal place so fractional widths produce a stable
|
|
55
|
+
* label offset and width when a container is added, removed, or resized.
|
|
56
|
+
*/
|
|
57
|
+
const roundWidth = (width) => Math.round(width * 10) / 10;
|
|
58
|
+
const measureContainers = () => {
|
|
59
|
+
const startContainer = getStartContainer();
|
|
60
|
+
if (!startContainer || !shouldMeasure()) {
|
|
61
|
+
return { adjustment: '', startEndWidth: '' };
|
|
45
62
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
* label offset when the start container is added, removed, or resized.
|
|
49
|
-
*/
|
|
50
|
-
const startContainerWidth = startSlot.getBoundingClientRect().width;
|
|
51
|
-
const roundedWidth = Math.round(startContainerWidth * 10) / 10;
|
|
63
|
+
const startContainerWidth = roundWidth(startContainer.getBoundingClientRect().width);
|
|
64
|
+
const endContainerWidth = roundWidth(getEndContainer()?.getBoundingClientRect().width ?? 0);
|
|
52
65
|
const sign = isRTL(el) ? '' : '-';
|
|
53
|
-
return
|
|
66
|
+
return {
|
|
67
|
+
adjustment: startContainerWidth ? `${sign}${startContainerWidth}px` : '0px',
|
|
68
|
+
startEndWidth: `${roundWidth(startContainerWidth + endContainerWidth)}px`,
|
|
69
|
+
};
|
|
54
70
|
};
|
|
55
|
-
const
|
|
71
|
+
const scheduleMeasurement = () => {
|
|
56
72
|
// Return if there is already a measurement queued to avoid a flicker
|
|
57
73
|
if (measurementRaf !== undefined) {
|
|
58
74
|
return;
|
|
@@ -63,7 +79,17 @@ export const createStartContainerController = (el, getStartContainer, shouldAppl
|
|
|
63
79
|
*/
|
|
64
80
|
measurementRaf = raf(() => {
|
|
65
81
|
measurementRaf = undefined;
|
|
66
|
-
const adjustment =
|
|
82
|
+
const { adjustment, startEndWidth } = measureContainers();
|
|
83
|
+
/*
|
|
84
|
+
* The width only changes how much of the label fits, so it can
|
|
85
|
+
* animate. The transition is not suppressed here because the end
|
|
86
|
+
* container can change size while the label is floating, such as
|
|
87
|
+
* when async content loads, and that should not cut the float short.
|
|
88
|
+
*/
|
|
89
|
+
if (startEndWidth !== appliedStartEndWidth) {
|
|
90
|
+
el.style.setProperty(START_END_CONTAINER_WIDTH_VAR, startEndWidth);
|
|
91
|
+
appliedStartEndWidth = startEndWidth;
|
|
92
|
+
}
|
|
67
93
|
// Only suppress the label transition when the label has to move
|
|
68
94
|
if (adjustment !== appliedAdjustment) {
|
|
69
95
|
// Discard a removal queued by an earlier change
|
|
@@ -86,29 +112,36 @@ export const createStartContainerController = (el, getStartContainer, shouldAppl
|
|
|
86
112
|
if (resizeObserver) {
|
|
87
113
|
resizeObserver.disconnect();
|
|
88
114
|
resizeObserver = undefined;
|
|
89
|
-
|
|
115
|
+
observedStartContainer = undefined;
|
|
116
|
+
observedEndContainer = undefined;
|
|
90
117
|
}
|
|
91
118
|
};
|
|
92
119
|
const setupResizeObserver = () => {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
120
|
+
const startContainer = getStartContainer();
|
|
121
|
+
const endContainer = getEndContainer();
|
|
122
|
+
// Stop watching once the measurements no longer apply
|
|
123
|
+
if (!startContainer || !shouldMeasure()) {
|
|
96
124
|
disconnectResizeObserver();
|
|
97
125
|
return;
|
|
98
126
|
}
|
|
99
|
-
// Return when prerendering or already watching
|
|
100
|
-
if (typeof ResizeObserver !== 'function' ||
|
|
127
|
+
// Return when prerendering or already watching these containers
|
|
128
|
+
if (typeof ResizeObserver !== 'function' ||
|
|
129
|
+
(resizeObserver && observedStartContainer === startContainer && observedEndContainer === endContainer)) {
|
|
101
130
|
return;
|
|
102
131
|
}
|
|
103
132
|
disconnectResizeObserver();
|
|
104
133
|
resizeObserver = new ResizeObserver(() => {
|
|
105
|
-
|
|
134
|
+
scheduleMeasurement();
|
|
106
135
|
});
|
|
107
|
-
|
|
108
|
-
resizeObserver.observe(
|
|
136
|
+
observedStartContainer = startContainer;
|
|
137
|
+
resizeObserver.observe(startContainer);
|
|
138
|
+
if (endContainer) {
|
|
139
|
+
observedEndContainer = endContainer;
|
|
140
|
+
resizeObserver.observe(endContainer);
|
|
141
|
+
}
|
|
109
142
|
};
|
|
110
|
-
const
|
|
111
|
-
|
|
143
|
+
const calculateContainerWidths = () => {
|
|
144
|
+
scheduleMeasurement();
|
|
112
145
|
};
|
|
113
146
|
const destroy = () => {
|
|
114
147
|
disconnectResizeObserver();
|
|
@@ -124,9 +157,10 @@ export const createStartContainerController = (el, getStartContainer, shouldAppl
|
|
|
124
157
|
}
|
|
125
158
|
// Re-apply from scratch if the element is connected again
|
|
126
159
|
appliedAdjustment = undefined;
|
|
160
|
+
appliedStartEndWidth = undefined;
|
|
127
161
|
};
|
|
128
162
|
return {
|
|
129
|
-
|
|
163
|
+
calculateContainerWidths,
|
|
130
164
|
destroy,
|
|
131
165
|
};
|
|
132
166
|
};
|
|
@@ -229,6 +229,17 @@ export const setPageHidden = (el, hidden) => {
|
|
|
229
229
|
el.classList.remove('ion-page-hidden');
|
|
230
230
|
}
|
|
231
231
|
};
|
|
232
|
+
/**
|
|
233
|
+
* Blocks clicks on `el` during a swipe to go back without animations,
|
|
234
|
+
* so releasing the pointer doesn't click whatever is under it. Returns
|
|
235
|
+
* a function that unblocks it after the release click.
|
|
236
|
+
*/
|
|
237
|
+
export const blockSwipeClicks = (el) => {
|
|
238
|
+
el.style.setProperty('pointer-events', 'none');
|
|
239
|
+
return () => {
|
|
240
|
+
setTimeout(() => el.style.removeProperty('pointer-events'));
|
|
241
|
+
};
|
|
242
|
+
};
|
|
232
243
|
const setZIndex = (enteringEl, leavingEl, direction) => {
|
|
233
244
|
if (enteringEl !== undefined) {
|
|
234
245
|
enteringEl.style.zIndex = direction === 'back' ? '99' : '101';
|
package/dist/docs.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2026-10-
|
|
2
|
+
"timestamp": "2026-10-28T03:31:14",
|
|
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",
|
|
@@ -118,8 +118,8 @@ const createFocusController = () => {
|
|
|
118
118
|
};
|
|
119
119
|
const LAST_FOCUS = 'ion-last-focus';
|
|
120
120
|
|
|
121
|
-
const iosTransitionAnimation = () => import('./ios.transition-
|
|
122
|
-
const mdTransitionAnimation = () => import('./md.transition-
|
|
121
|
+
const iosTransitionAnimation = () => import('./ios.transition-BkUGiDUz.js');
|
|
122
|
+
const mdTransitionAnimation = () => import('./md.transition-B6hlrWjR.js');
|
|
123
123
|
const focusController = createFocusController();
|
|
124
124
|
// TODO(FW-2832): types
|
|
125
125
|
/**
|
|
@@ -341,6 +341,17 @@ const setPageHidden = (el, hidden) => {
|
|
|
341
341
|
el.classList.remove('ion-page-hidden');
|
|
342
342
|
}
|
|
343
343
|
};
|
|
344
|
+
/**
|
|
345
|
+
* Blocks clicks on `el` during a swipe to go back without animations,
|
|
346
|
+
* so releasing the pointer doesn't click whatever is under it. Returns
|
|
347
|
+
* a function that unblocks it after the release click.
|
|
348
|
+
*/
|
|
349
|
+
const blockSwipeClicks = (el) => {
|
|
350
|
+
el.style.setProperty('pointer-events', 'none');
|
|
351
|
+
return () => {
|
|
352
|
+
setTimeout(() => el.style.removeProperty('pointer-events'));
|
|
353
|
+
};
|
|
354
|
+
};
|
|
344
355
|
const setZIndex = (enteringEl, leavingEl, direction) => {
|
|
345
356
|
if (enteringEl !== undefined) {
|
|
346
357
|
enteringEl.style.zIndex = direction === 'back' ? '99' : '101';
|
|
@@ -415,4 +426,4 @@ const getIosIonHeader = (opts) => {
|
|
|
415
426
|
return element.querySelector('ion-header');
|
|
416
427
|
};
|
|
417
428
|
|
|
418
|
-
export { LIFECYCLE_WILL_ENTER as L, LIFECYCLE_DID_ENTER as a, LIFECYCLE_WILL_LEAVE as b, LIFECYCLE_DID_LEAVE as c, LIFECYCLE_WILL_UNLOAD as d, deepReady as e, getIonPageElement as g, lifecycle as l, setPageHidden as s, transition as t, waitForMount as w };
|
|
429
|
+
export { LIFECYCLE_WILL_ENTER as L, LIFECYCLE_DID_ENTER as a, LIFECYCLE_WILL_LEAVE as b, LIFECYCLE_DID_LEAVE as c, LIFECYCLE_WILL_UNLOAD as d, deepReady as e, blockSwipeClicks as f, getIonPageElement as g, lifecycle as l, setPageHidden as s, transition as t, waitForMount as w };
|
package/dist/esm/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
4
|
export { c as createAnimation } from './animation-DmtJpz89.js';
|
|
5
|
-
export { a as LIFECYCLE_DID_ENTER, c as LIFECYCLE_DID_LEAVE, L as LIFECYCLE_WILL_ENTER, b as LIFECYCLE_WILL_LEAVE, d as LIFECYCLE_WILL_UNLOAD, g as getIonPageElement } from './index-
|
|
6
|
-
export { iosTransitionAnimation } from './ios.transition-
|
|
7
|
-
export { mdTransitionAnimation } from './md.transition-
|
|
5
|
+
export { a as LIFECYCLE_DID_ENTER, c as LIFECYCLE_DID_LEAVE, L as LIFECYCLE_WILL_ENTER, b as LIFECYCLE_WILL_LEAVE, d as LIFECYCLE_WILL_UNLOAD, g as getIonPageElement } from './index-z9vdZN7I.js';
|
|
6
|
+
export { iosTransitionAnimation } from './ios.transition-BkUGiDUz.js';
|
|
7
|
+
export { mdTransitionAnimation } from './md.transition-B6hlrWjR.js';
|
|
8
8
|
export { g as getTimeGivenProgression } from './cubic-bezier-hHmYLOfE.js';
|
|
9
9
|
export { createGesture } from './index-BmLuEdV7.js';
|
|
10
10
|
export { g as getPlatforms, i as initialize, a as isPlatform } from './ionic-global-Cep6oYzK.js';
|
|
@@ -12,7 +12,7 @@ import { c as createKeyboardController } from './keyboard-controller-B2NoF7bV.js
|
|
|
12
12
|
import { g as getTimeGivenProgression } from './cubic-bezier-hHmYLOfE.js';
|
|
13
13
|
import { a as attachComponent, d as detachComponent } from './framework-delegate-CDjM1vRH.js';
|
|
14
14
|
import { c as createLockController } from './lock-controller-B-hirT0v.js';
|
|
15
|
-
import { t as transition } from './index-
|
|
15
|
+
import { t as transition, f as blockSwipeClicks } from './index-z9vdZN7I.js';
|
|
16
16
|
import './gesture-controller-B_gJaBk0.js';
|
|
17
17
|
import './keyboard-Cmqp5iZD.js';
|
|
18
18
|
import './capacitor-CHJaJ9aX.js';
|
|
@@ -1262,6 +1262,14 @@ const RouterOutlet = class {
|
|
|
1262
1262
|
async connectedCallback() {
|
|
1263
1263
|
const onStart = () => {
|
|
1264
1264
|
this.gestureOrAnimationInProgress = true;
|
|
1265
|
+
/**
|
|
1266
|
+
* Without animations there's nothing for the swipe to drive, so
|
|
1267
|
+
* wait until the gesture ends to decide whether to go back.
|
|
1268
|
+
*/
|
|
1269
|
+
if (!(this.animated && config.getBoolean('animated', true))) {
|
|
1270
|
+
this.unblockSwipeClicks = blockSwipeClicks(this.el);
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1265
1273
|
if (this.swipeHandler) {
|
|
1266
1274
|
this.swipeHandler.onStart();
|
|
1267
1275
|
}
|
|
@@ -1295,7 +1303,21 @@ const RouterOutlet = class {
|
|
|
1295
1303
|
this.ani.progressEnd(shouldComplete ? 1 : 0, newStepValue, dur);
|
|
1296
1304
|
}
|
|
1297
1305
|
else {
|
|
1298
|
-
|
|
1306
|
+
const { swipeHandler, unblockSwipeClicks: unblock } = this;
|
|
1307
|
+
this.unblockSwipeClicks = undefined;
|
|
1308
|
+
// The stack can change during the swipe, so check that going back is still possible.
|
|
1309
|
+
if (unblock && shouldComplete && swipeHandler?.canStart()) {
|
|
1310
|
+
new Promise((resolve) => resolve(swipeHandler.onStart()))
|
|
1311
|
+
.then(() => swipeHandler.onEnd(true))
|
|
1312
|
+
.finally(() => {
|
|
1313
|
+
this.gestureOrAnimationInProgress = false;
|
|
1314
|
+
unblock();
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
else {
|
|
1318
|
+
this.gestureOrAnimationInProgress = false;
|
|
1319
|
+
unblock?.();
|
|
1320
|
+
}
|
|
1299
1321
|
}
|
|
1300
1322
|
});
|
|
1301
1323
|
if (this.swipeGesture === undefined) {
|
|
@@ -1318,6 +1340,12 @@ const RouterOutlet = class {
|
|
|
1318
1340
|
this.gesture.destroy();
|
|
1319
1341
|
this.gesture = undefined;
|
|
1320
1342
|
}
|
|
1343
|
+
// Destroying the gesture skips onEnd, so end a deferred swipe here.
|
|
1344
|
+
if (this.unblockSwipeClicks) {
|
|
1345
|
+
this.unblockSwipeClicks();
|
|
1346
|
+
this.unblockSwipeClicks = undefined;
|
|
1347
|
+
this.gestureOrAnimationInProgress = false;
|
|
1348
|
+
}
|
|
1321
1349
|
}
|
|
1322
1350
|
/** @internal */
|
|
1323
1351
|
async commit(enteringEl, leavingEl, opts) {
|
|
@@ -1429,7 +1457,7 @@ const RouterOutlet = class {
|
|
|
1429
1457
|
return true;
|
|
1430
1458
|
}
|
|
1431
1459
|
render() {
|
|
1432
|
-
return h("slot", { key: '
|
|
1460
|
+
return h("slot", { key: '811f32d8794e58fcc79deef1e217c4d419778742' });
|
|
1433
1461
|
}
|
|
1434
1462
|
get el() { return getElement(this); }
|
|
1435
1463
|
static get watchers() { return {
|
|
@@ -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 {
|