@lucca-front/ng 21.2.1 → 22.0.0-rc.1

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 (146) hide show
  1. package/fesm2022/lucca-front-ng-api.mjs.map +1 -1
  2. package/fesm2022/lucca-front-ng-callout.mjs +10 -4
  3. package/fesm2022/lucca-front-ng-callout.mjs.map +1 -1
  4. package/fesm2022/lucca-front-ng-clear.mjs.map +1 -1
  5. package/fesm2022/lucca-front-ng-comment.mjs +1 -1
  6. package/fesm2022/lucca-front-ng-comment.mjs.map +1 -1
  7. package/fesm2022/lucca-front-ng-core-select-api.mjs.map +1 -1
  8. package/fesm2022/lucca-front-ng-core-select-department.mjs +7 -5
  9. package/fesm2022/lucca-front-ng-core-select-department.mjs.map +1 -1
  10. package/fesm2022/lucca-front-ng-core-select-establishment.mjs.map +1 -1
  11. package/fesm2022/lucca-front-ng-core-select-job-qualification.mjs.map +1 -1
  12. package/fesm2022/lucca-front-ng-core-select-occupation-category.mjs.map +1 -1
  13. package/fesm2022/lucca-front-ng-core-select-user.mjs +16 -11
  14. package/fesm2022/lucca-front-ng-core-select-user.mjs.map +1 -1
  15. package/fesm2022/lucca-front-ng-core-select.mjs +46 -18
  16. package/fesm2022/lucca-front-ng-core-select.mjs.map +1 -1
  17. package/fesm2022/lucca-front-ng-core.mjs +11 -6
  18. package/fesm2022/lucca-front-ng-core.mjs.map +1 -1
  19. package/fesm2022/lucca-front-ng-data-table.mjs +31 -15
  20. package/fesm2022/lucca-front-ng-data-table.mjs.map +1 -1
  21. package/fesm2022/lucca-front-ng-date.mjs +10 -6
  22. package/fesm2022/lucca-front-ng-date.mjs.map +1 -1
  23. package/fesm2022/lucca-front-ng-date2.mjs +104 -88
  24. package/fesm2022/lucca-front-ng-date2.mjs.map +1 -1
  25. package/fesm2022/lucca-front-ng-department.mjs.map +1 -1
  26. package/fesm2022/lucca-front-ng-dialog.mjs +36 -25
  27. package/fesm2022/lucca-front-ng-dialog.mjs.map +1 -1
  28. package/fesm2022/lucca-front-ng-divider.mjs.map +1 -1
  29. package/fesm2022/lucca-front-ng-empty-state.mjs +5 -4
  30. package/fesm2022/lucca-front-ng-empty-state.mjs.map +1 -1
  31. package/fesm2022/lucca-front-ng-establishment.mjs +3 -3
  32. package/fesm2022/lucca-front-ng-establishment.mjs.map +1 -1
  33. package/fesm2022/lucca-front-ng-fancy-box.mjs +1 -1
  34. package/fesm2022/lucca-front-ng-fancy-box.mjs.map +1 -1
  35. package/fesm2022/lucca-front-ng-file-upload.mjs +5 -3
  36. package/fesm2022/lucca-front-ng-file-upload.mjs.map +1 -1
  37. package/fesm2022/lucca-front-ng-filter-pills.mjs +3 -3
  38. package/fesm2022/lucca-front-ng-filter-pills.mjs.map +1 -1
  39. package/fesm2022/lucca-front-ng-form-field.mjs +3 -3
  40. package/fesm2022/lucca-front-ng-form-field.mjs.map +1 -1
  41. package/fesm2022/lucca-front-ng-formly.mjs +1 -1
  42. package/fesm2022/lucca-front-ng-formly.mjs.map +1 -1
  43. package/fesm2022/lucca-front-ng-forms-phone-number-input.mjs +26 -21
  44. package/fesm2022/lucca-front-ng-forms-phone-number-input.mjs.map +1 -1
  45. package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-html.mjs +15 -13
  46. package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-html.mjs.map +1 -1
  47. package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-plain-text.mjs +5 -3
  48. package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-plain-text.mjs.map +1 -1
  49. package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs +26 -19
  50. package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs.map +1 -1
  51. package/fesm2022/lucca-front-ng-forms.mjs +3 -3
  52. package/fesm2022/lucca-front-ng-forms.mjs.map +1 -1
  53. package/fesm2022/lucca-front-ng-highlight-data.mjs +1 -1
  54. package/fesm2022/lucca-front-ng-highlight-data.mjs.map +1 -1
  55. package/fesm2022/lucca-front-ng-index-table.mjs +5 -5
  56. package/fesm2022/lucca-front-ng-index-table.mjs.map +1 -1
  57. package/fesm2022/lucca-front-ng-input.mjs +6 -5
  58. package/fesm2022/lucca-front-ng-input.mjs.map +1 -1
  59. package/fesm2022/lucca-front-ng-link.mjs.map +1 -1
  60. package/fesm2022/lucca-front-ng-mobile-push.mjs.map +1 -1
  61. package/fesm2022/lucca-front-ng-modal.mjs +5 -5
  62. package/fesm2022/lucca-front-ng-modal.mjs.map +1 -1
  63. package/fesm2022/lucca-front-ng-multi-select.mjs +27 -14
  64. package/fesm2022/lucca-front-ng-multi-select.mjs.map +1 -1
  65. package/fesm2022/lucca-front-ng-number-format.mjs +9 -8
  66. package/fesm2022/lucca-front-ng-number-format.mjs.map +1 -1
  67. package/fesm2022/lucca-front-ng-option.mjs +7 -3
  68. package/fesm2022/lucca-front-ng-option.mjs.map +1 -1
  69. package/fesm2022/lucca-front-ng-page-header.mjs.map +1 -1
  70. package/fesm2022/lucca-front-ng-popover.mjs +6 -2
  71. package/fesm2022/lucca-front-ng-popover.mjs.map +1 -1
  72. package/fesm2022/lucca-front-ng-popover2.mjs.map +1 -1
  73. package/fesm2022/lucca-front-ng-popup.mjs +1 -1
  74. package/fesm2022/lucca-front-ng-popup.mjs.map +1 -1
  75. package/fesm2022/lucca-front-ng-progress-bar.mjs.map +1 -1
  76. package/fesm2022/lucca-front-ng-read-more.mjs.map +1 -1
  77. package/fesm2022/lucca-front-ng-scroll-box.mjs.map +1 -1
  78. package/fesm2022/lucca-front-ng-scroll.mjs.map +1 -1
  79. package/fesm2022/lucca-front-ng-segmented-control-tabs.mjs.map +1 -1
  80. package/fesm2022/lucca-front-ng-select.mjs +5 -4
  81. package/fesm2022/lucca-front-ng-select.mjs.map +1 -1
  82. package/fesm2022/lucca-front-ng-sidepanel.mjs.map +1 -1
  83. package/fesm2022/lucca-front-ng-simple-select.mjs +11 -8
  84. package/fesm2022/lucca-front-ng-simple-select.mjs.map +1 -1
  85. package/fesm2022/lucca-front-ng-skeleton.mjs.map +1 -1
  86. package/fesm2022/lucca-front-ng-sortable-list.mjs.map +1 -1
  87. package/fesm2022/lucca-front-ng-time.mjs +2 -2
  88. package/fesm2022/lucca-front-ng-time.mjs.map +1 -1
  89. package/fesm2022/lucca-front-ng-title.mjs.map +1 -1
  90. package/fesm2022/lucca-front-ng-toast.mjs.map +1 -1
  91. package/fesm2022/lucca-front-ng-tree-select.mjs +11 -10
  92. package/fesm2022/lucca-front-ng-tree-select.mjs.map +1 -1
  93. package/fesm2022/lucca-front-ng-user-popover.mjs.map +1 -1
  94. package/fesm2022/lucca-front-ng-user.mjs +3 -3
  95. package/fesm2022/lucca-front-ng-user.mjs.map +1 -1
  96. package/package.json +4 -4
  97. package/types/lucca-front-ng-api.d.ts +9 -9
  98. package/types/lucca-front-ng-clear.d.ts +1 -1
  99. package/types/lucca-front-ng-core-select-api.d.ts +14 -14
  100. package/types/lucca-front-ng-core-select-department.d.ts +10 -10
  101. package/types/lucca-front-ng-core-select-establishment.d.ts +12 -12
  102. package/types/lucca-front-ng-core-select-job-qualification.d.ts +6 -6
  103. package/types/lucca-front-ng-core-select-occupation-category.d.ts +6 -6
  104. package/types/lucca-front-ng-core-select-user.d.ts +19 -19
  105. package/types/lucca-front-ng-core-select.d.ts +53 -53
  106. package/types/lucca-front-ng-core.d.ts +10 -9
  107. package/types/lucca-front-ng-data-table.d.ts +40 -40
  108. package/types/lucca-front-ng-date.d.ts +2 -2
  109. package/types/lucca-front-ng-date2.d.ts +93 -93
  110. package/types/lucca-front-ng-department.d.ts +2 -2
  111. package/types/lucca-front-ng-dialog.d.ts +4 -4
  112. package/types/lucca-front-ng-divider.d.ts +1 -1
  113. package/types/lucca-front-ng-establishment.d.ts +9 -9
  114. package/types/lucca-front-ng-file-upload.d.ts +17 -17
  115. package/types/lucca-front-ng-filter-pills.d.ts +32 -32
  116. package/types/lucca-front-ng-form-field.d.ts +8 -8
  117. package/types/lucca-front-ng-forms-phone-number-input.d.ts +7 -7
  118. package/types/lucca-front-ng-forms-rich-text-input.d.ts +15 -14
  119. package/types/lucca-front-ng-forms.d.ts +39 -39
  120. package/types/lucca-front-ng-index-table.d.ts +39 -39
  121. package/types/lucca-front-ng-input.d.ts +8 -8
  122. package/types/lucca-front-ng-link.d.ts +4 -4
  123. package/types/lucca-front-ng-mobile-push.d.ts +1 -1
  124. package/types/lucca-front-ng-modal.d.ts +12 -12
  125. package/types/lucca-front-ng-multi-select.d.ts +24 -24
  126. package/types/lucca-front-ng-number-format.d.ts +2 -2
  127. package/types/lucca-front-ng-option.d.ts +18 -18
  128. package/types/lucca-front-ng-page-header.d.ts +1 -1
  129. package/types/lucca-front-ng-popover.d.ts +1 -1
  130. package/types/lucca-front-ng-popover2.d.ts +20 -20
  131. package/types/lucca-front-ng-popup.d.ts +8 -8
  132. package/types/lucca-front-ng-progress-bar.d.ts +1 -1
  133. package/types/lucca-front-ng-read-more.d.ts +6 -6
  134. package/types/lucca-front-ng-scroll-box.d.ts +3 -3
  135. package/types/lucca-front-ng-segmented-control-tabs.d.ts +1 -1
  136. package/types/lucca-front-ng-select.d.ts +12 -12
  137. package/types/lucca-front-ng-sidepanel.d.ts +1 -1
  138. package/types/lucca-front-ng-simple-select.d.ts +11 -11
  139. package/types/lucca-front-ng-skeleton.d.ts +1 -1
  140. package/types/lucca-front-ng-sortable-list.d.ts +8 -8
  141. package/types/lucca-front-ng-time.d.ts +17 -17
  142. package/types/lucca-front-ng-title.d.ts +5 -5
  143. package/types/lucca-front-ng-toast.d.ts +1 -1
  144. package/types/lucca-front-ng-tree-select.d.ts +11 -11
  145. package/types/lucca-front-ng-user-popover.d.ts +6 -6
  146. package/types/lucca-front-ng-user.d.ts +8 -8
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, inject, LOCALE_ID, TemplateRef, ViewContainerRef, Input, Directive, ElementRef, input, computed, HostListener, HostBinding, booleanAttribute, model, output, viewChildren, effect, ChangeDetectionStrategy, ViewEncapsulation, Component, signal, Injector, viewChild, untracked, forwardRef } from '@angular/core';
3
- import { isNil, intlInputOptions, LuClass, ɵeffectWithDeps as _effectWithDeps, PortalDirective } from '@lucca-front/ng/core';
3
+ import { isNil, intlInputOptions, isNotNil, LuClass, ɵeffectWithDeps as _effectWithDeps, PortalDirective } from '@lucca-front/ng/core';
4
4
  import { LuTooltipTriggerDirective } from '@lucca-front/ng/tooltip';
