From f1cafa8f95e7c0029995d077ceebd89ca66ed3e6 Mon Sep 17 00:00:00 2001 From: Maksim Ivanov Date: Wed, 11 Oct 2023 19:08:44 +0300 Subject: [PATCH] feat(core): support `readonly TuiDay[]` in `calendar` (#5574) --- .../components/calendar/calendar.component.ts | 6 +++--- .../primitive-calendar.component.ts | 20 +++++++++++++------ .../primitive-year-picker.component.ts | 15 +++++++++----- .../components/calendar/calendar.component.ts | 5 +++++ .../components/calendar/calendar.module.ts | 2 ++ .../calendar/calendar.template.html | 8 ++++++++ .../components/calendar/examples/6/index.html | 5 +++++ .../components/calendar/examples/6/index.ts | 20 +++++++++++++++++++ 8 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 projects/demo/src/modules/components/calendar/examples/6/index.html create mode 100644 projects/demo/src/modules/components/calendar/examples/6/index.ts diff --git a/projects/core/components/calendar/calendar.component.ts b/projects/core/components/calendar/calendar.component.ts index 63a0f8c2376b..a7532d685320 100644 --- a/projects/core/components/calendar/calendar.component.ts +++ b/projects/core/components/calendar/calendar.component.ts @@ -28,7 +28,7 @@ import {TuiMarkerHandler} from '@taiga-ui/core/types'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class TuiCalendarComponent implements TuiWithOptionalMinMax { - private _value: TuiDay | TuiDayRange | null = null; + private _value: TuiDay | TuiDayRange | readonly TuiDay[] | null = null; @Input() month: TuiMonth = TuiMonth.currentLocal(); @@ -58,7 +58,7 @@ export class TuiCalendarComponent implements TuiWithOptionalMinMax { markerHandler: TuiMarkerHandler = TUI_DEFAULT_MARKER_HANDLER; @Input() - set value(value: TuiDay | TuiDayRange | null) { + set value(value: TuiDay | TuiDayRange | readonly TuiDay[] | null) { this._value = value; if (this.showAdjacent && value instanceof TuiDay) { @@ -66,7 +66,7 @@ export class TuiCalendarComponent implements TuiWithOptionalMinMax { } } - get value(): TuiDay | TuiDayRange | null { + get value(): TuiDay | TuiDayRange | readonly TuiDay[] | null { return this._value; } diff --git a/projects/core/components/primitive-calendar/primitive-calendar.component.ts b/projects/core/components/primitive-calendar/primitive-calendar.component.ts index 5056638132b6..66de9f66225d 100644 --- a/projects/core/components/primitive-calendar/primitive-calendar.component.ts +++ b/projects/core/components/primitive-calendar/primitive-calendar.component.ts @@ -42,7 +42,7 @@ export class TuiPrimitiveCalendarComponent { markerHandler: TuiMarkerHandler = TUI_DEFAULT_MARKER_HANDLER; @Input() - value: TuiDay | TuiDayRange | null = null; + value: TuiDay | TuiDayRange | readonly TuiDay[] | null = null; @Input() hoveredItem: TuiDay | null = null; @@ -64,11 +64,15 @@ export class TuiPrimitiveCalendarComponent { ) {} @HostBinding('class._single') + get isSingleDayRange(): boolean { + return this.value instanceof TuiDayRange && this.value.isSingleDay; + } + + /** + * @deprecated: use {@link this.isSingleDayRange} + */ get isSingle(): boolean { - return ( - this.value !== null && - (this.value instanceof TuiDay || this.value.isSingleDay) - ); + return this.isSingleDayRange; } readonly toMarkers = ( @@ -114,6 +118,10 @@ export class TuiPrimitiveCalendarComponent { return value.daySame(item) ? TuiRangeState.Single : null; } + if (!(value instanceof TuiDayRange)) { + return value.find(day => day.daySame(item)) ? TuiRangeState.Single : null; + } + if ( (value.from.daySame(item) && !value.isSingleDay) || (hoveredItem?.dayAfter(value.from) && @@ -154,7 +162,7 @@ export class TuiPrimitiveCalendarComponent { itemIsInterval(day: TuiDay): boolean { const {value, hoveredItem} = this; - if (value === null || value instanceof TuiDay) { + if (!(value instanceof TuiDayRange)) { return false; } diff --git a/projects/core/components/primitive-year-picker/primitive-year-picker.component.ts b/projects/core/components/primitive-year-picker/primitive-year-picker.component.ts index 63c878654a6b..9359d582b7af 100644 --- a/projects/core/components/primitive-year-picker/primitive-year-picker.component.ts +++ b/projects/core/components/primitive-year-picker/primitive-year-picker.component.ts @@ -11,6 +11,7 @@ import { TUI_FIRST_DAY, TUI_LAST_DAY, TuiBooleanHandler, + TuiDay, TuiDayRange, tuiInRange, TuiMonth, @@ -34,7 +35,7 @@ export class TuiPrimitiveYearPickerComponent { private readonly currentYear = TuiMonth.currentLocal().year; @Input() - value: TuiDayRange | TuiMonthRange | TuiYear | null = null; + value: TuiDayRange | TuiMonthRange | TuiYear | readonly TuiDay[] | null = null; @Input() initialItem: TuiYear = TuiMonth.currentLocal(); @@ -61,9 +62,7 @@ export class TuiPrimitiveYearPickerComponent { @HostBinding('class._single') get isSingle(): boolean { - const {value} = this; - - return !!value && this.isRange(value) && value.from.yearSame(value.to); + return this.isRange(this.value) && this.value.from.yearSame(this.value.to); } get rows(): number { @@ -84,7 +83,9 @@ export class TuiPrimitiveYearPickerComponent { return max.year < initial ? max.year + 1 : initial; } - isRange(item: TuiMonthRange | TuiYear): item is TuiMonthRange { + isRange( + item: TuiMonthRange | TuiYear | readonly TuiDay[] | null, + ): item is TuiMonthRange { return item instanceof TuiMonthRange; } @@ -129,6 +130,10 @@ export class TuiPrimitiveYearPickerComponent { return value.year === item ? TuiRangeState.Single : null; } + if (!(value instanceof TuiMonthRange)) { + return value.find(day => day.year === item) ? TuiRangeState.Single : null; + } + if ( (value.from.year === item && !value.from.yearSame(value.to)) || (hoveredItem !== null && diff --git a/projects/demo/src/modules/components/calendar/calendar.component.ts b/projects/demo/src/modules/components/calendar/calendar.component.ts index 5ff98f8ffa01..0c79f519e23a 100644 --- a/projects/demo/src/modules/components/calendar/calendar.component.ts +++ b/projects/demo/src/modules/components/calendar/calendar.component.ts @@ -54,6 +54,11 @@ export class ExampleTuiCalendarComponent { LESS: import('./examples/5/index.less?raw'), }; + readonly example6: TuiDocExample = { + TypeScript: import('./examples/6/index.ts?raw'), + HTML: import('./examples/6/index.html?raw'), + }; + showAdjacent = true; readonly minVariants = [ diff --git a/projects/demo/src/modules/components/calendar/calendar.module.ts b/projects/demo/src/modules/components/calendar/calendar.module.ts index 8522ec43ccc3..b66882fafd15 100644 --- a/projects/demo/src/modules/components/calendar/calendar.module.ts +++ b/projects/demo/src/modules/components/calendar/calendar.module.ts @@ -10,6 +10,7 @@ import {TuiCalendarExample2} from './examples/2'; import {TuiCalendarExample3} from './examples/3'; import {TuiCalendarExample4} from './examples/4'; import {TuiCalendarExample5} from './examples/5'; +import {TuiCalendarExample6} from './examples/6'; @NgModule({ imports: [ @@ -27,6 +28,7 @@ import {TuiCalendarExample5} from './examples/5'; TuiCalendarExample3, TuiCalendarExample4, TuiCalendarExample5, + TuiCalendarExample6, ], exports: [ExampleTuiCalendarComponent], }) diff --git a/projects/demo/src/modules/components/calendar/calendar.template.html b/projects/demo/src/modules/components/calendar/calendar.template.html index 8d6a7019717d..951ba52c12ee 100644 --- a/projects/demo/src/modules/components/calendar/calendar.template.html +++ b/projects/demo/src/modules/components/calendar/calendar.template.html @@ -79,6 +79,14 @@ + + + + diff --git a/projects/demo/src/modules/components/calendar/examples/6/index.html b/projects/demo/src/modules/components/calendar/examples/6/index.html new file mode 100644 index 000000000000..04fbb65bee39 --- /dev/null +++ b/projects/demo/src/modules/components/calendar/examples/6/index.html @@ -0,0 +1,5 @@ + +
Chosen dates: {{ value }}
diff --git a/projects/demo/src/modules/components/calendar/examples/6/index.ts b/projects/demo/src/modules/components/calendar/examples/6/index.ts new file mode 100644 index 000000000000..78cccd7f39ad --- /dev/null +++ b/projects/demo/src/modules/components/calendar/examples/6/index.ts @@ -0,0 +1,20 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {encapsulation} from '@demo/emulate/encapsulation'; +import {TuiDay} from '@taiga-ui/cdk'; + +@Component({ + selector: 'tui-calendar-example-6', + templateUrl: './index.html', + changeDetection, + encapsulation, +}) +export class TuiCalendarExample6 { + value: readonly TuiDay[] = []; + + onDayClick(day: TuiDay): void { + this.value = this.value.find(item => item.daySame(day)) + ? this.value.filter(item => !item.daySame(day)) + : this.value.concat(day); + } +}