@ionic/core 9.0.11-dev.11793728481.1fc40367 → 9.0.11-dev.11793792571.1765ff65

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 (71) hide show
  1. package/components/ion-badge.js +1 -1
  2. package/components/ion-button.js +1 -1
  3. package/components/ion-content.js +1 -1
  4. package/components/ion-datetime-button.js +1 -1
  5. package/components/ion-datetime.js +1 -1
  6. package/components/ion-input-password-toggle.js +1 -1
  7. package/components/ion-item-option.js +1 -1
  8. package/components/ion-select-modal.js +1 -1
  9. package/components/ion-select.js +1 -1
  10. package/components/{p-B7ExaLVL.js → p-BCQSEpww.js} +1 -1
  11. package/components/p-Da8LCPwo.js +4 -0
  12. package/components/p-DirxxGzo.js +4 -0
  13. package/components/{p-BCYVFy50.js → p-py1vB-7U.js} +1 -1
  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/dist/cjs/ion-app_8.cjs.entry.js +13 -5
  19. package/dist/cjs/ion-avatar_3.cjs.entry.js +1 -1
  20. package/dist/cjs/ion-button_2.cjs.entry.js +1 -1
  21. package/dist/cjs/ion-datetime-button.cjs.entry.js +6 -33
  22. package/dist/cjs/ion-datetime.cjs.entry.js +36 -353
  23. package/dist/cjs/ion-item-option_3.cjs.entry.js +1 -1
  24. package/dist/cjs/ionic.cjs.js +1 -1
  25. package/dist/cjs/loader.cjs.js +1 -1
  26. package/dist/collection/components/badge/badge.ionic.css +1 -1
  27. package/dist/collection/components/button/button.ionic.css +1 -1
  28. package/dist/collection/components/content/content.ionic.css +352 -0
  29. package/dist/collection/components/content/{content.css → content.ios.css} +65 -41
  30. package/dist/collection/components/content/content.js +9 -5
  31. package/dist/collection/components/content/content.md.css +347 -0
  32. package/dist/collection/components/datetime/datetime.ionic.css +5 -179
  33. package/dist/collection/components/datetime/datetime.ios.css +2 -134
  34. package/dist/collection/components/datetime/datetime.js +33 -406
  35. package/dist/collection/components/datetime/datetime.md.css +0 -120
  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/item-option/item-option.ionic.css +1 -1
  39. package/dist/docs.json +127 -160
  40. package/dist/esm/{format-DUHrIiJq.js → format-NT7iHsbA.js} +1 -1
  41. package/dist/esm/ion-app_8.entry.js +13 -5
  42. package/dist/esm/ion-avatar_3.entry.js +1 -1
  43. package/dist/esm/ion-button_2.entry.js +1 -1
  44. package/dist/esm/ion-datetime-button.entry.js +7 -34
  45. package/dist/esm/ion-datetime.entry.js +37 -354
  46. package/dist/esm/ion-item-option_3.entry.js +1 -1
  47. package/dist/esm/ionic.js +1 -1
  48. package/dist/esm/loader.js +1 -1
  49. package/dist/html.html-data.json +0 -20
  50. package/dist/ionic/ionic.esm.js +1 -1
  51. package/dist/ionic/p-0743a26a.entry.js +4 -0
  52. package/dist/ionic/p-1d709b26.entry.js +4 -0
  53. package/dist/ionic/p-39e3be74.entry.js +4 -0
  54. package/dist/ionic/p-6e4ee264.entry.js +4 -0
  55. package/dist/ionic/{p-CaOPF8Xt.js → p-BtccSO5J.js} +1 -1
  56. package/dist/ionic/p-ad46d2fd.entry.js +4 -0
  57. package/dist/ionic/{p-8231e914.entry.js → p-b51eb274.entry.js} +1 -1
  58. package/dist/types/components/datetime/datetime-interface.d.ts +0 -4
  59. package/dist/types/components/datetime/datetime.d.ts +2 -71
  60. package/dist/types/components/datetime/utils/state.d.ts +2 -5
  61. package/dist/types/components.d.ts +0 -33
  62. package/hydrate/index.js +59 -403
  63. package/hydrate/index.mjs +59 -403
  64. package/package.json +1 -1
  65. package/components/p-ByE0slik.js +0 -4
  66. package/components/p-DktrWeJE.js +0 -4
  67. package/dist/ionic/p-41680415.entry.js +0 -4
  68. package/dist/ionic/p-56d77e95.entry.js +0 -4
  69. package/dist/ionic/p-a52cba2f.entry.js +0 -4
  70. package/dist/ionic/p-b30b468d.entry.js +0 -4
  71. package/dist/ionic/p-ceca04fb.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.