5
5
  import { isSameYear, isSameMonth, isSameDay, startOfDecade, startOfYear, startOfMonth, parse, format, addYears, addMonths, subYears, subMonths, endOfWeek, startOfWeek, sub, add, eachDayOfInterval, endOfMonth, lastDayOfMonth, eachMonthOfInterval, endOfYear, eachYearOfInterval, endOfDecade, startOfDay, endOfDay, isAfter, isWithinInterval, addHours, isBefore, startOfQuarter, subQuarters, endOfQuarter, subWeeks } from 'date-fns';
6
6
  import { getLocaleWeekEndRange, getLocaleFirstDayOfWeek, NgTemplateOutlet } from '@angular/common';
@@ -117,13 +117,13 @@ const modeToPeriodStart = {
117
117
  year: startOfDecade,
118
118
  };
119
119
  function comparePeriods(mode, a, b) {
120
- return modeToComparator[mode](a, b);
120
+ return mode ? modeToComparator[mode](a, b) : false;
121
121
  }
122
122
  function compareCalendarPeriods(mode, a, b) {
123
- return modeToCalendarComparator[mode](a, b);
123
+ return mode ? modeToCalendarComparator[mode](a, b) : false;
124
124
  }
125
125
  function startOfPeriod(mode, date) {
126
- return modeToPeriodStart[mode](date);
126
+ return mode ? modeToPeriodStart[mode](date) : date;
127
127
  }
