@ionic/core 9.0.11-dev.11793666452.109ac2a5 → 9.0.11-dev.11793705116.185a3203

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.
Files changed (76) hide show
  1. package/components/ion-action-sheet.js +1 -1
  2. package/components/ion-alert.js +1 -1
  3. package/components/ion-datetime-button.js +1 -1
  4. package/components/ion-datetime.js +1 -1
  5. package/components/ion-modal.js +1 -1
  6. package/components/ion-popover.js +1 -1
  7. package/components/ion-select.js +1 -1
  8. package/components/ion-toast.js +1 -1
  9. package/components/{p-B7ExaLVL.js → p-BCQSEpww.js} +1 -1
  10. package/components/p-DibGn4gb.js +4 -0
  11. package/components/{p-1HReh-CB.js → p-DtZimz8H.js} +1 -1
  12. package/components/p-NZGZhPF5.js +4 -0
  13. package/components/p-PFwuhbqg.js +4 -0
  14. package/css/ionic/bundle.ionic.css +1 -1
  15. package/css/ionic/bundle.ionic.css.map +1 -1
  16. package/css/ionic/core.ionic.css +1 -1
  17. package/css/ionic/core.ionic.css.map +1 -1
  18. package/css/ionic/global.bundle.ionic.css.map +1 -1
  19. package/css/ionic/link.ionic.css.map +1 -1
  20. package/css/ionic/typography.ionic.css.map +1 -1
  21. package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
  22. package/dist/cjs/ion-alert.cjs.entry.js +1 -1
  23. package/dist/cjs/ion-datetime-button.cjs.entry.js +6 -33
  24. package/dist/cjs/ion-datetime.cjs.entry.js +36 -345
  25. package/dist/cjs/ion-modal.cjs.entry.js +1 -1
  26. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  27. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  28. package/dist/cjs/ionic.cjs.js +1 -1
  29. package/dist/cjs/loader.cjs.js +1 -1
  30. package/dist/collection/components/action-sheet/action-sheet.ionic.css +1 -1
  31. package/dist/collection/components/alert/alert.ionic.css +1 -1
  32. package/dist/collection/components/datetime/datetime.ionic.css +5 -170
  33. package/dist/collection/components/datetime/datetime.ios.css +2 -125
  34. package/dist/collection/components/datetime/datetime.js +33 -398
  35. package/dist/collection/components/datetime/datetime.md.css +0 -111
  36. package/dist/collection/components/datetime/utils/state.js +1 -18
  37. package/dist/collection/components/datetime-button/datetime-button.js +6 -34
  38. package/dist/collection/components/modal/modal.ionic.css +2 -2
  39. package/dist/collection/components/popover/popover.ionic.css +2 -1
  40. package/dist/collection/components/toast/toast.ionic.css +1 -1
  41. package/dist/docs.json +1 -151
  42. package/dist/esm/{format-DUHrIiJq.js → format-NT7iHsbA.js} +1 -1
  43. package/dist/esm/ion-action-sheet.entry.js +1 -1
  44. package/dist/esm/ion-alert.entry.js +1 -1
  45. package/dist/esm/ion-datetime-button.entry.js +7 -34
  46. package/dist/esm/ion-datetime.entry.js +37 -346
  47. package/dist/esm/ion-modal.entry.js +1 -1
  48. package/dist/esm/ion-popover.entry.js +1 -1
  49. package/dist/esm/ion-toast.entry.js +1 -1
  50. package/dist/esm/ionic.js +1 -1
  51. package/dist/esm/loader.js +1 -1
  52. package/dist/html.html-data.json +0 -20
  53. package/dist/ionic/ionic.esm.js +1 -1
  54. package/dist/ionic/p-0743a26a.entry.js +4 -0
  55. package/dist/ionic/p-1d87b153.entry.js +4 -0
  56. package/dist/ionic/{p-5a024b02.entry.js → p-3ddd32cc.entry.js} +1 -1
  57. package/dist/ionic/{p-CaOPF8Xt.js → p-BtccSO5J.js} +1 -1
  58. package/dist/ionic/p-a1555032.entry.js +4 -0
  59. package/dist/ionic/p-ad46d2fd.entry.js +4 -0
  60. package/dist/ionic/{p-3674a7de.entry.js → p-b076511a.entry.js} +1 -1
  61. package/dist/ionic/p-dbf53341.entry.js +4 -0
  62. package/dist/types/components/datetime/datetime-interface.d.ts +0 -4
  63. package/dist/types/components/datetime/datetime.d.ts +2 -66
  64. package/dist/types/components/datetime/utils/state.d.ts +2 -5
  65. package/dist/types/components.d.ts +0 -33
  66. package/hydrate/index.js +47 -391
  67. package/hydrate/index.mjs +47 -391
  68. package/package.json +2 -2
  69. package/components/p-DgNvIX46.js +0 -4
  70. package/components/p-DmyvpOqm.js +0 -4
  71. package/components/p-mG85e2ek.js +0 -4
  72. package/dist/ionic/p-1b7efcc2.entry.js +0 -4
  73. package/dist/ionic/p-9cce1ed5.entry.js +0 -4
  74. package/dist/ionic/p-ceca04fb.entry.js +0 -4
  75. package/dist/ionic/p-d7da66b1.entry.js +0 -4
  76. package/dist/ionic/p-f02c29cd.entry.js +0 -4
