From 72de46f8e777a61a483961de0798f88ed9103d65 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 10 Apr 2019 13:56:16 +0300 Subject: [PATCH 01/41] feat(calendar): calendar multi view #4282 --- .../src/lib/calendar/calendar.component.html | 56 +++++++------ .../src/lib/calendar/calendar.component.ts | 79 +++++++++++++++++++ .../src/lib/calendar/month-picker-base.ts | 7 +- src/app/calendar/calendar.sample.html | 2 +- 4 files changed, 117 insertions(+), 27 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index eb430a7cd22..fba7bf9c569 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -3,15 +3,19 @@ {{ getFormattedDate().monthday }} - - - {{ formattedMonth(viewDate) }} - - - {{ formattedYear(viewDate) }} - + + +
+ + {{ formattedMonth(view.viewDate) }} + + + {{ formattedYear(view.viewDate) }} + +
+
@@ -29,7 +33,7 @@

(click)="previousMonth()"> keyboard_arrow_left

-
+
@@ -38,20 +42,22 @@

- - +
+ + +
[locale]="locale" [formatView]="formatViews.year" [yearFormat]="formatOptions.year" - (onSelection)="changeYear($event)"> + (onSelection)="changeYear($event, dayViews)"> \ No newline at end of file diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 954a9eee595..7a21efb6933 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -21,9 +21,24 @@ import { CalendarView, IgxMonthPickerBase } from './month-picker-base'; import { IgxMonthsViewComponent } from './months-view/months-view.component'; import { IgxYearsViewComponent } from './years-view/years-view.component'; import { IgxDaysViewComponent } from './days-view/days-view.component'; +import { DateRangeDescriptor } from '../core/dates'; let NEXT_ID = 0; +export interface IDayView { + changeDaysView: boolean; + animationAction: string; + locale: string; + value: Date | Date[]; + viewDate: Date; + weekStart: number; + formatOptions: object; + formatViews: object; + selection: string; + disabledDates: DateRangeDescriptor[]; + specialDates: DateRangeDescriptor[]; +} + /** * **Ignite UI for Angular Calendar** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/calendar.html) @@ -90,6 +105,34 @@ export class IgxCalendarComponent extends IgxMonthPickerBase { @Input() public vertical = false; + /** + * Sets/gets the number of dayViews duisplayed. + * Default value is `1`. + * ```html + * + * ``` + * ```typescript + * let daysViewsDisplayed = this.calendar.daysViewNumber; + * ``` + */ + @Input() + get daysViewNumber() { + return this._daysViewNumber; + } + + set daysViewNumber(val: number) { + this._daysViewNumber = val; + + for (let i = 1; i < val; i++) { + const dayView = Object.assign({}, this.defaultDayView); + dayView.value = null; + const nextMonthDate = new Date(dayView.viewDate); + nextMonthDate.setMonth(nextMonthDate.getMonth() + i); + dayView.viewDate = nextMonthDate; + this.dayViews.push(dayView); + } + } + /** * The default `tabindex` attribute for the component. * @@ -273,6 +316,33 @@ export class IgxCalendarComponent extends IgxMonthPickerBase { */ private _monthAction = ''; + /** + *@hidden + */ + private _daysViewNumber = 1; + + /** + *@hidden + */ + private defaultDayView: IDayView = { + changeDaysView: true, + animationAction: this._monthAction, + locale: this.locale, + value: this.value, + viewDate: this.viewDate, + weekStart: this.weekStart, + formatOptions: this.formatOptions, + formatViews: this.formatViews, + selection: this.selection, + disabledDates: this.disabledDates, + specialDates: this.specialDates + }; + + /** + *@hidden + */ + private dayViews: Array = [this.defaultDayView]; + /** * Returns the locale representation of the month in the month view if enabled, * otherwise returns the default `Date.getMonth()` value. @@ -291,6 +361,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase { */ public previousMonth(isKeydownTrigger: boolean = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', -1); + this.dayViews.forEach((val, index) => { + val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', -1); + }); this._monthAction = 'prev'; if (this.daysView) { @@ -315,6 +388,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase { */ public nextMonth(isKeydownTrigger: boolean = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', 1); + this.dayViews.forEach((val, index) => { + val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', 1); + }); this._monthAction = 'next'; if (this.daysView) { @@ -401,6 +477,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase { */ public changeMonth(event: Date) { this.viewDate = new Date(this.viewDate.getFullYear(), event.getMonth()); + this.dayViews.forEach((val, index) => { + val.viewDate.setMonth(event.getMonth() + index); + }); this.activeView = CalendarView.DEFAULT; requestAnimationFrame(() => { diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts index 36c926bdb8c..db1f049c7ef 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts @@ -1,6 +1,7 @@ import { IgxCalendarBase } from './calendar-base'; import { ViewChild, ElementRef, HostBinding } from '@angular/core'; import { KEYS } from '../core/utils'; +import { IDayView } from './calendar.component'; /** * Sets the calender view - days, months or years. @@ -62,8 +63,12 @@ export class IgxMonthPickerBase extends IgxCalendarBase { /** * @hidden */ - public changeYear(event: Date) { + public changeYear(event: Date, dayViews: IDayView[]) { this.viewDate = new Date(event.getFullYear(), this.viewDate.getMonth()); + const yearsDiff = event.getFullYear() - dayViews[0].viewDate.getFullYear(); + dayViews.forEach((val, index) => { + val.viewDate.setMonth(event.getMonth() + 12 * yearsDiff + index); + }); this._activeView = CalendarView.DEFAULT; requestAnimationFrame(() => { diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index 7d840e265d3..21b21e2e072 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -11,7 +11,7 @@

Default Calendar

- + From cd7a1e7cbba6e0944f66de51299ea6afc0506cdf Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 20 Aug 2019 14:16:24 +0300 Subject: [PATCH 02/41] feat(calendar): multiview kboard navigation #4282 --- .../src/lib/calendar/calendar-base.ts | 14 ++ .../src/lib/calendar/calendar.component.html | 29 +-- .../src/lib/calendar/calendar.component.ts | 114 ++++++----- .../calendar/days-view/day-item.component.ts | 12 ++ .../days-view/days-view.component.html | 15 +- .../calendar/days-view/days-view.component.ts | 191 ++++++++++++------ .../src/lib/calendar/month-picker-base.ts | 4 +- 7 files changed, 244 insertions(+), 135 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index 7b35bc82e85..b414a18979c 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -210,6 +210,20 @@ export class IgxCalendarBase implements ControlValueAccessor { this._specialDates = value; } + /** + * Sets/gets whether the inactive dates (dates that are out of the current month) will be hidden. + * Default value is `false`. + * ```html + * + * ``` + * ```typescript + * let hideInactiveDates = this.calendar.hideInactiveDates; + * ``` + */ + + @Input() + public hideInactiveDates: boolean; + /** * Emits an event when a date is selected. * Provides reference the `selectedDates` property. diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index 2255afe7eea..88e1a6d8293 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -4,15 +4,15 @@
- +
- {{ formattedMonth(view.viewDate) }} + {{ formattedMonth(getViewDate(i)) }} - {{ formattedYear(view.viewDate) }} + {{ formattedYear(getViewDate(i)) }}
@@ -44,17 +44,18 @@

- diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 77839e6fd95..466aa959aaa 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -8,7 +8,9 @@ import { Input, ViewChild, ElementRef, - AfterViewInit + AfterViewInit, + ViewChildren, + QueryList } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { fadeIn, scaleInCenter } from '../animations/main'; @@ -21,26 +23,16 @@ import { ICalendarDate, monthRange } from './calendar'; import { CalendarView, IgxMonthPickerBase } from './month-picker-base'; import { IgxMonthsViewComponent } from './months-view/months-view.component'; import { IgxYearsViewComponent } from './years-view/years-view.component'; -import { IgxDaysViewComponent } from './days-view/days-view.component'; -import { DateRangeDescriptor } from '../core/dates'; +import { IgxDaysViewComponent, IViewChangedArgs } from './days-view/days-view.component'; import { interval } from 'rxjs'; import { takeUntil, debounce, skipLast, switchMap } from 'rxjs/operators'; import { ScrollMonth } from './calendar-base'; let NEXT_ID = 0; -export interface IDayView { - changeDaysView: boolean; - animationAction: string; - locale: string; +export interface IMonthView { value: Date | Date[]; viewDate: Date; - weekStart: number; - formatOptions: object; - formatViews: object; - selection: string; - disabledDates: DateRangeDescriptor[]; - specialDates: DateRangeDescriptor[]; } /** @@ -110,30 +102,31 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie public vertical = false; /** - * Sets/gets the number of dayViews duisplayed. + * Sets/gets the number of month views displayed. * Default value is `1`. * ```html - * + * * ``` * ```typescript - * let daysViewsDisplayed = this.calendar.daysViewNumber; + * let monthViewsDisplayed = this.calendar.monthsViewNumber; * ``` */ @Input() - get daysViewNumber() { - return this._daysViewNumber; + get monthsViewNumber() { + return this._monthsViewNumber; } - set daysViewNumber(val: number) { - this._daysViewNumber = val; + set monthsViewNumber(val: number) { + this._monthsViewNumber = val; - for (let i = 1; i < val; i++) { - const dayView = Object.assign({}, this.defaultDayView); - dayView.value = null; - const nextMonthDate = new Date(dayView.viewDate); + for (let i = 0; i < val; i++) { + const nextMonthDate = new Date(this.viewDate); nextMonthDate.setMonth(nextMonthDate.getMonth() + i); - dayView.viewDate = nextMonthDate; - this.dayViews.push(dayView); + const monthView: IMonthView = { + value: null, + viewDate: nextMonthDate + }; + this.dayViews.push(monthView); } } @@ -201,7 +194,10 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie * @hidden */ @ViewChild('days', { read: IgxDaysViewComponent, static: false }) - public daysView: IgxDaysViewComponent; + public daysView = new IgxDaysViewComponent; + + @ViewChildren('days', { read: IgxDaysViewComponent }) + public monthViews: QueryList; /** * @hidden @@ -335,32 +331,22 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** *@hidden */ - private _daysViewNumber = 1; - - /** - *@hidden - */ - private defaultDayView: IDayView = { - changeDaysView: true, - animationAction: this._monthAction, - locale: this.locale, - value: this.value, - viewDate: this.viewDate, - weekStart: this.weekStart, - formatOptions: this.formatOptions, - formatViews: this.formatViews, - selection: this.selection, - disabledDates: this.disabledDates, - specialDates: this.specialDates - }; + private _monthsViewNumber = 1; /** *@hidden */ - private dayViews: Array = [this.defaultDayView]; + private dayViews = []; public ngAfterViewInit() { + this.monthViews.forEach((item, index) => { + const prevMonthView = this.getMonthView(index - 1); + const nextMonthView = this.getMonthView(index + 1); + item.nextMonthView = nextMonthView; + item.prevMonthView = prevMonthView; + }); + this.startMonthScroll$.pipe( takeUntil(this.stopMonthScroll$), switchMap(() => this.daysView.scrollMonth$.pipe( @@ -400,7 +386,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie */ public previousMonth(isKeydownTrigger = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', -1); - this.dayViews.forEach((val, index) => { + this.dayViews.forEach((val) => { val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', -1); }); this._monthAction = 'prev'; @@ -415,6 +401,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie */ public nextMonth(isKeydownTrigger = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', 1); + this.dayViews.forEach((val) => { + val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', 1); + }); this._monthAction = 'next'; if (this.daysView) { @@ -518,8 +507,14 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** * @hidden */ - public viewChanged(event) { - this.viewDate = this.calendarModel.timedelta(event, 'month', 0); + public viewChanged(event: IViewChangedArgs) { + let date = this.viewDate, + delta = event.delta; + if (event.moveToFirst) { + delta = 0; + date = event.date; + } + this.viewDate = this.calendarModel.timedelta(date, 'month', delta); } /** @@ -570,6 +565,15 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie this._onChangeCallback(this.selectedDates); } + /** + * @hidden + */ + public getViewDate(i: number): Date { + const nextMonthDate = new Date(this.viewDate); + nextMonthDate.setMonth(nextMonthDate.getMonth() + i); + return nextMonthDate; + } + /** * @hidden */ @@ -746,4 +750,16 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie }; return { $implicit: formatObject }; } + + /** + * Helper method returning previous/next day views + * @hidden + */ + private getMonthView(index): IgxDaysViewComponent { + if (index === -1 || index === this.monthViews.length ) { + return null; + } else { + return this.monthViews.toArray()[index]; + } + } } diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index f55c26f4d01..f92d594b717 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -29,6 +29,9 @@ export class IgxDayItemComponent { @Input() public specialDates: DateRangeDescriptor[]; + @Input() + public hideInactiveDates: boolean; + @Output() public onDateSelection = new EventEmitter(); @@ -73,6 +76,10 @@ export class IgxDayItemComponent { return this.date.isNextMonth || this.date.isPrevMonth; } + public get isHidden(): boolean { + return this.hideInactiveDates && this.isInactive; + } + public get isToday(): boolean { const today = new Date(Date.now()); const date = this.date.date; @@ -124,6 +131,11 @@ export class IgxDayItemComponent { return this.isInactive; } + @HostBinding('class.igx-calendar__date--hidden') + get isHiddenCSS(): boolean { + return this.isHidden; + } + @HostBinding('class.igx-calendar__date--current') public get isTodayCSS(): boolean { return this.isToday && !this.selected; diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html index 643a9a9fd30..b272c746a05 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html @@ -4,8 +4,17 @@
-
- - {{ formattedDate(day.date) }} +
+ + {{ formattedDate(day.date) }}
diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index 025b18063db..cdec97a5356 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -19,6 +19,12 @@ import { IgxCalendarBase, ScrollMonth } from '../calendar-base'; let NEXT_ID = 0; +export interface IViewChangedArgs { + date: Date; + delta: number; + moveToFirst?: boolean; +} + @Component({ providers: [ { @@ -81,7 +87,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { * @hidden */ @Output() - public onViewChanged = new EventEmitter(); + public onViewChanged = new EventEmitter(); /** * @hidden @@ -109,6 +115,16 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ public outOfRangeDates: DateRangeDescriptor[]; + /** + * @hidden + */ + public nextMonthView = null; + + /** + * @hidden + */ + public prevMonthView = null; + /** * The default css class applied to the component. * @@ -236,36 +252,43 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ private focusPreviousUpDate(target, prevView = false) { const node = this.dates.find((date) => date.nativeElement === target); + let dates = this.dates.toArray(), + day: IgxDayItemComponent; + const index = dates.indexOf(node); + if (!node) { return; } - const dates = this.dates.toArray(); - for (let index = dates.indexOf(node); index - 7 > -1; index -= 7) { - const date = prevView ? dates[index] : dates[index - 7]; - if (!date.isDisabled) { - if (!date.isOutOfRange) { - date.nativeElement.focus(); - break; - } + // focus item in current month + for (let i = index; i - 7 > -1; i -= 7) { + day = prevView ? node : dates[index - 7]; + if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + day.nativeElement.focus(); + break; } } - if (this.changeDaysView && dates.indexOf(node) - 7 < 0) { - const dayItem = dates[dates.indexOf(node)]; - this.nextDate = new Date(dayItem.date.date); - - this.nextDate.setDate(this.nextDate.getDate() - 7); + // focus item in previous visible month + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -7); + day = dates[index - 7]; + if (this.prevMonthView && ((day && day.date.isPrevMonth) || !day)) { + dates = this.prevMonthView.dates.toArray(); + day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); + day.nativeElement.focus(); + } + // focus item in next month, which is currently out of view + if (this.changeDaysView && !this.prevMonthView && ((day && day.isPreviousMonth) || !day)) { this.isKeydownTrigger = true; this.animationAction = 'prev'; this.callback = (items?, next?) => { - const day = items.find((item) => item.date.date.getTime() === next.getTime()); + day = items.find((item) => item.date.date.getTime() === next.getTime()); if (day) { this.focusPreviousUpDate(day.nativeElement, true); } }; - this.onViewChanged.emit(this.nextDate); + this.onViewChanged.emit({ date: this.nextDate, delta: -1 }); } } @@ -274,113 +297,136 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ private focusNextDownDate(target, nextView = false) { const node = this.dates.find((date) => date.nativeElement === target); + let dates = this.dates.toArray(), + day: IgxDayItemComponent; + const index = dates.indexOf(node); + if (!node) { return; } - const dates = this.dates.toArray(); - for (let index = dates.indexOf(node); index + 7 < this.dates.length; index += 7) { - const date = nextView ? dates[index] : dates[index + 7]; - if (!date.isDisabled) { - if (!date.isOutOfRange) { - date.nativeElement.focus(); - break; - } + // focus item in current month + for (let i = index; i + 7 < 42; i += 7) { + day = nextView ? node : dates[i + 7]; + if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + day.nativeElement.focus(); + break; } } - if (this.changeDaysView && dates.indexOf(node) + 7 > this.dates.length - 1) { - const dayItem = dates[dates.indexOf(node)]; - this.nextDate = new Date(dayItem.date.date); - - this.nextDate.setDate(this.nextDate.getDate() + 7); + // focus item in next visible month + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 7); + day = dates[index + 7]; + if (this.nextMonthView && ((day && day.date.isNextMonth) || !day)) { + dates = this.nextMonthView.dates.toArray(); + day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); + day.nativeElement.focus(); + } + // focus item in next month, which is currently out of view + if (this.changeDaysView && !this.nextMonthView && ((day && day.isNextMonth) || !day)) { this.isKeydownTrigger = true; this.animationAction = 'next'; this.callback = (items?, next?) => { - const day = items.find((item) => item.date.date.getTime() === next.getTime()); + const monthView = this.getFirstMonthView(); + items = monthView.dates; + day = items.find((item) => item.date.date.getTime() === next.getTime()); if (day) { - this.focusNextDownDate(day.nativeElement, true); + monthView.focusNextDownDate(day.nativeElement, true); } }; - this.onViewChanged.emit(this.nextDate); + this.onViewChanged.emit({ date: this.nextDate, delta: 1, moveToFirst: true }); } } /** * @hidden */ - private focusPreviousDate(target) { + private focusPreviousDate(target, prevView = false) { const node = this.dates.find((date) => date.nativeElement === target); + let dates = this.dates.toArray(), + day: IgxDayItemComponent; + const index = dates.indexOf(node); + if (!node) { return; } - const dates = this.dates.toArray(); - for (let index = dates.indexOf(node); index > 0; index--) { - const date = dates[index - 1]; - if (!date.isDisabled) { - if (!date.isOutOfRange) { - date.nativeElement.focus(); - break; - } + for (let i = index; i > 0; i--) { + day = prevView ? node : dates[index - 1]; + if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + day.nativeElement.focus(); + break; } } - if (this.changeDaysView && dates.indexOf(node) === 0) { - const dayItem = dates[0]; - if (dayItem.isCurrentMonth) { - this.nextDate = this.calendarModel.timedelta(dayItem.date.date, 'day', -1); - } else { - this.nextDate = new Date(dayItem.date.date); - } + // focus item in previous visible month + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -1); + day = dates[index - 1]; + if (this.prevMonthView && ((day && day.date.isPrevMonth) || !day)) { + dates = this.prevMonthView.dates.toArray(); + day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); + day.nativeElement.focus(); + } + // focus item in previous month, which is currently out of view + if (this.changeDaysView && !this.prevMonthView && ((day && day.isPreviousMonth) || !day)) { this.isKeydownTrigger = true; this.animationAction = 'prev'; this.callback = (items?, next?) => { - const day = items.find((item) => item.date.date.getTime() === next.getTime()); + day = items.find((item) => item.date.date.getTime() === next.getTime()); if (day) { - this.focusPreviousDate(day.nativeElement); + this.focusPreviousDate(day.nativeElement, true); } }; - this.onViewChanged.emit(this.nextDate); + this.onViewChanged.emit({ date: this.nextDate, delta: -1 }); } } /** * @hidden */ - private focusNextDate(target) { + private focusNextDate(target, nextView = false) { const node = this.dates.find((date) => date.nativeElement === target); - if (!node) { return; } + let dates = this.dates.toArray(), + day: IgxDayItemComponent; + const index = dates.indexOf(node); - const dates = this.dates.toArray(); + if (!node) { return; } - for (let index = dates.indexOf(node); index < this.dates.length - 1; index++) { - const date = dates[index + 1]; - if (!date.isDisabled) { - if (!date.isOutOfRange) { - date.nativeElement.focus(); - break; - } + // focus item in current month + for (let i = index; i < dates.length - 1; i++) { + day = nextView ? node : dates[i + 1]; + if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + day.nativeElement.focus(); + break; } } - if (this.changeDaysView && dates.indexOf(node) === this.dates.length - 1) { - const dayItem = dates[this.dates.length - 1]; - this.nextDate = new Date(dayItem.date.date); + // focus item in next visible month + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 1); + day = dates[index + 1]; + if (this.nextMonthView && ((day && day.date.isNextMonth) || !day)) { + dates = this.nextMonthView.dates.toArray(); + day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); + day.nativeElement.focus(); + } + // focus item in next month, which is currently out of view + if (this.changeDaysView && !this.nextMonthView && ((day && day.isNextMonth) || !day)) { this.isKeydownTrigger = true; this.animationAction = 'next'; this.callback = (items?, next?) => { - const day = items.find((item) => item.date.date.getTime() === next.getTime()); + const monthView = this.getFirstMonthView(); + items = monthView.dates; + day = items.find((item) => item.date.date.getTime() === next.getTime()); if (day) { - this.focusNextDate(day.nativeElement); + monthView.focusNextDate(day.nativeElement, true); } }; - this.onViewChanged.emit(this.nextDate); + this.onViewChanged.emit({ date: this.nextDate, delta: 1, moveToFirst: true }); } } @@ -401,6 +447,17 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { }]; } + /** + * @hidden + */ + private getFirstMonthView(): IgxDaysViewComponent { + let monthView = this.prevMonthView; + while (monthView.prevMonthView) { + monthView = monthView.prevMonthView; + } + return monthView; + } + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts index 03d9060c607..d29fa34fc2a 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts @@ -1,7 +1,7 @@ import { IgxCalendarBase } from './calendar-base'; import { ViewChild, ElementRef, HostBinding } from '@angular/core'; import { KEYS } from '../core/utils'; -import { IDayView } from './calendar.component'; +import { IMonthView } from './calendar.component'; /** * Sets the calender view - days, months or years. @@ -63,7 +63,7 @@ export class IgxMonthPickerBase extends IgxCalendarBase { /** * @hidden */ - public changeYear(event: Date, dayViews: IDayView[]) { + public changeYear(event: Date, dayViews: IMonthView[]) { this.viewDate = new Date(event.getFullYear(), this.viewDate.getMonth()); const yearsDiff = event.getFullYear() - dayViews[0].viewDate.getFullYear(); dayViews.forEach((val, index) => { From ca93213d78581a84168bc20c9a30d7a8bbb8b653 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 20 Aug 2019 16:08:58 +0300 Subject: [PATCH 03/41] feat(calendar): add default month view #4282 --- .../src/lib/calendar/calendar.component.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 466aa959aaa..681c54a1713 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -336,7 +336,15 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** *@hidden */ - private dayViews = []; + private defaultDayView: IMonthView = { + value: this.value, + viewDate: this.viewDate, + }; + + /** + *@hidden + */ + private dayViews: Array = [this.defaultDayView]; public ngAfterViewInit() { From 083d7ea2f7e58751e70794b0ff1712b04f449645 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 20 Aug 2019 16:21:58 +0300 Subject: [PATCH 04/41] feat(calendar): dayViews just be public #4282 --- .../igniteui-angular/src/lib/calendar/calendar.component.ts | 2 +- .../src/lib/calendar/days-view/days-view.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 681c54a1713..d85843e522e 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -344,7 +344,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** *@hidden */ - private dayViews: Array = [this.defaultDayView]; + public dayViews: Array = [this.defaultDayView]; public ngAfterViewInit() { diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index cdec97a5356..43cab09df06 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -451,7 +451,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { * @hidden */ private getFirstMonthView(): IgxDaysViewComponent { - let monthView = this.prevMonthView; + let monthView = this; while (monthView.prevMonthView) { monthView = monthView.prevMonthView; } From c44e00f13c608eab5524577ba273bd46cfcb962b Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 20 Aug 2019 17:26:59 +0300 Subject: [PATCH 05/41] feat(calendar): set viewDate for per view #4282 --- .../igniteui-angular/src/lib/calendar/calendar.component.html | 2 +- .../igniteui-angular/src/lib/calendar/calendar.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index 88e1a6d8293..fd27a1dd43d 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -48,7 +48,7 @@

[animationAction]="monthAction" [locale]="locale" [value]="value" - [viewDate]="viewDate" + [viewDate]="getViewDate(i)" [weekStart]="weekStart" [formatOptions]="formatOptions" [formatViews]="formatViews" diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index d85843e522e..99caf48edb7 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -119,7 +119,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie set monthsViewNumber(val: number) { this._monthsViewNumber = val; - for (let i = 0; i < val; i++) { + for (let i = 1; i < val; i++) { const nextMonthDate = new Date(this.viewDate); nextMonthDate.setMonth(nextMonthDate.getMonth() + i); const monthView: IMonthView = { From bbbccba7e7e1e8b0bf0c575d06d97e84926211b0 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 21 Aug 2019 08:53:03 +0300 Subject: [PATCH 06/41] feat(calendar): dynamically set month views #4282 --- .../src/lib/calendar/calendar.component.ts | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 99caf48edb7..ef78ffee6a0 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -117,16 +117,22 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie } set monthsViewNumber(val: number) { - this._monthsViewNumber = val; - - for (let i = 1; i < val; i++) { - const nextMonthDate = new Date(this.viewDate); - nextMonthDate.setMonth(nextMonthDate.getMonth() + i); - const monthView: IMonthView = { - value: null, - viewDate: nextMonthDate - }; - this.dayViews.push(monthView); + if (this._monthsViewNumber === val || val === 0) { + return; + } else if (this._monthsViewNumber < val) { + for (let i = this._monthsViewNumber; i < val; i++) { + const nextMonthDate = new Date(this.viewDate); + nextMonthDate.setMonth(nextMonthDate.getMonth() + i); + const monthView: IMonthView = { + value: null, + viewDate: nextMonthDate + }; + this.dayViews.push(monthView); + } + this._monthsViewNumber = val; + } else { + this.dayViews.splice(val, this.dayViews.length - val); + this._monthsViewNumber = val; } } From 907efab229ba3b291878e70719825ead08c82173 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 21 Aug 2019 10:16:36 +0300 Subject: [PATCH 07/41] feat(calendar): fix bug in focusing prev day #4282 --- .../src/lib/calendar/days-view/days-view.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index 43cab09df06..862d395c309 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -260,7 +260,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { // focus item in current month for (let i = index; i - 7 > -1; i -= 7) { - day = prevView ? node : dates[index - 7]; + day = prevView ? node : dates[i - 7]; if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { day.nativeElement.focus(); break; @@ -351,7 +351,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { if (!node) { return; } for (let i = index; i > 0; i--) { - day = prevView ? node : dates[index - 1]; + day = prevView ? node : dates[i - 1]; if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { day.nativeElement.focus(); break; From eec448e2c1512353c7921850a55eee98d65edd4c Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 21 Aug 2019 10:41:35 +0300 Subject: [PATCH 08/41] fix(calendar): home/end find 1st/last view #4282 --- .../src/lib/calendar/calendar.component.ts | 4 ++-- .../lib/calendar/days-view/days-view.component.ts | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index ef78ffee6a0..0f8cdea4ec2 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -726,7 +726,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie @HostListener('keydown.home', ['$event']) public onKeydownHome(event: KeyboardEvent) { if (this.daysView) { - this.daysView.onKeydownHome(event); + this.monthViews.first.onKeydownHome(event); } } @@ -736,7 +736,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie @HostListener('keydown.end', ['$event']) public onKeydownEnd(event: KeyboardEvent) { if (this.daysView) { - this.daysView.onKeydownEnd(event); + this.monthViews.last.onKeydownEnd(event); } } diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index 862d395c309..a8786e1f5dd 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -458,6 +458,17 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { return monthView; } + /** + * @hidden + */ + private getLastMonthView(): IgxDaysViewComponent { + let monthView = this; + while (monthView.nextMonthView) { + monthView = monthView.nextMonthView; + } + return monthView; + } + /** * @hidden */ @@ -510,7 +521,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { event.preventDefault(); event.stopPropagation(); - const dates = this.dates.filter(d => d.isCurrentMonth); + const dates = this.getFirstMonthView().dates.filter(d => d.isCurrentMonth); for (let i = 0; i < dates.length; i++) { if (!dates[i].isDisabled) { dates[i].nativeElement.focus(); @@ -527,7 +538,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { event.preventDefault(); event.stopPropagation(); - const dates = this.dates.filter(d => d.isCurrentMonth); + const dates = this.getLastMonthView().dates.filter(d => d.isCurrentMonth); for (let i = dates.length - 1; i >= 0; i--) { if (!dates[i].isDisabled) { dates[i].nativeElement.focus(); From fd5f1f7b142c92f5da8fb514714fc69390126c5b Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 21 Aug 2019 15:00:21 +0300 Subject: [PATCH 09/41] style(calendar): add style for hidden days #4282 --- .../src/lib/calendar/calendar.component.ts | 3 +++ .../calendar/days-view/days-view.component.ts | 23 ++++++++++++------- .../calendar/_calendar-component.scss | 4 ++++ .../components/calendar/_calendar-theme.scss | 4 ++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 0f8cdea4ec2..643dde93bb8 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -202,6 +202,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie @ViewChild('days', { read: IgxDaysViewComponent, static: false }) public daysView = new IgxDaysViewComponent; + /** + * @hidden + */ @ViewChildren('days', { read: IgxDaysViewComponent }) public monthViews: QueryList; diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index a8786e1f5dd..6cb64614c97 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -118,12 +118,12 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { /** * @hidden */ - public nextMonthView = null; + public nextMonthView: IgxDaysViewComponent; /** * @hidden */ - public prevMonthView = null; + public prevMonthView: IgxDaysViewComponent; /** * The default css class applied to the component. @@ -261,7 +261,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { // focus item in current month for (let i = index; i - 7 > -1; i -= 7) { day = prevView ? node : dates[i - 7]; - if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + if (this.isDayFocusable(day)) { day.nativeElement.focus(); break; } @@ -306,7 +306,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { // focus item in current month for (let i = index; i + 7 < 42; i += 7) { day = nextView ? node : dates[i + 7]; - if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + if (this.isDayFocusable(day)) { day.nativeElement.focus(); break; } @@ -352,7 +352,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { for (let i = index; i > 0; i--) { day = prevView ? node : dates[i - 1]; - if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + if (this.isDayFocusable(day)) { day.nativeElement.focus(); break; } @@ -397,7 +397,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { // focus item in current month for (let i = index; i < dates.length - 1; i++) { day = nextView ? node : dates[i + 1]; - if (!day.isDisabled && !day.isHidden && !day.isOutOfRange && day.isCurrentMonth) { + if (this.isDayFocusable(day)) { day.nativeElement.focus(); break; } @@ -451,7 +451,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { * @hidden */ private getFirstMonthView(): IgxDaysViewComponent { - let monthView = this; + let monthView = this as IgxDaysViewComponent; while (monthView.prevMonthView) { monthView = monthView.prevMonthView; } @@ -462,13 +462,20 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { * @hidden */ private getLastMonthView(): IgxDaysViewComponent { - let monthView = this; + let monthView = this as IgxDaysViewComponent; while (monthView.nextMonthView) { monthView = monthView.nextMonthView; } return monthView; } + /** + * @hidden + */ + private isDayFocusable(day: IgxDayItemComponent): boolean { + return !!day && day.isCurrentMonth && !day.isHidden && !day.isDisabled && !day.isOutOfRange; + } + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss index 0ac28e3c00a..80fbb1c3867 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss @@ -79,6 +79,10 @@ } } + @include e(date, 'hidden') { + @extend %cal-value--hidden !optional; + } + @include e(date, 'weekend') { @extend %cal-value !optional; @extend %cal-value--weekend !optional; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 62493219055..ed9917c4476 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -498,6 +498,10 @@ %cal-value--hover { background: --var($theme, 'date-hover-background'); } + + %cal-value--hidden { + visibility: hidden; + } } /// Adds typography styles for the igx-calendar component. From ddef2bbb1f2ab95589319a2b3cb52ef7f84d9bec Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Fri, 23 Aug 2019 14:37:10 +0300 Subject: [PATCH 10/41] feat(calendar): add multiview to picker #4282 --- .../date-picker/_date-picker-theme.scss | 2 +- .../lib/date-picker/date-picker.component.ts | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss index a576e529f5c..298970af191 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss @@ -14,7 +14,7 @@ %date-picker { min-width: 200px; - max-width: 340px; + // max-width: 340px; box-shadow: igx-elevation($elevations, 24); border-radius: --var($theme, 'border-radius'); background: --var($theme, 'content-background'); diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts index 67adcca5a0a..5b7f65f4467 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts @@ -189,6 +189,32 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor return this._formatOptions; } + /** + * Sets/gets whether the inactive dates (dates that are out of the current month) will be hidden. + * Default value is `false`. + * ```html + * + * ``` + * ```typescript + * let hideInactiveDates = this.datePicker.hideInactiveDates; + * ``` + */ + @Input() + public hideInactiveDates: boolean; + + /** + * Sets/gets the number of month views displayed. + * Default value is `1`. + * ```html + * + * ``` + * ```typescript + * let monthViewsDisplayed = this.datePicker.monthsViewNumber; + * ``` + */ + @Input() + public monthsViewNumber = 1; + /** *Sets the format options of the `IgxDatePickerComponent`. *```typescript @@ -1259,6 +1285,8 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor this.calendar.disabledDates = this.disabledDates; this.calendar.headerTemplate = this.headerTemplate; this.calendar.subheaderTemplate = this.subheaderTemplate; + this.calendar.hideInactiveDates = this.hideInactiveDates; + this.calendar.monthsViewNumber = this.monthsViewNumber; this.calendar.onSelection.pipe(takeUntil(this._destroy$)).subscribe((ev: Date) => this.handleSelection(ev)); if (this.value) { From 7ea574327073c1c18b25437e4648b60fb1cc9dad Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Mon, 26 Aug 2019 11:03:23 +0300 Subject: [PATCH 11/41] fix(calendar): calendar sample typo #4282 --- src/app/calendar/calendar.sample.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index a8a5b8adc69..8f4c231ca81 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -11,7 +11,7 @@

Default Calendar

- + From 7fa2c6a66d846c99971d3f60aabc9bb1e24d7dbf Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 28 Aug 2019 16:44:52 +0300 Subject: [PATCH 12/41] style(calendar): align month headers #4282 --- .../lib/core/styles/components/calendar/_calendar-theme.scss | 5 ++++- .../styles/components/date-picker/_date-picker-theme.scss | 1 - src/app/calendar/calendar.sample.html | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index dc582a26eb1..6105ac6016f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -337,6 +337,7 @@ justify-content: space-between; align-items: center; padding-bottom: $cal-picker-padding; + position: relative; } %cal-picker-arrow { @@ -346,7 +347,9 @@ user-select: none; outline: none; cursor: pointer; - flex-basis: 14.28%; /* equals the width of a single date 100% / 7 (days) */ + position: absolute; + height: 100%; + align-items: center; &:focus, &:hover { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss index 298970af191..bcea688f87c 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/date-picker/_date-picker-theme.scss @@ -14,7 +14,6 @@ %date-picker { min-width: 200px; - // max-width: 340px; box-shadow: igx-elevation($elevations, 24); border-radius: --var($theme, 'border-radius'); background: --var($theme, 'content-background'); diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index 8f4c231ca81..f557dc481bb 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -11,8 +11,7 @@

Default Calendar

- - + From d93b6ef629efdb07f580598e4b1e3d90d0cf7847 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 28 Aug 2019 16:45:38 +0300 Subject: [PATCH 13/41] style(calendar): style month headers #4282 --- .../src/lib/calendar/calendar.component.html | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index fd27a1dd43d..328a3f051b8 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -5,7 +5,7 @@ -
+
{{ formattedMonth(getViewDate(i)) }} @@ -30,15 +30,21 @@

(swipeleft)="nextMonth()">
+ igxCalendarScrollMonth [startScroll]="startPrevMonthScroll" [stopScroll]="stopMonthScroll" [ngStyle]="{ + 'min-width.%': 100/(monthsViewNumber*7), + 'left': 0 + }"> keyboard_arrow_left
-
+
keyboard_arrow_right
From d15f2ae41d8ecfe4213346bdbf29b4b972841eb2 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Fri, 30 Aug 2019 14:18:01 +0300 Subject: [PATCH 14/41] style(calendar): select outside days #4282 --- .../lib/core/styles/components/calendar/_calendar-theme.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index d6f7291f623..6dbc5c142aa 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -624,7 +624,9 @@ } %cal-value--hidden { - visibility: hidden; + %cal-value-content { + visibility: hidden; + } } } From d5b413b07d41a713902eec6dd075141292736c57 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 3 Sep 2019 15:14:32 +0300 Subject: [PATCH 15/41] style(calendar): expose style class for day #4282 --- .../calendar/days-view/day-item.component.ts | 33 +++++++++++++++++-- .../calendar/_calendar-component.scss | 5 +++ .../components/calendar/_calendar-theme.scss | 13 ++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index 7f46a4a7fc9..0810ce50681 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -146,7 +146,12 @@ export class IgxDayItemComponent { @HostBinding('class.igx-calendar__date--selected') public get isSelectedCSS(): boolean { - return this.selected; + return this.selected && this.isCurrentMonth; + } + + @HostBinding('class.igx-calendar__date--selected-dimmed') + public get isSelectedDimmedCSS(): boolean { + return this.isSingleSelection && this.selected && !this.isCurrentMonth; } @HostBinding('class.igx-calendar__date--weekend') @@ -156,7 +161,7 @@ export class IgxDayItemComponent { @HostBinding('class.igx-calendar__date--disabled') public get isDisabledCSS(): boolean { - return this.isDisabled || this.isOutOfRange; + return this.isDisabled || this.isOutOfRange || this.isHidden; } @HostBinding('class.igx-calendar__date--range') @@ -204,11 +209,35 @@ export class IgxDayItemComponent { return (this.value as Date[]).length === this._index; } + @HostBinding('class.igx-calendar__date--lastday') + public get isLastInMonth(): boolean { + const checkLast = true; + return this.isFirstLastInMonth(checkLast); + } + + @HostBinding('class.igx-calendar__date--firstday') + public get isFirstInMonth(): boolean { + const checkLast = false; + return this.isFirstLastInMonth(checkLast); + } + private _index: Number; private _selected = false; constructor(private elementRef: ElementRef) { } + private isFirstLastInMonth(checkLast: boolean): boolean { + const inc = checkLast ? 1 : -1; + if (!this.isSingleSelection && this.isCurrentMonth && this.isWithinRange) { + const nextDay = new Date(this.date.date); + nextDay.setDate(nextDay.getDate() + inc); + if (this.date.date.getMonth() + inc === nextDay.getMonth()) { + return true; + } + } + return false; + } + @HostListener('click') @HostListener('keydown.enter') public onSelect() { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss index e721dc731a3..25b7a8d7e9b 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss @@ -59,6 +59,11 @@ @extend %cal-value--selected !optional; } + @include e(date, 'selected-dimmed') { + @extend %cal-value !optional; + @extend %cal-value--selected-dimmed !optional; + } + @include e(date, 'current') { @extend %cal-value !optional; @extend %cal-value--current !optional; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 6dbc5c142aa..697a311fb05 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -555,6 +555,15 @@ } } + %cal-value--selected-dimmed { + + %cal-value-content { + color: --var($theme, 'date-selected-text-color'); + background: --var($theme, 'date-selected-background') ; + opacity: 0.60; + } + } + %cal-value--disabled { pointer-events: none; cursor: not-allowed; @@ -589,6 +598,10 @@ } } + %cal-value--hidden%cal-value--disabled-range { + background: transparent !important; + } + %cal-value--first { position: relative; background: transparent; From 662ed9bb39ab8552f11db6a6bca2415e1319de57 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 4 Sep 2019 09:57:23 +0300 Subject: [PATCH 16/41] style(calendar): add space between views #4282 --- .../core/styles/components/calendar/_calendar-theme.scss | 5 +++++ src/app/calendar/calendar.sample.html | 8 ++++++-- src/app/calendar/calendar.sample.ts | 8 ++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 2a4c5f25c26..f8add0c00e4 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -316,6 +316,10 @@ border-radius: --var($theme, 'border-radius'); } + %cal-display + %cal-display { + margin-left: 1rem; + } + %cal-display--vertical { flex-flow: row nowrap; @@ -470,6 +474,7 @@ color: --var($theme, 'inactive-text-color'); cursor: default; border-radius: 0; + flex-basis: 14.28%; // 100 divided by the number of weekdays } %cal-value--weekend { diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index f557dc481bb..db7fc8d3a06 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -9,16 +9,20 @@

Default Calendar

+ + + +
- +

Vertical Calendar

- +
diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index 88898f353ff..83fd4e99dcc 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -28,6 +28,14 @@ export class CalendarSampleComponent implements OnInit { }]; } + public showHide() { + this.calendar1.hideInactiveDates = !this.calendar1.hideInactiveDates; + } + + public setMonthsViewNumber(args: HTMLInputElement) { + this.calendar1.monthsViewNumber = parseInt(args.value, 10); + } + public select() { // Working with range selection type // this.calendar1.selectDate([new Date('2018-09-20'), new Date('2018-09-26'), new Date('2018-09-28')]); From 65c3e58a670b850c67eb6ba9bd71c1351676e05c Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 4 Sep 2019 10:16:55 +0300 Subject: [PATCH 17/41] style(calendar): fix lint in theme files #4282 --- .../styles/components/calendar/_calendar-component.scss | 1 - .../core/styles/components/calendar/_calendar-theme.scss | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss index 7ae8a9aac32..2890455da5c 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss @@ -71,7 +71,6 @@ @include e(date, 'hidden') { @extend %cal-value--hidden !optional; - } @include e(date, $mods: ('selected', 'current')) { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index f8add0c00e4..b720d1bf615 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -474,7 +474,8 @@ color: --var($theme, 'inactive-text-color'); cursor: default; border-radius: 0; - flex-basis: 14.28%; // 100 divided by the number of weekdays + flex-basis: 14.28%; + // 100 divided by the number of weekdays } %cal-value--weekend { @@ -556,11 +557,10 @@ } %cal-value--selected-dimmed { - %cal-value-content { color: --var($theme, 'date-selected-text-color'); background: --var($theme, 'date-selected-background') ; - opacity: 0.60; + opacity: .6; } } From 8e6d7f6c0d83cfd14caab9b4c6dd032afe448685 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 4 Sep 2019 14:51:47 +0300 Subject: [PATCH 18/41] fix(calendar): fix multiselection bug #4282 --- .../src/lib/calendar/calendar-base.ts | 11 +++++++++-- .../src/lib/calendar/days-view/day-item.component.ts | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index b414a18979c..bcee5863e01 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -222,7 +222,7 @@ export class IgxCalendarBase implements ControlValueAccessor { */ @Input() - public hideInactiveDates: boolean; + public hideInactiveDates = false; /** * Emits an event when a date is selected. @@ -393,7 +393,14 @@ export class IgxCalendarBase implements ControlValueAccessor { */ private selectMultiple(value: Date | Date[]) { if (Array.isArray(value)) { - this.selectedDates = this.selectedDates.concat(value.map(v => this.getDateOnly(v))); + const newDates = value.map(v => this.getDateOnly(v).getTime()); + const selDates = this.selectedDates.map(v => this.getDateOnly(v).getTime()); + + if (JSON.stringify(newDates) === JSON.stringify(selDates)) { + return; + } + + this.selectedDates = Array.from(new Set([...newDates, ...selDates])).map(v => new Date(v)); } else { const valueDateOnly = this.getDateOnly(value); const newSelection = []; diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index 0810ce50681..ec79a7f5b8c 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -30,7 +30,7 @@ export class IgxDayItemComponent { public specialDates: DateRangeDescriptor[]; @Input() - public hideInactiveDates: boolean; + public hideInactiveDates = false; @Output() public onDateSelection = new EventEmitter(); From 4342be65d292fb6aaec528e50a9e85e08edbd728 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Thu, 5 Sep 2019 11:58:51 +0300 Subject: [PATCH 19/41] feat(calendar): set hideOutsideDays input #4282 --- .../igniteui-angular/src/lib/calendar/calendar-base.ts | 6 +++--- .../src/lib/calendar/calendar.component.html | 2 +- .../src/lib/calendar/days-view/day-item.component.ts | 4 ++-- .../lib/calendar/days-view/days-view.component.html | 2 +- .../src/lib/date-picker/date-picker.component.ts | 8 ++++---- src/app/calendar/calendar.sample.html | 2 +- src/app/calendar/calendar.sample.ts | 2 +- src/app/date-picker/date-picker.sample.html | 5 ++++- src/app/date-picker/date-picker.sample.ts | 10 +++++++++- 9 files changed, 26 insertions(+), 15 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index bcee5863e01..ee5c086d8be 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -214,15 +214,15 @@ export class IgxCalendarBase implements ControlValueAccessor { * Sets/gets whether the inactive dates (dates that are out of the current month) will be hidden. * Default value is `false`. * ```html - * + * * ``` * ```typescript - * let hideInactiveDates = this.calendar.hideInactiveDates; + * let hideOutsideDays = this.calendar.hideOutsideDays; * ``` */ @Input() - public hideInactiveDates = false; + public hideOutsideDays = false; /** * Emits an event when a date is selected. diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index 328a3f051b8..d8dda0d82e3 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -61,7 +61,7 @@

[selection]="selection" [disabledDates]="disabledDates" [specialDates]="specialDates" - [hideInactiveDates]="hideInactiveDates" + [hideOutsideDays]="hideOutsideDays" (onViewChanged)="viewChanged($event)" (onDateSelection)="childClicked($event)"> diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index ec79a7f5b8c..172ad972108 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -30,7 +30,7 @@ export class IgxDayItemComponent { public specialDates: DateRangeDescriptor[]; @Input() - public hideInactiveDates = false; + public hideOutsideDays = false; @Output() public onDateSelection = new EventEmitter(); @@ -80,7 +80,7 @@ export class IgxDayItemComponent { } public get isHidden(): boolean { - return this.hideInactiveDates && this.isInactive; + return this.hideOutsideDays && this.isInactive; } public get isToday(): boolean { diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html index 5464f2952d7..978f9046b86 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html @@ -15,7 +15,7 @@ [disabledDates]="disabledDates" [specialDates]="specialDates" [outOfRangeDates]="outOfRangeDates" - [hideInactiveDates]="hideInactiveDates" + [hideOutsideDays]="hideOutsideDays" (onDateSelection)="selectDay($event)"> {{ formattedDate(day.date) }} diff --git a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts index f3edd543de2..a15519ef657 100644 --- a/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts +++ b/projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts @@ -193,14 +193,14 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor * Sets/gets whether the inactive dates (dates that are out of the current month) will be hidden. * Default value is `false`. * ```html - * + * * ``` * ```typescript - * let hideInactiveDates = this.datePicker.hideInactiveDates; + * let hideOutsideDays = this.datePicker.hideOutsideDays; * ``` */ @Input() - public hideInactiveDates: boolean; + public hideOutsideDays: boolean; /** * Sets/gets the number of month views displayed. @@ -1285,7 +1285,7 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor this.calendar.disabledDates = this.disabledDates; this.calendar.headerTemplate = this.headerTemplate; this.calendar.subheaderTemplate = this.subheaderTemplate; - this.calendar.hideInactiveDates = this.hideInactiveDates; + this.calendar.hideOutsideDays = this.hideOutsideDays; this.calendar.monthsViewNumber = this.monthsViewNumber; this.calendar.onSelection.pipe(takeUntil(this._destroy$)).subscribe((ev: Date) => this.handleSelection(ev)); diff --git a/src/app/calendar/calendar.sample.html b/src/app/calendar/calendar.sample.html index db7fc8d3a06..6cd034ad29f 100644 --- a/src/app/calendar/calendar.sample.html +++ b/src/app/calendar/calendar.sample.html @@ -15,7 +15,7 @@

Default Calendar

- +
diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index 83fd4e99dcc..a28c39ad3fb 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -29,7 +29,7 @@ export class CalendarSampleComponent implements OnInit { } public showHide() { - this.calendar1.hideInactiveDates = !this.calendar1.hideInactiveDates; + this.calendar1.hideOutsideDays = !this.calendar1.hideOutsideDays; } public setMonthsViewNumber(args: HTMLInputElement) { diff --git a/src/app/date-picker/date-picker.sample.html b/src/app/date-picker/date-picker.sample.html index bc37cbbbb14..d765cb0bbc1 100644 --- a/src/app/date-picker/date-picker.sample.html +++ b/src/app/date-picker/date-picker.sample.html @@ -14,8 +14,11 @@

Default Date Picker - dialog mode

Default Date Picker

Date Picker with passed date

+ + +
- +
diff --git a/src/app/date-picker/date-picker.sample.ts b/src/app/date-picker/date-picker.sample.ts index ca5f16fb7ce..3d03ef75b12 100644 --- a/src/app/date-picker/date-picker.sample.ts +++ b/src/app/date-picker/date-picker.sample.ts @@ -21,7 +21,7 @@ export class DatePickerSampleComponent { weekday: 'short', year: 'numeric' }; - // @ViewChild('dp99') public datePicker99: IgxDatePickerComponent; + @ViewChild('datepicker1', { read: IgxDatePickerComponent, static: true }) datepicker1: IgxDatePickerComponent; public date1; public date2; @@ -50,6 +50,14 @@ export class DatePickerSampleComponent { datePicker.deselectDate(); } + public showHide() { + this.datepicker1.hideOutsideDays = !this.datepicker1.hideOutsideDays; + } + + public setMonthsViewNumber(args: HTMLInputElement) { + this.datepicker1.monthsViewNumber = parseInt(args.value, 10); + } + constructor() { registerLocaleData(localeJA); // registerLocaleData(localeDE); From 2e006ffed43dffe70de72dcd712e46d50d6ef61c Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 10 Sep 2019 15:00:53 +0300 Subject: [PATCH 20/41] fix(calendar): edge case and test kb navig #4282 --- .../lib/calendar/calendar.component.spec.ts | 10 +++ .../calendar/days-view/days-view.component.ts | 83 +++++++++++++------ src/app/calendar/calendar.sample.ts | 14 ++-- 3 files changed, 77 insertions(+), 30 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 41e6b51d807..22718592477 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -1804,6 +1804,8 @@ describe('IgxCalendar', () => { fixture.detectChanges(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); + await wait(400); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); @@ -1818,6 +1820,8 @@ describe('IgxCalendar', () => { fixture.detectChanges(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); + fixture.detectChanges(); + await wait(400); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft'); fixture.detectChanges(); await wait(400); @@ -1851,6 +1855,8 @@ describe('IgxCalendar', () => { fixture.detectChanges(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + await wait(400); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); fixture.detectChanges(); await wait(400); @@ -1859,6 +1865,8 @@ describe('IgxCalendar', () => { expect(date.nativeElement).toBe(document.activeElement); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + await wait(400); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); fixture.detectChanges(); await wait(400); @@ -1892,6 +1900,8 @@ describe('IgxCalendar', () => { fixture.detectChanges(); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown'); + fixture.detectChanges(); + await wait(400); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight'); fixture.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index 6cb64614c97..d3285663b09 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -257,23 +257,31 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { const index = dates.indexOf(node); if (!node) { return; } + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -7); // focus item in current month for (let i = index; i - 7 > -1; i -= 7) { - day = prevView ? node : dates[i - 7]; + day = prevView ? dates[i] : dates[i - 7]; + this.nextDate = day.date.date; + if (day.date.isPrevMonth) { + break; + } if (this.isDayFocusable(day)) { day.nativeElement.focus(); - break; + return; } } // focus item in previous visible month - this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -7); - day = dates[index - 7]; - if (this.prevMonthView && ((day && day.date.isPrevMonth) || !day)) { + if (this.prevMonthView) { dates = this.prevMonthView.dates.toArray(); day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); - day.nativeElement.focus(); + + if (this.isDayFocusable(day)) { + day.nativeElement.focus(); + return; + } + this.prevMonthView.focusPreviousUpDate(day.nativeElement); } // focus item in next month, which is currently out of view @@ -302,23 +310,31 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { const index = dates.indexOf(node); if (!node) { return; } + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 7); // focus item in current month for (let i = index; i + 7 < 42; i += 7) { - day = nextView ? node : dates[i + 7]; + day = nextView ? dates[i] : dates[i + 7]; + this.nextDate = day.date.date; + if (day.date.isNextMonth) { + break; + } if (this.isDayFocusable(day)) { day.nativeElement.focus(); - break; + return; } } // focus item in next visible month - this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 7); - day = dates[index + 7]; - if (this.nextMonthView && ((day && day.date.isNextMonth) || !day)) { + if (this.nextMonthView) { dates = this.nextMonthView.dates.toArray(); day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); - day.nativeElement.focus(); + + if (this.isDayFocusable(day)) { + day.nativeElement.focus(); + return; + } + this.nextMonthView.focusNextDownDate(day.nativeElement); } // focus item in next month, which is currently out of view @@ -349,22 +365,30 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { const index = dates.indexOf(node); if (!node) { return; } + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -1); for (let i = index; i > 0; i--) { - day = prevView ? node : dates[i - 1]; + day = prevView ? dates[i] : dates[i - 1]; + this.nextDate = day.date.date; + if (day.date.isPrevMonth) { + break; + } if (this.isDayFocusable(day)) { day.nativeElement.focus(); - break; + return; } } // focus item in previous visible month - this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -1); - day = dates[index - 1]; - if (this.prevMonthView && ((day && day.date.isPrevMonth) || !day)) { + if (this.prevMonthView) { dates = this.prevMonthView.dates.toArray(); day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); - day.nativeElement.focus(); + + if (this.isDayFocusable(day)) { + day.nativeElement.focus(); + return; + } + this.prevMonthView.focusPreviousDate(day.nativeElement); } // focus item in previous month, which is currently out of view @@ -390,26 +414,35 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { const node = this.dates.find((date) => date.nativeElement === target); let dates = this.dates.toArray(), day: IgxDayItemComponent; - const index = dates.indexOf(node); + let index = dates.indexOf(node); if (!node) { return; } + this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 1); // focus item in current month for (let i = index; i < dates.length - 1; i++) { - day = nextView ? node : dates[i + 1]; + day = nextView ? dates[i] : dates[i + 1]; + this.nextDate = day.date.date; + if (day.date.isNextMonth) { + break; + } if (this.isDayFocusable(day)) { day.nativeElement.focus(); - break; + return; } } // focus item in next visible month - this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 1); - day = dates[index + 1]; - if (this.nextMonthView && ((day && day.date.isNextMonth) || !day)) { + if (this.nextMonthView) { dates = this.nextMonthView.dates.toArray(); day = dates.find((item) => item.date.date.getTime() === this.nextDate.getTime()); - day.nativeElement.focus(); + index = dates.indexOf(day); + + if (this.isDayFocusable(day)) { + day.nativeElement.focus(); + return; + } + this.nextMonthView.focusNextDate(day.nativeElement); } // focus item in next month, which is currently out of view diff --git a/src/app/calendar/calendar.sample.ts b/src/app/calendar/calendar.sample.ts index a28c39ad3fb..f6a9cf2eeee 100644 --- a/src/app/calendar/calendar.sample.ts +++ b/src/app/calendar/calendar.sample.ts @@ -12,9 +12,13 @@ export class CalendarSampleComponent implements OnInit { ngOnInit() { this.calendar.disabledDates = [{ - type: DateRangeType.Between, dateRange: [ - new Date(2019, 7, 2), - new Date(2019, 7, 5) + type: DateRangeType.Specific, dateRange: [ + new Date(2019, 5, 13), + new Date(2019, 5, 27), + new Date(2019, 5, 30), + new Date(2019, 6, 1), + new Date(2019, 5, 1), + new Date(2019, 4, 31) ] }]; @@ -29,11 +33,11 @@ export class CalendarSampleComponent implements OnInit { } public showHide() { - this.calendar1.hideOutsideDays = !this.calendar1.hideOutsideDays; + this.calendar.hideOutsideDays = !this.calendar.hideOutsideDays; } public setMonthsViewNumber(args: HTMLInputElement) { - this.calendar1.monthsViewNumber = parseInt(args.value, 10); + this.calendar.monthsViewNumber = parseInt(args.value, 10); } public select() { From d26af7980a8ac7183250f93b1dff4fb0464f9459 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 11 Sep 2019 12:00:10 +0300 Subject: [PATCH 21/41] fix(calendar): fix custom sbheader templates #4282 --- .../src/lib/calendar/calendar.component.html | 28 ++++++++----------- .../src/lib/calendar/calendar.component.ts | 12 +++++++- .../components/calendar/_calendar-theme.scss | 3 ++ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index d8dda0d82e3..21cc5a9a8fd 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -3,19 +3,15 @@ {{ getFormattedDate().monthday }} - - -
- - {{ formattedMonth(getViewDate(i)) }} - - - {{ formattedYear(getViewDate(i)) }} - -
-
+ + + {{ formattedMonth(getViewDate(obj.index)) }} + + + {{ formattedYear(getViewDate(obj.index)) }} +
@@ -36,9 +32,9 @@

}"> keyboard_arrow_left

-
- - +
+ +
{ - const prevMonthView = this.getMonthView(index - 1); - const nextMonthView = this.getMonthView(index + 1); - item.nextMonthView = nextMonthView; - item.prevMonthView = prevMonthView; + this.monthViews.changes.subscribe(c => { + c.forEach((item, index) => { + const prevMonthView = this.getMonthView(index - 1); + const nextMonthView = this.getMonthView(index + 1); + item.nextMonthView = nextMonthView; + item.prevMonthView = prevMonthView; + }); }); this.startMonthScroll$.pipe( @@ -385,6 +388,15 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie }); } + public ngAfterViewChecked() { + this.monthViews.forEach((item, index) => { + const prevMonthView = this.getMonthView(index - 1); + const nextMonthView = this.getMonthView(index + 1); + item.nextMonthView = nextMonthView; + item.prevMonthView = prevMonthView; + }); + } + /** * Returns the locale representation of the month in the month view if enabled, * otherwise returns the default `Date.getMonth()` value. @@ -403,9 +415,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie */ public previousMonth(isKeydownTrigger = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', -1); - this.dayViews.forEach((val) => { - val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', -1); - }); + // this.dayViews.forEach((val) => { + // val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', -1); + // }); this._monthAction = 'prev'; if (this.daysView) { @@ -418,9 +430,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie */ public nextMonth(isKeydownTrigger = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', 1); - this.dayViews.forEach((val) => { - val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', 1); - }); + // this.dayViews.forEach((val) => { + // val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', 1); + // }); this._monthAction = 'next'; if (this.daysView) { @@ -534,14 +546,23 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie this.viewDate = this.calendarModel.timedelta(date, 'month', delta); } + /** + * @hidden + */ + public daysViewInit(event: IgxDaysViewComponent) { + // this.monthViews. + } + /** * @hidden */ public changeMonth(event: Date) { this.viewDate = new Date(this.viewDate.getFullYear(), event.getMonth()); - this.dayViews.forEach((val, index) => { - val.viewDate.setMonth(event.getMonth() + index); - }); + // this.dayViews.forEach((val, index) => { + // // val.viewDate.setMonth(event.getMonth() + index); + // val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', index); + // }); + this.activeView = CalendarView.DEFAULT; requestAnimationFrame(() => { From 74eeda296d989ad88cb2d84a2163949d00065491 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Wed, 11 Sep 2019 18:19:19 +0300 Subject: [PATCH 23/41] fix(calendar): keep track of month changes #4282 --- .../src/lib/calendar/calendar.component.ts | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index a758b4ca4f3..11104fdc71d 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -10,8 +10,7 @@ import { ElementRef, AfterViewInit, ViewChildren, - QueryList, - AfterViewChecked + QueryList } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { fadeIn, scaleInCenter } from '../animations/main'; @@ -70,7 +69,7 @@ export interface IMonthView { selector: 'igx-calendar', templateUrl: 'calendar.component.html' }) -export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterViewInit, AfterViewChecked { +export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterViewInit { /** * Sets/gets the `id` of the calendar. * If not set, the `id` will have value `"igx-calendar-0"`. @@ -388,15 +387,6 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie }); } - public ngAfterViewChecked() { - this.monthViews.forEach((item, index) => { - const prevMonthView = this.getMonthView(index - 1); - const nextMonthView = this.getMonthView(index + 1); - item.nextMonthView = nextMonthView; - item.prevMonthView = prevMonthView; - }); - } - /** * Returns the locale representation of the month in the month view if enabled, * otherwise returns the default `Date.getMonth()` value. @@ -415,9 +405,6 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie */ public previousMonth(isKeydownTrigger = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', -1); - // this.dayViews.forEach((val) => { - // val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', -1); - // }); this._monthAction = 'prev'; if (this.daysView) { @@ -430,9 +417,6 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie */ public nextMonth(isKeydownTrigger = false) { this.viewDate = this.calendarModel.timedelta(this.viewDate, 'month', 1); - // this.dayViews.forEach((val) => { - // val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', 1); - // }); this._monthAction = 'next'; if (this.daysView) { @@ -558,10 +542,6 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie */ public changeMonth(event: Date) { this.viewDate = new Date(this.viewDate.getFullYear(), event.getMonth()); - // this.dayViews.forEach((val, index) => { - // // val.viewDate.setMonth(event.getMonth() + index); - // val.viewDate = this.calendarModel.timedelta(val.viewDate, 'month', index); - // }); this.activeView = CalendarView.DEFAULT; From 47f63cc0cd22af60e838cdb538cb9de9fd494be9 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Thu, 12 Sep 2019 11:49:00 +0300 Subject: [PATCH 24/41] build(calendar): fix npm lint error #4282 --- .../src/lib/core/styles/components/calendar/_calendar-theme.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 63ce9199bde..03ec14a2988 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -360,6 +360,7 @@ align-items: center; padding-bottom: $cal-picker-padding; position: relative; + div { text-align: center; } From 17f856830b7e97898bf23103eb48662f48f7d1b8 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Thu, 12 Sep 2019 14:16:31 +0300 Subject: [PATCH 25/41] fix(calendar): unsubscribe from changes #4282 --- .../src/lib/calendar/calendar.component.ts | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 11104fdc71d..78cb5f89140 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -10,7 +10,8 @@ import { ElementRef, AfterViewInit, ViewChildren, - QueryList + QueryList, + OnDestroy } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { fadeIn, scaleInCenter } from '../animations/main'; @@ -24,7 +25,7 @@ import { CalendarView, IgxMonthPickerBase } from './month-picker-base'; import { IgxMonthsViewComponent } from './months-view/months-view.component'; import { IgxYearsViewComponent } from './years-view/years-view.component'; import { IgxDaysViewComponent, IViewChangedArgs } from './days-view/days-view.component'; -import { interval } from 'rxjs'; +import { interval, Subscription } from 'rxjs'; import { takeUntil, debounce, skipLast, switchMap } from 'rxjs/operators'; import { ScrollMonth } from './calendar-base'; @@ -69,7 +70,7 @@ export interface IMonthView { selector: 'igx-calendar', templateUrl: 'calendar.component.html' }) -export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterViewInit { +export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterViewInit, OnDestroy { /** * Sets/gets the `id` of the calendar. * If not set, the `id` will have value `"igx-calendar-0"`. @@ -350,20 +351,20 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie viewDate: this.viewDate, }; + /** + *@hidden + */ + private _monthViewsChanges$: Subscription; + /** *@hidden */ public dayViews: Array = [this.defaultDayView]; public ngAfterViewInit() { - - this.monthViews.changes.subscribe(c => { - c.forEach((item, index) => { - const prevMonthView = this.getMonthView(index - 1); - const nextMonthView = this.getMonthView(index + 1); - item.nextMonthView = nextMonthView; - item.prevMonthView = prevMonthView; - }); + this.setSiblingMonths(this.monthViews); + this._monthViewsChanges$ = this.monthViews.changes.subscribe(c => { + this.setSiblingMonths(c); }); this.startMonthScroll$.pipe( @@ -763,6 +764,15 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie } } + /** + * @hidden + */ + public ngOnDestroy(): void { + if (this._monthViewsChanges$) { + this._monthViewsChanges$.unsubscribe(); + } + } + /** * Helper method building and returning the context object inside * the calendar templates. @@ -779,11 +789,25 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie return { $implicit: formatObject }; } + + /** + * Helper method sthat sets references for prev/next months for each month in the view + * @hidden + */ + private setSiblingMonths(monthViews: QueryList) { + monthViews.forEach((item, index) => { + const prevMonthView = this.getMonthView(index - 1); + const nextMonthView = this.getMonthView(index + 1); + item.nextMonthView = nextMonthView; + item.prevMonthView = prevMonthView; + }); + } + /** * Helper method returning previous/next day views * @hidden */ - private getMonthView(index): IgxDaysViewComponent { + private getMonthView(index: number): IgxDaysViewComponent { if (index === -1 || index === this.monthViews.length ) { return null; } else { From 18c5a61e14529ac9e1b6fed514d42be17acbce9b Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Thu, 12 Sep 2019 15:07:32 +0300 Subject: [PATCH 26/41] refactor(calendar): refactor and clean #4282 --- .../src/lib/calendar/calendar-base.ts | 2 +- .../src/lib/calendar/calendar.component.html | 4 +-- .../src/lib/calendar/calendar.component.ts | 33 +++++++------------ .../calendar/days-view/day-item.component.ts | 2 +- .../days-view/days-view.component.html | 2 +- .../src/lib/calendar/month-picker-base.ts | 7 +--- 6 files changed, 18 insertions(+), 32 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index ee5c086d8be..669b20f89e0 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -211,7 +211,7 @@ export class IgxCalendarBase implements ControlValueAccessor { } /** - * Sets/gets whether the inactive dates (dates that are out of the current month) will be hidden. + * Sets/gets whether the outside dates (dates that are out of the current month) will be hidden. * Default value is `false`. * ```html * diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index 21cc5a9a8fd..2716707cefd 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -33,8 +33,8 @@

keyboard_arrow_left

- - + +
- {{ formattedDate(day.date) }} + {{ formattedDate(day.date) }}
diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts index d29fa34fc2a..3e8c5ef365b 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker-base.ts @@ -1,7 +1,6 @@ import { IgxCalendarBase } from './calendar-base'; import { ViewChild, ElementRef, HostBinding } from '@angular/core'; import { KEYS } from '../core/utils'; -import { IMonthView } from './calendar.component'; /** * Sets the calender view - days, months or years. @@ -63,12 +62,8 @@ export class IgxMonthPickerBase extends IgxCalendarBase { /** * @hidden */ - public changeYear(event: Date, dayViews: IMonthView[]) { + public changeYear(event: Date) { this.viewDate = new Date(event.getFullYear(), this.viewDate.getMonth()); - const yearsDiff = event.getFullYear() - dayViews[0].viewDate.getFullYear(); - dayViews.forEach((val, index) => { - val.viewDate.setMonth(event.getMonth() + 12 * yearsDiff + index); - }); this._activeView = CalendarView.DEFAULT; requestAnimationFrame(() => { From 8f9980c5dad0328b3109bb9b1d1df8eabbdfe1e7 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Thu, 12 Sep 2019 15:28:09 +0300 Subject: [PATCH 27/41] fix(calendar): remove redundant paramater #4282 --- .../igniteui-angular/src/lib/calendar/calendar.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index 2716707cefd..81fc5867e90 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -77,5 +77,5 @@

[locale]="locale" [formatView]="formatViews.year" [yearFormat]="formatOptions.year" - (onSelection)="changeYear($event, dayViews)"> + (onSelection)="changeYear($event)"> \ No newline at end of file From 08b5093cbb572eb2ad627cf3227e718c238e1d4a Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Thu, 12 Sep 2019 15:51:08 +0300 Subject: [PATCH 28/41] docs(calendar): update readme files #4282 --- .../src/lib/calendar/README.md | 18 ++++++++++++++++-- .../src/lib/date-picker/README.md | 8 ++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/README.md b/projects/igniteui-angular/src/lib/calendar/README.md index 83b18711873..4a978e202fd 100644 --- a/projects/igniteui-angular/src/lib/calendar/README.md +++ b/projects/igniteui-angular/src/lib/calendar/README.md @@ -55,6 +55,12 @@ A multiple selection calendar with different locale and templating for the subhe ``` +A calendar displaying more than one month in the view and hiding the days that are outside of the current month +```html + + +``` + The **igxCalendar** implements the `ControlValueAccessor` interface, providing two-way data-binding and the expected behavior when used both in Template-driven or Reactive Forms. @@ -65,8 +71,8 @@ When the **igxCalendar** component is focused: - `PageDown` will move to the next month. - `Shift + PageUp` will move to the previous year. - `Shift + PageDown` will move to the next year. -- `Home` will focus the first day of the current month that is into view. -- `End` will focus the last day of the current month that is into view. +- `Home` will focus the first day of the current month (or first month if more months are displayed) hat is into view. +- `End` will focus the last day of the current month ((or last month if more months are displayed)) that is into view. - `Tab` will navigate through the subheader buttons; When `prev` or `next` month buttons (in the subheader) are focused: @@ -82,6 +88,7 @@ When a day inside the current month is focused: - Arrow keys will navigate through the days. - Arrow keys will allow navigation to previous/next month as well. - `Enter` will select the currently focused day. +- When more than one month view is displayed, navigating with the arrow keys should move to next/previous month after navigating from first/last day in current month. When a month inside the months view is focused: - Arrow keys will navigate through the months. @@ -154,6 +161,13 @@ The default values are listed below. { day: false, month: true, year: false } ``` +- `monthViewsNumber: number` +Controls the number of month views displayed. Default is 1. + +- `hideOusideDays: boolean` +Controls the visibility of the dates that do not belong to the current month. + + ### Outputs - `onSelection(): Date | Date[]` diff --git a/projects/igniteui-angular/src/lib/date-picker/README.md b/projects/igniteui-angular/src/lib/date-picker/README.md index 29265dcaff8..9c29c5375eb 100644 --- a/projects/igniteui-angular/src/lib/date-picker/README.md +++ b/projects/igniteui-angular/src/lib/date-picker/README.md @@ -59,6 +59,12 @@ The DatePicker also supports binding through `ngModel` if two-way date-bind is n ``` +A date-picker opening a calendar than one month in the view and hiding the days that are outside of the current month +```html + + +``` + The DatePicker has `dropdown` mode as well. Custom display format and editor mask can be configured by setting the `format` and `mask` properties. ```html @@ -127,6 +133,8 @@ The DatePicker action buttons could be retemplated. | `vertical` | `boolean` | Configure the calendar mode - horizontal or vertical in read-only datePicker. | | `mode` | `InteractionMode` | Configure the datePicker mode - `dialog` or `dropdown`. In `dropdown` mode, the datePicker input is editable and drop down calendar is displayed, in a `dialog` mode - the input is read-only and calendar dialog appears to select a date.| | `isSpinLoop` | `boolean` | Configure whether the date parts would spin continuously or stop when min/max value is reached in `dropdown` mode.| +| `monthViewsNumber` | `number` | Controls the number of month views displayed. | +| `hideOutsideDays`| `boolean` | Controls the visibility of the dates that do not belong to the current month. | ### Outputs From 1a16ff7a9962f5dbe1c4ed4afd7749e11aaf47ab Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Fri, 13 Sep 2019 15:05:47 +0300 Subject: [PATCH 29/41] perf(calendar): multi and range selection #4282 --- .../src/lib/calendar/calendar-base.ts | 6 +- .../calendar/days-view/day-item.component.ts | 117 +++++------------ .../days-view/days-view.component.html | 7 +- .../calendar/days-view/days-view.component.ts | 121 +++++++++++++++++- 4 files changed, 165 insertions(+), 86 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts index 669b20f89e0..8d46a6bd19e 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar-base.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar-base.ts @@ -143,6 +143,10 @@ export class IgxCalendarBase implements ControlValueAccessor { * Otherwise it is an array of `Date` objects. */ public set value(value: Date | Date[]) { + if (!value || !!value && (value as Date[]).length === 0) { + return; + } + this.selectDate(value); } @@ -416,7 +420,7 @@ export class IgxCalendarBase implements ControlValueAccessor { this.selectedDates = this.selectedDates.concat(newSelection); } } - + this.selectedDates.sort((a: Date, b: Date) => a.valueOf() - b.valueOf()); this._onChangeCallback(this.selectedDates); } diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index 67fa6785c53..fa081510bbc 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -1,6 +1,6 @@ import { Component, Input, Output, EventEmitter, HostBinding, ElementRef, HostListener } from '@angular/core'; import { ICalendarDate, isDateInRanges } from '../calendar'; -import { DateRangeDescriptor, DateRangeType } from '../../core/dates'; +import { DateRangeDescriptor } from '../../core/dates'; import { CalendarSelection } from '../calendar-base'; /** @@ -17,8 +17,21 @@ export class IgxDayItemComponent { @Input() public selection: string; + /** + * Returns boolean indicating if the day is selected + * + */ @Input() - public value: Date | Date[]; + public get selected(): any { + return this._selected; + } + + /** + * Selects the day + */ + public set selected(value: any) { + this._selected = value; + } @Input() public disabledDates: DateRangeDescriptor[]; @@ -32,32 +45,29 @@ export class IgxDayItemComponent { @Input() public hideOutsideDays = false; - @Output() - public onDateSelection = new EventEmitter(); + @Input() + @HostBinding('class.igx-calendar__date--last') + public isLastInRange = false; - public get selected(): boolean { - const date = this.date.date; + @Input() + @HostBinding('class.igx-calendar__date--first') + public isFirstInRange = false; - if (!this.value) { - return; - } + @Input() + @HostBinding('class.igx-calendar__date--firstday') + public isFirstInMonth = false; - if (this.selection === CalendarSelection.SINGLE) { - this._selected = (this.value as Date).getTime() === date.getTime(); - } else { - const selectedDates = (this.value as Date[]); - const currentDate = selectedDates.find(element => element.getTime() === date.getTime()); + @Input() + @HostBinding('class.igx-calendar__date--lastday') + public isLastInMonth = false; - this._index = selectedDates.indexOf(currentDate) + 1; - this._selected = !!this._index; - } + @Input() + @HostBinding('class.igx-calendar__date--range') + public isWithinRange = false; - return this._selected; - } + @Output() + public onDateSelection = new EventEmitter(); - public set selected(value: boolean) { - this._selected = value; - } public get isCurrentMonth(): boolean { return this.date.isCurrentMonth; @@ -146,12 +156,12 @@ export class IgxDayItemComponent { @HostBinding('class.igx-calendar__date--selected') public get isSelectedCSS(): boolean { - return this.selected && this.isCurrentMonth; + return this.isCurrentMonth && this.selected; } @HostBinding('class.igx-calendar__date--selected-dimmed') public get isSelectedDimmedCSS(): boolean { - return this.isSingleSelection && this.selected && !this.isCurrentMonth; + return !this.isCurrentMonth && this.isSingleSelection && this.selected; } @HostBinding('class.igx-calendar__date--weekend') @@ -161,25 +171,9 @@ export class IgxDayItemComponent { @HostBinding('class.igx-calendar__date--disabled') public get isDisabledCSS(): boolean { - return this.isDisabled || this.isOutOfRange || this.isHidden; + return this.isHidden || this.isDisabled || this.isOutOfRange; } - @HostBinding('class.igx-calendar__date--range') - public get isWithinRange() { - if (Array.isArray(this.value) && this.value.length > 1) { - - return isDateInRanges(this.date.date, - [ - { - type: DateRangeType.Between, - dateRange: [this.value[0], this.value[this.value.length - 1]] - } - ] - ); - } - - return false; - } @HostBinding('class.igx-calendar__date--special') public get isSpecialCSS(): boolean { @@ -191,52 +185,11 @@ export class IgxDayItemComponent { return this.selection !== CalendarSelection.RANGE; } - @HostBinding('class.igx-calendar__date--first') - public get isFirstInRange(): boolean { - if (this.isSingleSelection) { - return false; - } - - return this._index === 1; - } - - @HostBinding('class.igx-calendar__date--last') - public get isLastInRange(): boolean { - if (this.isSingleSelection) { - return false; - } - - return (this.value as Date[]).length === this._index; - } - - @HostBinding('class.igx-calendar__date--lastday') - public get isLastInMonth(): boolean { - const checkLast = true; - return this.isFirstLastInMonth(checkLast); - } - - @HostBinding('class.igx-calendar__date--firstday') - public get isFirstInMonth(): boolean { - const checkLast = false; - return this.isFirstLastInMonth(checkLast); - } - private _index: Number; private _selected = false; constructor(private elementRef: ElementRef) { } - private isFirstLastInMonth(checkLast: boolean): boolean { - const inc = checkLast ? 1 : -1; - if (!this.isSingleSelection && this.isCurrentMonth && this.isWithinRange) { - const nextDay = new Date(this.date.date); - nextDay.setDate(nextDay.getDate() + inc); - if (this.date.date.getMonth() + inc === nextDay.getMonth()) { - return true; - } - } - return false; - } @HostListener('click') @HostListener('keydown.enter') diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html index 4899b4a2062..3925f4892ac 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html @@ -11,7 +11,12 @@ *ngFor="let day of week; trackBy: dateTracker" [date]="day" [selection]="selection" - [value]="value" + [selected]="isSelected(day)" + [isLastInRange]="isLastInRange(day)" + [isFirstInRange]="isFirstInRange(day)" + [isFirstInMonth]="isFirstInMonth(day)" + [isLastInMonth]="isLastInMonth(day)" + [isWithinRange]="isWithinRange(day.date, true)" [disabledDates]="disabledDates" [specialDates]="specialDates" [outOfRangeDates]="outOfRangeDates" diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index d3285663b09..cbb1bd92f70 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -9,13 +9,14 @@ import { HostBinding, DoCheck } from '@angular/core'; -import { ICalendarDate } from '../../calendar'; +import { ICalendarDate, isDateInRanges } from '../../calendar'; import { trigger, transition, useAnimation } from '@angular/animations'; import { slideInLeft, slideInRight } from '../../animations/main'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { IgxDayItemComponent } from './day-item.component'; import { DateRangeDescriptor, DateRangeType } from '../../core/dates'; -import { IgxCalendarBase, ScrollMonth } from '../calendar-base'; +import { IgxCalendarBase, ScrollMonth, CalendarSelection } from '../calendar-base'; +import { isEqual } from '../../core/utils'; let NEXT_ID = 0; @@ -202,6 +203,100 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { return this.viewDate.getFullYear() === value.getFullYear(); } + /** + * @hidden + */ + public isSelected(date: ICalendarDate): boolean { + const selectedDates = (this.value as Date[]); + if (!date.isCurrentMonth) { + return; + } + + if (!this.value || selectedDates.length === 0) { + return; + } + + if (selectedDates.length === 1) { + return this.value[0].getTime() === date.date.getTime(); + } + + if (this.selection === CalendarSelection.MULTI) { + const start = this.getDateOnly(selectedDates[0]); + const end = this.getDateOnly(selectedDates[selectedDates.length - 1]); + + if (this.isWithinRange(date.date, false, start, end)) { + const currentDate = selectedDates.find(element => element.getTime() === date.date.getTime()); + return !!currentDate; + } else { + return false; + } + + } else { + return this.isWithinRange(date.date, false); + } + } + + /** + * @hidden + */ + public isLastInRange(date: ICalendarDate): boolean { + if (this.isSingleSelection || !this.value) { + return false; + } + + const dates = this.value as Date[]; + const lastDate = dates[dates.length - 1]; + return isEqual(lastDate, date.date); + } + + /** + * @hidden + */ + public isFirstInRange(date: ICalendarDate): boolean { + if (this.isSingleSelection || !this.value) { + return false; + } + + return isEqual((this.value as Date[])[0], date.date); + } + + /** + * @hidden + */ + public isFirstInMonth(date: ICalendarDate): boolean { + const checkLast = false; + return this.isFirstLastInMonth(checkLast, date); + } + + /** + * @hidden + */ + public isLastInMonth(date: ICalendarDate): boolean { + const checkLast = false; + return this.isFirstLastInMonth(checkLast, date); + } + + /** + * @hidden + */ + public isWithinRange(date: Date, checkForRange: boolean, min?: Date, max?: Date): boolean { + if (checkForRange && !(Array.isArray(this.value) && this.value.length > 1)) { + return; + } + + min = min ? min : this.value[0]; + max = max ? max : this.value[(this.value as Date[]).length - 1]; + + return isDateInRanges(date, + [ + { + type: DateRangeType.Between, + dateRange: [min, max] + } + ] + ); + } + /** *@hidden */ @@ -509,6 +604,28 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { return !!day && day.isCurrentMonth && !day.isHidden && !day.isDisabled && !day.isOutOfRange; } + /** + * @hidden + */ + private isFirstLastInMonth(checkLast: boolean, date: ICalendarDate): boolean { + const inc = checkLast ? 1 : -1; + if (date.isCurrentMonth && !this.isSingleSelection && this.isWithinRange(date.date, true)) { + const nextDay = new Date(date.date); + nextDay.setDate(nextDay.getDate() + inc); + if (this.isWithinRange(nextDay, false) && date.date.getMonth() + inc === nextDay.getMonth()) { + return true; + } + } + return false; + } + + /** + * @hidden + */ + private get isSingleSelection(): boolean { + return this.selection !== CalendarSelection.RANGE; + } + /** * @hidden */ From 978dd57a83df4fb8ebb403263b7a999701de100d Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Fri, 13 Sep 2019 15:32:16 +0300 Subject: [PATCH 30/41] fix(calendar): check for range selection #4282 --- .../src/lib/calendar/days-view/day-item.component.ts | 1 - .../src/lib/calendar/days-view/days-view.component.ts | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index fa081510bbc..31ce468e30b 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -190,7 +190,6 @@ export class IgxDayItemComponent { constructor(private elementRef: ElementRef) { } - @HostListener('click') @HostListener('keydown.enter') public onSelect() { diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index cbb1bd92f70..b90f386f4a4 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -209,11 +209,11 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { public isSelected(date: ICalendarDate): boolean { const selectedDates = (this.value as Date[]); if (!date.isCurrentMonth) { - return; + return false; } if (!this.value || selectedDates.length === 0) { - return; + return false; } if (selectedDates.length === 1) { @@ -232,7 +232,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { } } else { - return this.isWithinRange(date.date, false); + return this.isWithinRange(date.date, true); } } @@ -281,7 +281,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ public isWithinRange(date: Date, checkForRange: boolean, min?: Date, max?: Date): boolean { if (checkForRange && !(Array.isArray(this.value) && this.value.length > 1)) { - return; + return false; } min = min ? min : this.value[0]; @@ -612,7 +612,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { if (date.isCurrentMonth && !this.isSingleSelection && this.isWithinRange(date.date, true)) { const nextDay = new Date(date.date); nextDay.setDate(nextDay.getDate() + inc); - if (this.isWithinRange(nextDay, false) && date.date.getMonth() + inc === nextDay.getMonth()) { + if (this.isWithinRange(nextDay, true) && date.date.getMonth() + inc === nextDay.getMonth()) { return true; } } From b883778cf061f654741b015bfa9feadd4056cc9c Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Fri, 13 Sep 2019 16:50:08 +0300 Subject: [PATCH 31/41] fix(calendar): treat value type accordingly #4282 --- .../lib/calendar/days-view/days-view.component.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index b90f386f4a4..05d72ddf5ae 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -207,17 +207,23 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { * @hidden */ public isSelected(date: ICalendarDate): boolean { - const selectedDates = (this.value as Date[]); + let selectedDates: Date | Date[]; if (!date.isCurrentMonth) { return false; } - if (!this.value || selectedDates.length === 0) { + if (!this.value || (Array.isArray(this.value) && this.value.length === 0)) { return false; } - if (selectedDates.length === 1) { - return this.value[0].getTime() === date.date.getTime(); + if (this.selection === CalendarSelection.SINGLE) { + selectedDates = (this.value as Date); + return this.getDateOnly(selectedDates).getTime() === date.date.getTime(); + } + + selectedDates = (this.value as Date[]); + if (this.selection === CalendarSelection.RANGE && selectedDates.length === 1) { + return this.getDateOnly(selectedDates[0]).getTime() === date.date.getTime(); } if (this.selection === CalendarSelection.MULTI) { From 6c0ec082a10fcce6c84b2f388aa5a51338f99401 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Fri, 13 Sep 2019 17:36:50 +0300 Subject: [PATCH 32/41] fix(calendar): exclude disabled dates #4282 --- .../src/lib/calendar/days-view/days-view.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index 05d72ddf5ae..d27d34b247a 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -208,7 +208,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ public isSelected(date: ICalendarDate): boolean { let selectedDates: Date | Date[]; - if (!date.isCurrentMonth) { + if (!date.isCurrentMonth || this.isDateDisabled(date.date)) { return false; } From 825b2e2c010f9ab128f75365734349e12ec97282 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Mon, 16 Sep 2019 11:25:58 +0300 Subject: [PATCH 33/41] refactor(calendar): remove circ dependency #4282 --- .../src/lib/calendar/calendar.component.ts | 8 ++------ .../src/lib/calendar/calendar.interface.ts | 16 ++++++++++++++++ .../calendar/days-view/days-view.component.ts | 9 ++------- 3 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/calendar/calendar.interface.ts diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 5cd59bfef52..ffee6084f11 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -24,18 +24,14 @@ import { ICalendarDate, monthRange } from './calendar'; import { CalendarView, IgxMonthPickerBase } from './month-picker-base'; import { IgxMonthsViewComponent } from './months-view/months-view.component'; import { IgxYearsViewComponent } from './years-view/years-view.component'; -import { IgxDaysViewComponent, IViewChangedArgs } from './days-view/days-view.component'; +import { IgxDaysViewComponent } from './days-view/days-view.component'; import { interval, Subscription } from 'rxjs'; import { takeUntil, debounce, skipLast, switchMap } from 'rxjs/operators'; import { ScrollMonth } from './calendar-base'; +import { IMonthView, IViewChangedArgs } from './calendar.interface'; let NEXT_ID = 0; -export interface IMonthView { - value: Date | Date[]; - viewDate: Date; -} - /** * **Ignite UI for Angular Calendar** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/calendar.html) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.interface.ts b/projects/igniteui-angular/src/lib/calendar/calendar.interface.ts new file mode 100644 index 00000000000..1a9499f30e1 --- /dev/null +++ b/projects/igniteui-angular/src/lib/calendar/calendar.interface.ts @@ -0,0 +1,16 @@ +/** + * @hidden + */ +export interface IMonthView { + value: Date | Date[]; + viewDate: Date; +} + +/** + * @hidden + */ +export interface IViewChangedArgs { + date: Date; + delta: number; + moveToFirst?: boolean; +} diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index d27d34b247a..5b275ed0a24 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -9,7 +9,7 @@ import { HostBinding, DoCheck } from '@angular/core'; -import { ICalendarDate, isDateInRanges } from '../../calendar'; +import { ICalendarDate, isDateInRanges } from '../../calendar/calendar'; import { trigger, transition, useAnimation } from '@angular/animations'; import { slideInLeft, slideInRight } from '../../animations/main'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; @@ -17,15 +17,10 @@ import { IgxDayItemComponent } from './day-item.component'; import { DateRangeDescriptor, DateRangeType } from '../../core/dates'; import { IgxCalendarBase, ScrollMonth, CalendarSelection } from '../calendar-base'; import { isEqual } from '../../core/utils'; +import { IViewChangedArgs } from '../calendar.interface'; let NEXT_ID = 0; -export interface IViewChangedArgs { - date: Date; - delta: number; - moveToFirst?: boolean; -} - @Component({ providers: [ { From cc58e3076fa223c1a398eae8e8a2f6d50607ec99 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 08:22:38 +0300 Subject: [PATCH 34/41] fix(calendar): fix selection bugs clear code #4282 --- .../src/lib/calendar/calendar.component.ts | 20 ++-- .../src/lib/calendar/calendar.interface.ts | 16 ---- .../calendar/days-view/day-item.component.ts | 43 ++------- .../calendar/days-view/days-view.component.ts | 93 ++++++++++++++++--- .../calendar/_calendar-component.scss | 5 - .../components/calendar/_calendar-theme.scss | 8 -- 6 files changed, 90 insertions(+), 95 deletions(-) delete mode 100644 projects/igniteui-angular/src/lib/calendar/calendar.interface.ts diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index ffee6084f11..516e3c0d528 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -28,7 +28,6 @@ import { IgxDaysViewComponent } from './days-view/days-view.component'; import { interval, Subscription } from 'rxjs'; import { takeUntil, debounce, skipLast, switchMap } from 'rxjs/operators'; import { ScrollMonth } from './calendar-base'; -import { IMonthView, IViewChangedArgs } from './calendar.interface'; let NEXT_ID = 0; @@ -120,7 +119,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie for (let i = this._monthsViewNumber; i < val; i++) { const nextMonthDate = new Date(this.viewDate); nextMonthDate.setMonth(nextMonthDate.getMonth() + i); - const monthView: IMonthView = { + const monthView = { value: null, viewDate: nextMonthDate }; @@ -347,7 +346,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** *@hidden */ - private defaultDayView: IMonthView = { + private defaultDayView = { value: this.value, viewDate: this.viewDate, }; @@ -355,7 +354,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** *@hidden */ - public dayViews: Array = [this.defaultDayView]; + public dayViews = [this.defaultDayView]; public ngAfterViewInit() { this.setSiblingMonths(this.monthViews); @@ -518,16 +517,9 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** * @hidden */ - public viewChanged(event: IViewChangedArgs) { - let date = this.viewDate, - delta = event.delta; - if (event.moveToFirst) { - delta = 0; - date = event.date; - } - this.viewDate = this.calendarModel.timedelta(date, 'month', delta); + public viewChanged(event) { + this.viewDate = this.calendarModel.timedelta(event, 'month', 0); } - /** * @hidden */ @@ -778,7 +770,7 @@ export class IgxCalendarComponent extends IgxMonthPickerBase implements AfterVie /** - * Helper method sthat sets references for prev/next months for each month in the view + * Helper method that sets references for prev/next months for each month in the view * @hidden */ private setSiblingMonths(monthViews: QueryList) { diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.interface.ts b/projects/igniteui-angular/src/lib/calendar/calendar.interface.ts deleted file mode 100644 index 1a9499f30e1..00000000000 --- a/projects/igniteui-angular/src/lib/calendar/calendar.interface.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @hidden - */ -export interface IMonthView { - value: Date | Date[]; - viewDate: Date; -} - -/** - * @hidden - */ -export interface IViewChangedArgs { - date: Date; - delta: number; - moveToFirst?: boolean; -} diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index 31ce468e30b..9af60d01799 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -22,6 +22,7 @@ export class IgxDayItemComponent { * */ @Input() + @HostBinding('class.igx-calendar__date--selected') public get selected(): any { return this._selected; } @@ -85,14 +86,17 @@ export class IgxDayItemComponent { return this.elementRef.nativeElement; } + @HostBinding('class.igx-calendar__date--inactive') public get isInactive(): boolean { return this.date.isNextMonth || this.date.isPrevMonth; } + @HostBinding('class.igx-calendar__date--hidden') public get isHidden(): boolean { return this.hideOutsideDays && this.isInactive; } + @HostBinding('class.igx-calendar__date--current') public get isToday(): boolean { const today = new Date(Date.now()); const date = this.date.date; @@ -102,6 +106,7 @@ export class IgxDayItemComponent { ); } + @HostBinding('class.igx-calendar__date--weekend') public get isWeekend(): boolean { const day = this.date.date.getDay(); return day === 0 || day === 6; @@ -123,6 +128,7 @@ export class IgxDayItemComponent { return isDateInRanges(this.date.date, this.outOfRangeDates); } + @HostBinding('class.igx-calendar__date--special') public get isSpecial(): boolean { if (this.specialDates === null) { return false; @@ -139,53 +145,16 @@ export class IgxDayItemComponent { return this.date.isCurrentMonth && !(this.isWeekend && this.selected); } - @HostBinding('class.igx-calendar__date--inactive') - public get isInactiveCSS(): boolean { - return this.isInactive; - } - - @HostBinding('class.igx-calendar__date--hidden') - get isHiddenCSS(): boolean { - return this.isHidden; - } - - @HostBinding('class.igx-calendar__date--current') - public get isTodayCSS(): boolean { - return this.isToday; - } - - @HostBinding('class.igx-calendar__date--selected') - public get isSelectedCSS(): boolean { - return this.isCurrentMonth && this.selected; - } - - @HostBinding('class.igx-calendar__date--selected-dimmed') - public get isSelectedDimmedCSS(): boolean { - return !this.isCurrentMonth && this.isSingleSelection && this.selected; - } - - @HostBinding('class.igx-calendar__date--weekend') - public get isWeekendCSS(): boolean { - return this.isWeekend; - } - @HostBinding('class.igx-calendar__date--disabled') public get isDisabledCSS(): boolean { return this.isHidden || this.isDisabled || this.isOutOfRange; } - - @HostBinding('class.igx-calendar__date--special') - public get isSpecialCSS(): boolean { - return this.isSpecial; - } - @HostBinding('class.igx-calendar__date--single') public get isSingleSelection(): boolean { return this.selection !== CalendarSelection.RANGE; } - private _selected = false; constructor(private elementRef: ElementRef) { } diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index 5b275ed0a24..3bd08c62f23 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -17,7 +17,6 @@ import { IgxDayItemComponent } from './day-item.component'; import { DateRangeDescriptor, DateRangeType } from '../../core/dates'; import { IgxCalendarBase, ScrollMonth, CalendarSelection } from '../calendar-base'; import { isEqual } from '../../core/utils'; -import { IViewChangedArgs } from '../calendar.interface'; let NEXT_ID = 0; @@ -83,7 +82,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { * @hidden */ @Output() - public onViewChanged = new EventEmitter(); + public onViewChanged = new EventEmitter(); /** * @hidden @@ -203,7 +202,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ public isSelected(date: ICalendarDate): boolean { let selectedDates: Date | Date[]; - if (!date.isCurrentMonth || this.isDateDisabled(date.date)) { + if (this.isDateDisabled(date.date)) { return false; } @@ -318,6 +317,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ public selectDay(event) { this.selectDateFromClient(event.date); + this.deselectDateInMonthViews(event.date); this.onDateSelection.emit(event); this.onSelection.emit(this.selectedDates); @@ -349,14 +349,14 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { private focusPreviousUpDate(target, prevView = false) { const node = this.dates.find((date) => date.nativeElement === target); let dates = this.dates.toArray(), - day: IgxDayItemComponent; + day: IgxDayItemComponent, i; const index = dates.indexOf(node); if (!node) { return; } this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -7); // focus item in current month - for (let i = index; i - 7 > -1; i -= 7) { + for (i = index; i - 7 > -1; i -= 7) { day = prevView ? dates[i] : dates[i - 7]; this.nextDate = day.date.date; if (day.date.isPrevMonth) { @@ -380,6 +380,13 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { this.prevMonthView.focusPreviousUpDate(day.nativeElement); } + if (!this.isDayFocusable(day)) { + day = dates[i - 7]; + if (!day) { + this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', -7); + } + } + // focus item in next month, which is currently out of view if (this.changeDaysView && !this.prevMonthView && ((day && day.isPreviousMonth) || !day)) { this.isKeydownTrigger = true; @@ -392,7 +399,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { } }; - this.onViewChanged.emit({ date: this.nextDate, delta: -1 }); + this.onViewChanged.emit(this.nextDate); } } @@ -402,14 +409,14 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { private focusNextDownDate(target, nextView = false) { const node = this.dates.find((date) => date.nativeElement === target); let dates = this.dates.toArray(), - day: IgxDayItemComponent; + day: IgxDayItemComponent, i; const index = dates.indexOf(node); if (!node) { return; } this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 7); // focus item in current month - for (let i = index; i + 7 < 42; i += 7) { + for (i = index; i + 7 < 42; i += 7) { day = nextView ? dates[i] : dates[i + 7]; this.nextDate = day.date.date; if (day.date.isNextMonth) { @@ -433,6 +440,14 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { this.nextMonthView.focusNextDownDate(day.nativeElement); } + if (!this.isDayFocusable(day)) { + day = dates[i + 7]; + if (!day) { + this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', 7); + } + + } + // focus item in next month, which is currently out of view if (this.changeDaysView && !this.nextMonthView && ((day && day.isNextMonth) || !day)) { this.isKeydownTrigger = true; @@ -447,7 +462,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { } }; - this.onViewChanged.emit({ date: this.nextDate, delta: 1, moveToFirst: true }); + this.onViewChanged.emit(this.nextDate); } } @@ -457,13 +472,13 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { private focusPreviousDate(target, prevView = false) { const node = this.dates.find((date) => date.nativeElement === target); let dates = this.dates.toArray(), - day: IgxDayItemComponent; + day: IgxDayItemComponent, i: number; const index = dates.indexOf(node); if (!node) { return; } this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', -1); - for (let i = index; i > 0; i--) { + for (i = index; i > 0; i--) { day = prevView ? dates[i] : dates[i - 1]; this.nextDate = day.date.date; if (day.date.isPrevMonth) { @@ -487,6 +502,13 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { this.prevMonthView.focusPreviousDate(day.nativeElement); } + if (!this.isDayFocusable(day)) { + day = dates[i - 1]; + if (!day) { + this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', -1); + } + } + // focus item in previous month, which is currently out of view if (this.changeDaysView && !this.prevMonthView && ((day && day.isPreviousMonth) || !day)) { this.isKeydownTrigger = true; @@ -499,7 +521,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { } }; - this.onViewChanged.emit({ date: this.nextDate, delta: -1 }); + this.onViewChanged.emit(this.nextDate); } } @@ -509,14 +531,14 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { private focusNextDate(target, nextView = false) { const node = this.dates.find((date) => date.nativeElement === target); let dates = this.dates.toArray(), - day: IgxDayItemComponent; + day: IgxDayItemComponent, i; let index = dates.indexOf(node); if (!node) { return; } this.nextDate = this.calendarModel.timedelta(node.date.date, 'day', 1); // focus item in current month - for (let i = index; i < dates.length - 1; i++) { + for (i = index; i < dates.length - 1; i++) { day = nextView ? dates[i] : dates[i + 1]; this.nextDate = day.date.date; if (day.date.isNextMonth) { @@ -541,6 +563,13 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { this.nextMonthView.focusNextDate(day.nativeElement); } + if (!this.isDayFocusable(day)) { + day = dates[i + 1]; + if (!day) { + this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', 1); + } + } + // focus item in next month, which is currently out of view if (this.changeDaysView && !this.nextMonthView && ((day && day.isNextMonth) || !day)) { this.isKeydownTrigger = true; @@ -555,7 +584,7 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { } }; - this.onViewChanged.emit({ date: this.nextDate, delta: 1, moveToFirst: true }); + this.onViewChanged.emit(this.nextDate); } } @@ -576,6 +605,40 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { }]; } + /** + * Helper method that does deselection for all month views when selection is "multi" + * If not called, selection in other month views stays + * @hidden + */ + private deselectDateInMonthViews(value: Date) { + let monthView = this as IgxDaysViewComponent; + while (monthView.prevMonthView) { + monthView = monthView.prevMonthView; + this.deselectMultipleInMonth(monthView, value); + } + monthView = this as IgxDaysViewComponent; + while (monthView.nextMonthView) { + monthView = monthView.nextMonthView; + this.deselectMultipleInMonth(monthView, value); + } + } + + /** + * @hidden + */ + private deselectMultipleInMonth(monthView: IgxDaysViewComponent, value: Date) { + const mDates = monthView.selectedDates.map(v => this.getDateOnly(v).getTime()); + const selDates = this.selectedDates.map(v => this.getDateOnly(v).getTime()); + + if (JSON.stringify(mDates) === JSON.stringify(selDates)) { + return; + } + const valueDateOnly = this.getDateOnly(value); + monthView.selectedDates = monthView.selectedDates.filter( + (date: Date) => date.getTime() !== valueDateOnly.getTime() + ); + } + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss index 2890455da5c..9277f96e3cc 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss @@ -59,11 +59,6 @@ @extend %cal-value--selected !optional; } - @include e(date, 'selected-dimmed') { - @extend %cal-value !optional; - @extend %cal-value--selected-dimmed !optional; - } - @include e(date, 'current') { @extend %cal-value !optional; @extend %cal-value--current !optional; diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 03ec14a2988..76bcd70343f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -560,14 +560,6 @@ } } - %cal-value--selected-dimmed { - %cal-value-content { - color: --var($theme, 'date-selected-text-color'); - background: --var($theme, 'date-selected-background') ; - opacity: .6; - } - } - %cal-value--current { %cal-value-content { color: --var($theme, 'date-current-text-color'); From 237163e72f2014f7ed4d812723c8cd49271b5818 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 08:30:34 +0300 Subject: [PATCH 35/41] style(month-picker): alighn m-picker header #4282 --- .../month-picker/month-picker.component.html | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html index 478e15edb61..11c40c1c4a7 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html @@ -1,14 +1,20 @@
-
+
keyboard_arrow_left
-
+
{{ formattedYear(viewDate) }}
-
+
keyboard_arrow_right
From 644d6e82e83c1bc73a4c01ddee7c1a5464085ead Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 08:33:07 +0300 Subject: [PATCH 36/41] test(calendar): dont test duplicated getter #4282 --- .../src/lib/calendar/calendar.component.spec.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 22718592477..6614785392c 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -1070,7 +1070,6 @@ describe('IgxCalendar', () => { specialDates.forEach(d => { expect(d.isSpecial).toBe(true); - expect(d.isSpecialCSS).toBe(true); }); let disabledDates = calendar.daysView.dates.toArray().filter(d => { @@ -1098,7 +1097,6 @@ describe('IgxCalendar', () => { specialDates.forEach(d => { expect(d.isSpecial).toBe(true); - expect(d.isSpecialCSS).toBe(true); }); disabledDates = calendar.daysView.dates.toArray().filter(d => { @@ -2070,7 +2068,6 @@ class DateTester { static testDatesSpeciality(dates: IgxDayItemComponent[], special: boolean): void { for (const date of dates) { expect(date.isSpecial).toBe(special); - expect(date.isSpecialCSS).toBe(special); } } } From e36bea7531d7615119c60ca6b156e661611e1a17 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 09:23:50 +0300 Subject: [PATCH 37/41] fix(calendar): dont recalculate next date #4282 --- .../src/lib/calendar/calendar.component.spec.ts | 2 -- .../lib/calendar/days-view/days-view.component.ts | 12 ------------ 2 files changed, 14 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 6614785392c..21354c687cd 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -1040,7 +1040,6 @@ describe('IgxCalendar', () => { selectedDates.forEach(d => { expect(d.selected).toBe(true); - expect(d.isSelectedCSS).toBe(true); }); const notSelectedDates = calendar.daysView.dates.toArray().filter(d => { @@ -1051,7 +1050,6 @@ describe('IgxCalendar', () => { notSelectedDates.forEach(d => { expect(d.selected).toBe(false); - expect(d.isSelectedCSS).toBe(false); }); }); }); diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index 3bd08c62f23..b29359b8021 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -382,9 +382,6 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { if (!this.isDayFocusable(day)) { day = dates[i - 7]; - if (!day) { - this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', -7); - } } // focus item in next month, which is currently out of view @@ -442,9 +439,6 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { if (!this.isDayFocusable(day)) { day = dates[i + 7]; - if (!day) { - this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', 7); - } } @@ -504,9 +498,6 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { if (!this.isDayFocusable(day)) { day = dates[i - 1]; - if (!day) { - this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', -1); - } } // focus item in previous month, which is currently out of view @@ -565,9 +556,6 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { if (!this.isDayFocusable(day)) { day = dates[i + 1]; - if (!day) { - this.nextDate = this.calendarModel.timedelta(this.nextDate, 'day', 1); - } } // focus item in next month, which is currently out of view From f371d65a716313aa4f46642f50f8cf13d0ab1212 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 13:13:15 +0300 Subject: [PATCH 38/41] fix(calendar): fix coloring inactive days #4282 --- .../calendar/days-view/day-item.component.ts | 15 +++----- .../days-view/days-view.component.html | 2 - .../calendar/days-view/days-view.component.ts | 38 ++----------------- .../calendar/_calendar-component.scss | 4 ++ .../components/calendar/_calendar-theme.scss | 22 +++++++++++ 5 files changed, 34 insertions(+), 47 deletions(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index 9af60d01799..8ab60cb353d 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -22,7 +22,6 @@ export class IgxDayItemComponent { * */ @Input() - @HostBinding('class.igx-calendar__date--selected') public get selected(): any { return this._selected; } @@ -54,14 +53,6 @@ export class IgxDayItemComponent { @HostBinding('class.igx-calendar__date--first') public isFirstInRange = false; - @Input() - @HostBinding('class.igx-calendar__date--firstday') - public isFirstInMonth = false; - - @Input() - @HostBinding('class.igx-calendar__date--lastday') - public isLastInMonth = false; - @Input() @HostBinding('class.igx-calendar__date--range') public isWithinRange = false; @@ -69,7 +60,6 @@ export class IgxDayItemComponent { @Output() public onDateSelection = new EventEmitter(); - public get isCurrentMonth(): boolean { return this.date.isCurrentMonth; } @@ -86,6 +76,11 @@ export class IgxDayItemComponent { return this.elementRef.nativeElement; } + @HostBinding('class.igx-calendar__date--selected') + public get isSelectedCSS(): boolean { + return (!this.isDisabled && this.selected); + } + @HostBinding('class.igx-calendar__date--inactive') public get isInactive(): boolean { return this.date.isNextMonth || this.date.isPrevMonth; diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html index 3925f4892ac..03787f95cec 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.html @@ -14,8 +14,6 @@ [selected]="isSelected(day)" [isLastInRange]="isLastInRange(day)" [isFirstInRange]="isFirstInRange(day)" - [isFirstInMonth]="isFirstInMonth(day)" - [isLastInMonth]="isLastInMonth(day)" [isWithinRange]="isWithinRange(day.date, true)" [disabledDates]="disabledDates" [specialDates]="specialDates" diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index b29359b8021..c80cd9aea9f 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -202,11 +202,9 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ public isSelected(date: ICalendarDate): boolean { let selectedDates: Date | Date[]; - if (this.isDateDisabled(date.date)) { - return false; - } - - if (!this.value || (Array.isArray(this.value) && this.value.length === 0)) { + if (this.isDateDisabled(date.date) || !this.value || + (Array.isArray(this.value) && this.value.length === 0) + ) { return false; } @@ -260,21 +258,6 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { return isEqual((this.value as Date[])[0], date.date); } - /** - * @hidden - */ - public isFirstInMonth(date: ICalendarDate): boolean { - const checkLast = false; - return this.isFirstLastInMonth(checkLast, date); - } - - /** - * @hidden - */ - public isLastInMonth(date: ICalendarDate): boolean { - const checkLast = false; - return this.isFirstLastInMonth(checkLast, date); - } /** * @hidden @@ -656,21 +639,6 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { return !!day && day.isCurrentMonth && !day.isHidden && !day.isDisabled && !day.isOutOfRange; } - /** - * @hidden - */ - private isFirstLastInMonth(checkLast: boolean, date: ICalendarDate): boolean { - const inc = checkLast ? 1 : -1; - if (date.isCurrentMonth && !this.isSingleSelection && this.isWithinRange(date.date, true)) { - const nextDay = new Date(date.date); - nextDay.setDate(nextDay.getDate() + inc); - if (this.isWithinRange(nextDay, true) && date.date.getMonth() + inc === nextDay.getMonth()) { - return true; - } - } - return false; - } - /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss index 9277f96e3cc..700e45e043e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss @@ -68,6 +68,10 @@ @extend %cal-value--hidden !optional; } + @include e(date, 'range') { + @extend %cal-value--range !optional; + } + @include e(date, $mods: ('selected', 'current')) { @extend %cal-value--current--selected !optional; } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 76bcd70343f..c0e865676fc 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -627,6 +627,28 @@ %cal-value--hidden%cal-value--disabled-range { background: transparent !important; + + &::after, &::before { + background: transparent !important; + } + } + + %cal-value--range%cal-value--inactive%cal-value--selected { + background: transparent !important; + + %cal-value-content { + color: --var($theme, 'date-disabled-text-color'); + background: transparent !important; + } + } + + %cal-value--range%cal-value--inactive%cal-value--selected%cal-value--single { + background: transparent !important; + + %cal-value-content { + color: --var($theme, 'date-selected-text-color'); + background: --var($theme, 'date-selected-background') !important; + } } %cal-value--first { From 5b569fe456ca07b0775bb74fdfd36378fa25d80c Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 13:20:54 +0300 Subject: [PATCH 39/41] fix(calendar): fix single selecetion error #4282 --- .../src/lib/calendar/days-view/days-view.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts index c80cd9aea9f..cfad868dd5b 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/days-view.component.ts @@ -300,7 +300,9 @@ export class IgxDaysViewComponent extends IgxCalendarBase implements DoCheck { */ public selectDay(event) { this.selectDateFromClient(event.date); - this.deselectDateInMonthViews(event.date); + if (this.selection === 'multi') { + this.deselectDateInMonthViews(event.date); + } this.onDateSelection.emit(event); this.onSelection.emit(this.selectedDates); From 866557b870fa3a28c5f5a83ed76b8122d26a0378 Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 13:33:03 +0300 Subject: [PATCH 40/41] fix(calendar): make tslint happy #4282 --- .../lib/core/styles/components/calendar/_calendar-theme.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index c0e865676fc..17412259ac8 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -628,7 +628,8 @@ %cal-value--hidden%cal-value--disabled-range { background: transparent !important; - &::after, &::before { + &::after, + &::before { background: transparent !important; } } From d2a53867a36fb1cfc1868f4f5948ba06daacc11c Mon Sep 17 00:00:00 2001 From: Hristo Anastasov Date: Tue, 17 Sep 2019 15:40:06 +0300 Subject: [PATCH 41/41] style(calendar): fix style in rang selection #4282 --- .../src/lib/calendar/days-view/day-item.component.ts | 5 ++++- .../styles/components/calendar/_calendar-theme.scss | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts index 8ab60cb353d..4e97a268267 100644 --- a/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/days-view/day-item.component.ts @@ -54,7 +54,6 @@ export class IgxDayItemComponent { public isFirstInRange = false; @Input() - @HostBinding('class.igx-calendar__date--range') public isWithinRange = false; @Output() @@ -122,6 +121,10 @@ export class IgxDayItemComponent { return isDateInRanges(this.date.date, this.outOfRangeDates); } + @HostBinding('class.igx-calendar__date--range') + public get isWithinRangeCSS(): boolean { + return !this.isSingleSelection && this.isWithinRange; + } @HostBinding('class.igx-calendar__date--special') public get isSpecial(): boolean { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 17412259ac8..53fffd6cc8d 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -652,6 +652,18 @@ } } + %cal-value--inactive%cal-value--selected%cal-value--first { + &::after { + background: transparent !important; + } + } + + %cal-value--inactive%cal-value--selected%cal-value--last { + &::before { + background: transparent !important; + } + } + %cal-value--first { position: relative; background: transparent;