128
128
  function stringToDateISO(value) {
129
129
  const res = parse(value, DATE_ISO_FORMAT, new Date());
@@ -157,17 +157,19 @@ function transformDateRangeInputToDateRange(value) {
157
157
  if (!isDateRangeInput(value)) {
158
158
  return value;
159
159
  }
160
+ const valueEnd = value.end ? transformDateInputToDate(value.end) : null;
160
161
  return {
161
162
  ...value,
162
163
  start: transformDateInputToDate(value.start),
163
- end: transformDateInputToDate(value.end),
164
+ end: valueEnd,
164
165
  };
165
166
  }
166
167
  function transformDateRangeToDateRangeInput(value) {
168
+ const valueEnd = value.end ? transformDateToDateISO(value.end) : null;
167
169
  return {
168
170
  ...value,
169
171
  start: transformDateToDateISO(value.start),
170
- end: transformDateToDateISO(value.end),
172
+ end: valueEnd,
171
173
  };
172
174
  }
173
175
 
@@ -278,7 +280,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
278
280
  args: ['keydown', ['$event']]
279
281
  }] } });
280
282
 
281
- const MODE_HIERARCHY = ['day', 'month', 'year'];
283
+ const MODE_HIERARCHY = ['day', 'month', 'year', null];
282
284
  class Calendar2Component {
283
285
  #locale;
284
286
  #weekInfo;
@@ -398,7 +400,6 @@ class Calendar2Component {
398
400
  return monthsOfYear
399
401
  .map((month) => {
400
402
  return {
401
- date: month,
402
403
  short: this.#intlMonthsShort.format(month),
403
404
  long: this.#intlMonthsLong.format(month),
404
405
  ...this.dateToCellInfo(month),
@@ -419,7 +420,6 @@ class Calendar2Component {
419
420
  return yearsOfDecade
420
421
  .map((year) => {
421
422
  return {
422
- date: year,
423
423
  ...this.dateToCellInfo(year),
424
424
  name: this.#intlDateYear.format(year),
425
425
  isCurrent: isSameYear(new Date(), year),
@@ -510,7 +510,7 @@ class Calendar2Component {
510
510
  // Is it weekend day? for is-dayOff class toggle
511
511
  const isWeekend = isDayMode && this.#weekInfo.weekend.includes(getIntlWeekDay(date)) && !this.hideWeekend();
512
512
  // Is it first day of month? Mostly used for overflow display logic
513
- const isFirstDayOfMonth = isDayMode && isSameDay(startOfMonth(date), rangeInfo?.range.start);
513
+ const isFirstDayOfMonth = isDayMode && rangeInfo && isSameDay(startOfMonth(date), rangeInfo.range.start);
514
514
  // Is this the current period? Will match if same day as today, or same month in month display, or same year if year display
515
515
  const isCurrent = comparePeriods(this.displayMode(), new Date(), date) && !this.hideToday();
516
516
  // Are we currently in a range that's being created (start date selected, end date is being hovered)
@@ -530,7 +530,7 @@ class Calendar2Component {
530
530
  }
531
531
  const hoveredRange = {
532
532
  start,
533
- end: startOfDay(this.dateHovered()),
533
+ end: startOfDay(this.dateHovered() ?? 0),
534
534
  };
535
535
  // If start is after end, fix this by inverting the two, we always want to work with start before end
536
536
  if (isAfter(hoveredRange.start, hoveredRange.end)) {
@@ -553,8 +553,8 @@ class Calendar2Component {
553
553
  isProgressStart = !isOverflow && comparePeriods(this.displayMode(), date, hoveredRange.start);
554
554
  isProgressEnd = !isOverflow && comparePeriods(this.displayMode(), date, hoveredRange.end);
555
555
  // This is the case where you clicked a first date and then are hovering it, which requires a specific case for CSS
556
- if (isSameDay(rangeInfo.range.start, this.dateHovered())) {
557
- isSingleDayInProgress = !isOverflow && isSameDay(hoveredRange.start, hoveredRange.end) && isSameDay(hoveredRange.start, this.dateHovered());
556
+ if (isSameDay(rangeInfo.range.start, this.dateHovered() ?? 0)) {
557
+ isSingleDayInProgress = !isOverflow && isSameDay(hoveredRange.start, hoveredRange.end) && isSameDay(hoveredRange.start, this.dateHovered() ?? 0);
558
558
  }
559
559
  }
560
560
  const isSelected = status.selected || (!!rangeInfo?.range && !isInProgress);
@@ -575,8 +575,8 @@ class Calendar2Component {
575
575
  'is-daysOff': isWeekend,
576
576
  'is-overflow': isOverflow,
577
577
  'is-current': isCurrent,
578
- 'is-start': !isOverflow && (rangeInfo?.isStart || status.selected) && !isInProgress,
579
- 'is-end': !isOverflow && (rangeInfo?.isEnd || status.selected) && !isInProgress,
578
+ 'is-start': Boolean(!isOverflow && (rangeInfo?.isStart || status.selected) && !isInProgress),
579
+ 'is-end': Boolean(!isOverflow && (rangeInfo?.isEnd || status.selected) && !isInProgress),
580
580
  'is-selected': isSelected,
581
581
  // Range in progress statuses
582
582
  'is-selectionInProgress': isProgressBody,
@@ -599,16 +599,16 @@ class Calendar2Component {
599
599
  }
600
600
  else if (this.dateHovered() !== null) {
601
601
  // Nominal case: end is after start
602
- if (isAfter(this.dateHovered(), startOfDay(range.start))) {
602
+ if (isAfter(this.dateHovered() ?? 0, startOfDay(range.start))) {
603
603
  return isWithinInterval(date, {
604
604
  start: startOfDay(range.start),
605
- end: endOfDay(this.dateHovered()),
605
+ end: endOfDay(this.dateHovered() ?? 0),
606
606
  });
607
607
  }
608
608
  else {
609
609
  // When user clicked end date first and now wants to select a start date
610
610
  return isWithinInterval(date, {
611
- start: startOfDay(this.dateHovered()),
611
+ start: startOfDay(this.dateHovered() ?? 0),
612
612
  end: endOfDay(range.start),
613
613
  });
614
614
  }
@@ -630,7 +630,7 @@ class Calendar2Component {
630
630
  return null;
631
631
  }
632
632
  const isStart = range && isSameDay(date, range.start);
633
- const isEnd = range && range.end && isSameDay(date, range.end);
633
+ const isEnd = Boolean(range && range.end && isSameDay(date, range.end));
634
634
  return {
635
635
  range,
636
636
  isStart,
@@ -742,7 +742,7 @@ class AbstractDateComponent {
742
742
  this.min = input(new Date('1/1/1000'), { ...(ngDevMode ? { debugName: "min" } : {}), transform: transformDateInputToDate });
743
743
  this.max = input(null, { ...(ngDevMode ? { debugName: "max" } : {}), transform: transformDateInputToDate });
744
744
  this.focusedDate = input(null, { ...(ngDevMode ? { debugName: "focusedDate" } : {}), transform: transformDateInputToDate });
745
- this.calendarMode = model(...(ngDevMode ? [undefined, { debugName: "calendarMode" }] : []));
745
+ this.calendarMode = model(null, ...(ngDevMode ? [{ debugName: "calendarMode" }] : []));
746
746
  this.panelOpened = output();
747
747
  this.panelClosed = output();
748
748
  this.dateFormatLocalized = computed(() => getLocalizedDateFormat(this.locale, this.mode()), ...(ngDevMode ? [{ debugName: "dateFormatLocalized" }] : []));
@@ -759,37 +759,39 @@ class AbstractDateComponent {
759
759
  return this.isAfterMin(date, mode) && this.isBeforeMax(date, mode);
760
760
  }
761
761
  isAfterMin(date, mode) {
762
- if (!this.min()) {
762
+ const min = this.min();
763
+ if (!min) {
763
764
  return true;
764
765
  }
765
766
  switch (mode) {
766
767
  case 'day':
767
- return this.min().getTime() <= date.getTime();
768
+ return min.getTime() <= date.getTime();
768
769
  case 'month':
769
- return isBefore(startOfMonth(this.min()), startOfMonth(date)) || isSameMonth(this.min(), date);
770
+ return isBefore(startOfMonth(min), startOfMonth(date)) || isSameMonth(min, date);
770
771
  case 'year':
771
- return this.min().getFullYear() <= date.getFullYear();
772
+ return min.getFullYear() <= date.getFullYear();
772
773
  default:
773
774
  return true;
774
775
  }
775
776
  }
776
777
  isBeforeMax(date, mode) {
777
- if (!this.max()) {
778
- return true;
779
- }
780
- switch (mode) {
781
- case 'day':
782
- return this.max().getTime() >= date.getTime();
783
- case 'month':
784
- return isAfter(startOfMonth(this.max()), startOfMonth(date)) || isSameMonth(this.max(), date);
785
- case 'year':
786
- return this.max().getFullYear() >= date.getFullYear();
787
- default:
788
- return true;
778
+ const max = this.max();
779
+ if (max) {
780
+ switch (mode) {
781
+ case 'day':
782
+ return max.getTime() >= date.getTime();
783
+ case 'month':
784
+ return isAfter(startOfMonth(max), startOfMonth(date)) || isSameMonth(max, date);
785
+ case 'year':
786
+ return max.getFullYear() >= date.getFullYear();
787
+ default:
788
+ return true;
789
+ }
789
790
  }
791
+ return true;
790
792
  }
791
793
  isValidDate(date) {
792
- return !!date && !isNaN(date.getTime());
794
+ return isNotNil(date) && !isNaN(date.getTime());
793
795
  }
794
796
  prev(mode) {
795
797
  this.move(-1, mode);
@@ -807,15 +809,15 @@ class AbstractDateComponent {
807
809
  switch (mode) {
808
810
  case 'year':
809
811
  this.currentDate.set(addYears(this.currentDate(), direction * 10));
810
- this.tabbableDate.set(addYears(this.tabbableDate(), direction * 10));
812
+ this.tabbableDate.set(addYears(this.tabbableDate() ?? 0, direction * 10));
811
813
  break;
812
814
  case 'month':
813
815
  this.currentDate.set(addYears(this.currentDate(), direction));
814
- this.tabbableDate.set(addYears(this.tabbableDate(), direction));
816
+ this.tabbableDate.set(addYears(this.tabbableDate() ?? 0, direction));
815
817
  break;
816
818
  case 'day':
817
819
  this.currentDate.set(addMonths(this.currentDate(), direction));
818
- this.tabbableDate.set(addMonths(this.tabbableDate(), direction));
820
+ this.tabbableDate.set(addMonths(this.tabbableDate() ?? 0, direction));
819
821
  break;
820
822
  }
821
823
  }
@@ -842,7 +844,7 @@ class DateInputComponent extends AbstractDateComponent {
842
844
  #defaultClearable;
843
845
  #defaultFilterPillClearable;
844
846
  get isNavigationButtonFocused() {
845
- return [this.previousButton()?.nativeElement, this.nextButton()?.nativeElement].includes(document.activeElement);
847
+ return [this.previousButton()?.nativeElement, this.nextButton()?.nativeElement].includes(document.activeElement || undefined);
846
848
  }
847
849
  constructor() {
848
850
  super();
@@ -876,7 +878,8 @@ class DateInputComponent extends AbstractDateComponent {
876
878
  return textInput;
877
879
  }
878
880
  }
879
- if (this.selectedDate() && this.isValidDate(this.selectedDate())) {
881
+ const selectedDate = this.selectedDate();
882
+ if (selectedDate && this.isValidDate(selectedDate)) {
880
883
  let formatter;
881
884
  switch (this.mode()) {
882
885
  case 'day':
@@ -889,7 +892,7 @@ class DateInputComponent extends AbstractDateComponent {
889
892
  formatter = this.intlDateTimeFormatYear;
890
893
  break;
891
894
  }
892
- return formatter.format(this.selectedDate());
895
+ return formatter.format(selectedDate);
893
896
  }
894
897
  // If we are initializing the component, we don't want to display the value
895
898
  if (textInput === 'ɵ') {
@@ -901,10 +904,11 @@ class DateInputComponent extends AbstractDateComponent {
901
904
  this.userTextInput = signal('ɵ', ...(ngDevMode ? [{ debugName: "userTextInput" }] : []));
902
905
  this.combinedGetCellInfo = (date, mode) => {
903
906
  const infoFromInput = this.getCellInfo()?.(date, mode);
907
+ const selectedDate = this.selectedDate();
904
908
  return {
905
909
  classes: [...(infoFromInput?.classes || [])],
906
910
  disabled: infoFromInput?.disabled || !this.isInMinMax(date, mode),
907
- selected: this.selectedDate() && this.calendarMode() === mode && comparePeriods(mode, date, this.selectedDate()),
911
+ selected: isNotNil(selectedDate) && this.calendarMode() === mode && comparePeriods(mode, date, selectedDate),
908
912
  label: infoFromInput?.label,
909
913
  };
910
914
  };
@@ -942,6 +946,7 @@ class DateInputComponent extends AbstractDateComponent {
942
946
  }
943
947
  catch {
944
948
  /* not a correct date */
949
+ parsed = null;
945
950
  }
946
951
  if (parsed instanceof Date && parsed.getFullYear() > 999) {
947
952
  this.selectedDate.set(startOfDay(parsed));
@@ -975,8 +980,8 @@ class DateInputComponent extends AbstractDateComponent {
975
980
  }
976
981
  });
977
982
  _effectWithDeps([this.calendarMode, this.tabbableDate], (calendarMode, tabbableDate) => {
978
- if (tabbableDate && !comparePeriods(calendarMode, tabbableDate, this.currentDate())) {
979
- this.currentDate.set(startOfPeriod(calendarMode, tabbableDate));
983
+ if (tabbableDate && !comparePeriods(calendarMode ?? null, tabbableDate, this.currentDate())) {
984
+ this.currentDate.set(startOfPeriod(calendarMode ?? null, tabbableDate));
980
985
  }
981
986
  if (!this.isNavigationButtonFocused && !this.inputFocused()) {
982
987
  this.calendar()?.blurTabbableDate();
@@ -1036,7 +1041,7 @@ class DateInputComponent extends AbstractDateComponent {
1036
1041
  validate(control) {
1037
1042
  // null is not an error but means we'll skip everything else, we'll let the presence of a
1038
1043
  // Validators.required (or not) decide if it's an error.
1039
- if (control.value === null || control.value === undefined) {
1044
+ if (isNil(control.value)) {
1040
1045
  return null;
1041
1046
  }
1042
1047
  const date = transformDateInputToDate(control.value);
@@ -1072,7 +1077,7 @@ class DateInputComponent extends AbstractDateComponent {
1072
1077
  if (this.initialValue() === undefined) {
1073
1078
  this.initialValue.set(_date);
1074
1079
  }
1075
- if (date != null) {
1080
+ if (isNotNil(date) && isNotNil(_date)) {
1076
1081
  const start = startOfDay(_date);
1077
1082
  this.dateFromWriteValue.set(start);
1078
1083
  this.selectedDate.set(start);
@@ -1089,10 +1094,10 @@ class DateInputComponent extends AbstractDateComponent {
1089
1094
  }
1090
1095
  setDisabledState(isDisabled) {
1091
1096
  this.filterPillDisabled.set(isDisabled);
1092
- super.setDisabledState(isDisabled);
1097
+ super.setDisabledState?.(isDisabled);
1093
1098
  }
1094
1099
  reset() {
1095
- const newValue = this.clearBehavior() === 'reset' ? this.initialValue() : null;
1100
+ const newValue = this.clearBehavior() === 'reset' ? (this.initialValue() ?? null) : null;
1096
1101
  this.dateFromWriteValue.set(newValue);
1097
1102
  this.selectedDate.set(newValue);
1098
1103
  return newValue;
@@ -1247,7 +1252,7 @@ class DateRangeInputComponent extends AbstractDateComponent {
1247
1252
  #defaultClearable;
1248
1253
  #defaultFilterPillClearable;
1249
1254
  get isNavigationButtonFocused() {
1250
- return [this.previousButton()?.nativeElement, this.nextButton()?.nativeElement].includes(document.activeElement);
1255
+ return [this.previousButton()?.nativeElement, this.nextButton()?.nativeElement].includes(document.activeElement ?? undefined);
1251
1256
  }
1252
1257
  constructor() {
1253
1258
  super();
@@ -1324,8 +1329,9 @@ class DateRangeInputComponent extends AbstractDateComponent {
1324
1329
  if (inputValue !== 'ɵ') {
1325
1330
  return inputValue;
1326
1331
  }
1327
- if (this.selectedRange()?.start && this.isValidDate(this.selectedRange()?.start)) {
1328
- return this.getDateLabelForInput(this.selectedRange()?.start);
1332
+ const range = this.selectedRange();
1333
+ if (range?.start && this.isValidDate(range.start)) {
1334
+ return this.getDateLabelForInput(range.start);
1329
1335
  }
1330
1336
  return '';
1331
1337
  }, ...(ngDevMode ? [{ debugName: "startLabel" }] : []));
@@ -1334,8 +1340,9 @@ class DateRangeInputComponent extends AbstractDateComponent {
1334
1340
  if (inputValue !== 'ɵ') {
1335
1341
  return inputValue;
1336
1342
  }
1337
- if (this.selectedRange()?.end && this.isValidDate(this.selectedRange()?.end)) {
1338
- return this.getDateLabelForInput(this.selectedRange()?.end);
1343
+ const range = this.selectedRange();
1344
+ if (range?.end && this.isValidDate(range.end)) {
1345
+ return this.getDateLabelForInput(range.end);
1339
1346
  }
1340
1347
  return '';
1341
1348
  }, ...(ngDevMode ? [{ debugName: "endLabel" }] : []));
@@ -1431,14 +1438,15 @@ class DateRangeInputComponent extends AbstractDateComponent {
1431
1438
  this.fixOrderIfNeeded();
1432
1439
  }
1433
1440
  fixOrderIfNeeded() {
1434
- if (this.selectedRange() && isAfter(this.selectedRange()?.start, this.selectedRange()?.end)) {
1435
- const range = this.selectedRange();
1436
- this.selectedRange.set({
1441
+ const range = this.selectedRange();
1442
+ if (range && range.end && isAfter(range.start, range.end)) {
1443
+ const swappedRange = {
1437
1444
  ...range,
1438
1445
  end: range.start,
1439
1446
  start: range.end,
1440
- });
1441
- this.#onChange?.(this.selectedRange());
1447
+ };
1448
+ this.selectedRange.set(swappedRange);
1449
+ this.#onChange?.(swappedRange);
1442
1450
  }
1443
1451
  }
1444
1452
  tabbableDateChange(date, calendarIndex) {
@@ -1456,18 +1464,21 @@ class DateRangeInputComponent extends AbstractDateComponent {
1456
1464
  // Once popover is opened, aka in the next CD cycle, focus current tabbable date
1457
1465
  setTimeout(() => {
1458
1466
  this.focusedCalendarIndex.set(0);
1459
- if (propertyToFocus && this.selectedRange()?.[propertyToFocus]) {
1467
+ const selectedRange = this.selectedRange();
1468
+ if (propertyToFocus && selectedRange && selectedRange[propertyToFocus]) {
1460
1469
  // Specific case: if range is on a single month, focus on it on left calendar
1461
1470
  // Same goes for focus on start date, we want it on left panel
1462
- if (propertyToFocus === 'start' || compareCalendarPeriods(this.mode(), this.selectedRange()?.start, this.selectedRange()?.end)) {
1463
- this.currentDate.set(this.selectedRange()?.[propertyToFocus]);
1464
- this.tabbableDate.set(this.selectedRange()?.[propertyToFocus]);
1471
+ if (propertyToFocus === 'start' || (selectedRange.end && compareCalendarPeriods(this.mode(), selectedRange.start, selectedRange.end))) {
1472
+ this.currentDate.set(selectedRange[propertyToFocus]);
1473
+ this.tabbableDate.set(selectedRange[propertyToFocus]);
1465
1474
  }
1466
1475
  else {
1467
1476
  // Compute the date to use for proper focus on left panel, minus one calendar on focus date basically
1468
- const leftPanelFocus = this.selectedRange()?.end;
1469
- this.currentDate.set(leftPanelFocus);
1470
- this.tabbableDate.set(leftPanelFocus);
1477
+ const leftPanelFocus = selectedRange.end;
1478
+ if (leftPanelFocus) {
1479
+ this.currentDate.set(leftPanelFocus);
1480
+ this.tabbableDate.set(leftPanelFocus);
1481
+ }
1471
1482
  }
1472
1483
  }
1473
1484
  if (focusTabbableDate) {
@@ -1476,11 +1487,14 @@ class DateRangeInputComponent extends AbstractDateComponent {
1476
1487
  });
1477
1488
  }
1478
1489
  dateClicked(date, popoverRef) {
1479
- if (this.selectedRange() === null) {
1480
- this.selectedRange.set({
1490
+ const selectedRange = this.selectedRange();
1491
+ let newRange;
1492
+ if (selectedRange === null) {
1493
+ newRange = {
1481
1494
  start: date,
1482
1495
  scope: this.mode(),
1483
- });
1496
+ };
1497
+ this.selectedRange.set(newRange);
1484
1498
  this.editedField.set(1);
1485
1499
  this.highlightedField.set(1);
1486
1500
  }
@@ -1488,20 +1502,21 @@ class DateRangeInputComponent extends AbstractDateComponent {
1488
1502
  // If we're editing end field
1489
1503
  if (this.editedField() === 1) {
1490
1504
  // If end is before start, invert them
1491
- if (isBefore(date, this.selectedRange()?.start)) {
1492
- this.selectedRange.set({
1505
+ if (isBefore(date, selectedRange.start)) {
1506
+ newRange = {
1493
1507
  start: date,
1494
1508
  scope: this.mode(),
1495
- end: this.selectedRange().start,
1496
- });
1509
+ end: selectedRange.start,
1510
+ };
1497
1511
  }
1498
1512
  else {
1499
- this.selectedRange.set({
1500
- ...this.selectedRange(),
1513
+ newRange = {
1514
+ ...selectedRange,
1501
1515
  scope: this.mode(),
1502
1516
  end: date,
1503
- });
1517
+ };
1504
1518
  }
1519
+ this.selectedRange.set(newRange);
1505
1520
  popoverRef?.close();
1506
1521
  this.filterPillPopoverCloseFn?.();
1507
1522
  this.endTextInputRef()?.nativeElement.focus();
@@ -1511,25 +1526,26 @@ class DateRangeInputComponent extends AbstractDateComponent {
1511
1526
  else {
1512
1527
  // Else, we're editing start field
1513
1528
  // If start is after end, invert them
1514
- if (isAfter(date, this.selectedRange()?.end)) {
1515
- this.selectedRange.set({
1529
+ if (selectedRange.end && isAfter(date, selectedRange.end)) {
1530
+ newRange = {
1516
1531
  start: date,
1517
1532
  scope: this.mode(),
1518
- });
1533
+ };
1519
1534
  }
1520
1535
  else {
1521
- this.selectedRange.set({
1522
- ...this.selectedRange(),
1536
+ newRange = {
1537
+ ...selectedRange,
1523
1538
  start: date,
1524
1539
  scope: this.mode(),
1525
- });
1540
+ };
1526
1541
  }
1542
+ this.selectedRange.set(newRange);
1527
1543
  this.editedField.set(1);
1528
1544
  this.highlightedField.set(1);
1529
1545
  this.dateHovered.set(null);
1530
1546
  }
1531
1547
  }
1532
- this.#onChange?.(this.selectedRange());
1548
+ this.#onChange?.(newRange);
1533
1549
  }
1534
1550
  arrowDown(popoverRef, fieldToFocus) {
1535
1551
  this.openPopover(popoverRef, fieldToFocus, true);
@@ -1555,9 +1571,9 @@ class DateRangeInputComponent extends AbstractDateComponent {
1555
1571
  }
1556
1572
  const _dateRange = transformDateRangeInputToDateRange(dateRange);
1557
1573
  if (isNil(this.initialValue())) {
1558
- this.selectedRange.set(this.clearBehavior() === 'reset' ? this.initialValue() : _dateRange);
1574
+ this.selectedRange.set(this.clearBehavior() === 'reset' ? (this.initialValue() ?? null) : _dateRange);
1559
1575
  }
1560
- if (dateRange != null) {
1576
+ if (isNotNil(dateRange)) {
1561
1577
  this.selectedRange.set(_dateRange);
1562
1578
  this.currentDate.set(startOfDay(dateRange.start));
1563
1579
  }
@@ -1569,10 +1585,10 @@ class DateRangeInputComponent extends AbstractDateComponent {
1569
1585
  }
1570
1586
  setDisabledState(isDisabled) {
1571
1587
  this.filterPillDisabled.set(isDisabled);
1572
- super.setDisabledState(isDisabled);
1588
+ super.setDisabledState?.(isDisabled);
1573
1589
  }
1574
1590
  clear() {
1575
- const newValue = this.clearBehavior() === 'reset' ? this.initialValue() : null;
1591
+ const newValue = this.clearBehavior() === 'reset' ? (this.initialValue() ?? null) : null;
1576
1592
  this.selectedRange.set(newValue);
1577
1593
  this.#onChange?.(this.selectedRange());
1578
1594
  this.onTouched?.();