@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.
@@ -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 data = require('./data-DLTUw-KF.js');
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 && data.isBefore(refParts, 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 && data.isAfter(refParts, 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) => data.isSameDay(refParts, parts)) !== undefined;
107
- const isToday = data.isSameDay(refParts, todayParts);
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: data.generateDayAriaLabel(locale, isToday, refParts),
119
- text: refParts.day != null ? data.getDay(locale, refParts) : 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 && data.isBefore(refParts, minParts)) || (maxParts && data.isAfter(refParts, maxParts))) {
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({}, data.getPreviousMonth(refParts)), { day: null });
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({}, data.getNextMonth(refParts)), { day: null });
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 = data.validateParts(parts, minParts, maxParts);
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) => !data.isSameDay(p, validatedParts));
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 = data.getPartsFromCalendarDay(activeElement);
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 = data.getNextWeek(parts);
1041
+ partsToFocus = format.getNextWeek(parts);
519
1042
  break;
520
1043
  case 'ArrowUp':
521
1044
  ev.preventDefault();
522
- partsToFocus = data.getPreviousWeek(parts);
1045
+ partsToFocus = format.getPreviousWeek(parts);
523
1046
  break;
524
1047
  case 'ArrowRight':
525
1048
  ev.preventDefault();
526
- partsToFocus = data.getNextDay(parts);
1049
+ partsToFocus = format.getNextDay(parts);
527
1050
  break;
528
1051
  case 'ArrowLeft':
529
1052
  ev.preventDefault();
530
- partsToFocus = data.getPreviousDay(parts);
1053
+ partsToFocus = format.getPreviousDay(parts);
531
1054
  break;
532
1055
  case 'Home':
533
1056
  ev.preventDefault();
534
- partsToFocus = data.getStartOfWeek(parts);
1057
+ partsToFocus = format.getStartOfWeek(parts);
535
1058
  break;
536
1059
  case 'End':
537
1060
  ev.preventDefault();
538
- partsToFocus = data.getEndOfWeek(parts);
1061
+ partsToFocus = format.getEndOfWeek(parts);
539
1062
  break;
540
1063
  case 'PageUp':
541
1064
  ev.preventDefault();
542
- partsToFocus = ev.shiftKey ? data.getPreviousYear(parts) : data.getPreviousMonth(parts);
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 ? data.getNextYear(parts) : data.getNextMonth(parts);
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 = data.parseMinParts(min, defaultParts);
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 = data.parseMaxParts(max, defaultParts);
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 data.getPreviousMonth(parts);
1215
+ return format.getPreviousMonth(parts);
693
1216
  }
694
1217
  else if (month === endMonth) {
695
- return data.getNextMonth(parts);
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 ? data.parseDate(value) : this.defaultParts;
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
- data.warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
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 = data.clampDate(singleValue, minParts, maxParts);
1394
+ const targetValue = format.clampDate(singleValue, minParts, maxParts);
872
1395
  const { month, day, year, hour, minute } = targetValue;
873
- const ampm = data.parseAmPm(hour);
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 = data.isBefore(targetValue, workingParts);
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 = data.convertToArrayOfNumbers(this.yearValues);
1547
+ this.parsedYearValues = format.convertToArrayOfNumbers(this.yearValues);
1025
1548
  }
1026
1549
  monthValuesChanged() {
1027
- this.parsedMonthValues = data.convertToArrayOfNumbers(this.monthValues);
1550
+ this.parsedMonthValues = format.convertToArrayOfNumbers(this.monthValues);
1028
1551
  }
1029
1552
  dayValuesChanged() {
1030
- this.parsedDayValues = data.convertToArrayOfNumbers(this.dayValues);
1553
+ this.parsedDayValues = format.convertToArrayOfNumbers(this.dayValues);
1031
1554
  }
1032
1555
  hourValuesChanged() {
1033
- this.parsedHourValues = data.convertToArrayOfNumbers(this.hourValues);
1556
+ this.parsedHourValues = format.convertToArrayOfNumbers(this.hourValues);
1034
1557
  }
1035
1558
  minuteValuesChanged() {
1036
- this.parsedMinuteValues = data.convertToArrayOfNumbers(this.minuteValues);
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(data.convertDataToISO(workingParts));
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(data.convertDataToISO(activeParts));
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 = data.convertToArrayOfNumbers(this.hourValues));
1296
- const minuteValues = (this.parsedMinuteValues = data.convertToArrayOfNumbers(this.minuteValues));
1297
- const monthValues = (this.parsedMonthValues = data.convertToArrayOfNumbers(this.monthValues));
1298
- const yearValues = (this.parsedYearValues = data.convertToArrayOfNumbers(this.yearValues));
1299
- const dayValues = (this.parsedDayValues = data.convertToArrayOfNumbers(this.dayValues));
1300
- const todayParts = (this.todayParts = data.parseDate(data.getToday()));
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 = data.getClosestValidDate({
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 = data.generateMonths(workingParts);
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 = data.getNumDaysInMonth(lastMonth.month, lastMonth.year);
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 && data.isAfter(minParts, monthsToRender[0]) ? minParts : monthsToRender[0];
1402
- const max = maxParts !== undefined && data.isBefore(maxParts, lastMonth) ? maxParts : lastMonth;
1403
- const result = data.getCombinedDateColumnData(locale, todayParts, min, max, this.parsedDayValues, this.parsedMonthValues);
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(data.convertDataToISO(referenceParts));
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
- ? data.getMonthColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedMonthValues)
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
- ? data.getDayColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedDayValues)
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(data.convertDataToISO(referenceParts));
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
- ? data.getYearColumnData(this.locale, this.defaultParts, this.minParts, this.maxParts, this.parsedYearValues)
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 = data.isMonthFirstLocale(this.locale, { month: 'numeric', day: 'numeric' });
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 } = data.getTimeColumnsData(this.locale, this.workingParts, this.hourCycle, userHasSelectedDate ? this.minParts : undefined, userHasSelectedDate ? this.maxParts : undefined, this.parsedHourValues, this.parsedMinuteValues);
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 = data.isLocaleDayPeriodRTL(this.locale);
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 = data.calculateHourFromAMPM(workingParts, ev.detail.value);
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 = data.isMonthFirstLocale(locale);
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" }, data.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" }, data.getDaysOfWeek(this.locale, mode, this.firstDayOfWeek % 7).map((d) => {
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" }, data.getDaysOfMonth(month, year, this.firstDayOfWeek % 7, this.showAdjacentDays).map((dateObject, index$1) => {
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 = data.convertDataToISO(referenceParts);
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" }, data.generateMonths(this.workingParts, this.forceRenderDate).map(({ month, year }) => {
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 = data.getHourCycle(locale, hourCycle);
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
- } }, data.getLocalizedTime(locale, activePart, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time)),
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(data.convertDataToISO(activeParts));
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 = data.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' });
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, data.formatValue(value), disabled);
1929
- return (index.h(index.Host, { key: '323c8c2327088f00934b8c93c3306538cb9b5677', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, theme.createColorClasses(color, {
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: '1e0855c8909bc3f1e48a21ad68159fa782060691', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
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 {