@@ -50,11 +50,6 @@ import { checkForPresentationFormatMismatch, warnIfTimeZoneProvided } from "./ut
50
50
  * @part calendar-day today - The calendar day that contains the current day.
51
51
  * @part calendar-day disabled - The calendar day that is disabled.
52
52
  *
53
- * @part range-start - The calendar day button that is the start of a range selection.
54
- * @part range-end - The calendar day button that is the end of a range selection.
55
- * @part range-selection - The calendar day button that is part of a range selection (includes start and end).
56
- * @part range-track - The track that connects the start and end days of a range selection.
57
- *
58
53
  * @part datetime-header - The datetime header contains the content for the `title` slot and the selected date.
59
54
  * @part datetime-title - The element that contains the `title` slot content.
60
55
  * @part datetime-selected-date - The element that contains the selected date.
@@ -135,22 +130,8 @@ export class Datetime {
135
130
  /**
136
131
  * If `true`, multiple dates can be selected at once. Only
137
132
  * applies to `presentation="date"` and `preferWheel="false"`.
138
- *
139
- * @deprecated Use `selectionMode="multiple"` instead.
140
133
  */
141
134
  this.multiple = false;
142
- /**
143
- * The text shown in the datetime header when the start of the range
144
- * is empty, also used by screen readers to announce the start date.
145
- * Only applies when `selectionMode="range"`.
146
- */
147
- this.startDateLabel = 'Start date';
148
- /**
149
- * The text shown in the datetime header when the end of the range
150
- * is empty, also used by screen readers to announce the end date.
151
- * Only applies when `selectionMode="range"`.
152
- */
153
- this.endDateLabel = 'End date';
154
135
  /**
155
136
  * If `true`, a header will be shown above the calendar
156
137
  * picker. This will include both the slotted title, and
@@ -203,8 +184,8 @@ export class Datetime {
203
184
  */
204
185
  this.preferWheel = false;
205
186
  this.warnIfIncorrectValueUsage = () => {
206
- const { value } = this;
207
- if (!this.isMultipleMode && !this.isRangeMode && Array.isArray(value)) {
187
+ const { multiple, value } = this;
188
+ if (!multiple && Array.isArray(value)) {
208
189
  /**
209
190
  * We do some processing on the `value` array so
210
191
  * that it looks more like an array when logged to
@@ -213,13 +194,7 @@ export class Datetime {
213
194
  * Default toString() behavior: a,b
214
195
  * Custom behavior: ['a', 'b']
215
196
  */
216
- printIonWarning(`[ion-datetime] - An array of values was passed, but neither selectionMode="multiple" nor selectionMode="range" is set. This is incorrect usage and may result in unexpected behaviors.
217
-
218
- Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
219
- `, this.el);
220
- }
221
- if (this.isRangeMode && Array.isArray(value) && value.length > 2) {
222
- printIonWarning(`[ion-datetime] - More than 2 values were passed with selectionMode="range". Only the first and last values will be used.
197
+ printIonWarning(`[ion-datetime] - An array of values was passed, but multiple is "false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false".
223
198
 
224
199
  Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
225
200
  `, this.el);
@@ -245,9 +220,6 @@ export class Datetime {
245
220
  };
246
221
  this.getActivePart = () => {
247
222
  const { activeParts } = this;
248
- if (this.isRangeParts(activeParts)) {
249
- return activeParts.start;
250
- }
251
223
  return Array.isArray(activeParts) ? activeParts[0] : activeParts;
252
224
  };
253
225
  this.closeParentOverlay = (role) => {
@@ -262,33 +234,6 @@ export class Datetime {
262
234
  ...parts,
263
235
  };
264
236
  };
265
- /**
266
- * Checks whether the span from start to end contains any disabled day.
267
- * Used by range mode to prevent selecting across disabled dates.
268
- */
269
- this.rangeContainsDisabledDate = (start, end) => {
270
- const { minParts, maxParts, parsedDayValues, parsedMonthValues, parsedYearValues, isDateEnabled } = this;
271
- let cursor = getNextDay(start);
272
- while (isBefore(cursor, end)) {
273
- if (isDayDisabled(cursor, minParts, maxParts, parsedDayValues) ||
274
- (parsedMonthValues !== undefined && !parsedMonthValues.includes(cursor.month)) ||
275
- (parsedYearValues !== undefined && !parsedYearValues.includes(cursor.year))) {
276
- return true;
277
- }
278
- if (isDateEnabled) {
279
- try {
280
- if (!isDateEnabled(convertDataToISO(cursor))) {
281
- return true;
282
- }
283
- }
284
- catch {
285
- // Swallow user callback exceptions during validation
286
- }
287
- }
288
- cursor = getNextDay(cursor);
289
- }
290
- return false;
291
- };
292
237
  this.setActiveParts = (parts, removeDate = false) => {
293
238
  /** if the datetime component is in readonly mode,
294
239
  * allow browsing of the calendar without changing
@@ -298,7 +243,7 @@ export class Datetime {
298
243
  return;
299
244
  }
300
245
  this.hasUnconfirmedSelection = true;
301
- const { minParts, maxParts, activeParts } = this;
246
+ const { multiple, minParts, maxParts, activeParts } = this;
302
247
  /**
303
248
  * When setting the active parts, it is possible
304
249
  * to set invalid data. For example,
@@ -311,10 +256,7 @@ export class Datetime {
311
256
  */
312
257
  const validatedParts = validateParts(parts, minParts, maxParts);
313
258
  this.setWorkingParts(validatedParts);
314
- if (this.isRangeMode) {
315
- this.setActivePartsRange(validatedParts);
316
- }
317
- else if (this.isMultipleMode) {
259
+ if (multiple) {
318
260
  const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
319
261
  if (removeDate) {
320
262
  this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
@@ -334,25 +276,6 @@ export class Datetime {
334
276
  }
335
277
  this.confirm();
336
278
  };
337
- /**
338
- * Handles range selection logic when a day is clicked.
339
- *
340
- * Creating a new range: first click sets start, second sets end.
341
- * Modifying an existing range:
342
- * - Before range → new start
343
- * - Within range → new end
344
- * - After range → new end
345
- * If the resulting span contains a disabled date, start a new range instead.
346
- */
347
- this.setActivePartsRange = (parts) => {
348
- const current = this.rangeParts;
349
- if (!current || isBefore(parts, current.start) || this.rangeContainsDisabledDate(current.start, parts)) {
350
- this.activeParts = { start: parts };
351
- }
352
- else {
353
- this.activeParts = { start: current.start, end: parts };
354
- }
355
- };
356
279
  this.initializeKeyboardListeners = () => {
357
280
  const calendarBodyRef = this.calendarBodyRef;
358
281
  if (!calendarBodyRef) {
@@ -764,57 +687,6 @@ export class Datetime {
764
687
  if (hasValue) {
765
688
  warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
766
689
  }
767
- /**
768
- * Range mode: convert the value array into DatetimeRangeParts.
769
- */
770
- if (this.isRangeMode) {
771
- /**
772
- * The calendar navigates to the start of the range, or to the default
773
- * date when there is nothing selected, so that an empty range mode
774
- * opens on the same month as the other selection modes.
775
- */
776
- let navigateTo;
777
- if (hasValue && Array.isArray(valueToProcess)) {
778
- let rangeValues = valueToProcess;
779
- // If more than 2 entries, use first and last
780
- if (rangeValues.length > 2) {
781
- rangeValues = [rangeValues[0], rangeValues[rangeValues.length - 1]];
782
- }
783
- let startParts = rangeValues[0];
784
- let endParts = rangeValues.length > 1 ? rangeValues[1] : undefined;
785
- // Normalize reversed pairs so earlier date is start
786
- if (endParts && isAfter(startParts, endParts)) {
787
- const temp = startParts;
788
- startParts = endParts;
789
- endParts = temp;
790
- }
791
- this.activeParts = endParts ? { start: startParts, end: endParts } : { start: startParts };
792
- /**
793
- * Stay on the end date's month when it is already showing, such as
794
- * right after the user picks it, instead of jumping back to the start.
795
- */
796
- navigateTo =
797
- endParts && endParts.month === workingParts.month && endParts.year === workingParts.year
798
- ? endParts
799
- : startParts;
800
- }
801
- else {
802
- this.activeParts = [];
803
- navigateTo = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
804
- }
805
- const targetValue = clampDate(navigateTo, minParts, maxParts);
806
- const { month, day, year } = targetValue;
807
- const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
808
- const bodyIsVisible = el.classList.contains('datetime-ready');
809
- const { isGridStyle, showMonthAndYear } = this;
810
- if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
811
- this.animateToDate(targetValue);
812
- }
813
- else {
814
- this.setWorkingParts({ month, day, year, hour: 0, minute: 0, ampm: 'am' });
815
- }
816
- return;
817
- }
818
690
  /**
819
691
  * If there are multiple values, clamp to the last one.
820
692
  * This is because the last value is the one that the user
@@ -976,27 +848,6 @@ export class Datetime {
976
848
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
977
849
  return hasDatePresentation && !preferWheel;
978
850
  }
979
- get isMultipleMode() {
980
- return this.selectionMode === 'multiple' || (this.selectionMode === undefined && this.multiple);
981
- }
982
- get isRangeMode() {
983
- return this.selectionMode === 'range';
984
- }
985
- /**
986
- * Type guard: returns true if the given activeParts is a DatetimeRangeParts object.
987
- */
988
- isRangeParts(parts) {
989
- return this.isRangeMode && parts !== null && typeof parts === 'object' && !Array.isArray(parts) && 'start' in parts;
990
- }
991
- /**
992
- * Returns the current range parts if in range mode, or undefined otherwise.
993
- */
994
- get rangeParts() {
995
- if (this.isRangeParts(this.activeParts)) {
996
- return this.activeParts;
997
- }
998
- return undefined;
999
- }
1000
851
  yearValuesChanged() {
1001
852
  this.parsedYearValues = convertToArrayOfNumbers(this.yearValues);
1002
853
  }
@@ -1032,19 +883,6 @@ export class Datetime {
1032
883
  */
1033
884
  async confirm(closeOverlay = false) {
1034
885
  const { isCalendarPicker, activeParts, preferWheel, workingParts } = this;
1035
- /**
1036
- * In range mode, only confirm when both start and end are selected.
1037
- */
1038
- if (this.isRangeMode) {
1039
- if (!this.isRangeParts(activeParts) || !activeParts.end) {
1040
- return;
1041
- }
1042
- this.setValue([convertDataToISO(activeParts.start), convertDataToISO(activeParts.end)]);
1043
- if (closeOverlay) {
1044
- this.closeParentOverlay(CONFIRM_ROLE);
1045
- }
1046
- return;
1047
- }
1048
886
  /**
1049
887
  * We only update the value if the presentation is not a calendar picker.
1050
888
  */
@@ -1080,22 +918,6 @@ export class Datetime {
1080
918
  * @param startDate A valid [ISO-8601 string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format) to reset the datetime state to.
1081
919
  */
1082
920
  async reset(startDate) {
1083
- if (this.isRangeMode) {
1084
- /**
1085
- * In range mode, reset clears the full range. If a startDate
1086
- * is provided, the calendar navigates to that month without
1087
- * selecting anything so the user begins a fresh selection.
1088
- */
1089
- this.activeParts = [];
1090
- if (startDate) {
1091
- const parsed = parseDate(startDate);
1092
- if (parsed) {
1093
- const target = Array.isArray(parsed) ? parsed[0] : parsed;
1094
- this.setWorkingParts(target);
1095
- }
1096
- }
1097
- return;
1098
- }
1099
921
  this.processValue(startDate);
1100
922
  }
1101
923
  /**
@@ -1331,11 +1153,8 @@ export class Datetime {
1331
1153
  });
1332
1154
  }
1333
1155
  componentWillLoad() {
1334
- const { el, formatOptions, highlightedDates, multiple, selectionMode, presentation, preferWheel } = this;
1335
- if (selectionMode === undefined && multiple) {
1336
- printIonWarning('[ion-datetime] - The "multiple" property is deprecated. Use selectionMode="multiple" instead.', el);
1337
- }
1338
- if (this.isMultipleMode) {
1156
+ const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
1157
+ if (multiple) {
1339
1158
  if (presentation !== 'date') {
1340
1159
  printIonWarning('[ion-datetime] - Multiple date selection is only supported for presentation="date".', el);
1341
1160
  }
@@ -1343,17 +1162,6 @@ export class Datetime {
1343
1162
  printIonWarning('[ion-datetime] - Multiple date selection is not supported with preferWheel="true".', el);
1344
1163
  }
1345
1164
  }
1346
- if (this.isRangeMode) {
1347
- if (presentation !== 'date') {
1348
- printIonWarning('[ion-datetime] - Range selection is only supported for presentation="date".', el);
1349
- }
1350
- if (preferWheel) {
1351
- printIonWarning('[ion-datetime] - Range selection is not supported with preferWheel="true".', el);
1352
- }
1353
- }
1354
- if (selectionMode !== undefined && multiple) {
1355
- printIonWarning('[ion-datetime] - Both "selectionMode" and "multiple" are set. "selectionMode" takes precedence.', el);
1356
- }
1357
1165
  if (highlightedDates !== undefined) {
1358
1166
  if (presentation !== 'date' && presentation !== 'date-time' && presentation !== 'time-date') {
1359
1167
  printIonWarning('[ion-datetime] - The highlightedDates property is only supported with the date, date-time, and time-date presentations.', el);
@@ -1408,12 +1216,6 @@ export class Datetime {
1408
1216
  * is disabled or readonly.
1409
1217
  */
1410
1218
  const isButtonDisabled = disabled || readonly;
1411
- /**
1412
- * In range mode, the confirm button should be disabled until
1413
- * both a start and end date have been selected.
1414
- */
1415
- const isRangeIncomplete = this.isRangeMode && (!this.isRangeParts(this.activeParts) || !this.activeParts.end);
1416
- const isConfirmDisabled = isButtonDisabled || isRangeIncomplete;
1417
1219
  const confirmFill = theme === 'ionic' ? 'solid' : undefined;
1418
1220
  const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
1419
1221
  if (!hasSlottedButtons && !showDefaultButtons && !showClearButton) {
@@ -1433,7 +1235,7 @@ export class Datetime {
1433
1235
  return (h("div", { class: "datetime-footer" }, h("div", { class: "datetime-buttons" }, h("div", { class: {
1434
1236
  ['datetime-action-buttons']: true,
1435
1237
  ['has-clear-button']: this.showClearButton,
1436
- } }, h("slot", { name: "buttons" }, showDefaultButtons && (h("ion-button", { id: "cancel-button", color: this.color, onClick: () => this.cancel(true), disabled: isButtonDisabled }, this.cancelText)), h("div", { class: "datetime-action-buttons-container" }, showClearButton && (h("ion-button", { id: "clear-button", color: this.color, onClick: () => clearButtonClick(), disabled: isButtonDisabled }, this.clearText)), showDefaultButtons && (h("ion-button", { id: "confirm-button", fill: confirmFill, color: this.color, onClick: () => this.confirm(true), disabled: isConfirmDisabled }, this.doneText))))))));
1238
+ } }, h("slot", { name: "buttons" }, showDefaultButtons && (h("ion-button", { id: "cancel-button", color: this.color, onClick: () => this.cancel(true), disabled: isButtonDisabled }, this.cancelText)), h("div", { class: "datetime-action-buttons-container" }, showClearButton && (h("ion-button", { id: "clear-button", color: this.color, onClick: () => clearButtonClick(), disabled: isButtonDisabled }, this.clearText)), showDefaultButtons && (h("ion-button", { id: "confirm-button", fill: confirmFill, color: this.color, onClick: () => this.confirm(true), disabled: isButtonDisabled }, this.doneText))))))));
1437
1239
  }
1438
1240
  /**
1439
1241
  * Wheel picker render methods
@@ -1622,8 +1424,8 @@ export class Datetime {
1622
1424
  ...this.workingParts,
1623
1425
  month: ev.detail.value,
1624
1426
  });
1625
- // Month wheel is navigation-only in multi-select and range modes as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1626
- if (!this.isMultipleMode && !this.isRangeMode) {
1427
+ // Month wheel is navigation-only in multi-select mode as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1428
+ if (!this.multiple) {
1627
1429
  this.setActiveParts({
1628
1430
  ...activePart,
1629
1431
  month: ev.detail.value,
@@ -1644,8 +1446,8 @@ export class Datetime {
1644
1446
  ...this.workingParts,
1645
1447
  year: ev.detail.value,
1646
1448
  });
1647
- // Year wheel is navigation-only in multi-select and range modes as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1648
- if (!this.isMultipleMode && !this.isRangeMode) {
1449
+ // Year wheel is navigation-only in multi-select mode as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1450
+ if (!this.multiple) {
1649
1451
  this.setActiveParts({
1650
1452
  ...activePart,
1651
1453
  year: ev.detail.value,
@@ -1789,7 +1591,7 @@ export class Datetime {
1789
1591
  'calendar-month-disabled': !isWorkingMonth && swipeDisabled,
1790
1592
  } }, h("div", { class: "calendar-month-grid" }, getDaysOfMonth(month, year, this.firstDayOfWeek % 7, this.showAdjacentDays).map((dateObject, index) => {
1791
1593
  const { day, dayOfWeek, isAdjacentDay } = dateObject;
1792
- const { el, highlightedDates, isDateEnabled, showAdjacentDays } = this;
1594
+ const { el, highlightedDates, isDateEnabled, multiple, showAdjacentDays } = this;
1793
1595
  let _month = month;
1794
1596
  let _year = year;
1795
1597
  if (showAdjacentDays && isAdjacentDay && day !== null) {
@@ -1818,7 +1620,7 @@ export class Datetime {
1818
1620
  }
1819
1621
  const referenceParts = { month: _month, day, year: _year, isAdjacentDay };
1820
1622
  const isCalendarPadding = day === null;
1821
- const { isActive, isToday, ariaLabel, ariaSelected, disabled: isDayDisabled, isRangeStart, isRangeEnd, isInRange, text, } = getCalendarDayState(this.locale, referenceParts, this.isRangeParts(this.activeParts) ? [] : this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues, this.rangeParts);
1623
+ const { isActive, isToday, ariaLabel, ariaSelected, disabled: isDayDisabled, text, } = getCalendarDayState(this.locale, referenceParts, this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
1822
1624
  const dateIsoString = convertDataToISO(referenceParts);
1823
1625
  let isCalDayDisabled = isCalMonthDisabled || isDayDisabled;
1824
1626
  if (!isCalDayDisabled && isDateEnabled !== undefined) {
@@ -1841,60 +1643,24 @@ export class Datetime {
1841
1643
  */
1842
1644
  const isCalDayConstrained = isCalDayDisabled && isDatetimeDisabled;
1843
1645
  const isButtonDisabled = isCalDayDisabled || isDatetimeDisabled;
1844
- /**
1845
- * Determine if this day is part of the range selection.
1846
- * Range styling takes priority over highlightedDates.
1847
- */
1848
- const isPartOfRange = isRangeStart || isRangeEnd || isInRange;
1849
1646
  let dateStyle = undefined;
1850
1647
  /**
1851
- * Custom highlight styles should not override the style for selected dates
1852
- * or range selection, nor apply to "filler days" at the start of the grid.
1648
+ * Custom highlight styles should not override the style for selected dates,
1649
+ * nor apply to "filler days" at the start of the grid.
1853
1650
  */
1854
- if (highlightedDates !== undefined && !isActive && !isPartOfRange && day !== null && !isAdjacentDay) {
1651
+ if (highlightedDates !== undefined && !isActive && day !== null && !isAdjacentDay) {
1855
1652
  dateStyle = getHighlightStyles(highlightedDates, dateIsoString, el);
1856
1653
  }
1857
1654
  let dateParts = undefined;
1858
1655
  // "Filler days" at the beginning of the grid should not get the calendar day
1859
1656
  // CSS parts added to them
1860
1657
  if (!isCalendarPadding && !isAdjacentDay) {
1861
- dateParts = `calendar-day${isActive || isRangeStart || isRangeEnd ? ' active' : ''}${isToday ? ' today' : ''}${isCalDayDisabled ? ' disabled' : ''}${isRangeStart ? ' range-start range-selection' : ''}${isRangeEnd ? ' range-end range-selection' : ''}${isInRange ? ' range-selection' : ''}`;
1658
+ dateParts = `calendar-day${isActive ? ' active' : ''}${isToday ? ' today' : ''}${isCalDayDisabled ? ' disabled' : ''}`;
1862
1659
  }
1863
1660
  else if (isAdjacentDay) {
1864
- /**
1865
- * Adjacent days skip 'active' and 'today' parts but still
1866
- * include range parts so ::part() styling is consistent
1867
- * with the visual range track rendering.
1868
- */
1869
- dateParts = `calendar-day${isCalDayDisabled ? ' disabled' : ''}${isRangeStart ? ' range-start range-selection' : ''}${isRangeEnd ? ' range-end range-selection' : ''}${isInRange ? ' range-selection' : ''}`;
1661
+ dateParts = `calendar-day${isCalDayDisabled ? ' disabled' : ''}`;
1870
1662
  }
1871
- /**
1872
- * Build the wrapper's shadow part attribute for range track styling.
1873
- */
1874
- const hasCompleteRange = this.rangeParts?.end !== undefined;
1875
- const wrapperParts = isPartOfRange && hasCompleteRange && !isCalendarPadding ? 'range-track' : undefined;
1876
- /**
1877
- * Build the aria-label for range mode accessibility.
1878
- */
1879
- let rangeAriaLabel = ariaLabel;
1880
- if (this.isRangeMode && ariaLabel) {
1881
- if (isRangeStart) {
1882
- rangeAriaLabel += `, ${this.startDateLabel}`;
1883
- }
1884
- if (isRangeEnd) {
1885
- rangeAriaLabel += `, ${this.endDateLabel}`;
1886
- }
1887
- if (isInRange) {
1888
- rangeAriaLabel += ', in range';
1889
- }
1890
- }
1891
- return (h("div", { class: {
1892
- 'calendar-day-wrapper': true,
1893
- // A start without an end is only the circle until the range is complete
1894
- 'calendar-day-wrapper-range-start': isRangeStart && this.rangeParts?.end !== undefined,
1895
- 'calendar-day-wrapper-in-range': isInRange,
1896
- 'calendar-day-wrapper-range-end': isRangeEnd,
1897
- }, part: wrapperParts }, h("button", {
1663
+ return (h("div", { class: "calendar-day-wrapper" }, h("button", {
1898
1664
  // We need to use !important for the inline styles here because
1899
1665
  // otherwise the CSS shadow parts will override these styles.
1900
1666
  // See https://github.com/WICG/webcomponents/issues/847
@@ -1910,40 +1676,28 @@ export class Datetime {
1910
1676
  }, tabindex: "-1", "data-day": day, "data-month": _month, "data-year": _year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isButtonDisabled, class: {
1911
1677
  'calendar-day-padding': isCalendarPadding,
1912
1678
  'calendar-day': true,
1913
- 'calendar-day-active': isActive || isRangeStart || isRangeEnd,
1679
+ 'calendar-day-active': isActive,
1914
1680
  'calendar-day-constrained': isCalDayConstrained,
1915
1681
  'calendar-day-today': isToday,
1916
1682
  'calendar-day-adjacent-day': isAdjacentDay,
1917
- 'calendar-day-range-start': isRangeStart,
1918
- 'calendar-day-range-end': isRangeEnd,
1919
- 'calendar-day-in-range': isInRange,
1920
- }, part: dateParts, "aria-hidden": isCalendarPadding ? 'true' : null, "aria-selected": isActive || isRangeStart || isRangeEnd ? 'true' : ariaSelected, "aria-label": rangeAriaLabel, onClick: () => {
1683
+ }, part: dateParts, "aria-hidden": isCalendarPadding ? 'true' : null, "aria-selected": ariaSelected, "aria-label": ariaLabel, onClick: () => {
1921
1684
  if (isCalendarPadding) {
1922
1685
  return;
1923
1686
  }
1924
1687
  if (isAdjacentDay) {
1925
1688
  // The user selected a day outside the current month. Ignore this button, as the month will be re-rendered.
1926
1689
  this.el.blur();
1927
- if (!this.isRangeMode) {
1928
- this.activeParts = { ...activePart, ...referenceParts };
1929
- }
1690
+ this.activeParts = { ...activePart, ...referenceParts };
1930
1691
  this.animateToDate(referenceParts);
1931
- if (this.isRangeMode) {
1932
- this.setActiveParts(referenceParts);
1933
- }
1934
- else {
1935
- this.confirm();
1936
- }
1692
+ this.confirm();
1937
1693
  }
1938
1694
  else {
1939
1695
  this.setWorkingParts({
1940
1696
  ...this.workingParts,
1941
1697
  ...referenceParts,
1942
1698
  });
1943
- if (this.isRangeMode) {
1944
- this.setActiveParts(referenceParts);
1945
- }
1946
- else if (this.isMultipleMode) {
1699
+ // Multiple only needs date info so we can wipe out other fields like time.
1700
+ if (multiple) {
1947
1701
  this.setActiveParts(referenceParts, isActive);
1948
1702
  }
1949
1703
  else {
@@ -1963,17 +1717,7 @@ export class Datetime {
1963
1717
  })));
1964
1718
  }
1965
1719
  renderCalendar(theme) {
1966
- return (h("div", { class: "datetime-calendar", key: "datetime-calendar" }, this.renderCalendarHeader(theme), this.renderCalendarBody(), this.isRangeMode && this.rangeParts && !this.rangeParts.end && (h("div", { "aria-live": "polite", role: "status", style: {
1967
- position: 'absolute',
1968
- width: '1px',
1969
- height: '1px',
1970
- padding: '0',
1971
- margin: '-1px',
1972
- overflow: 'hidden',
1973
- clip: 'rect(0, 0, 0, 0)',
1974
- whiteSpace: 'nowrap',
1975
- border: '0',
1976
- } }, `${this.startDateLabel} selected, select ${this.endDateLabel.toLowerCase()}`))));
1720
+ return (h("div", { class: "datetime-calendar", key: "datetime-calendar" }, this.renderCalendarHeader(theme), this.renderCalendarBody()));
1977
1721
  }
1978
1722
  renderTimeLabel() {
1979
1723
  const hasSlottedTimeLabel = this.el.querySelector('[slot="time-label"]') !== null;
@@ -2026,23 +1770,10 @@ export class Datetime {
2026
1770
  ];
2027
1771
  }
2028
1772
  getHeaderSelectedDateText() {
2029
- const { activeParts, formatOptions, titleSelectedDatesFormatter } = this;
1773
+ const { activeParts, formatOptions, multiple, titleSelectedDatesFormatter } = this;
2030
1774
  const isArray = Array.isArray(activeParts);
2031
- const dateFormatOptions = formatOptions?.date ?? { weekday: 'short', month: 'short', day: 'numeric' };
2032
1775
  let headerText;
2033
- if (this.isRangeMode) {
2034
- headerText = this.getRangeHeaderText(formatOptions?.date ?? { month: 'short', day: 'numeric' });
2035
- if (titleSelectedDatesFormatter !== undefined) {
2036
- try {
2037
- const rangeValues = this.getRangeValueArray();
2038
- headerText = titleSelectedDatesFormatter(rangeValues);
2039
- }
2040
- catch (e) {
2041
- printIonError('[ion-datetime] - Exception in provided `titleSelectedDatesFormatter`:', e);
2042
- }
2043
- }
2044
- }
2045
- else if (this.isMultipleMode && isArray && activeParts.length !== 1) {
1776
+ if (multiple && isArray && activeParts.length !== 1) {
2046
1777
  headerText = `${activeParts.length} days`; // default/fallback for multiple selection
2047
1778
  if (titleSelectedDatesFormatter !== undefined) {
2048
1779
  try {
@@ -2055,37 +1786,10 @@ export class Datetime {
2055
1786
  }
2056
1787
  else {
2057
1788
  // for exactly 1 day selected (multiple set or not), show a formatted version of that
2058
- headerText = getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), dateFormatOptions);
1789
+ headerText = getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), formatOptions?.date ?? { weekday: 'short', month: 'short', day: 'numeric' });
2059
1790
  }
2060
1791
  return headerText;
2061
1792
  }
2062
- /**
2063
- * Returns the formatted range header text.
2064
- * Shows "Start date - End date" with placeholders from startDateLabel/endDateLabel.
2065
- */
2066
- getRangeHeaderText(dateFormatOptions) {
2067
- const range = this.rangeParts;
2068
- if (!range) {
2069
- return `${this.startDateLabel} - ${this.endDateLabel}`;
2070
- }
2071
- const startText = getLocalizedDateTime(this.locale, range.start, dateFormatOptions);
2072
- const endText = range.end ? getLocalizedDateTime(this.locale, range.end, dateFormatOptions) : this.endDateLabel;
2073
- return `${startText} - ${endText}`;
2074
- }
2075
- /**
2076
- * Returns the current range value as an ISO string array for
2077
- * titleSelectedDatesFormatter and ionChange.
2078
- */
2079
- getRangeValueArray() {
2080
- const range = this.rangeParts;
2081
- if (!range) {
2082
- return [];
2083
- }
2084
- if (!range.end) {
2085
- return [convertDataToISO(range.start)];
2086
- }
2087
- return [convertDataToISO(range.start), convertDataToISO(range.end)];
2088
- }
2089
1793
  renderHeader(showExpandedHeader = true) {
2090
1794
  const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
2091
1795
  if (!hasSlottedTitle && !this.showDefaultTitle) {
@@ -2209,7 +1913,7 @@ export class Datetime {
2209
1913
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
2210
1914
  const hasWheelVariant = hasDatePresentation && preferWheel;
2211
1915
  renderHiddenInput(true, el, name, formatValue(value), disabled);
2212
- return (h(Host, { key: 'bbda23db005004f03b23e39d1e8c622e588ba7c2', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: {
1916
+ return (h(Host, { key: '6ee2389238b42b0d10c5f5254a8ba61bfc53c677', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: {
2213
1917
  ...createColorClasses(color, {
2214
1918
  [theme]: true,
2215
1919
  ['datetime-readonly']: readonly,
@@ -2220,9 +1924,8 @@ export class Datetime {
2220
1924
  [`datetime-size-${size}`]: true,
2221
1925
  [`datetime-prefer-wheel`]: hasWheelVariant,
2222
1926
  [`datetime-grid`]: isGridStyle,
2223
- [`datetime-range`]: this.isRangeMode,
2224
1927
  }),
2225
- } }, h("div", { key: '788e47cd7e8b022a450c7938d713a7d50d43e4f7', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(theme)));
1928
+ } }, h("div", { key: '531803dfb77fa3d694c90b6fc45e71e304876fa8', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(theme)));
2226
1929
  }
2227
1930
  static get is() { return "ion-datetime"; }
2228
1931
  static get encapsulation() { return "shadow"; }
@@ -2684,10 +2387,7 @@ export class Datetime {
2684
2387
  "required": false,
2685
2388
  "optional": false,
2686
2389
  "docs": {
2687
- "tags": [{
2688
- "name": "deprecated",
2689
- "text": "Use `selectionMode=\"multiple\"` instead."
2690
- }],
2390
+ "tags": [],
2691
2391
  "text": "If `true`, multiple dates can be selected at once. Only\napplies to `presentation=\"date\"` and `preferWheel=\"false\"`."
2692
2392
  },
2693
2393
  "getter": false,
@@ -2696,65 +2396,6 @@ export class Datetime {
2696
2396
  "attribute": "multiple",
2697
2397
  "defaultValue": "false"
2698
2398
  },
2699
- "selectionMode": {
2700
- "type": "string",
2701
- "mutable": false,
2702
- "complexType": {
2703
- "original": "'multiple' | 'range'",
2704
- "resolved": "\"multiple\" | \"range\" | undefined",
2705
- "references": {}
2706
- },
2707
- "required": false,
2708
- "optional": true,
2709
- "docs": {
2710
- "tags": [],
2711
- "text": "Controls the date selection behavior.\n`'multiple'` enables selecting multiple individual dates.\n`'range'` enables selecting a start and end date range.\nWhen unset, single-date selection is used.\n\nRange selection only works with `presentation=\"date\"` and `preferWheel=\"false\"`."
2712
- },
2713
- "getter": false,
2714
- "setter": false,
2715
- "reflect": false,
2716
- "attribute": "selection-mode"
2717
- },
2718
- "startDateLabel": {
2719
- "type": "string",
2720
- "mutable": false,
2721
- "complexType": {
2722
- "original": "string",
2723
- "resolved": "string",
2724
- "references": {}
2725
- },
2726
- "required": false,
2727
- "optional": false,
2728
- "docs": {
2729
- "tags": [],
2730
- "text": "The text shown in the datetime header when the start of the range\nis empty, also used by screen readers to announce the start date.\nOnly applies when `selectionMode=\"range\"`."
2731
- },
2732
- "getter": false,
2733
- "setter": false,
2734
- "reflect": false,
2735
- "attribute": "start-date-label",
2736
- "defaultValue": "'Start date'"
2737
- },
2738
- "endDateLabel": {
2739
- "type": "string",
2740
- "mutable": false,
2741
- "complexType": {
2742
- "original": "string",
2743
- "resolved": "string",
2744
- "references": {}
2745
- },
2746
- "required": false,
2747
- "optional": false,
2748
- "docs": {
2749
- "tags": [],
2750
- "text": "The text shown in the datetime header when the end of the range\nis empty, also used by screen readers to announce the end date.\nOnly applies when `selectionMode=\"range\"`."
2751
- },
2752
- "getter": false,
2753
- "setter": false,
2754
- "reflect": false,
2755
- "attribute": "end-date-label",
2756
- "defaultValue": "'End date'"
2757
- },
2758
2399
  "highlightedDates": {
2759
2400
  "type": "unknown",
2760
2401
  "mutable": false,
@@ -3113,12 +2754,6 @@ export class Datetime {
3113
2754
  "Promise": {
3114
2755
  "location": "global",
3115
2756
  "id": "global::Promise"
3116
- },
3117
- "DatetimeParts": {
3118
- "location": "import",
3119
- "path": "./datetime-interface",
3120
- "id": "src/components/datetime/datetime-interface.ts::DatetimeParts",
3121
- "referenceLocation": "DatetimeParts"
3122
2757
  }
3123
2758
  },
3124
2759
  "return": "Promise<void>"