@ionic/core 8.8.12 → 8.8.13-nightly.20260626
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-datetime-button.js +1 -1
- package/components/ion-datetime.js +1 -1
- package/components/p-Cf2jSDS8.js +4 -0
- package/dist/cjs/{data-DLTUw-KF.js → format-PxvGiOik.js} +8 -532
- package/dist/cjs/ion-datetime-button.cjs.entry.js +17 -15
- package/dist/cjs/ion-datetime_3.cjs.entry.js +603 -70
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/datetime/datetime.js +38 -2
- package/dist/collection/components/datetime-button/datetime-button.js +8 -7
- package/dist/docs.json +6 -1
- package/dist/esm/{data-DZI70dKr.js → format-CAmvpAez.js} +1 -524
- package/dist/esm/ion-datetime-button.entry.js +9 -7
- package/dist/esm/ion-datetime_3.entry.js +536 -3
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-5c255ce3.entry.js +4 -0
- package/dist/ionic/p-C0eMdTCW.js +4 -0
- package/dist/ionic/p-c38b648e.entry.js +4 -0
- package/dist/types/components/datetime/datetime.d.ts +8 -0
- package/dist/types/components.d.ts +6 -2
- package/hydrate/index.js +22 -9
- package/hydrate/index.mjs +22 -9
- package/package.json +4 -4
- package/components/p-BAYYcg3o.js +0 -4
- package/dist/ionic/p-0d005398.entry.js +0 -4
- package/dist/ionic/p-81ea5652.entry.js +0 -4
- package/dist/ionic/p-DAAFkPFT.js +0 -4
|
@@ -11,7 +11,7 @@ var dir = require('./dir-Cn0z1rJH.js');
|
|
|
11
11
|
var theme = require('./theme-CeDs6Hcv.js');
|
|
12
12
|
var index$1 = require('./index-DqmRDbxg.js');
|
|
13
13
|
var ionicGlobal = require('./ionic-global-B-cA6LkY.js');
|
|
14
|
-
var
|
|
14
|
+
var format = require('./format-PxvGiOik.js');
|
|
15
15
|
var lockController = require('./lock-controller-aDB9wrEf.js');
|
|
16
16
|
var animation = require('./animation-BJq0kcy2.js');
|
|
17
17
|
var haptic = require('./haptic-ClPPQ_PS.js');
|
|
@@ -21,6 +21,529 @@ require('./framework-delegate-BtICZDHr.js');
|
|
|
21
21
|
require('./gesture-controller-dtqlP_q4.js');
|
|
22
22
|
require('./capacitor-DmA66EwP.js');
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Returns the current date as
|
|
26
|
+
* an ISO string in the user's
|
|
27
|
+
* time zone.
|
|
28
|
+
*/
|
|
29
|
+
const getToday = () => {
|
|
30
|
+
/**
|
|
31
|
+
* ion-datetime intentionally does not
|
|
32
|
+
* parse time zones/do automatic time zone
|
|
33
|
+
* conversion when accepting user input.
|
|
34
|
+
* However when we get today's date string,
|
|
35
|
+
* we want it formatted relative to the user's
|
|
36
|
+
* time zone.
|
|
37
|
+
*
|
|
38
|
+
* When calling toISOString(), the browser
|
|
39
|
+
* will convert the date to UTC time by either adding
|
|
40
|
+
* or subtracting the time zone offset.
|
|
41
|
+
* To work around this, we need to either add
|
|
42
|
+
* or subtract the time zone offset to the Date
|
|
43
|
+
* object prior to calling toISOString().
|
|
44
|
+
* This allows us to get an ISO string
|
|
45
|
+
* that is in the user's time zone.
|
|
46
|
+
*/
|
|
47
|
+
return format.removeDateTzOffset(new Date()).toISOString();
|
|
48
|
+
};
|
|
49
|
+
const minutes = [
|
|
50
|
+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
51
|
+
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
|
52
|
+
];
|
|
53
|
+
// h11 hour system uses 0-11. Midnight starts at 0:00am.
|
|
54
|
+
const hour11 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
55
|
+
// h12 hour system uses 0-12. Midnight starts at 12:00am.
|
|
56
|
+
const hour12 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
57
|
+
// h23 hour system uses 0-23. Midnight starts at 0:00.
|
|
58
|
+
const hour23 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
|
|
59
|
+
// h24 hour system uses 1-24. Midnight starts at 24:00.
|
|
60
|
+
const hour24 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0];
|
|
61
|
+
/**
|
|
62
|
+
* Given a locale and a mode,
|
|
63
|
+
* return an array with formatted days
|
|
64
|
+
* of the week. iOS should display days
|
|
65
|
+
* such as "Mon" or "Tue".
|
|
66
|
+
* MD should display days such as "M"
|
|
67
|
+
* or "T".
|
|
68
|
+
*/
|
|
69
|
+
const getDaysOfWeek = (locale, mode, firstDayOfWeek = 0) => {
|
|
70
|
+
/**
|
|
71
|
+
* Nov 1st, 2020 starts on a Sunday.
|
|
72
|
+
* ion-datetime assumes weeks start on Sunday,
|
|
73
|
+
* but is configurable via `firstDayOfWeek`.
|
|
74
|
+
*/
|
|
75
|
+
const weekdayFormat = mode === 'ios' ? 'short' : 'narrow';
|
|
76
|
+
const intl = new Intl.DateTimeFormat(locale, { weekday: weekdayFormat });
|
|
77
|
+
const startDate = new Date('11/01/2020');
|
|
78
|
+
const daysOfWeek = [];
|
|
79
|
+
/**
|
|
80
|
+
* For each day of the week,
|
|
81
|
+
* get the day name.
|
|
82
|
+
*/
|
|
83
|
+
for (let i = firstDayOfWeek; i < firstDayOfWeek + 7; i++) {
|
|
84
|
+
const currentDate = new Date(startDate);
|
|
85
|
+
currentDate.setDate(currentDate.getDate() + i);
|
|
86
|
+
daysOfWeek.push(intl.format(currentDate));
|
|
87
|
+
}
|
|
88
|
+
return daysOfWeek;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Returns an array containing all of the
|
|
92
|
+
* days in a month for a given year. Values are
|
|
93
|
+
* aligned with a week calendar starting on
|
|
94
|
+
* the firstDayOfWeek value (Sunday by default)
|
|
95
|
+
* using null values.
|
|
96
|
+
*/
|
|
97
|
+
const getDaysOfMonth = (month, year, firstDayOfWeek, showAdjacentDays = false) => {
|
|
98
|
+
const numDays = format.getNumDaysInMonth(month, year);
|
|
99
|
+
let previousNumDays; //previous month number of days
|
|
100
|
+
if (month === 1) {
|
|
101
|
+
// If the current month is January, the previous month should be December of the previous year.
|
|
102
|
+
previousNumDays = format.getNumDaysInMonth(12, year - 1);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Otherwise, the previous month should be the current month - 1 of the same year.
|
|
106
|
+
previousNumDays = format.getNumDaysInMonth(month - 1, year);
|
|
107
|
+
}
|
|
108
|
+
const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
|
|
109
|
+
/**
|
|
110
|
+
* To get the first day of the month aligned on the correct
|
|
111
|
+
* day of the week, we need to determine how many "filler" days
|
|
112
|
+
* to generate. These filler days as empty/disabled buttons
|
|
113
|
+
* that fill the space of the days of the week before the first
|
|
114
|
+
* of the month.
|
|
115
|
+
*
|
|
116
|
+
* There are two cases here:
|
|
117
|
+
*
|
|
118
|
+
* 1. If firstOfMonth = 4, firstDayOfWeek = 0 then the offset
|
|
119
|
+
* is (4 - (0 + 1)) = 3. Since the offset loop goes from 0 to 3 inclusive,
|
|
120
|
+
* this will generate 4 filler days (0, 1, 2, 3), and then day of week 4 will have
|
|
121
|
+
* the first day of the month.
|
|
122
|
+
*
|
|
123
|
+
* 2. If firstOfMonth = 2, firstDayOfWeek = 4 then the offset
|
|
124
|
+
* is (6 - (4 - 2)) = 4. Since the offset loop goes from 0 to 4 inclusive,
|
|
125
|
+
* this will generate 5 filler days (0, 1, 2, 3, 4), and then day of week 5 will have
|
|
126
|
+
* the first day of the month.
|
|
127
|
+
*/
|
|
128
|
+
const offset = firstOfMonth >= firstDayOfWeek ? firstOfMonth - (firstDayOfWeek + 1) : 6 - (firstDayOfWeek - firstOfMonth);
|
|
129
|
+
let days = [];
|
|
130
|
+
for (let i = 1; i <= numDays; i++) {
|
|
131
|
+
days.push({ day: i, dayOfWeek: (offset + i) % 7, isAdjacentDay: false });
|
|
132
|
+
}
|
|
133
|
+
if (showAdjacentDays) {
|
|
134
|
+
for (let i = 0; i <= offset; i++) {
|
|
135
|
+
// Using offset create previous month adjacent day, starting from last day
|
|
136
|
+
days = [{ day: previousNumDays - i, dayOfWeek: (previousNumDays - i) % 7, isAdjacentDay: true }, ...days];
|
|
137
|
+
}
|
|
138
|
+
// Calculate positiveOffset
|
|
139
|
+
// The calendar will display 42 days (6 rows of 7 columns)
|
|
140
|
+
// Knowing this the offset is 41 (we start at index 0)
|
|
141
|
+
// minus (the previous offset + the current month days)
|
|
142
|
+
const positiveOffset = 41 - (numDays + offset);
|
|
143
|
+
for (let i = 0; i < positiveOffset; i++) {
|
|
144
|
+
days.push({ day: i + 1, dayOfWeek: (numDays + offset + i) % 7, isAdjacentDay: true });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
for (let i = 0; i <= offset; i++) {
|
|
149
|
+
days = [{ day: null, dayOfWeek: null, isAdjacentDay: false }, ...days];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return days;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Returns an array of pre-defined hour
|
|
156
|
+
* values based on the provided hourCycle.
|
|
157
|
+
*/
|
|
158
|
+
const getHourData = (hourCycle) => {
|
|
159
|
+
switch (hourCycle) {
|
|
160
|
+
case 'h11':
|
|
161
|
+
return hour11;
|
|
162
|
+
case 'h12':
|
|
163
|
+
return hour12;
|
|
164
|
+
case 'h23':
|
|
165
|
+
return hour23;
|
|
166
|
+
case 'h24':
|
|
167
|
+
return hour24;
|
|
168
|
+
default:
|
|
169
|
+
throw new Error(`Invalid hour cycle "${hourCycle}"`);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Given a local, reference datetime parts and option
|
|
174
|
+
* max/min bound datetime parts, calculate the acceptable
|
|
175
|
+
* hour and minute values according to the bounds and locale.
|
|
176
|
+
*/
|
|
177
|
+
const generateTime = (locale, refParts, hourCycle = 'h12', minParts, maxParts, hourValues, minuteValues) => {
|
|
178
|
+
const computedHourCycle = format.getHourCycle(locale, hourCycle);
|
|
179
|
+
const use24Hour = format.is24Hour(computedHourCycle);
|
|
180
|
+
let processedHours = getHourData(computedHourCycle);
|
|
181
|
+
let processedMinutes = minutes;
|
|
182
|
+
let isAMAllowed = true;
|
|
183
|
+
let isPMAllowed = true;
|
|
184
|
+
if (hourValues) {
|
|
185
|
+
processedHours = processedHours.filter((hour) => hourValues.includes(hour));
|
|
186
|
+
}
|
|
187
|
+
if (minuteValues) {
|
|
188
|
+
processedMinutes = processedMinutes.filter((minute) => minuteValues.includes(minute));
|
|
189
|
+
}
|
|
190
|
+
if (minParts) {
|
|
191
|
+
/**
|
|
192
|
+
* If ref day is the same as the
|
|
193
|
+
* minimum allowed day, filter hour/minute
|
|
194
|
+
* values according to min hour and minute.
|
|
195
|
+
*/
|
|
196
|
+
if (format.isSameDay(refParts, minParts)) {
|
|
197
|
+
/**
|
|
198
|
+
* Users may not always set the hour/minute for
|
|
199
|
+
* min value (i.e. 2021-06-02) so we should allow
|
|
200
|
+
* all hours/minutes in that case.
|
|
201
|
+
*/
|
|
202
|
+
if (minParts.hour !== undefined) {
|
|
203
|
+
processedHours = processedHours.filter((hour) => {
|
|
204
|
+
const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
|
|
205
|
+
return (use24Hour ? hour : convertedHour) >= minParts.hour;
|
|
206
|
+
});
|
|
207
|
+
isAMAllowed = minParts.hour < 13;
|
|
208
|
+
}
|
|
209
|
+
if (minParts.minute !== undefined) {
|
|
210
|
+
/**
|
|
211
|
+
* The minimum minute range should not be enforced when
|
|
212
|
+
* the hour is greater than the min hour.
|
|
213
|
+
*
|
|
214
|
+
* For example with a minimum range of 09:30, users
|
|
215
|
+
* should be able to select 10:00-10:29 and beyond.
|
|
216
|
+
*/
|
|
217
|
+
let isPastMinHour = false;
|
|
218
|
+
if (minParts.hour !== undefined && refParts.hour !== undefined) {
|
|
219
|
+
if (refParts.hour > minParts.hour) {
|
|
220
|
+
isPastMinHour = true;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
processedMinutes = processedMinutes.filter((minute) => {
|
|
224
|
+
if (isPastMinHour) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
return minute >= minParts.minute;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* If ref day is before minimum
|
|
232
|
+
* day do not render any hours/minute values
|
|
233
|
+
*/
|
|
234
|
+
}
|
|
235
|
+
else if (format.isBefore(refParts, minParts)) {
|
|
236
|
+
processedHours = [];
|
|
237
|
+
processedMinutes = [];
|
|
238
|
+
isAMAllowed = isPMAllowed = false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (maxParts) {
|
|
242
|
+
/**
|
|
243
|
+
* If ref day is the same as the
|
|
244
|
+
* maximum allowed day, filter hour/minute
|
|
245
|
+
* values according to max hour and minute.
|
|
246
|
+
*/
|
|
247
|
+
if (format.isSameDay(refParts, maxParts)) {
|
|
248
|
+
/**
|
|
249
|
+
* Users may not always set the hour/minute for
|
|
250
|
+
* max value (i.e. 2021-06-02) so we should allow
|
|
251
|
+
* all hours/minutes in that case.
|
|
252
|
+
*/
|
|
253
|
+
if (maxParts.hour !== undefined) {
|
|
254
|
+
processedHours = processedHours.filter((hour) => {
|
|
255
|
+
const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
|
|
256
|
+
return (use24Hour ? hour : convertedHour) <= maxParts.hour;
|
|
257
|
+
});
|
|
258
|
+
isPMAllowed = maxParts.hour >= 12;
|
|
259
|
+
}
|
|
260
|
+
if (maxParts.minute !== undefined && refParts.hour === maxParts.hour) {
|
|
261
|
+
// The available minutes should only be filtered when the hour is the same as the max hour.
|
|
262
|
+
// For example if the max hour is 10:30 and the current hour is 10:00,
|
|
263
|
+
// users should be able to select 00-30 minutes.
|
|
264
|
+
// If the current hour is 09:00, users should be able to select 00-60 minutes.
|
|
265
|
+
processedMinutes = processedMinutes.filter((minute) => minute <= maxParts.minute);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* If ref day is after minimum
|
|
269
|
+
* day do not render any hours/minute values
|
|
270
|
+
*/
|
|
271
|
+
}
|
|
272
|
+
else if (format.isAfter(refParts, maxParts)) {
|
|
273
|
+
processedHours = [];
|
|
274
|
+
processedMinutes = [];
|
|
275
|
+
isAMAllowed = isPMAllowed = false;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
hours: processedHours,
|
|
280
|
+
minutes: processedMinutes,
|
|
281
|
+
am: isAMAllowed,
|
|
282
|
+
pm: isPMAllowed,
|
|
283
|
+
};
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* Given DatetimeParts, generate the previous,
|
|
287
|
+
* current, and and next months.
|
|
288
|
+
*/
|
|
289
|
+
const generateMonths = (refParts, forcedDate) => {
|
|
290
|
+
const current = { month: refParts.month, year: refParts.year, day: refParts.day };
|
|
291
|
+
/**
|
|
292
|
+
* If we're forcing a month to appear, and it's different from the current month,
|
|
293
|
+
* ensure it appears by replacing the next or previous month as appropriate.
|
|
294
|
+
*/
|
|
295
|
+
if (forcedDate !== undefined && (refParts.month !== forcedDate.month || refParts.year !== forcedDate.year)) {
|
|
296
|
+
const forced = { month: forcedDate.month, year: forcedDate.year, day: forcedDate.day };
|
|
297
|
+
const forcedMonthIsBefore = format.isBefore(forced, current);
|
|
298
|
+
return forcedMonthIsBefore
|
|
299
|
+
? [forced, current, format.getNextMonth(refParts)]
|
|
300
|
+
: [format.getPreviousMonth(refParts), current, forced];
|
|
301
|
+
}
|
|
302
|
+
return [format.getPreviousMonth(refParts), current, format.getNextMonth(refParts)];
|
|
303
|
+
};
|
|
304
|
+
const getMonthColumnData = (locale, refParts, minParts, maxParts, monthValues, formatOptions = {
|
|
305
|
+
month: 'long',
|
|
306
|
+
}) => {
|
|
307
|
+
const { year } = refParts;
|
|
308
|
+
const months = [];
|
|
309
|
+
if (monthValues !== undefined) {
|
|
310
|
+
let processedMonths = monthValues;
|
|
311
|
+
if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.month) !== undefined) {
|
|
312
|
+
processedMonths = processedMonths.filter((month) => month <= maxParts.month);
|
|
313
|
+
}
|
|
314
|
+
if ((minParts === null || minParts === void 0 ? void 0 : minParts.month) !== undefined) {
|
|
315
|
+
processedMonths = processedMonths.filter((month) => month >= minParts.month);
|
|
316
|
+
}
|
|
317
|
+
processedMonths.forEach((processedMonth) => {
|
|
318
|
+
const date = new Date(`${processedMonth}/1/${year} GMT+0000`);
|
|
319
|
+
const monthString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
|
|
320
|
+
months.push({ text: monthString, value: processedMonth });
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
const maxMonth = maxParts && maxParts.year === year ? maxParts.month : 12;
|
|
325
|
+
const minMonth = minParts && minParts.year === year ? minParts.month : 1;
|
|
326
|
+
for (let i = minMonth; i <= maxMonth; i++) {
|
|
327
|
+
/**
|
|
328
|
+
*
|
|
329
|
+
* There is a bug on iOS 14 where
|
|
330
|
+
* Intl.DateTimeFormat takes into account
|
|
331
|
+
* the local timezone offset when formatting dates.
|
|
332
|
+
*
|
|
333
|
+
* Forcing the timezone to 'UTC' fixes the issue. However,
|
|
334
|
+
* we should keep this workaround as it is safer. In the event
|
|
335
|
+
* this breaks in another browser, we will not be impacted
|
|
336
|
+
* because all dates will be interpreted in UTC.
|
|
337
|
+
*
|
|
338
|
+
* Example:
|
|
339
|
+
* new Intl.DateTimeFormat('en-US', { month: 'long' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "March"
|
|
340
|
+
* new Intl.DateTimeFormat('en-US', { month: 'long', timeZone: 'UTC' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "April"
|
|
341
|
+
*
|
|
342
|
+
* In certain timezones, iOS 14 shows the wrong
|
|
343
|
+
* date for .toUTCString(). To combat this, we
|
|
344
|
+
* force all of the timezones to GMT+0000 (UTC).
|
|
345
|
+
*
|
|
346
|
+
* Example:
|
|
347
|
+
* Time Zone: Central European Standard Time
|
|
348
|
+
* new Date('1/1/1992').toUTCString() // "Tue, 31 Dec 1991 23:00:00 GMT"
|
|
349
|
+
* new Date('1/1/1992 GMT+0000').toUTCString() // "Wed, 01 Jan 1992 00:00:00 GMT"
|
|
350
|
+
*/
|
|
351
|
+
const date = new Date(`${i}/1/${year} GMT+0000`);
|
|
352
|
+
const monthString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
|
|
353
|
+
months.push({ text: monthString, value: i });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return months;
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* Returns information regarding
|
|
360
|
+
* selectable dates (i.e 1st, 2nd, 3rd, etc)
|
|
361
|
+
* within a reference month.
|
|
362
|
+
* @param locale The locale to format the date with
|
|
363
|
+
* @param refParts The reference month/year to generate dates for
|
|
364
|
+
* @param minParts The minimum bound on the date that can be returned
|
|
365
|
+
* @param maxParts The maximum bound on the date that can be returned
|
|
366
|
+
* @param dayValues The allowed date values
|
|
367
|
+
* @returns Date data to be used in ion-picker-column
|
|
368
|
+
*/
|
|
369
|
+
const getDayColumnData = (locale, refParts, minParts, maxParts, dayValues, formatOptions = {
|
|
370
|
+
day: 'numeric',
|
|
371
|
+
}) => {
|
|
372
|
+
const { month, year } = refParts;
|
|
373
|
+
const days = [];
|
|
374
|
+
/**
|
|
375
|
+
* If we have max/min bounds that in the same
|
|
376
|
+
* month/year as the refParts, we should
|
|
377
|
+
* use the define day as the max/min day.
|
|
378
|
+
* Otherwise, fallback to the max/min days in a month.
|
|
379
|
+
*/
|
|
380
|
+
const numDaysInMonth = format.getNumDaysInMonth(month, year);
|
|
381
|
+
const maxDay = (maxParts === null || maxParts === void 0 ? void 0 : maxParts.day) !== null && (maxParts === null || maxParts === void 0 ? void 0 : maxParts.day) !== undefined && maxParts.year === year && maxParts.month === month
|
|
382
|
+
? maxParts.day
|
|
383
|
+
: numDaysInMonth;
|
|
384
|
+
const minDay = (minParts === null || minParts === void 0 ? void 0 : minParts.day) !== null && (minParts === null || minParts === void 0 ? void 0 : minParts.day) !== undefined && minParts.year === year && minParts.month === month
|
|
385
|
+
? minParts.day
|
|
386
|
+
: 1;
|
|
387
|
+
if (dayValues !== undefined) {
|
|
388
|
+
let processedDays = dayValues;
|
|
389
|
+
processedDays = processedDays.filter((day) => day >= minDay && day <= maxDay);
|
|
390
|
+
processedDays.forEach((processedDay) => {
|
|
391
|
+
const date = new Date(`${month}/${processedDay}/${year} GMT+0000`);
|
|
392
|
+
const dayString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
|
|
393
|
+
days.push({ text: dayString, value: processedDay });
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
for (let i = minDay; i <= maxDay; i++) {
|
|
398
|
+
const date = new Date(`${month}/${i}/${year} GMT+0000`);
|
|
399
|
+
const dayString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
|
|
400
|
+
days.push({ text: dayString, value: i });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return days;
|
|
404
|
+
};
|
|
405
|
+
const getYearColumnData = (locale, refParts, minParts, maxParts, yearValues) => {
|
|
406
|
+
var _a, _b;
|
|
407
|
+
let processedYears = [];
|
|
408
|
+
if (yearValues !== undefined) {
|
|
409
|
+
processedYears = yearValues;
|
|
410
|
+
if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) !== undefined) {
|
|
411
|
+
processedYears = processedYears.filter((year) => year <= maxParts.year);
|
|
412
|
+
}
|
|
413
|
+
if ((minParts === null || minParts === void 0 ? void 0 : minParts.year) !== undefined) {
|
|
414
|
+
processedYears = processedYears.filter((year) => year >= minParts.year);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
const { year } = refParts;
|
|
419
|
+
const maxYear = (_a = maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) !== null && _a !== void 0 ? _a : year;
|
|
420
|
+
const minYear = (_b = minParts === null || minParts === void 0 ? void 0 : minParts.year) !== null && _b !== void 0 ? _b : year - 100;
|
|
421
|
+
for (let i = minYear; i <= maxYear; i++) {
|
|
422
|
+
processedYears.push(i);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return processedYears.map((year) => ({
|
|
426
|
+
text: format.getYear(locale, { year, month: refParts.month, day: refParts.day }),
|
|
427
|
+
value: year,
|
|
428
|
+
}));
|
|
429
|
+
};
|
|
430
|
+
/**
|
|
431
|
+
* Given a starting date and an upper bound,
|
|
432
|
+
* this functions returns an array of all
|
|
433
|
+
* month objects in that range.
|
|
434
|
+
*/
|
|
435
|
+
const getAllMonthsInRange = (currentParts, maxParts) => {
|
|
436
|
+
if (currentParts.month === maxParts.month && currentParts.year === maxParts.year) {
|
|
437
|
+
return [currentParts];
|
|
438
|
+
}
|
|
439
|
+
return [currentParts, ...getAllMonthsInRange(format.getNextMonth(currentParts), maxParts)];
|
|
440
|
+
};
|
|
441
|
+
/**
|
|
442
|
+
* Creates and returns picker items
|
|
443
|
+
* that represent the days in a month.
|
|
444
|
+
* Example: "Thu, Jun 2"
|
|
445
|
+
*/
|
|
446
|
+
const getCombinedDateColumnData = (locale, todayParts, minParts, maxParts, dayValues, monthValues) => {
|
|
447
|
+
let items = [];
|
|
448
|
+
let parts = [];
|
|
449
|
+
/**
|
|
450
|
+
* Get all month objects from the min date
|
|
451
|
+
* to the max date. Note: Do not use getMonthColumnData
|
|
452
|
+
* as that function only generates dates within a
|
|
453
|
+
* single year.
|
|
454
|
+
*/
|
|
455
|
+
let months = getAllMonthsInRange(minParts, maxParts);
|
|
456
|
+
/**
|
|
457
|
+
* Filter out any disallowed month values.
|
|
458
|
+
*/
|
|
459
|
+
if (monthValues) {
|
|
460
|
+
months = months.filter(({ month }) => monthValues.includes(month));
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Get all of the days in the month.
|
|
464
|
+
* From there, generate an array where
|
|
465
|
+
* each item has the month, date, and day
|
|
466
|
+
* of work as the text.
|
|
467
|
+
*/
|
|
468
|
+
months.forEach((monthObject) => {
|
|
469
|
+
const referenceMonth = { month: monthObject.month, day: null, year: monthObject.year };
|
|
470
|
+
const monthDays = getDayColumnData(locale, referenceMonth, minParts, maxParts, dayValues, {
|
|
471
|
+
month: 'short',
|
|
472
|
+
day: 'numeric',
|
|
473
|
+
weekday: 'short',
|
|
474
|
+
});
|
|
475
|
+
const dateParts = [];
|
|
476
|
+
const dateColumnItems = [];
|
|
477
|
+
monthDays.forEach((dayObject) => {
|
|
478
|
+
const isToday = format.isSameDay(Object.assign(Object.assign({}, referenceMonth), { day: dayObject.value }), todayParts);
|
|
479
|
+
/**
|
|
480
|
+
* Today's date should read as "Today" (localized)
|
|
481
|
+
* not the actual date string
|
|
482
|
+
*/
|
|
483
|
+
dateColumnItems.push({
|
|
484
|
+
text: isToday ? format.getTodayLabel(locale) : dayObject.text,
|
|
485
|
+
value: `${referenceMonth.year}-${referenceMonth.month}-${dayObject.value}`,
|
|
486
|
+
});
|
|
487
|
+
/**
|
|
488
|
+
* When selecting a date in the wheel picker
|
|
489
|
+
* we need access to the raw datetime parts data.
|
|
490
|
+
* The picker column only accepts values of
|
|
491
|
+
* type string or number, so we need to return
|
|
492
|
+
* two sets of data: A data set to be passed
|
|
493
|
+
* to the picker column, and a data set to
|
|
494
|
+
* be used to reference the raw data when
|
|
495
|
+
* updating the picker column value.
|
|
496
|
+
*/
|
|
497
|
+
dateParts.push({
|
|
498
|
+
month: referenceMonth.month,
|
|
499
|
+
year: referenceMonth.year,
|
|
500
|
+
day: dayObject.value,
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
parts = [...parts, ...dateParts];
|
|
504
|
+
items = [...items, ...dateColumnItems];
|
|
505
|
+
});
|
|
506
|
+
return {
|
|
507
|
+
parts,
|
|
508
|
+
items,
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
const getTimeColumnsData = (locale, refParts, hourCycle, minParts, maxParts, allowedHourValues, allowedMinuteValues) => {
|
|
512
|
+
const computedHourCycle = format.getHourCycle(locale, hourCycle);
|
|
513
|
+
const use24Hour = format.is24Hour(computedHourCycle);
|
|
514
|
+
const { hours, minutes, am, pm } = generateTime(locale, refParts, computedHourCycle, minParts, maxParts, allowedHourValues, allowedMinuteValues);
|
|
515
|
+
const hoursItems = hours.map((hour) => {
|
|
516
|
+
return {
|
|
517
|
+
text: format.getFormattedHour(hour, computedHourCycle),
|
|
518
|
+
value: format.getInternalHourValue(hour, use24Hour, refParts.ampm),
|
|
519
|
+
};
|
|
520
|
+
});
|
|
521
|
+
const minutesItems = minutes.map((minute) => {
|
|
522
|
+
return {
|
|
523
|
+
text: format.addTimePadding(minute),
|
|
524
|
+
value: minute,
|
|
525
|
+
};
|
|
526
|
+
});
|
|
527
|
+
const dayPeriodItems = [];
|
|
528
|
+
if (am && !use24Hour) {
|
|
529
|
+
dayPeriodItems.push({
|
|
530
|
+
text: format.getLocalizedDayPeriod(locale, 'am'),
|
|
531
|
+
value: 'am',
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
if (pm && !use24Hour) {
|
|
535
|
+
dayPeriodItems.push({
|
|
536
|
+
text: format.getLocalizedDayPeriod(locale, 'pm'),
|
|
537
|
+
value: 'pm',
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
return {
|
|
541
|
+
minutesData: minutesItems,
|
|
542
|
+
hoursData: hoursItems,
|
|
543
|
+
dayPeriodData: dayPeriodItems,
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
|
|
24
547
|
const isYearDisabled = (refYear, minParts, maxParts) => {
|
|
25
548
|
if (minParts && minParts.year > refYear) {
|
|
26
549
|
return true;
|
|
@@ -62,7 +585,7 @@ const isDayDisabled = (refParts, minParts, maxParts, dayValues) => {
|
|
|
62
585
|
* current month === min allow month, but the current
|
|
63
586
|
* day < the min allowed day?
|
|
64
587
|
*/
|
|
65
|
-
if (minParts &&
|
|
588
|
+
if (minParts && format.isBefore(refParts, minParts)) {
|
|
66
589
|
return true;
|
|
67
590
|
}
|
|
68
591
|
/**
|
|
@@ -76,7 +599,7 @@ const isDayDisabled = (refParts, minParts, maxParts, dayValues) => {
|
|
|
76
599
|
* current month === max allow month, but the current
|
|
77
600
|
* day > the max allowed day?
|
|
78
601
|
*/
|
|
79
|
-
if (maxParts &&
|
|
602
|
+
if (maxParts && format.isAfter(refParts, maxParts)) {
|
|
80
603
|
return true;
|
|
81
604
|
}
|
|
82
605
|
/**
|
|
@@ -103,8 +626,8 @@ const getCalendarDayState = (locale, refParts, activeParts, todayParts, minParts
|
|
|
103
626
|
* The day button is active if it is selected, or in other words, if refParts
|
|
104
627
|
* matches at least one selected date.
|
|
105
628
|
*/
|
|
106
|
-
const isActive = activePartsArray.find((parts) =>
|
|
107
|
-
const isToday =
|
|
629
|
+
const isActive = activePartsArray.find((parts) => format.isSameDay(refParts, parts)) !== undefined;
|
|
630
|
+
const isToday = format.isSameDay(refParts, todayParts);
|
|
108
631
|
const disabled = isDayDisabled(refParts, minParts, maxParts, dayValues);
|
|
109
632
|
/**
|
|
110
633
|
* Note that we always return one object regardless of whether activeParts
|
|
@@ -115,8 +638,8 @@ const getCalendarDayState = (locale, refParts, activeParts, todayParts, minParts
|
|
|
115
638
|
isActive,
|
|
116
639
|
isToday,
|
|
117
640
|
ariaSelected: isActive ? 'true' : null,
|
|
118
|
-
ariaLabel:
|
|
119
|
-
text: refParts.day != null ?
|
|
641
|
+
ariaLabel: format.generateDayAriaLabel(locale, isToday, refParts),
|
|
642
|
+
text: refParts.day != null ? format.getDay(locale, refParts) : null,
|
|
120
643
|
};
|
|
121
644
|
};
|
|
122
645
|
/**
|
|
@@ -130,7 +653,7 @@ const isMonthDisabled = (refParts, { minParts, maxParts, }) => {
|
|
|
130
653
|
}
|
|
131
654
|
// If the date value is before the min date, then the month is disabled.
|
|
132
655
|
// If the date value is after the max date, then the month is disabled.
|
|
133
|
-
if ((minParts &&
|
|
656
|
+
if ((minParts && format.isBefore(refParts, minParts)) || (maxParts && format.isAfter(refParts, maxParts))) {
|
|
134
657
|
return true;
|
|
135
658
|
}
|
|
136
659
|
return false;
|
|
@@ -141,7 +664,7 @@ const isMonthDisabled = (refParts, { minParts, maxParts, }) => {
|
|
|
141
664
|
* previous navigation button is disabled.
|
|
142
665
|
*/
|
|
143
666
|
const isPrevMonthDisabled = (refParts, minParts, maxParts) => {
|
|
144
|
-
const prevMonth = Object.assign(Object.assign({},
|
|
667
|
+
const prevMonth = Object.assign(Object.assign({}, format.getPreviousMonth(refParts)), { day: null });
|
|
145
668
|
return isMonthDisabled(prevMonth, {
|
|
146
669
|
minParts,
|
|
147
670
|
maxParts,
|
|
@@ -152,7 +675,7 @@ const isPrevMonthDisabled = (refParts, minParts, maxParts) => {
|
|
|
152
675
|
* determine if the next navigation button is disabled.
|
|
153
676
|
*/
|
|
154
677
|
const isNextMonthDisabled = (refParts, maxParts) => {
|
|
155
|
-
const nextMonth = Object.assign(Object.assign({},
|
|
678
|
+
const nextMonth = Object.assign(Object.assign({}, format.getNextMonth(refParts)), { day: null });
|
|
156
679
|
return isMonthDisabled(nextMonth, {
|
|
157
680
|
maxParts,
|
|
158
681
|
});
|
|
@@ -445,12 +968,12 @@ const Datetime = class {
|
|
|
445
968
|
* Additionally, we need to update the working parts
|
|
446
969
|
* too in the event that the validated parts are different.
|
|
447
970
|
*/
|
|
448
|
-
const validatedParts =
|
|
971
|
+
const validatedParts = format.validateParts(parts, minParts, maxParts);
|
|
449
972
|
this.setWorkingParts(validatedParts);
|
|
450
973
|
if (multiple) {
|
|
451
974
|
const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
|
|
452
975
|
if (removeDate) {
|
|
453
|
-
this.activeParts = activePartsArray.filter((p) => !
|
|
976
|
+
this.activeParts = activePartsArray.filter((p) => !format.isSameDay(p, validatedParts));
|
|
454
977
|
}
|
|
455
978
|
else {
|
|
456
979
|
this.activeParts = [...activePartsArray, validatedParts];
|
|
@@ -510,40 +1033,40 @@ const Datetime = class {
|
|
|
510
1033
|
if (!activeElement || !activeElement.classList.contains('calendar-day')) {
|
|
511
1034
|
return;
|
|
512
1035
|
}
|
|
513
|
-
const parts =
|
|
1036
|
+
const parts = format.getPartsFromCalendarDay(activeElement);
|
|
514
1037
|
let partsToFocus;
|
|
515
1038
|
switch (ev.key) {
|
|
516
1039
|
case 'ArrowDown':
|
|
517
1040
|
ev.preventDefault();
|
|
518
|
-
partsToFocus =
|
|
1041
|
+
partsToFocus = format.getNextWeek(parts);
|
|
519
1042
|
break;
|
|
520
1043
|
case 'ArrowUp':
|
|
521
1044
|
ev.preventDefault();
|
|
522
|
-
partsToFocus =
|
|
1045
|
+
partsToFocus = format.getPreviousWeek(parts);
|
|
523
1046
|
break;
|
|
524
1047
|
case 'ArrowRight':
|
|
525
1048
|
ev.preventDefault();
|
|
526
|
-
partsToFocus =
|
|
1049
|
+
partsToFocus = format.getNextDay(parts);
|
|
527
1050
|
break;
|
|
528
1051
|
case 'ArrowLeft':
|
|
529
1052
|
ev.preventDefault();
|
|
530
|
-
partsToFocus =
|
|
1053
|
+
partsToFocus = format.getPreviousDay(parts);
|
|
531
1054
|
break;
|
|
532
1055
|
case 'Home':
|
|
533
1056
|
ev.preventDefault();
|
|
534
|
-
partsToFocus =
|
|
1057
|
+
partsToFocus = format.getStartOfWeek(parts);
|
|
535
1058
|
break;
|
|
536
1059
|
case 'End':
|
|
537
1060
|
ev.preventDefault();
|
|
538
|
-
partsToFocus =
|
|
1061
|
+
partsToFocus = format.getEndOfWeek(parts);
|
|
539
1062
|
break;
|
|
540
1063
|
case 'PageUp':
|
|
541
1064
|
ev.preventDefault();
|
|
542
|
-
partsToFocus = ev.shiftKey ?
|
|
1065
|
+
partsToFocus = ev.shiftKey ? format.getPreviousYear(parts) : format.getPreviousMonth(parts);
|
|
543
1066
|
break;
|
|
544
1067
|
case 'PageDown':
|
|
545
1068
|
ev.preventDefault();
|
|
546
|
-
partsToFocus = ev.shiftKey ?
|
|
1069
|
+
partsToFocus = ev.shiftKey ? format.getNextYear(parts) : format.getNextMonth(parts);
|
|
547
1070
|
break;
|
|
548
1071
|
/**
|
|
549
1072
|
* Do not preventDefault here
|
|
@@ -598,7 +1121,7 @@ const Datetime = class {
|
|
|
598
1121
|
this.minParts = undefined;
|
|
599
1122
|
return;
|
|
600
1123
|
}
|
|
601
|
-
this.minParts =
|
|
1124
|
+
this.minParts = format.parseMinParts(min, defaultParts);
|
|
602
1125
|
};
|
|
603
1126
|
this.processMaxParts = () => {
|
|
604
1127
|
const { max, defaultParts } = this;
|
|
@@ -606,7 +1129,7 @@ const Datetime = class {
|
|
|
606
1129
|
this.maxParts = undefined;
|
|
607
1130
|
return;
|
|
608
1131
|
}
|
|
609
|
-
this.maxParts =
|
|
1132
|
+
this.maxParts = format.parseMaxParts(max, defaultParts);
|
|
610
1133
|
};
|
|
611
1134
|
this.initializeCalendarListener = () => {
|
|
612
1135
|
const calendarBodyRef = this.calendarBodyRef;
|
|
@@ -689,10 +1212,10 @@ const Datetime = class {
|
|
|
689
1212
|
* the scroll callback early.
|
|
690
1213
|
*/
|
|
691
1214
|
if (month === startMonth) {
|
|
692
|
-
return
|
|
1215
|
+
return format.getPreviousMonth(parts);
|
|
693
1216
|
}
|
|
694
1217
|
else if (month === endMonth) {
|
|
695
|
-
return
|
|
1218
|
+
return format.getNextMonth(parts);
|
|
696
1219
|
}
|
|
697
1220
|
else {
|
|
698
1221
|
return;
|
|
@@ -841,7 +1364,7 @@ const Datetime = class {
|
|
|
841
1364
|
};
|
|
842
1365
|
this.processValue = (value) => {
|
|
843
1366
|
const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
|
|
844
|
-
const valueToProcess = hasValue ?
|
|
1367
|
+
const valueToProcess = hasValue ? format.parseDate(value) : this.defaultParts;
|
|
845
1368
|
const { minParts, maxParts, workingParts, el } = this;
|
|
846
1369
|
this.warnIfIncorrectValueUsage();
|
|
847
1370
|
/**
|
|
@@ -860,7 +1383,7 @@ const Datetime = class {
|
|
|
860
1383
|
* not true.
|
|
861
1384
|
*/
|
|
862
1385
|
if (hasValue) {
|
|
863
|
-
|
|
1386
|
+
format.warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
|
|
864
1387
|
}
|
|
865
1388
|
/**
|
|
866
1389
|
* If there are multiple values, clamp to the last one.
|
|
@@ -868,9 +1391,9 @@ const Datetime = class {
|
|
|
868
1391
|
* has most recently interacted with.
|
|
869
1392
|
*/
|
|
870
1393
|
const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
|
|
871
|
-
const targetValue =
|
|
1394
|
+
const targetValue = format.clampDate(singleValue, minParts, maxParts);
|
|
872
1395
|
const { month, day, year, hour, minute } = targetValue;
|
|
873
|
-
const ampm =
|
|
1396
|
+
const ampm = format.parseAmPm(hour);
|
|
874
1397
|
/**
|
|
875
1398
|
* Since `activeParts` indicates a value that been explicitly selected
|
|
876
1399
|
* either by the user or the app, only update `activeParts` if the
|
|
@@ -946,7 +1469,7 @@ const Datetime = class {
|
|
|
946
1469
|
* Animate smoothly to the forced month. This will also update
|
|
947
1470
|
* workingParts and correct the surrounding months for us.
|
|
948
1471
|
*/
|
|
949
|
-
const targetMonthIsBefore =
|
|
1472
|
+
const targetMonthIsBefore = format.isBefore(targetValue, workingParts);
|
|
950
1473
|
targetMonthIsBefore ? this.prevMonth() : this.nextMonth();
|
|
951
1474
|
await forceDateScrollingPromise;
|
|
952
1475
|
this.resolveForceDateScrolling = undefined;
|
|
@@ -1021,19 +1544,19 @@ const Datetime = class {
|
|
|
1021
1544
|
return hasDatePresentation && !preferWheel;
|
|
1022
1545
|
}
|
|
1023
1546
|
yearValuesChanged() {
|
|
1024
|
-
this.parsedYearValues =
|
|
1547
|
+
this.parsedYearValues = format.convertToArrayOfNumbers(this.yearValues);
|
|
1025
1548
|
}
|
|
1026
1549
|
monthValuesChanged() {
|
|
1027
|
-
this.parsedMonthValues =
|
|
1550
|
+
this.parsedMonthValues = format.convertToArrayOfNumbers(this.monthValues);
|
|
1028
1551
|
}
|
|
1029
1552
|
dayValuesChanged() {
|
|
1030
|
-
this.parsedDayValues =
|
|
1553
|
+
this.parsedDayValues = format.convertToArrayOfNumbers(this.dayValues);
|
|
1031
1554
|
}
|
|
1032
1555
|
hourValuesChanged() {
|
|
1033
|
-
this.parsedHourValues =
|
|
1556
|
+
this.parsedHourValues = format.convertToArrayOfNumbers(this.hourValues);
|
|
1034
1557
|
}
|
|
1035
1558
|
minuteValuesChanged() {
|
|
1036
|
-
this.parsedMinuteValues =
|
|
1559
|
+
this.parsedMinuteValues = format.convertToArrayOfNumbers(this.minuteValues);
|
|
1037
1560
|
}
|
|
1038
1561
|
/**
|
|
1039
1562
|
* Update the datetime value when the value changes
|
|
@@ -1067,14 +1590,14 @@ const Datetime = class {
|
|
|
1067
1590
|
* active parts are empty, then the user has confirmed the
|
|
1068
1591
|
* initial value (working parts) presented to them.
|
|
1069
1592
|
*/
|
|
1070
|
-
this.setValue(
|
|
1593
|
+
this.setValue(format.convertDataToISO(workingParts));
|
|
1071
1594
|
}
|
|
1072
1595
|
else {
|
|
1073
1596
|
this.setValue(undefined);
|
|
1074
1597
|
}
|
|
1075
1598
|
}
|
|
1076
1599
|
else {
|
|
1077
|
-
this.setValue(
|
|
1600
|
+
this.setValue(format.convertDataToISO(activeParts));
|
|
1078
1601
|
}
|
|
1079
1602
|
}
|
|
1080
1603
|
if (closeOverlay) {
|
|
@@ -1105,6 +1628,16 @@ const Datetime = class {
|
|
|
1105
1628
|
this.closeParentOverlay(CANCEL_ROLE);
|
|
1106
1629
|
}
|
|
1107
1630
|
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Returns the default parts the datetime falls back to when no value is set:
|
|
1633
|
+
* today's date and time snapped to the closest value allowed by the
|
|
1634
|
+
* component's constraints (`min`, `max`, and the `*Values` props).
|
|
1635
|
+
*
|
|
1636
|
+
* @internal
|
|
1637
|
+
*/
|
|
1638
|
+
async getDefaultPart() {
|
|
1639
|
+
return this.defaultParts;
|
|
1640
|
+
}
|
|
1108
1641
|
get isCalendarPicker() {
|
|
1109
1642
|
const { presentation } = this;
|
|
1110
1643
|
return presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
@@ -1292,15 +1825,15 @@ const Datetime = class {
|
|
|
1292
1825
|
checkForPresentationFormatMismatch(el, presentation, formatOptions);
|
|
1293
1826
|
warnIfTimeZoneProvided(el, formatOptions);
|
|
1294
1827
|
}
|
|
1295
|
-
const hourValues = (this.parsedHourValues =
|
|
1296
|
-
const minuteValues = (this.parsedMinuteValues =
|
|
1297
|
-
const monthValues = (this.parsedMonthValues =
|
|
1298
|
-
const yearValues = (this.parsedYearValues =
|
|
1299
|
-
const dayValues = (this.parsedDayValues =
|
|
1300
|
-
const todayParts = (this.todayParts =
|
|
1828
|
+
const hourValues = (this.parsedHourValues = format.convertToArrayOfNumbers(this.hourValues));
|
|
1829
|
+
const minuteValues = (this.parsedMinuteValues = format.convertToArrayOfNumbers(this.minuteValues));
|
|
1830
|
+
const monthValues = (this.parsedMonthValues = format.convertToArrayOfNumbers(this.monthValues));
|
|
1831
|
+
const yearValues = (this.parsedYearValues = format.convertToArrayOfNumbers(this.yearValues));
|
|
1832
|
+
const dayValues = (this.parsedDayValues = format.convertToArrayOfNumbers(this.dayValues));
|
|
1833
|
+
const todayParts = (this.todayParts = format.parseDate(getToday()));
|
|
1301
1834
|
this.processMinParts();
|
|
1302
1835
|
this.processMaxParts();
|
|
1303
|
-
this.defaultParts =
|
|
1836
|
+
this.defaultParts = format.getClosestValidDate({
|
|
1304
1837
|
refParts: todayParts,
|
|
1305
1838
|
monthValues,
|
|
1306
1839
|
dayValues,
|
|
@@ -1383,13 +1916,13 @@ const Datetime = class {
|
|
|
1383
1916
|
* By default, generate a range of 3 months:
|
|
1384
1917
|
* Previous month, current month, and next month
|
|
1385
1918
|
*/
|
|
1386
|
-
const monthsToRender =
|
|
1919
|
+
const monthsToRender = generateMonths(workingParts);
|
|
1387
1920
|
const lastMonth = monthsToRender[monthsToRender.length - 1];
|
|
1388
1921
|
/**
|
|
1389
1922
|
* Ensure that users can select the entire window of dates.
|
|
1390
1923
|
*/
|
|
1391
1924
|
monthsToRender[0].day = 1;
|
|
1392
|
-
lastMonth.day =
|
|
1925
|
+
lastMonth.day = format.getNumDaysInMonth(lastMonth.month, lastMonth.year);
|
|
1393
1926
|
/**
|
|
1394
1927
|
* Narrow the dates rendered based on min/max dates (if any).
|
|
1395
1928
|
* The `min` date is used if the min is after the generated min month.
|
|
@@ -1398,9 +1931,9 @@ const Datetime = class {
|
|
|
1398
1931
|
* but still allows future dates to be lazily rendered based on any min/max
|
|
1399
1932
|
* constraints.
|
|
1400
1933
|
*/
|
|
1401
|
-
const min = minParts !== undefined &&
|
|
1402
|
-
const max = maxParts !== undefined &&
|
|
1403
|
-
const result =
|
|
1934
|
+
const min = minParts !== undefined && format.isAfter(minParts, monthsToRender[0]) ? minParts : monthsToRender[0];
|
|
1935
|
+
const max = maxParts !== undefined && format.isBefore(maxParts, lastMonth) ? maxParts : lastMonth;
|
|
1936
|
+
const result = getCombinedDateColumnData(locale, todayParts, min, max, this.parsedDayValues, this.parsedMonthValues);
|
|
1404
1937
|
let items = result.items;
|
|
1405
1938
|
const parts = result.parts;
|
|
1406
1939
|
if (isDateEnabled) {
|
|
@@ -1413,7 +1946,7 @@ const Datetime = class {
|
|
|
1413
1946
|
* to prevent exceptions in the user's function from
|
|
1414
1947
|
* interrupting the calendar rendering.
|
|
1415
1948
|
*/
|
|
1416
|
-
disabled = !isDateEnabled(
|
|
1949
|
+
disabled = !isDateEnabled(format.convertDataToISO(referenceParts));
|
|
1417
1950
|
}
|
|
1418
1951
|
catch (e) {
|
|
1419
1952
|
index.printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
|
|
@@ -1440,11 +1973,11 @@ const Datetime = class {
|
|
|
1440
1973
|
const { workingParts, isDateEnabled } = this;
|
|
1441
1974
|
const shouldRenderMonths = forcePresentation !== 'year' && forcePresentation !== 'time';
|
|
1442
1975
|
const months = shouldRenderMonths
|
|
1443
|
-
?
|
|
1976
|
+
? getMonthColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedMonthValues)
|
|
1444
1977
|
: [];
|
|
1445
1978
|
const shouldRenderDays = forcePresentation === 'date';
|
|
1446
1979
|
let days = shouldRenderDays
|
|
1447
|
-
?
|
|
1980
|
+
? getDayColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedDayValues)
|
|
1448
1981
|
: [];
|
|
1449
1982
|
if (isDateEnabled) {
|
|
1450
1983
|
days = days.map((dayObject) => {
|
|
@@ -1462,7 +1995,7 @@ const Datetime = class {
|
|
|
1462
1995
|
* to prevent exceptions in the user's function from
|
|
1463
1996
|
* interrupting the calendar rendering.
|
|
1464
1997
|
*/
|
|
1465
|
-
disabled = !isDateEnabled(
|
|
1998
|
+
disabled = !isDateEnabled(format.convertDataToISO(referenceParts));
|
|
1466
1999
|
}
|
|
1467
2000
|
catch (e) {
|
|
1468
2001
|
index.printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
|
|
@@ -1472,12 +2005,12 @@ const Datetime = class {
|
|
|
1472
2005
|
}
|
|
1473
2006
|
const shouldRenderYears = forcePresentation !== 'month' && forcePresentation !== 'time';
|
|
1474
2007
|
const years = shouldRenderYears
|
|
1475
|
-
?
|
|
2008
|
+
? getYearColumnData(this.locale, this.defaultParts, this.minParts, this.maxParts, this.parsedYearValues)
|
|
1476
2009
|
: [];
|
|
1477
2010
|
/**
|
|
1478
2011
|
* Certain locales show the day before the month.
|
|
1479
2012
|
*/
|
|
1480
|
-
const showMonthFirst =
|
|
2013
|
+
const showMonthFirst = format.isMonthFirstLocale(this.locale, { month: 'numeric', day: 'numeric' });
|
|
1481
2014
|
let renderArray = [];
|
|
1482
2015
|
if (showMonthFirst) {
|
|
1483
2016
|
renderArray = [
|
|
@@ -1548,7 +2081,7 @@ const Datetime = class {
|
|
|
1548
2081
|
*/
|
|
1549
2082
|
const activePart = this.getActivePart();
|
|
1550
2083
|
const userHasSelectedDate = activePart !== undefined;
|
|
1551
|
-
const { hoursData, minutesData, dayPeriodData } =
|
|
2084
|
+
const { hoursData, minutesData, dayPeriodData } = getTimeColumnsData(this.locale, this.workingParts, this.hourCycle, userHasSelectedDate ? this.minParts : undefined, userHasSelectedDate ? this.maxParts : undefined, this.parsedHourValues, this.parsedMinuteValues);
|
|
1552
2085
|
return [
|
|
1553
2086
|
this.renderHourPickerColumn(hoursData),
|
|
1554
2087
|
this.renderMinutePickerColumn(minutesData),
|
|
@@ -1583,9 +2116,9 @@ const Datetime = class {
|
|
|
1583
2116
|
return [];
|
|
1584
2117
|
}
|
|
1585
2118
|
const activePart = this.getActivePartsWithFallback();
|
|
1586
|
-
const isDayPeriodRTL =
|
|
2119
|
+
const isDayPeriodRTL = format.isLocaleDayPeriodRTL(this.locale);
|
|
1587
2120
|
return (index.h("ion-picker-column", { part: WHEEL_PART, "aria-label": "Select a day period", style: isDayPeriodRTL ? { order: '-1' } : {}, color: this.color, disabled: disabled, value: activePart.ampm, onIonChange: (ev) => {
|
|
1588
|
-
const hour =
|
|
2121
|
+
const hour = format.calculateHourFromAMPM(workingParts, ev.detail.value);
|
|
1589
2122
|
this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { ampm: ev.detail.value, hour }));
|
|
1590
2123
|
this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { ampm: ev.detail.value, hour }));
|
|
1591
2124
|
ev.stopPropagation();
|
|
@@ -1593,7 +2126,7 @@ const Datetime = class {
|
|
|
1593
2126
|
}
|
|
1594
2127
|
renderWheelView(forcePresentation) {
|
|
1595
2128
|
const { locale } = this;
|
|
1596
|
-
const showMonthFirst =
|
|
2129
|
+
const showMonthFirst = format.isMonthFirstLocale(locale);
|
|
1597
2130
|
const columnOrder = showMonthFirst ? 'month-first' : 'year-first';
|
|
1598
2131
|
return (index.h("div", { class: {
|
|
1599
2132
|
[`wheel-order-${columnOrder}`]: true,
|
|
@@ -1614,7 +2147,7 @@ const Datetime = class {
|
|
|
1614
2147
|
'calendar-month-year-toggle': true,
|
|
1615
2148
|
'ion-activatable': true,
|
|
1616
2149
|
'ion-focusable': true,
|
|
1617
|
-
}, part: "month-year-button", disabled: disabled, "aria-label": this.showMonthAndYear ? 'Hide year picker' : 'Show year picker', onClick: () => this.toggleMonthAndYearView() }, index.h("span", { id: "toggle-wrapper" },
|
|
2150
|
+
}, part: "month-year-button", disabled: disabled, "aria-label": this.showMonthAndYear ? 'Hide year picker' : 'Show year picker', onClick: () => this.toggleMonthAndYearView() }, index.h("span", { id: "toggle-wrapper" }, format.getMonthAndYear(this.locale, this.workingParts), index.h("ion-icon", { "aria-hidden": "true", icon: this.showMonthAndYear ? expandedIcon : collapsedIcon, lazy: false, flipRtl: true })), mode === 'md' && index.h("ion-ripple-effect", null))), index.h("div", { class: "calendar-next-prev" }, index.h("ion-buttons", null, index.h("ion-button", { "aria-label": "Previous month", disabled: prevMonthDisabled, onClick: () => this.prevMonth(), part: "navigation-button previous-button" }, index.h("ion-icon", { dir: hostDir, "aria-hidden": "true", slot: "icon-only", icon: index$1.chevronBack, lazy: false, flipRtl: true })), index.h("ion-button", { "aria-label": "Next month", disabled: nextMonthDisabled, onClick: () => this.nextMonth(), part: "navigation-button next-button" }, index.h("ion-icon", { dir: hostDir, "aria-hidden": "true", slot: "icon-only", icon: index$1.chevronForward, lazy: false, flipRtl: true }))))), index.h("div", { class: "calendar-days-of-week", "aria-hidden": "true", part: "calendar-days-of-week" }, getDaysOfWeek(this.locale, mode, this.firstDayOfWeek % 7).map((d) => {
|
|
1618
2151
|
return index.h("div", { class: "day-of-week" }, d);
|
|
1619
2152
|
}))));
|
|
1620
2153
|
}
|
|
@@ -1645,7 +2178,7 @@ const Datetime = class {
|
|
|
1645
2178
|
'calendar-month': true,
|
|
1646
2179
|
// Prevents scroll snap swipe gestures for months outside of the min/max bounds
|
|
1647
2180
|
'calendar-month-disabled': !isWorkingMonth && swipeDisabled,
|
|
1648
|
-
} }, index.h("div", { class: "calendar-month-grid" },
|
|
2181
|
+
} }, index.h("div", { class: "calendar-month-grid" }, getDaysOfMonth(month, year, this.firstDayOfWeek % 7, this.showAdjacentDays).map((dateObject, index$1) => {
|
|
1649
2182
|
const { day, dayOfWeek, isAdjacentDay } = dateObject;
|
|
1650
2183
|
const { el, highlightedDates, isDateEnabled, multiple, showAdjacentDays } = this;
|
|
1651
2184
|
let _month = month;
|
|
@@ -1677,7 +2210,7 @@ const Datetime = class {
|
|
|
1677
2210
|
const referenceParts = { month: _month, day, year: _year, isAdjacentDay };
|
|
1678
2211
|
const isCalendarPadding = day === null;
|
|
1679
2212
|
const { isActive, isToday, ariaLabel, ariaSelected, disabled: isDayDisabled, text, } = getCalendarDayState(this.locale, referenceParts, this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
|
|
1680
|
-
const dateIsoString =
|
|
2213
|
+
const dateIsoString = format.convertDataToISO(referenceParts);
|
|
1681
2214
|
let isCalDayDisabled = isCalMonthDisabled || isDayDisabled;
|
|
1682
2215
|
if (!isCalDayDisabled && isDateEnabled !== undefined) {
|
|
1683
2216
|
try {
|
|
@@ -1762,7 +2295,7 @@ const Datetime = class {
|
|
|
1762
2295
|
}))));
|
|
1763
2296
|
}
|
|
1764
2297
|
renderCalendarBody() {
|
|
1765
|
-
return (index.h("div", { class: "calendar-body ion-focusable", ref: (el) => (this.calendarBodyRef = el), tabindex: "0" },
|
|
2298
|
+
return (index.h("div", { class: "calendar-body ion-focusable", ref: (el) => (this.calendarBodyRef = el), tabindex: "0" }, generateMonths(this.workingParts, this.forceRenderDate).map(({ month, year }) => {
|
|
1766
2299
|
return this.renderMonth(month, year);
|
|
1767
2300
|
})));
|
|
1768
2301
|
}
|
|
@@ -1778,7 +2311,7 @@ const Datetime = class {
|
|
|
1778
2311
|
}
|
|
1779
2312
|
renderTimeOverlay() {
|
|
1780
2313
|
const { disabled, hourCycle, isTimePopoverOpen, locale, formatOptions } = this;
|
|
1781
|
-
const computedHourCycle =
|
|
2314
|
+
const computedHourCycle = format.getHourCycle(locale, hourCycle);
|
|
1782
2315
|
const activePart = this.getActivePartsWithFallback();
|
|
1783
2316
|
return [
|
|
1784
2317
|
index.h("div", { class: "time-header" }, this.renderTimeLabel()),
|
|
@@ -1797,7 +2330,7 @@ const Datetime = class {
|
|
|
1797
2330
|
await popoverRef.onWillDismiss();
|
|
1798
2331
|
this.isTimePopoverOpen = false;
|
|
1799
2332
|
}
|
|
1800
|
-
} },
|
|
2333
|
+
} }, format.getLocalizedTime(locale, activePart, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time)),
|
|
1801
2334
|
index.h("ion-popover", { alignment: "center", translucent: true, overlayIndex: 1, arrow: false, onWillPresent: (ev) => {
|
|
1802
2335
|
/**
|
|
1803
2336
|
* Intersection Observers do not consistently fire between Blink and Webkit
|
|
@@ -1828,7 +2361,7 @@ const Datetime = class {
|
|
|
1828
2361
|
headerText = `${activeParts.length} days`; // default/fallback for multiple selection
|
|
1829
2362
|
if (titleSelectedDatesFormatter !== undefined) {
|
|
1830
2363
|
try {
|
|
1831
|
-
headerText = titleSelectedDatesFormatter(
|
|
2364
|
+
headerText = titleSelectedDatesFormatter(format.convertDataToISO(activeParts));
|
|
1832
2365
|
}
|
|
1833
2366
|
catch (e) {
|
|
1834
2367
|
index.printIonError('[ion-datetime] - Exception in provided `titleSelectedDatesFormatter`:', e);
|
|
@@ -1837,7 +2370,7 @@ const Datetime = class {
|
|
|
1837
2370
|
}
|
|
1838
2371
|
else {
|
|
1839
2372
|
// for exactly 1 day selected (multiple set or not), show a formatted version of that
|
|
1840
|
-
headerText =
|
|
2373
|
+
headerText = format.getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), (_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _a !== void 0 ? _a : { weekday: 'short', month: 'short', day: 'numeric' });
|
|
1841
2374
|
}
|
|
1842
2375
|
return headerText;
|
|
1843
2376
|
}
|
|
@@ -1925,8 +2458,8 @@ const Datetime = class {
|
|
|
1925
2458
|
const monthYearPickerOpen = showMonthAndYear && !isMonthAndYearPresentation;
|
|
1926
2459
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1927
2460
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1928
|
-
helpers.renderHiddenInput(true, el, name,
|
|
1929
|
-
return (index.h(index.Host, { key: '
|
|
2461
|
+
helpers.renderHiddenInput(true, el, name, format.formatValue(value), disabled);
|
|
2462
|
+
return (index.h(index.Host, { key: '0a7b458dac2de870a81d2495b5fc7ac86989f2b8', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, theme.createColorClasses(color, {
|
|
1930
2463
|
[mode]: true,
|
|
1931
2464
|
['datetime-readonly']: readonly,
|
|
1932
2465
|
['datetime-disabled']: disabled,
|
|
@@ -1936,7 +2469,7 @@ const Datetime = class {
|
|
|
1936
2469
|
[`datetime-size-${size}`]: true,
|
|
1937
2470
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1938
2471
|
[`datetime-grid`]: isGridStyle,
|
|
1939
|
-
})) }, index.h("div", { key: '
|
|
2472
|
+
})) }, index.h("div", { key: '47e77df9dd5846d46addc210d29287f34bf3cd56', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1940
2473
|
}
|
|
1941
2474
|
get el() { return index.getElement(this); }
|
|
1942
2475
|
static get watchers() { return {
|