diff --git a/projects/demo/src/modules/components/calendar-range/examples/5/index.html b/projects/demo/src/modules/components/calendar-range/examples/5/index.html
new file mode 100644
index 000000000000..61834ba374a6
--- /dev/null
+++ b/projects/demo/src/modules/components/calendar-range/examples/5/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+ You are seeing {{ selected }}.
+
+
diff --git a/projects/demo/src/modules/components/calendar-range/examples/5/index.ts b/projects/demo/src/modules/components/calendar-range/examples/5/index.ts
new file mode 100644
index 000000000000..d22fd6064097
--- /dev/null
+++ b/projects/demo/src/modules/components/calendar-range/examples/5/index.ts
@@ -0,0 +1,80 @@
+import {Component} from '@angular/core';
+import {changeDetection} from '@demo/emulate/change-detection';
+import {encapsulation} from '@demo/emulate/encapsulation';
+import {TuiDay, TuiDayRange} from '@taiga-ui/cdk';
+import {TuiDayRangePeriod} from '@taiga-ui/kit';
+
+const today = TuiDay.currentLocal();
+const startOfWeek = today.append({day: -today.dayOfWeek()});
+const startOfMonth = today.append({day: 1 - today.day});
+const startOfQuarter = startOfMonth.append({month: -(startOfMonth.month % 3)});
+
+@Component({
+ selector: 'tui-calendar-range-example-5',
+ templateUrl: './index.html',
+ encapsulation,
+ changeDetection,
+})
+export class TuiCalendarRangeExample5 {
+ readonly items = [
+ new TuiDayRangePeriod(
+ new TuiDayRange(today.append({day: -30}), today),
+ 'Default',
+ ),
+ new TuiDayRangePeriod(new TuiDayRange(startOfWeek, today), 'Week'),
+ new TuiDayRangePeriod(new TuiDayRange(startOfMonth, today), 'Month'),
+ new TuiDayRangePeriod(new TuiDayRange(startOfQuarter, today), 'Quarter'),
+ ];
+
+ selected: TuiDayRangePeriod | null = this.default;
+ value: TuiDayRange | null = this.default.range;
+
+ get default(): TuiDayRangePeriod {
+ return this.items[0];
+ }
+
+ get isDefault(): boolean {
+ return this.selected === this.default;
+ }
+
+ get isSelected(): boolean {
+ return !!this.items.find(item => item === this.selected);
+ }
+
+ get isLastVisible(): boolean {
+ return this.selected === this.items[this.items.length - 1];
+ }
+
+ get opposite(): TuiDayRangePeriod | null {
+ if (!this.isSelected) {
+ return null;
+ }
+
+ switch (this.selected) {
+ case this.default:
+ return null;
+ case this.items[1]:
+ return this.items[2];
+ case this.items[2]:
+ return this.items[3];
+ case this.items[3]:
+ return null;
+ default:
+ return null;
+ }
+ }
+
+ onValue(value: TuiDayRange | null): void {
+ this.value = value;
+ }
+
+ reset(): void {
+ this.selected = this.default;
+ this.value = this.selected.range;
+ }
+
+ toggle(): void {
+ this.selected = this.opposite;
+ this.value = this.selected?.range ?? null;
+ }
+}
diff --git a/projects/kit/components/calendar-range/calendar-range.component.ts b/projects/kit/components/calendar-range/calendar-range.component.ts
index e6ac62dcbd77..a90d55d8e29d 100644
--- a/projects/kit/components/calendar-range/calendar-range.component.ts
+++ b/projects/kit/components/calendar-range/calendar-range.component.ts
@@ -48,6 +48,11 @@ import {takeUntil} from 'rxjs/operators';
providers: [TuiDestroyService],
})
export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax {
+ /**
+ * @deprecated use `item`
+ */
+ private selectedPeriod: TuiDayRangePeriod | null = null;
+
@Input()
defaultViewedMonth: TuiMonth = TuiMonth.currentLocal();
@@ -75,14 +80,18 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax
@Input()
value: TuiDayRange | null = null;
+ @Input()
+ item: TuiDayRangePeriod | null = null;
+
@Output()
readonly valueChange = new EventEmitter();
+ @Output()
+ readonly itemChange = new EventEmitter();
+
availableRange: TuiDayRange | null = null;
previousValue: TuiDayRange | null = null;
- selectedActivePeriod: TuiDayRangePeriod | null = null;
-
readonly maxLengthMapper = MAX_DAY_RANGE_LENGTH_MAPPER;
get computedMin(): TuiDay {
@@ -93,6 +102,20 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax
return this.max ?? TUI_LAST_DAY;
}
+ /**
+ * @deprecated use `item`
+ */
+ get selectedActivePeriod(): TuiDayRangePeriod | null {
+ return this.selectedPeriod;
+ }
+
+ /**
+ * @deprecated use `item`
+ */
+ set selectedActivePeriod(period: TuiDayRangePeriod | null) {
+ this.selectedPeriod = period;
+ }
+
constructor(
@Optional()
@Inject(TUI_CALENDAR_DATE_STREAM)
@@ -180,17 +203,22 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax
if (value === null || !value.isSingleDay) {
this.value = new TuiDayRange(day, day);
this.availableRange = this.findAvailableRange();
+ this.itemChange.emit(this.findItemByDayRange(this.value));
return;
}
- this.updateValue(TuiDayRange.sort(value.from, day));
+ const sortedDayRange = TuiDayRange.sort(value.from, day);
+
+ this.updateValue(sortedDayRange);
+ this.itemChange.emit(this.findItemByDayRange(sortedDayRange));
}
onItemSelect(item: TuiDayRangePeriod | string): void {
if (!tuiIsString(item)) {
this.selectedActivePeriod = item;
this.updateValue(item.range.dayLimit(this.min, this.max));
+ this.itemChange.emit(item);
return;
}
@@ -198,6 +226,7 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax
if (this.activePeriod !== null) {
this.selectedActivePeriod = null;
this.updateValue(null);
+ this.itemChange.emit(null);
}
}
@@ -208,6 +237,7 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax
private get activePeriod(): TuiDayRangePeriod | null {
return (
+ this.item ??
this.selectedActivePeriod ??
(this.items.find(item =>
tuiNullableSame(
@@ -297,4 +327,8 @@ export class TuiCalendarRangeComponent implements TuiWithOptionalMinMax
return new TuiDayRange(from, to);
}
+
+ private findItemByDayRange(dayRange: TuiDayRange): TuiDayRangePeriod | null {
+ return this.items.find(item => dayRange.daySame(item.range)) ?? null;
+ }
}