@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.
- package/fesm2022/lucca-front-ng-api.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-callout.mjs +10 -4
- package/fesm2022/lucca-front-ng-callout.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-clear.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-comment.mjs +1 -1
- package/fesm2022/lucca-front-ng-comment.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-api.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-department.mjs +7 -5
- package/fesm2022/lucca-front-ng-core-select-department.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-establishment.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-job-qualification.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-occupation-category.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-user.mjs +16 -11
- package/fesm2022/lucca-front-ng-core-select-user.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select.mjs +46 -18
- package/fesm2022/lucca-front-ng-core-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core.mjs +11 -6
- package/fesm2022/lucca-front-ng-core.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-data-table.mjs +31 -15
- package/fesm2022/lucca-front-ng-data-table.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-date.mjs +10 -6
- package/fesm2022/lucca-front-ng-date.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-date2.mjs +104 -88
- package/fesm2022/lucca-front-ng-date2.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-department.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-dialog.mjs +36 -25
- package/fesm2022/lucca-front-ng-dialog.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-divider.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-empty-state.mjs +5 -4
- package/fesm2022/lucca-front-ng-empty-state.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-establishment.mjs +3 -3
- package/fesm2022/lucca-front-ng-establishment.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-fancy-box.mjs +1 -1
- package/fesm2022/lucca-front-ng-fancy-box.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-file-upload.mjs +5 -3
- package/fesm2022/lucca-front-ng-file-upload.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-filter-pills.mjs +3 -3
- package/fesm2022/lucca-front-ng-filter-pills.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-form-field.mjs +3 -3
- package/fesm2022/lucca-front-ng-form-field.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-formly.mjs +1 -1
- package/fesm2022/lucca-front-ng-formly.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms-phone-number-input.mjs +26 -21
- package/fesm2022/lucca-front-ng-forms-phone-number-input.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-html.mjs +15 -13
- package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-html.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-plain-text.mjs +5 -3
- package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-plain-text.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs +26 -19
- package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms.mjs +3 -3
- package/fesm2022/lucca-front-ng-forms.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-highlight-data.mjs +1 -1
- package/fesm2022/lucca-front-ng-highlight-data.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-index-table.mjs +5 -5
- package/fesm2022/lucca-front-ng-index-table.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-input.mjs +6 -5
- package/fesm2022/lucca-front-ng-input.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-link.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-mobile-push.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-modal.mjs +5 -5
- package/fesm2022/lucca-front-ng-modal.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-multi-select.mjs +27 -14
- package/fesm2022/lucca-front-ng-multi-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-number-format.mjs +9 -8
- package/fesm2022/lucca-front-ng-number-format.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-option.mjs +7 -3
- package/fesm2022/lucca-front-ng-option.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-page-header.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-popover.mjs +6 -2
- package/fesm2022/lucca-front-ng-popover.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-popover2.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-popup.mjs +1 -1
- package/fesm2022/lucca-front-ng-popup.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-progress-bar.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-read-more.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-scroll-box.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-scroll.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-segmented-control-tabs.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-select.mjs +5 -4
- package/fesm2022/lucca-front-ng-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-sidepanel.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-simple-select.mjs +11 -8
- package/fesm2022/lucca-front-ng-simple-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-skeleton.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-sortable-list.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-time.mjs +2 -2
- package/fesm2022/lucca-front-ng-time.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-title.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-toast.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-tree-select.mjs +11 -10
- package/fesm2022/lucca-front-ng-tree-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-user-popover.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-user.mjs +3 -3
- package/fesm2022/lucca-front-ng-user.mjs.map +1 -1
- package/package.json +4 -4
- package/types/lucca-front-ng-api.d.ts +9 -9
- package/types/lucca-front-ng-clear.d.ts +1 -1
- package/types/lucca-front-ng-core-select-api.d.ts +14 -14
- package/types/lucca-front-ng-core-select-department.d.ts +10 -10
- package/types/lucca-front-ng-core-select-establishment.d.ts +12 -12
- package/types/lucca-front-ng-core-select-job-qualification.d.ts +6 -6
- package/types/lucca-front-ng-core-select-occupation-category.d.ts +6 -6
- package/types/lucca-front-ng-core-select-user.d.ts +19 -19
- package/types/lucca-front-ng-core-select.d.ts +53 -53
- package/types/lucca-front-ng-core.d.ts +10 -9
- package/types/lucca-front-ng-data-table.d.ts +40 -40
- package/types/lucca-front-ng-date.d.ts +2 -2
- package/types/lucca-front-ng-date2.d.ts +93 -93
- package/types/lucca-front-ng-department.d.ts +2 -2
- package/types/lucca-front-ng-dialog.d.ts +4 -4
- package/types/lucca-front-ng-divider.d.ts +1 -1
- package/types/lucca-front-ng-establishment.d.ts +9 -9
- package/types/lucca-front-ng-file-upload.d.ts +17 -17
- package/types/lucca-front-ng-filter-pills.d.ts +32 -32
- package/types/lucca-front-ng-form-field.d.ts +8 -8
- package/types/lucca-front-ng-forms-phone-number-input.d.ts +7 -7
- package/types/lucca-front-ng-forms-rich-text-input.d.ts +15 -14
- package/types/lucca-front-ng-forms.d.ts +39 -39
- package/types/lucca-front-ng-index-table.d.ts +39 -39
- package/types/lucca-front-ng-input.d.ts +8 -8
- package/types/lucca-front-ng-link.d.ts +4 -4
- package/types/lucca-front-ng-mobile-push.d.ts +1 -1
- package/types/lucca-front-ng-modal.d.ts +12 -12
- package/types/lucca-front-ng-multi-select.d.ts +24 -24
- package/types/lucca-front-ng-number-format.d.ts +2 -2
- package/types/lucca-front-ng-option.d.ts +18 -18
- package/types/lucca-front-ng-page-header.d.ts +1 -1
- package/types/lucca-front-ng-popover.d.ts +1 -1
- package/types/lucca-front-ng-popover2.d.ts +20 -20
- package/types/lucca-front-ng-popup.d.ts +8 -8
- package/types/lucca-front-ng-progress-bar.d.ts +1 -1
- package/types/lucca-front-ng-read-more.d.ts +6 -6
- package/types/lucca-front-ng-scroll-box.d.ts +3 -3
- package/types/lucca-front-ng-segmented-control-tabs.d.ts +1 -1
- package/types/lucca-front-ng-select.d.ts +12 -12
- package/types/lucca-front-ng-sidepanel.d.ts +1 -1
- package/types/lucca-front-ng-simple-select.d.ts +11 -11
- package/types/lucca-front-ng-skeleton.d.ts +1 -1
- package/types/lucca-front-ng-sortable-list.d.ts +8 -8
- package/types/lucca-front-ng-time.d.ts +17 -17
- package/types/lucca-front-ng-title.d.ts +5 -5
- package/types/lucca-front-ng-toast.d.ts +1 -1
- package/types/lucca-front-ng-tree-select.d.ts +11 -11
- package/types/lucca-front-ng-user-popover.d.ts +6 -6
- 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:
|
|
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:
|
|
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
|
|
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 ? [
|
|
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
|
-
|
|
762
|
+
const min = this.min();
|
|
763
|
+
if (!min) {
|
|
763
764
|
return true;
|
|
764
765
|
}
|
|
765
766
|
switch (mode) {
|
|
766
767
|
case 'day':
|
|
767
|
-
return
|
|
768
|
+
return min.getTime() <= date.getTime();
|
|
768
769
|
case 'month':
|
|
769
|
-
return isBefore(startOfMonth(
|
|
770
|
+
return isBefore(startOfMonth(min), startOfMonth(date)) || isSameMonth(min, date);
|
|
770
771
|
case 'year':
|
|
771
|
-
return
|
|
772
|
+
return min.getFullYear() <= date.getFullYear();
|
|
772
773
|
default:
|
|
773
774
|
return true;
|
|
774
775
|
}
|
|
775
776
|
}
|
|
776
777
|
isBeforeMax(date, mode) {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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
|
|
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
|
|
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
|
-
|
|
1328
|
-
|
|
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
|
-
|
|
1338
|
-
|
|
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
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
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
|
|
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
|
-
|
|
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(),
|
|
1463
|
-
this.currentDate.set(
|
|
1464
|
-
this.tabbableDate.set(
|
|
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 =
|
|
1469
|
-
|
|
1470
|
-
|
|
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
|
-
|
|
1480
|
-
|
|
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,
|
|
1492
|
-
|
|
1505
|
+
if (isBefore(date, selectedRange.start)) {
|
|
1506
|
+
newRange = {
|
|
1493
1507
|
start: date,
|
|
1494
1508
|
scope: this.mode(),
|
|
1495
|
-
end:
|
|
1496
|
-
}
|
|
1509
|
+
end: selectedRange.start,
|
|
1510
|
+
};
|
|
1497
1511
|
}
|
|
1498
1512
|
else {
|
|
1499
|
-
|
|
1500
|
-
...
|
|
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,
|
|
1515
|
-
|
|
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
|
-
|
|
1522
|
-
...
|
|
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?.(
|
|
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
|
|
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?.();
|