@@ -62,11 +57,6 @@ import { checkForPresentationFormatMismatch, warnIfTimeZoneProvided } from "./ut
62
57
  export class Datetime {
63
58
  constructor() {
64
59
  this.inputId = `ion-dt-${datetimeIds++}`;
65
- /**
66
- * Set when the user completes a range interactively, so processValue
67
- * can skip navigation and keep the calendar on the current month.
68
- */
69
- this.rangeCompletedInteractively = false;
70
60
  /**
71
61
  * Set when the user selects a value, cleared when it's confirmed
72
62
  * or `processValue` runs (`reset()`, or `value` being set to a
@@ -140,22 +130,8 @@ export class Datetime {
140
130
  /**
141
131
  * If `true`, multiple dates can be selected at once. Only
142
132
  * applies to `presentation="date"` and `preferWheel="false"`.
143
- *
144
- * @deprecated Use `selectionMode="multiple"` instead.
145
133
  */
146
134
  this.multiple = false;
147
- /**
148
- * The text shown in the datetime header when the start of the range
149
- * is empty, also used by screen readers to announce the start date.
150
- * Only applies when `selectionMode="range"`.
151
- */
152
- this.startDateLabel = 'Start date';
153
- /**
154
- * The text shown in the datetime header when the end of the range
155
- * is empty, also used by screen readers to announce the end date.
156
- * Only applies when `selectionMode="range"`.
157
- */
158
- this.endDateLabel = 'End date';
159
135
  /**
160
136
  * If `true`, a header will be shown above the calendar
161
137
  * picker. This will include both the slotted title, and
@@ -208,8 +184,8 @@ export class Datetime {
208
184
  */
209
185
  this.preferWheel = false;
210
186
  this.warnIfIncorrectValueUsage = () => {
211
- const { value } = this;
212
- if (!this.isMultipleMode && !this.isRangeMode && Array.isArray(value)) {
187
+ const { multiple, value } = this;
188
+ if (!multiple && Array.isArray(value)) {
213
189
  /**
214
190
  * We do some processing on the `value` array so
215
191
  * that it looks more like an array when logged to
@@ -218,13 +194,7 @@ export class Datetime {
218
194
  * Default toString() behavior: a,b
219
195
  * Custom behavior: ['a', 'b']
220
196
  */
221
- 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.
222
-
223
- Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
224
- `, this.el);
225
- }
226
- if (this.isRangeMode && Array.isArray(value) && value.length > 2) {
227
- 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".
228
198
 
229
199
  Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
230
200
  `, this.el);
@@ -250,9 +220,6 @@ export class Datetime {
250
220
  };
251
221
  this.getActivePart = () => {
252
222
  const { activeParts } = this;
253
- if (this.isRangeParts(activeParts)) {
254
- return activeParts.start;
255
- }
256
223
  return Array.isArray(activeParts) ? activeParts[0] : activeParts;
257
224
  };
258
225
  this.closeParentOverlay = (role) => {
@@ -267,33 +234,6 @@ export class Datetime {
267
234
  ...parts,
268
235
  };
269
236
  };
270
- /**
271
- * Checks whether the span from start to end contains any disabled day.
272
- * Used by range mode to prevent selecting across disabled dates.
273
- */
274
- this.rangeContainsDisabledDate = (start, end) => {
275
- const { minParts, maxParts, parsedDayValues, parsedMonthValues, parsedYearValues, isDateEnabled } = this;
276
- let cursor = getNextDay(start);
277
- while (isBefore(cursor, end)) {
278
- if (isDayDisabled(cursor, minParts, maxParts, parsedDayValues) ||
279
- (parsedMonthValues !== undefined && !parsedMonthValues.includes(cursor.month)) ||
280
- (parsedYearValues !== undefined && !parsedYearValues.includes(cursor.year))) {
281
- return true;
282
- }
283
- if (isDateEnabled) {
284
- try {
285
- if (!isDateEnabled(convertDataToISO(cursor))) {
286
- return true;
287
- }
288
- }
289
- catch {
290
- // Swallow user callback exceptions during validation
291
- }
292
- }
293
- cursor = getNextDay(cursor);
294
- }
295
- return false;
296
- };
297
237
  this.setActiveParts = (parts, removeDate = false) => {
298
238
  /** if the datetime component is in readonly mode,
299
239
  * allow browsing of the calendar without changing
@@ -303,7 +243,7 @@ export class Datetime {
303
243
  return;
304
244
  }
305
245
  this.hasUnconfirmedSelection = true;
306
- const { minParts, maxParts, activeParts } = this;
246
+ const { multiple, minParts, maxParts, activeParts } = this;
307
247
  /**
308
248
  * When setting the active parts, it is possible
309
249
  * to set invalid data. For example,
@@ -316,10 +256,7 @@ export class Datetime {
316
256
  */
317
257
  const validatedParts = validateParts(parts, minParts, maxParts);
318
258
  this.setWorkingParts(validatedParts);
319
- if (this.isRangeMode) {
320
- this.setActivePartsRange(validatedParts);
321
- }
322
- else if (this.isMultipleMode) {
259
+ if (multiple) {
323
260
  const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
324
261
  if (removeDate) {
325
262
  this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
@@ -339,26 +276,6 @@ export class Datetime {
339
276
  }
340
277
  this.confirm();
341
278
  };
342
- /**
343
- * Handles range selection logic when a day is clicked.
344
- *
345
- * Creating a new range: first click sets start, second sets end.
346
- * Modifying an existing range:
347
- * - Before range → new start
348
- * - Within range → new end
349
- * - After range → new end
350
- * If the resulting span contains a disabled date, start a new range instead.
351
- */
352
- this.setActivePartsRange = (parts) => {
353
- const current = this.rangeParts;
354
- if (!current || isBefore(parts, current.start) || this.rangeContainsDisabledDate(current.start, parts)) {
355
- this.activeParts = { start: parts };
356
- }
357
- else {
358
- this.rangeCompletedInteractively = true;
359
- this.activeParts = { start: current.start, end: parts };
360
- }
361
- };
362
279
  this.initializeKeyboardListeners = () => {
363
280
  const calendarBodyRef = this.calendarBodyRef;
364
281
  if (!calendarBodyRef) {
@@ -770,59 +687,6 @@ export class Datetime {
770
687
  if (hasValue) {
771
688
  warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
772
689
  }
773
- /**
774
- * Range mode: convert the value array into DatetimeRangeParts.
775
- */
776
- if (this.isRangeMode) {
777
- /**
778
- * The calendar navigates to the start of the range, or to the default
779
- * date when there is nothing selected, so that an empty range mode
780
- * opens on the same month as the other selection modes.
781
- */
782
- let navigateTo;
783
- if (hasValue && Array.isArray(valueToProcess)) {
784
- let rangeValues = valueToProcess;
785
- // If more than 2 entries, use first and last
786
- if (rangeValues.length > 2) {
787
- rangeValues = [rangeValues[0], rangeValues[rangeValues.length - 1]];
788
- }
789
- let startParts = rangeValues[0];
790
- let endParts = rangeValues.length > 1 ? rangeValues[1] : undefined;
791
- // Normalize reversed pairs so earlier date is start
792
- if (endParts && isAfter(startParts, endParts)) {
793
- const temp = startParts;
794
- startParts = endParts;
795
- endParts = temp;
796
- }
797
- this.activeParts = endParts ? { start: startParts, end: endParts } : { start: startParts };
798
- /**
799
- * When the user just completed the range interactively, stay on the
800
- * current month instead of jumping back to the start. The flag is
801
- * set in setActivePartsRange and consumed here.
802
- */
803
- if (endParts && this.rangeCompletedInteractively) {
804
- this.rangeCompletedInteractively = false;
805
- return;
806
- }
807
- navigateTo = startParts;
808
- }
809
- else {
810
- this.activeParts = [];
811
- navigateTo = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
812
- }
813
- const targetValue = clampDate(navigateTo, minParts, maxParts);
814
- const { month, day, year } = targetValue;
815
- const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
816
- const bodyIsVisible = el.classList.contains('datetime-ready');
817
- const { isGridStyle, showMonthAndYear } = this;
818
- if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
819
- this.animateToDate(targetValue);
820
- }
821
- else {
822
- this.setWorkingParts({ month, day, year, hour: 0, minute: 0, ampm: 'am' });
823
- }
824
- return;
825
- }
826
690
  /**
827
691
  * If there are multiple values, clamp to the last one.
828
692
  * This is because the last value is the one that the user
@@ -984,27 +848,6 @@ export class Datetime {
984
848
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
985
849
  return hasDatePresentation && !preferWheel;
986
850
  }
987
- get isMultipleMode() {
988
- return this.selectionMode === 'multiple' || (this.selectionMode === undefined && this.multiple);
989
- }
990
- get isRangeMode() {
991
- return this.selectionMode === 'range';
992
- }
993
- /**
994
- * Type guard: returns true if the given activeParts is a DatetimeRangeParts object.
995
- */
996
- isRangeParts(parts) {
997
- return this.isRangeMode && parts !== null && typeof parts === 'object' && !Array.isArray(parts) && 'start' in parts;
998
- }
999
- /**
1000
- * Returns the current range parts if in range mode, or undefined otherwise.
1001
- */
1002
- get rangeParts() {
1003
- if (this.isRangeParts(this.activeParts)) {
1004
- return this.activeParts;
1005
- }
1006
- return undefined;
1007
- }
1008
851
  yearValuesChanged() {
1009
852
  this.parsedYearValues = convertToArrayOfNumbers(this.yearValues);
1010
853
  }
@@ -1040,19 +883,6 @@ export class Datetime {
1040
883
  */
1041
884
  async confirm(closeOverlay = false) {
1042
885
  const { isCalendarPicker, activeParts, preferWheel, workingParts } = this;
1043
- /**
1044
- * In range mode, only confirm when both start and end are selected.
1045
- */
1046
- if (this.isRangeMode) {
1047
- if (!this.isRangeParts(activeParts) || !activeParts.end) {
1048
- return;
1049
- }
1050
- this.setValue([convertDataToISO(activeParts.start), convertDataToISO(activeParts.end)]);
1051
- if (closeOverlay) {
1052
- this.closeParentOverlay(CONFIRM_ROLE);
1053
- }
1054
- return;
1055
- }
1056
886
  /**
1057
887
  * We only update the value if the presentation is not a calendar picker.
1058
888
  */
@@ -1088,22 +918,6 @@ export class Datetime {
1088
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.
1089
919
  */
1090
920
  async reset(startDate) {
1091
- if (this.isRangeMode) {
1092
- /**
1093
- * In range mode, reset clears the full range. If a startDate
1094
- * is provided, the calendar navigates to that month without
1095
- * selecting anything so the user begins a fresh selection.
1096
- */
1097
- this.activeParts = [];
1098
- if (startDate) {
1099
- const parsed = parseDate(startDate);
1100
- if (parsed) {
1101
- const target = Array.isArray(parsed) ? parsed[0] : parsed;
1102
- this.setWorkingParts(target);
1103
- }
1104
- }
1105
- return;
1106
- }
1107
921
  this.processValue(startDate);
1108
922
  }
1109
923
  /**
@@ -1339,11 +1153,8 @@ export class Datetime {
1339
1153
  });
1340
1154
  }
1341
1155
  componentWillLoad() {
1342
- const { el, formatOptions, highlightedDates, multiple, selectionMode, presentation, preferWheel } = this;
1343
- if (selectionMode === undefined && multiple) {
1344
- printIonWarning('[ion-datetime] - The "multiple" property is deprecated. Use selectionMode="multiple" instead.', el);
1345
- }
1346
- if (this.isMultipleMode) {
1156
+ const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
1157
+ if (multiple) {
1347
1158
  if (presentation !== 'date') {
1348
1159
  printIonWarning('[ion-datetime] - Multiple date selection is only supported for presentation="date".', el);
1349
1160
  }
@@ -1351,17 +1162,6 @@ export class Datetime {
1351
1162
  printIonWarning('[ion-datetime] - Multiple date selection is not supported with preferWheel="true".', el);
1352
1163
  }
1353
1164
  }
1354
- if (this.isRangeMode) {
1355
- if (presentation !== 'date') {
1356
- printIonWarning('[ion-datetime] - Range selection is only supported for presentation="date".', el);
1357
- }
1358
- if (preferWheel) {
1359
- printIonWarning('[ion-datetime] - Range selection is not supported with preferWheel="true".', el);
1360
- }
1361
- }
1362
- if (selectionMode !== undefined && multiple) {
1363
- printIonWarning('[ion-datetime] - Both "selectionMode" and "multiple" are set. "selectionMode" takes precedence.', el);
1364
- }
1365
1165
  if (highlightedDates !== undefined) {
1366
1166
  if (presentation !== 'date' && presentation !== 'date-time' && presentation !== 'time-date') {
1367
1167
  printIonWarning('[ion-datetime] - The highlightedDates property is only supported with the date, date-time, and time-date presentations.', el);
@@ -1416,12 +1216,6 @@ export class Datetime {
1416
1216
  * is disabled or readonly.
1417
1217
  */
1418
1218
  const isButtonDisabled = disabled || readonly;
1419
- /**
1420
- * In range mode, the confirm button should be disabled until
1421
- * both a start and end date have been selected.
1422
- */
1423
- const isRangeIncomplete = this.isRangeMode && (!this.isRangeParts(this.activeParts) || !this.activeParts.end);
1424
- const isConfirmDisabled = isButtonDisabled || isRangeIncomplete;
1425
1219
  const confirmFill = theme === 'ionic' ? 'solid' : undefined;
1426
1220
  const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
1427
1221
  if (!hasSlottedButtons && !showDefaultButtons && !showClearButton) {
@@ -1441,7 +1235,7 @@ export class Datetime {
1441
1235
  return (h("div", { class: "datetime-footer" }, h("div", { class: "datetime-buttons" }, h("div", { class: {
1442
1236
  ['datetime-action-buttons']: true,
1443
1237
  ['has-clear-button']: this.showClearButton,
1444
- } }, 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))))))));
1445
1239
  }
1446
1240
  /**
1447
1241
  * Wheel picker render methods
@@ -1630,8 +1424,8 @@ export class Datetime {
1630
1424
  ...this.workingParts,
1631
1425
  month: ev.detail.value,
1632
1426
  });
1633
- // Month wheel is navigation-only in multi-select and range modes as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1634
- 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) {
1635
1429
  this.setActiveParts({
1636
1430
  ...activePart,
1637
1431
  month: ev.detail.value,
@@ -1652,8 +1446,8 @@ export class Datetime {
1652
1446
  ...this.workingParts,
1653
1447
  year: ev.detail.value,
1654
1448
  });
1655
- // Year wheel is navigation-only in multi-select and range modes as a fix for https://github.com/ionic-team/ionic-framework/issues/29673
1656
- 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) {
1657
1451
  this.setActiveParts({
1658
1452
  ...activePart,
1659
1453
  year: ev.detail.value,
@@ -1797,7 +1591,7 @@ export class Datetime {
1797
1591
  'calendar-month-disabled': !isWorkingMonth && swipeDisabled,
1798
1592
  } }, h("div", { class: "calendar-month-grid" }, getDaysOfMonth(month, year, this.firstDayOfWeek % 7, this.showAdjacentDays).map((dateObject, index) => {
1799
1593
  const { day, dayOfWeek, isAdjacentDay } = dateObject;
1800
- const { el, highlightedDates, isDateEnabled, showAdjacentDays } = this;
1594
+ const { el, highlightedDates, isDateEnabled, multiple, showAdjacentDays } = this;
1801
1595
  let _month = month;
1802
1596
  let _year = year;
1803
1597
  if (showAdjacentDays && isAdjacentDay && day !== null) {
@@ -1826,7 +1620,7 @@ export class Datetime {
1826
1620
  }
1827
1621
  const referenceParts = { month: _month, day, year: _year, isAdjacentDay };
1828
1622
  const isCalendarPadding = day === null;
1829
- 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);
1830
1624
  const dateIsoString = convertDataToISO(referenceParts);
1831
1625
  let isCalDayDisabled = isCalMonthDisabled || isDayDisabled;
1832
1626
  if (!isCalDayDisabled && isDateEnabled !== undefined) {
@@ -1849,60 +1643,24 @@ export class Datetime {
1849
1643
  */
1850
1644
  const isCalDayConstrained = isCalDayDisabled && isDatetimeDisabled;
1851
1645
  const isButtonDisabled = isCalDayDisabled || isDatetimeDisabled;
1852
- /**
1853
- * Determine if this day is part of the range selection.
1854
- * Range styling takes priority over highlightedDates.
1855
- */
1856
- const isPartOfRange = isRangeStart || isRangeEnd || isInRange;
1857
1646
  let dateStyle = undefined;
1858
1647
  /**
1859
- * Custom highlight styles should not override the style for selected dates
1860
- * 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.
1861
1650
  */
1862
- if (highlightedDates !== undefined && !isActive && !isPartOfRange && day !== null && !isAdjacentDay) {
1651
+ if (highlightedDates !== undefined && !isActive && day !== null && !isAdjacentDay) {
1863
1652
  dateStyle = getHighlightStyles(highlightedDates, dateIsoString, el);
1864
1653
  }
1865
1654
  let dateParts = undefined;
1866
1655
  // "Filler days" at the beginning of the grid should not get the calendar day
1867
1656
  // CSS parts added to them
1868
1657
  if (!isCalendarPadding && !isAdjacentDay) {
1869
- 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' : ''}`;
1870
1659
  }
1871
1660
  else if (isAdjacentDay) {
1872
- /**
1873
- * Adjacent days skip 'active' and 'today' parts but still
1874
- * include range parts so ::part() styling is consistent
1875
- * with the visual range track rendering.
1876
- */
1877
- dateParts = `calendar-day${isCalDayDisabled ? ' disabled' : ''}${isRangeStart ? ' range-start range-selection' : ''}${isRangeEnd ? ' range-end range-selection' : ''}${isInRange ? ' range-selection' : ''}`;
1661
+ dateParts = `calendar-day${isCalDayDisabled ? ' disabled' : ''}`;
1878
1662
  }
1879
- /**
1880
- * Build the wrapper's shadow part attribute for range track styling.
1881
- */
1882
- const hasCompleteRange = this.rangeParts?.end !== undefined;
1883
- const wrapperParts = isPartOfRange && hasCompleteRange && !isCalendarPadding ? 'range-track' : undefined;
1884
- /**
1885
- * Build the aria-label for range mode accessibility.
1886
- */
1887
- let rangeAriaLabel = ariaLabel;
1888
- if (this.isRangeMode && ariaLabel) {
1889
- if (isRangeStart) {
1890
- rangeAriaLabel += `, ${this.startDateLabel}`;
1891
- }
1892
- if (isRangeEnd) {
1893
- rangeAriaLabel += `, ${this.endDateLabel}`;
1894
- }
1895
- if (isInRange) {
1896
- rangeAriaLabel += ', in range';
1897
- }
1898
- }
1899
- return (h("div", { class: {
1900
- 'calendar-day-wrapper': true,
1901
- // A start without an end is only the circle until the range is complete
1902
- 'calendar-day-wrapper-range-start': isRangeStart && this.rangeParts?.end !== undefined,
1903
- 'calendar-day-wrapper-in-range': isInRange,
1904
- 'calendar-day-wrapper-range-end': isRangeEnd,
1905
- }, part: wrapperParts }, h("button", {
1663
+ return (h("div", { class: "calendar-day-wrapper" }, h("button", {
1906
1664
  // We need to use !important for the inline styles here because
1907
1665
  // otherwise the CSS shadow parts will override these styles.
1908
1666
  // See https://github.com/WICG/webcomponents/issues/847
@@ -1918,40 +1676,28 @@ export class Datetime {
1918
1676
  }, tabindex: "-1", "data-day": day, "data-month": _month, "data-year": _year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isButtonDisabled, class: {
1919
1677
  'calendar-day-padding': isCalendarPadding,
1920
1678
  'calendar-day': true,
1921
- 'calendar-day-active': isActive || isRangeStart || isRangeEnd,
1679
+ 'calendar-day-active': isActive,
1922
1680
  'calendar-day-constrained': isCalDayConstrained,
1923
1681
  'calendar-day-today': isToday,
1924
1682
  'calendar-day-adjacent-day': isAdjacentDay,
1925
- 'calendar-day-range-start': isRangeStart,
1926
- 'calendar-day-range-end': isRangeEnd,
1927
- 'calendar-day-in-range': isInRange,
1928
- }, 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: () => {
1929
1684
  if (isCalendarPadding) {
1930
1685
  return;
1931
1686
  }
1932
1687
  if (isAdjacentDay) {
1933
1688
  // The user selected a day outside the current month. Ignore this button, as the month will be re-rendered.
1934
1689
  this.el.blur();
1935
- if (!this.isRangeMode) {
1936
- this.activeParts = { ...activePart, ...referenceParts };
1937
- }
1690
+ this.activeParts = { ...activePart, ...referenceParts };
1938
1691
  this.animateToDate(referenceParts);
1939
- if (this.isRangeMode) {
1940
- this.setActiveParts(referenceParts);
1941
- }
1942
- else {
1943
- this.confirm();
1944
- }
1692
+ this.confirm();
1945
1693
  }
1946
1694
  else {
1947
1695
  this.setWorkingParts({
1948
1696
  ...this.workingParts,
1949
1697
  ...referenceParts,
1950
1698
  });
1951
- if (this.isRangeMode) {
1952
- this.setActiveParts(referenceParts);
1953
- }
1954
- else if (this.isMultipleMode) {
1699
+ // Multiple only needs date info so we can wipe out other fields like time.
1700
+ if (multiple) {
1955
1701
  this.setActiveParts(referenceParts, isActive);
1956
1702
  }
1957
1703
  else {
@@ -1971,17 +1717,7 @@ export class Datetime {
1971
1717
  })));
1972
1718
  }
1973
1719
  renderCalendar(theme) {
1974
- 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: {
1975
- position: 'absolute',
1976
- width: '1px',
1977
- height: '1px',
1978
- padding: '0',
1979
- margin: '-1px',
1980
- overflow: 'hidden',
1981
- clip: 'rect(0, 0, 0, 0)',
1982
- whiteSpace: 'nowrap',
1983
- border: '0',
1984
- } }, `${this.startDateLabel} selected, select ${this.endDateLabel.toLowerCase()}`))));
1720
+ return (h("div", { class: "datetime-calendar", key: "datetime-calendar" }, this.renderCalendarHeader(theme), this.renderCalendarBody()));
1985
1721
  }
1986
1722
  renderTimeLabel() {
1987
1723
  const hasSlottedTimeLabel = this.el.querySelector('[slot="time-label"]') !== null;
@@ -2034,23 +1770,10 @@ export class Datetime {
2034
1770
  ];
2035
1771
  }
2036
1772
  getHeaderSelectedDateText() {
2037
- const { activeParts, formatOptions, titleSelectedDatesFormatter } = this;
1773
+ const { activeParts, formatOptions, multiple, titleSelectedDatesFormatter } = this;
2038
1774
  const isArray = Array.isArray(activeParts);
2039
- const dateFormatOptions = formatOptions?.date ?? { weekday: 'short', month: 'short', day: 'numeric' };
2040
1775
  let headerText;
2041
- if (this.isRangeMode) {
2042
- headerText = this.getRangeHeaderText(formatOptions?.date ?? { month: 'short', day: 'numeric' });
2043
- if (titleSelectedDatesFormatter !== undefined) {
2044
- try {
2045
- const rangeValues = this.getRangeValueArray();
2046
- headerText = titleSelectedDatesFormatter(rangeValues);
2047
- }
2048
- catch (e) {
2049
- printIonError('[ion-datetime] - Exception in provided `titleSelectedDatesFormatter`:', e);
2050
- }
2051
- }
2052
- }
2053
- else if (this.isMultipleMode && isArray && activeParts.length !== 1) {
1776
+ if (multiple && isArray && activeParts.length !== 1) {
2054
1777
  headerText = `${activeParts.length} days`; // default/fallback for multiple selection
2055
1778
  if (titleSelectedDatesFormatter !== undefined) {
2056
1779
  try {
@@ -2063,37 +1786,10 @@ export class Datetime {
2063
1786
  }
2064
1787
  else {
2065
1788
  // for exactly 1 day selected (multiple set or not), show a formatted version of that
2066
- headerText = getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), dateFormatOptions);
1789
+ headerText = getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), formatOptions?.date ?? { weekday: 'short', month: 'short', day: 'numeric' });
2067
1790
  }
2068
1791
  return headerText;
2069
1792
  }
2070
- /**
2071
- * Returns the formatted range header text.
2072
- * Shows "Start date - End date" with placeholders from startDateLabel/endDateLabel.
2073
- */
2074
- getRangeHeaderText(dateFormatOptions) {
2075
- const range = this.rangeParts;
2076
- if (!range) {
2077
- return `${this.startDateLabel} - ${this.endDateLabel}`;
2078
- }
2079
- const startText = getLocalizedDateTime(this.locale, range.start, dateFormatOptions);
2080
- const endText = range.end ? getLocalizedDateTime(this.locale, range.end, dateFormatOptions) : this.endDateLabel;
2081
- return `${startText} - ${endText}`;
2082
- }
2083
- /**
2084
- * Returns the current range value as an ISO string array for
2085
- * titleSelectedDatesFormatter and ionChange.
2086
- */
2087
- getRangeValueArray() {
2088
- const range = this.rangeParts;
2089
- if (!range) {
2090
- return [];
2091
- }
2092
- if (!range.end) {
2093
- return [convertDataToISO(range.start)];
2094
- }
2095
- return [convertDataToISO(range.start), convertDataToISO(range.end)];
2096
- }
2097
1793
  renderHeader(showExpandedHeader = true) {
2098
1794
  const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
2099
1795
  if (!hasSlottedTitle && !this.showDefaultTitle) {
@@ -2217,7 +1913,7 @@ export class Datetime {
2217
1913
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
2218
1914
  const hasWheelVariant = hasDatePresentation && preferWheel;
2219
1915
  renderHiddenInput(true, el, name, formatValue(value), disabled);
2220
- return (h(Host, { key: '0a05835fa52e91147d72250941201b89fd850dda', "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: {
2221
1917
  ...createColorClasses(color, {
2222
1918
  [theme]: true,
2223
1919
  ['datetime-readonly']: readonly,
@@ -2228,9 +1924,8 @@ export class Datetime {
2228
1924
  [`datetime-size-${size}`]: true,
2229
1925
  [`datetime-prefer-wheel`]: hasWheelVariant,
2230
1926
  [`datetime-grid`]: isGridStyle,
2231
- [`datetime-range`]: this.isRangeMode,
2232
1927
  }),
2233
- } }, h("div", { key: '5b5d6999f55b85523f65763a906f7f16c25f2eb2', 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)));
2234
1929
  }
2235
1930
  static get is() { return "ion-datetime"; }
2236
1931
  static get encapsulation() { return "shadow"; }
@@ -2692,10 +2387,7 @@ export class Datetime {
2692
2387
  "required": false,
2693
2388
  "optional": false,
2694
2389
  "docs": {
2695
- "tags": [{
2696
- "name": "deprecated",
2697
- "text": "Use `selectionMode=\"multiple\"` instead."
2698
- }],
2390
+ "tags": [],
2699
2391
  "text": "If `true`, multiple dates can be selected at once. Only\napplies to `presentation=\"date\"` and `preferWheel=\"false\"`."
2700
2392
  },
2701
2393
  "getter": false,
@@ -2704,65 +2396,6 @@ export class Datetime {
2704
2396
  "attribute": "multiple",
2705
2397
  "defaultValue": "false"
2706
2398
  },
2707
- "selectionMode": {
2708
- "type": "string",
2709
- "mutable": false,
2710
- "complexType": {
2711
- "original": "'multiple' | 'range'",
2712
- "resolved": "\"multiple\" | \"range\" | undefined",
2713
- "references": {}
2714
- },
2715
- "required": false,
2716
- "optional": true,
2717
- "docs": {
2718
- "tags": [],
2719
- "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\"`."
2720
- },
2721
- "getter": false,
2722
- "setter": false,
2723
- "reflect": false,
2724
- "attribute": "selection-mode"
2725
- },
2726
- "startDateLabel": {
2727
- "type": "string",
2728
- "mutable": false,
2729
- "complexType": {
2730
- "original": "string",
2731
- "resolved": "string",
2732
- "references": {}
2733
- },
2734
- "required": false,
2735
- "optional": false,
2736
- "docs": {
2737
- "tags": [],
2738
- "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\"`."
2739
- },
2740
- "getter": false,
2741
- "setter": false,
2742
- "reflect": false,
2743
- "attribute": "start-date-label",
2744
- "defaultValue": "'Start date'"
2745
- },
2746
- "endDateLabel": {
2747
- "type": "string",
2748
- "mutable": false,
2749
- "complexType": {
2750
- "original": "string",
2751
- "resolved": "string",
2752
- "references": {}
2753
- },
2754
- "required": false,
2755
- "optional": false,
2756
- "docs": {
2757
- "tags": [],
2758
- "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\"`."
2759
- },
2760
- "getter": false,
2761
- "setter": false,
2762
- "reflect": false,
2763
- "attribute": "end-date-label",
2764
- "defaultValue": "'End date'"
2765
- },
2766
2399
  "highlightedDates": {
2767
2400
  "type": "unknown",
2768
2401
  "mutable": false,
@@ -3121,12 +2754,6 @@ export class Datetime {
3121
2754
  "Promise": {
3122
2755
  "location": "global",
3123
2756
  "id": "global::Promise"
3124
- },
3125
- "DatetimeParts": {
3126
- "location": "import",
3127
- "path": "./datetime-interface",
3128
- "id": "src/components/datetime/datetime-interface.ts::DatetimeParts",
3129
- "referenceLocation": "DatetimeParts"
3130
2757
  }
3131
2758
  },
3132
2759
  "return": "Promise<void>"