@imihai/angular-datetime-picker 21.0.2 → 22.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.browserslistrc +9 -0
  2. package/.editorconfig +13 -0
  3. package/.eslintrc.js +208 -0
  4. package/.github/workflows/ci_test.yml +35 -0
  5. package/.prettierrc +2 -0
  6. package/.travis.yml +16 -0
  7. package/angular.json +221 -0
  8. package/e2e/protractor.conf.js +28 -0
  9. package/e2e/src/app.e2e-spec.ts +14 -0
  10. package/e2e/src/app.po.ts +11 -0
  11. package/e2e/tsconfig.e2e.json +13 -0
  12. package/package.json +77 -33
  13. package/projects/picker/karma.conf.js +62 -0
  14. package/projects/picker/ng-package.json +7 -0
  15. package/projects/picker/package.json +23 -0
  16. package/projects/picker/src/lib/date-time/adapter/date-time-adapter.class.ts +313 -0
  17. package/projects/picker/src/lib/date-time/adapter/date-time-format.class.ts +18 -0
  18. package/projects/picker/src/lib/date-time/adapter/luxon-date-time-adapter.class.ts +307 -0
  19. package/projects/picker/src/lib/date-time/adapter/luxon-date-time-format.class.ts +11 -0
  20. package/projects/picker/src/lib/date-time/adapter/luxon-date-time.module.ts +31 -0
  21. package/projects/picker/src/lib/date-time/adapter/unix-timestamp-adapter/unix-timestamp-date-time-adapter.class.ts +356 -0
  22. package/projects/picker/src/lib/date-time/adapter/unix-timestamp-adapter/unix-timestamp-date-time-format.class.ts +14 -0
  23. package/projects/picker/src/lib/date-time/adapter/unix-timestamp-adapter/unix-timestamp-date-time.module.ts +26 -0
  24. package/projects/picker/src/lib/date-time/calendar-body.component.html +38 -0
  25. package/projects/picker/src/lib/date-time/calendar-body.component.scss +0 -0
  26. package/projects/picker/src/lib/date-time/calendar-body.component.spec.ts +120 -0
  27. package/projects/picker/src/lib/date-time/calendar-body.component.ts +190 -0
  28. package/projects/picker/src/lib/date-time/calendar-month-view.component.html +47 -0
  29. package/projects/picker/src/lib/date-time/calendar-month-view.component.scss +16 -0
  30. package/projects/picker/src/lib/date-time/calendar-month-view.component.spec.ts +394 -0
  31. package/projects/picker/src/lib/date-time/calendar-month-view.component.ts +705 -0
  32. package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.html +44 -0
  33. package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.scss +0 -0
  34. package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.spec.ts +343 -0
  35. package/projects/picker/src/lib/date-time/calendar-multi-year-view.component.ts +465 -0
  36. package/projects/picker/src/lib/date-time/calendar-year-view.component.html +16 -0
  37. package/projects/picker/src/lib/date-time/calendar-year-view.component.scss +0 -0
  38. package/projects/picker/src/lib/date-time/calendar-year-view.component.spec.ts +381 -0
  39. package/projects/picker/src/lib/date-time/calendar-year-view.component.ts +549 -0
  40. package/projects/picker/src/lib/date-time/calendar.component.html +169 -0
  41. package/projects/picker/src/lib/date-time/calendar.component.scss +0 -0
  42. package/projects/picker/src/lib/date-time/calendar.component.spec.ts +592 -0
  43. package/projects/picker/src/lib/date-time/calendar.component.ts +496 -0
  44. package/projects/picker/src/lib/date-time/date-time-inline.component.html +1 -0
  45. package/projects/picker/src/lib/date-time/date-time-inline.component.scss +4 -0
  46. package/projects/picker/src/lib/date-time/date-time-inline.component.ts +365 -0
  47. package/projects/picker/src/lib/date-time/date-time-picker-animation-event.ts +4 -0
  48. package/projects/picker/src/lib/date-time/date-time-picker-container.component.html +126 -0
  49. package/projects/picker/src/lib/date-time/date-time-picker-container.component.scss +0 -0
  50. package/projects/picker/src/lib/date-time/date-time-picker-container.component.ts +631 -0
  51. package/projects/picker/src/lib/date-time/date-time-picker-input.directive.ts +851 -0
  52. package/projects/picker/src/lib/date-time/date-time-picker-intl.service.ts +76 -0
  53. package/projects/picker/src/lib/date-time/date-time-picker-trigger.directive.ts +88 -0
  54. package/projects/picker/src/lib/date-time/date-time-picker.component.html +0 -0
  55. package/projects/picker/src/lib/date-time/date-time-picker.component.scss +0 -0
  56. package/projects/picker/src/lib/date-time/date-time-picker.component.spec.ts +2648 -0
  57. package/projects/picker/src/lib/date-time/date-time-picker.component.ts +731 -0
  58. package/projects/picker/src/lib/date-time/date-time.class.ts +256 -0
  59. package/projects/picker/src/lib/date-time/date-time.module.ts +61 -0
  60. package/projects/picker/src/lib/date-time/numberedFixLen.pipe.ts +28 -0
  61. package/projects/picker/src/lib/date-time/options-provider.ts +44 -0
  62. package/projects/picker/src/lib/date-time/timer-box.component.html +79 -0
  63. package/projects/picker/src/lib/date-time/timer-box.component.scss +0 -0
  64. package/projects/picker/src/lib/date-time/timer-box.component.ts +175 -0
  65. package/projects/picker/src/lib/date-time/timer.component.html +58 -0
  66. package/projects/picker/src/lib/date-time/timer.component.scss +0 -0
  67. package/projects/picker/src/lib/date-time/timer.component.spec.ts +399 -0
  68. package/projects/picker/src/lib/date-time/timer.component.ts +371 -0
  69. package/projects/picker/src/lib/dialog/dialog-config.class.ts +220 -0
  70. package/projects/picker/src/lib/dialog/dialog-container.component.html +1 -0
  71. package/projects/picker/src/lib/dialog/dialog-container.component.scss +0 -0
  72. package/projects/picker/src/lib/dialog/dialog-container.component.ts +231 -0
  73. package/projects/picker/src/lib/dialog/dialog-ref.class.ts +178 -0
  74. package/projects/picker/src/lib/dialog/dialog.module.ts +25 -0
  75. package/projects/picker/src/lib/dialog/dialog.service.ts +353 -0
  76. package/projects/picker/src/lib/utils/array.utils.ts +12 -0
  77. package/projects/picker/src/lib/utils/constants.ts +59 -0
  78. package/projects/picker/src/lib/utils/date.utils.ts +97 -0
  79. package/projects/picker/src/lib/utils/index.ts +5 -0
  80. package/projects/picker/src/lib/utils/object.utils.ts +29 -0
  81. package/projects/picker/src/public_api.ts +56 -0
  82. package/projects/picker/src/sass/picker.scss +743 -0
  83. package/projects/picker/src/test-helpers.ts +125 -0
  84. package/projects/picker/src/test.ts +52 -0
  85. package/projects/picker/tsconfig.lib.json +19 -0
  86. package/projects/picker/tsconfig.lib.prod.json +7 -0
  87. package/projects/picker/tsconfig.spec.json +17 -0
  88. package/projects/picker/tslint.json +8 -0
  89. package/src/app/app.component.html +77 -0
  90. package/src/app/app.component.scss +32 -0
  91. package/src/app/app.component.spec.ts +16 -0
  92. package/src/app/app.component.ts +35 -0
  93. package/src/assets/.gitkeep +0 -0
  94. package/src/environments/environment.prod.ts +3 -0
  95. package/src/environments/environment.ts +16 -0
  96. package/src/favicon.ico +0 -0
  97. package/src/index.html +14 -0
  98. package/src/karma.conf.js +31 -0
  99. package/src/main.ts +16 -0
  100. package/src/polyfills.ts +53 -0
  101. package/src/styles.scss +7 -0
  102. package/src/test.ts +50 -0
  103. package/src/tsconfig.app.json +16 -0
  104. package/src/tsconfig.spec.json +18 -0
  105. package/src/tslint.json +17 -0
  106. package/tsconfig.base.json +31 -0
  107. package/tsconfig.json +30 -0
  108. package/tslint.json +130 -0
  109. package/assets/style/picker.min.css +0 -1
  110. package/fesm2022/imihai-angular-datetime-picker.mjs +0 -5845
  111. package/fesm2022/imihai-angular-datetime-picker.mjs.map +0 -1
  112. package/imihai-angular-datetime-picker-21.0.2.tgz +0 -0
  113. package/types/imihai-angular-datetime-picker.d.ts +0 -2193
@@ -0,0 +1,592 @@
1
+ /**
2
+ * calendar.component.spec
3
+ */
4
+
5
+ import {
6
+ ComponentFixture,
7
+ inject,
8
+ TestBed
9
+ } from '@angular/core/testing';
10
+ import { Component, NgZone } from '@angular/core';
11
+ import {
12
+ MockNgZone,
13
+ dispatchFakeEvent,
14
+ dispatchMouseEvent,
15
+ dispatchKeyboardEvent
16
+ } from '../../test-helpers';
17
+ import { OwlNativeDateTimeModule } from './adapter/native-date-time.module';
18
+ import { OwlDateTimeModule } from './date-time.module';
19
+ import { OwlCalendarComponent } from './calendar.component';
20
+ import { OwlDateTimeIntl } from './date-time-picker-intl.service';
21
+ import { By } from '@angular/platform-browser';
22
+ import { ENTER, RIGHT_ARROW } from '@angular/cdk/keycodes';
23
+ import { OwlMonthViewComponent } from './calendar-month-view.component';
24
+ import { OwlYearViewComponent } from './calendar-year-view.component';
25
+ import { OwlMultiYearViewComponent } from './calendar-multi-year-view.component';
26
+ import {DateView} from './date-time.class';
27
+
28
+ export const JAN = 0,
29
+ FEB = 1,
30
+ MAR = 2,
31
+ APR = 3,
32
+ MAY = 4,
33
+ JUN = 5,
34
+ JUL = 6,
35
+ AUG = 7,
36
+ SEP = 8,
37
+ OCT = 9,
38
+ NOV = 10,
39
+ DEC = 11;
40
+
41
+ describe('OwlCalendarComponent', () => {
42
+ let zone: MockNgZone;
43
+
44
+ beforeEach(() => {
45
+ TestBed.configureTestingModule({
46
+ imports: [OwlNativeDateTimeModule, OwlDateTimeModule],
47
+ declarations: [
48
+ StandardCalendarComponent,
49
+ CalendarWithCalendarWeeks,
50
+ CalendarWithMinMaxComponent,
51
+ CalendarWithDateFilterComponent
52
+ ],
53
+ providers: [
54
+ OwlDateTimeIntl,
55
+ { provide: NgZone, useFactory: () => (zone = new MockNgZone()) }
56
+ ]
57
+ }).compileComponents();
58
+ });
59
+
60
+ describe('standard calendar', () => {
61
+ let fixture: ComponentFixture<StandardCalendarComponent>;
62
+ let testComponent: StandardCalendarComponent;
63
+ let calendarElement: HTMLElement;
64
+ let periodButton: HTMLElement;
65
+ let calendarInstance: OwlCalendarComponent<Date>;
66
+
67
+ beforeEach(() => {
68
+ fixture = TestBed.createComponent(StandardCalendarComponent);
69
+ fixture.detectChanges();
70
+
71
+ const calendarDebugElement = fixture.debugElement.query(
72
+ By.directive(OwlCalendarComponent)
73
+ );
74
+ calendarElement = calendarDebugElement.nativeElement;
75
+
76
+ periodButton = calendarElement.querySelector(
77
+ '.owl-dt-control-period-button'
78
+ ) as HTMLElement;
79
+ calendarInstance = calendarDebugElement.componentInstance;
80
+ testComponent = fixture.componentInstance;
81
+ });
82
+
83
+ it('should be in month view with specified month active', () => {
84
+ expect(calendarInstance.currentView).toBe(DateView.MONTH);
85
+ expect(calendarInstance.pickerMoment).toEqual(
86
+ new Date(2018, JAN, 31)
87
+ );
88
+ });
89
+
90
+ it('should select date in month view', () => {
91
+ const monthCell = calendarElement.querySelector(
92
+ '[aria-label="January 31, 2018"]'
93
+ );
94
+ (monthCell as HTMLElement).click();
95
+
96
+ fixture.detectChanges();
97
+ expect(calendarInstance.currentView).toBe(DateView.MONTH);
98
+ expect(testComponent.selected).toEqual(new Date(2018, JAN, 31));
99
+ });
100
+
101
+ it('should emit the selected month on cell clicked in year view', () => {
102
+ periodButton.click();
103
+ fixture.detectChanges();
104
+
105
+ expect(calendarInstance.currentView).toBe(DateView.MULTI_YEARS);
106
+ expect(calendarInstance.pickerMoment).toEqual(
107
+ new Date(2018, JAN, 31)
108
+ );
109
+
110
+ (calendarElement.querySelector(
111
+ '.owl-dt-calendar-cell-active'
112
+ ) as HTMLElement).click();
113
+
114
+ fixture.detectChanges();
115
+
116
+ expect(calendarInstance.currentView).toBe(DateView.YEAR);
117
+
118
+ (calendarElement.querySelector(
119
+ '.owl-dt-calendar-cell-active'
120
+ ) as HTMLElement).click();
121
+
122
+ const normalizedMonth: Date =
123
+ fixture.componentInstance.selectedMonth;
124
+ expect(normalizedMonth.getMonth()).toEqual(0);
125
+ });
126
+
127
+ it('should emit the selected year on cell clicked in multi-years view', () => {
128
+ periodButton.click();
129
+ fixture.detectChanges();
130
+
131
+ expect(calendarInstance.currentView).toBe(DateView.MULTI_YEARS);
132
+ expect(calendarInstance.pickerMoment).toEqual(
133
+ new Date(2018, JAN, 31)
134
+ );
135
+ (calendarElement.querySelector(
136
+ '.owl-dt-calendar-cell-active'
137
+ ) as HTMLElement).click();
138
+
139
+ fixture.detectChanges();
140
+
141
+ const normalizedYear: Date = fixture.componentInstance.selectedYear;
142
+ expect(normalizedYear.getFullYear()).toEqual(2018);
143
+ });
144
+
145
+ it('should re-render when the i18n labels have changed', () => {
146
+ inject([OwlDateTimeIntl], (intl: OwlDateTimeIntl) => {
147
+ const button = fixture.debugElement.nativeElement.querySelector(
148
+ '.owl-dt-control-period-button'
149
+ );
150
+
151
+ intl.switchToMultiYearViewLabel = 'Go to multi-year view?';
152
+ intl.changes.next();
153
+ fixture.detectChanges();
154
+
155
+ expect(button.getAttribute('aria-label')).toBe(
156
+ 'Go to multi-year view?'
157
+ );
158
+ });
159
+ });
160
+
161
+ it('should set all buttons to be `type="button"`', () => {
162
+ const invalidButtons = calendarElement.querySelectorAll(
163
+ 'button:not([type="button"])'
164
+ );
165
+ expect(invalidButtons.length).toBe(0);
166
+ });
167
+
168
+ describe('a11y', () => {
169
+ describe('calendar body', () => {
170
+ let calendarMainEl: HTMLElement;
171
+
172
+ beforeEach(() => {
173
+ calendarMainEl = calendarElement.querySelector(
174
+ '.owl-dt-calendar-main'
175
+ ) as HTMLElement;
176
+ expect(calendarMainEl).not.toBeNull();
177
+
178
+ dispatchFakeEvent(calendarMainEl, 'focus');
179
+ fixture.detectChanges();
180
+ });
181
+
182
+ it('should initially set pickerMoment', () => {
183
+ expect(calendarInstance.pickerMoment).toEqual(
184
+ new Date(2018, JAN, 31)
185
+ );
186
+ });
187
+
188
+ it('should make the calendar main focusable', () => {
189
+ expect(calendarMainEl.getAttribute('tabindex')).toBe('-1');
190
+ });
191
+
192
+ it('should not move focus to the active cell on init', () => {
193
+ const activeCell = calendarMainEl.querySelector(
194
+ '.owl-dt-calendar-cell-active'
195
+ ) as HTMLElement;
196
+
197
+ spyOn(activeCell, 'focus').and.callThrough();
198
+ fixture.detectChanges();
199
+
200
+ expect(activeCell.focus).not.toHaveBeenCalled();
201
+ });
202
+
203
+ it('should move focus to the active cell when the view changes', () => {
204
+ const activeCell = calendarMainEl.querySelector(
205
+ '.owl-dt-calendar-cell-active'
206
+ ) as HTMLElement;
207
+
208
+ spyOn(activeCell, 'focus').and.callThrough();
209
+ fixture.detectChanges();
210
+
211
+ expect(activeCell.focus).not.toHaveBeenCalled();
212
+
213
+ calendarInstance.currentView = DateView.MULTI_YEARS;
214
+ fixture.detectChanges();
215
+
216
+ expect(activeCell.focus).toHaveBeenCalled();
217
+ });
218
+
219
+ describe('year view', () => {
220
+ beforeEach(() => {
221
+ dispatchMouseEvent(periodButton, 'click');
222
+ fixture.detectChanges();
223
+
224
+ expect(calendarInstance.currentView).toBe(
225
+ DateView.MULTI_YEARS
226
+ );
227
+
228
+ (calendarMainEl.querySelector(
229
+ '.owl-dt-calendar-cell-active'
230
+ ) as HTMLElement).click();
231
+ fixture.detectChanges();
232
+
233
+ expect(calendarInstance.currentView).toBe(DateView.YEAR);
234
+ });
235
+
236
+ it('should return to month view on enter', () => {
237
+ const tableBodyEl = calendarMainEl.querySelector(
238
+ '.owl-dt-calendar-body'
239
+ ) as HTMLElement;
240
+
241
+ dispatchKeyboardEvent(
242
+ tableBodyEl,
243
+ 'keydown',
244
+ RIGHT_ARROW
245
+ );
246
+ fixture.detectChanges();
247
+
248
+ dispatchKeyboardEvent(tableBodyEl, 'keydown', ENTER);
249
+ fixture.detectChanges();
250
+
251
+ expect(calendarInstance.currentView).toBe(DateView.MONTH);
252
+ expect(calendarInstance.pickerMoment).toEqual(
253
+ new Date(2018, FEB, 28)
254
+ );
255
+ expect(testComponent.selected).toBeUndefined();
256
+ });
257
+ });
258
+
259
+ describe('multi-years view', () => {
260
+ beforeEach(() => {
261
+ dispatchMouseEvent(periodButton, 'click');
262
+ fixture.detectChanges();
263
+
264
+ expect(calendarInstance.currentView).toBe(
265
+ DateView.MULTI_YEARS
266
+ );
267
+ });
268
+
269
+ it('should return to year view on enter', () => {
270
+ const tableBodyEl = calendarMainEl.querySelector(
271
+ '.owl-dt-calendar-body'
272
+ ) as HTMLElement;
273
+
274
+ dispatchKeyboardEvent(
275
+ tableBodyEl,
276
+ 'keydown',
277
+ RIGHT_ARROW
278
+ );
279
+ fixture.detectChanges();
280
+
281
+ dispatchKeyboardEvent(tableBodyEl, 'keydown', ENTER);
282
+ fixture.detectChanges();
283
+
284
+ expect(calendarInstance.currentView).toBe(DateView.YEAR);
285
+ expect(calendarInstance.pickerMoment).toEqual(
286
+ new Date(2019, JAN, 31)
287
+ );
288
+ expect(testComponent.selected).toBeUndefined();
289
+ });
290
+ });
291
+ });
292
+ });
293
+ });
294
+
295
+ describe('calendar with Calendar Weeks', () => {
296
+ let fixture: ComponentFixture<CalendarWithCalendarWeeks>;
297
+ let testComponent: CalendarWithCalendarWeeks;
298
+ let calendarElement: HTMLElement;
299
+ let calendarInstance: OwlCalendarComponent<Date>;
300
+
301
+ beforeEach(() => {
302
+ fixture = TestBed.createComponent(CalendarWithCalendarWeeks);
303
+
304
+ const calendarDebugElement = fixture.debugElement.query(
305
+ By.directive(OwlCalendarComponent)
306
+ );
307
+ calendarElement = calendarDebugElement.nativeElement;
308
+
309
+ calendarInstance = calendarDebugElement.componentInstance;
310
+ testComponent = fixture.componentInstance;
311
+
312
+ fixture.detectChanges();
313
+ });
314
+
315
+ it('should show calendar weeks when attribute showCalendarWeeks in true', () => {
316
+ // Check the initial value is false
317
+ expect(calendarInstance.showCalendarWeeks).toBe(false);
318
+ testComponent.showCalendarWeeks = true;
319
+ fixture.detectChanges(); // Trigger change detection to apply the new value
320
+ // Now check if the calendarInstance reflects this change
321
+ expect(calendarInstance.showCalendarWeeks).toBe(true);
322
+ });
323
+
324
+ it('should show calendar weeks classes only when attribute showCalendarWeeks in true', () => {
325
+ // Check the initial value is false
326
+ expect(calendarInstance.showCalendarWeeks).toBe(false);
327
+
328
+ // Verify classes are not present initially
329
+ let weekNumberElement = fixture.debugElement.nativeElement.querySelector('.week-number');
330
+ let owlCalendarWeeksElement = fixture.debugElement.nativeElement.querySelector('.owl-calendar-weeks');
331
+ expect(weekNumberElement).toBeNull();
332
+ expect(owlCalendarWeeksElement).toBeNull();
333
+
334
+ // Set showCalendarWeeks to true
335
+ testComponent.showCalendarWeeks = true;
336
+ fixture.detectChanges(); // Trigger change detection to apply the new value
337
+
338
+ // Now check if the calendarInstance reflects this change
339
+ expect(calendarInstance.showCalendarWeeks).toBe(true);
340
+
341
+ // Verify classes are present after the change
342
+ weekNumberElement = fixture.debugElement.nativeElement.querySelector('.week-number');
343
+ owlCalendarWeeksElement = fixture.debugElement.nativeElement.querySelector('.owl-calendar-weeks');
344
+ expect(weekNumberElement).toBeTruthy();
345
+ expect(owlCalendarWeeksElement).toBeTruthy();
346
+ });
347
+ });
348
+
349
+
350
+ describe('calendar with min and max', () => {
351
+ let fixture: ComponentFixture<CalendarWithMinMaxComponent>;
352
+ let testComponent: CalendarWithMinMaxComponent;
353
+ let calendarElement: HTMLElement;
354
+ let calendarInstance: OwlCalendarComponent<Date>;
355
+
356
+ beforeEach(() => {
357
+ fixture = TestBed.createComponent(CalendarWithMinMaxComponent);
358
+ fixture.detectChanges();
359
+
360
+ const calendarDebugElement = fixture.debugElement.query(
361
+ By.directive(OwlCalendarComponent)
362
+ );
363
+ calendarElement = calendarDebugElement.nativeElement;
364
+
365
+ calendarInstance = calendarDebugElement.componentInstance;
366
+ testComponent = fixture.componentInstance;
367
+ });
368
+
369
+ it('should re-render the month view when the minDate changes', () => {
370
+ const monthViewDebugElm = fixture.debugElement.query(
371
+ By.directive(OwlMonthViewComponent)
372
+ );
373
+ const monthViewComp = monthViewDebugElm.componentInstance;
374
+ expect(monthViewComp).toBeTruthy();
375
+
376
+ spyOn(monthViewComp, 'generateCalendar').and.callThrough();
377
+ testComponent.minDate = new Date(2017, NOV, 1);
378
+ fixture.detectChanges();
379
+
380
+ expect(monthViewComp.generateCalendar).toHaveBeenCalled();
381
+ });
382
+
383
+ it('should re-render the month view when the maxDate changes', () => {
384
+ const monthViewDebugElm = fixture.debugElement.query(
385
+ By.directive(OwlMonthViewComponent)
386
+ );
387
+ const monthViewComp = monthViewDebugElm.componentInstance;
388
+ expect(monthViewComp).toBeTruthy();
389
+
390
+ spyOn(monthViewComp, 'generateCalendar').and.callThrough();
391
+ testComponent.maxDate = new Date(2017, NOV, 1);
392
+ fixture.detectChanges();
393
+
394
+ expect(monthViewComp.generateCalendar).toHaveBeenCalled();
395
+ });
396
+
397
+ it('should re-render the year view when the minDate changes', () => {
398
+ fixture.detectChanges();
399
+ const periodButton = calendarElement.querySelector(
400
+ '.owl-dt-control-period-button'
401
+ ) as HTMLElement;
402
+ periodButton.click();
403
+ fixture.detectChanges();
404
+
405
+ (calendarElement.querySelector(
406
+ '.owl-dt-calendar-cell-active'
407
+ ) as HTMLElement).click();
408
+ fixture.detectChanges();
409
+
410
+ const yearViewDebugElm = fixture.debugElement.query(
411
+ By.directive(OwlYearViewComponent)
412
+ );
413
+ const yearViewComp = yearViewDebugElm.componentInstance;
414
+ expect(yearViewComp).toBeTruthy();
415
+
416
+ spyOn(yearViewComp, 'generateMonthList').and.callThrough();
417
+ testComponent.minDate = new Date(2017, NOV, 1);
418
+ fixture.detectChanges();
419
+
420
+ expect(yearViewComp.generateMonthList).toHaveBeenCalled();
421
+ });
422
+
423
+ it('should re-render the year view when the maxDate changes', () => {
424
+ fixture.detectChanges();
425
+ const periodButton = calendarElement.querySelector(
426
+ '.owl-dt-control-period-button'
427
+ ) as HTMLElement;
428
+ periodButton.click();
429
+ fixture.detectChanges();
430
+
431
+ (calendarElement.querySelector(
432
+ '.owl-dt-calendar-cell-active'
433
+ ) as HTMLElement).click();
434
+ fixture.detectChanges();
435
+
436
+ const yearViewDebugElm = fixture.debugElement.query(
437
+ By.directive(OwlYearViewComponent)
438
+ );
439
+ const yearViewComp = yearViewDebugElm.componentInstance;
440
+ expect(yearViewComp).toBeTruthy();
441
+
442
+ spyOn(yearViewComp, 'generateMonthList').and.callThrough();
443
+ testComponent.maxDate = new Date(2017, NOV, 1);
444
+ fixture.detectChanges();
445
+
446
+ expect(yearViewComp.generateMonthList).toHaveBeenCalled();
447
+ });
448
+
449
+ it('should re-render the multi-years view when the minDate changes', () => {
450
+ fixture.detectChanges();
451
+ const periodButton = calendarElement.querySelector(
452
+ '.owl-dt-control-period-button'
453
+ ) as HTMLElement;
454
+ periodButton.click();
455
+ fixture.detectChanges();
456
+
457
+ const multiYearsViewDebugElm = fixture.debugElement.query(
458
+ By.directive(OwlMultiYearViewComponent)
459
+ );
460
+ const multiYearsViewComp = multiYearsViewDebugElm.componentInstance;
461
+ expect(multiYearsViewComp).toBeTruthy();
462
+
463
+ spyOn(multiYearsViewComp, 'generateYearList').and.callThrough();
464
+ testComponent.minDate = new Date(2017, NOV, 1);
465
+ fixture.detectChanges();
466
+
467
+ expect(multiYearsViewComp.generateYearList).toHaveBeenCalled();
468
+ });
469
+
470
+ it('should re-render the multi-years view when the maxDate changes', () => {
471
+ fixture.detectChanges();
472
+ const periodButton = calendarElement.querySelector(
473
+ '.owl-dt-control-period-button'
474
+ ) as HTMLElement;
475
+ periodButton.click();
476
+ fixture.detectChanges();
477
+
478
+ const multiYearsViewDebugElm = fixture.debugElement.query(
479
+ By.directive(OwlMultiYearViewComponent)
480
+ );
481
+ const multiYearsViewComp = multiYearsViewDebugElm.componentInstance;
482
+ expect(multiYearsViewComp).toBeTruthy();
483
+
484
+ spyOn(multiYearsViewComp, 'generateYearList').and.callThrough();
485
+ testComponent.maxDate = new Date(2017, NOV, 1);
486
+ fixture.detectChanges();
487
+
488
+ expect(multiYearsViewComp.generateYearList).toHaveBeenCalled();
489
+ });
490
+ });
491
+
492
+ describe('calendar with date filter', () => {
493
+ let fixture: ComponentFixture<CalendarWithDateFilterComponent>;
494
+ let testComponent: CalendarWithDateFilterComponent;
495
+ let calendarElement: HTMLElement;
496
+ let calendarInstance: OwlCalendarComponent<Date>;
497
+
498
+ beforeEach(() => {
499
+ fixture = TestBed.createComponent(CalendarWithDateFilterComponent);
500
+ fixture.detectChanges();
501
+
502
+ const calendarDebugElement = fixture.debugElement.query(
503
+ By.directive(OwlCalendarComponent)
504
+ );
505
+ calendarElement = calendarDebugElement.nativeElement;
506
+ calendarInstance = calendarDebugElement.componentInstance;
507
+ testComponent = fixture.componentInstance;
508
+ });
509
+
510
+ it('should disable and prevent selection of filtered dates', () => {
511
+ const monthCell = calendarElement.querySelector(
512
+ '[aria-label="January 2, 2018"]'
513
+ );
514
+ expect(testComponent.selected).toBeFalsy();
515
+
516
+ (monthCell as HTMLElement).click();
517
+ fixture.detectChanges();
518
+
519
+ expect(testComponent.selected).toEqual(new Date(2018, JAN, 2));
520
+ });
521
+ });
522
+ });
523
+
524
+ @Component({
525
+ standalone: false,
526
+ template: `
527
+ <owl-date-time-calendar
528
+ [(selected)]="selected"
529
+ [selectMode]="selectMode"
530
+ [pickerMoment]="pickerMoment"
531
+ (monthSelected)="selectedMonth=$event"
532
+ (yearSelected)="selectedYear=$event"></owl-date-time-calendar>
533
+ `
534
+ })
535
+ class StandardCalendarComponent {
536
+ selectMode = 'single';
537
+ selected: Date;
538
+ selectedYear: Date;
539
+ selectedMonth: Date;
540
+ pickerMoment = new Date(2018, JAN, 31);
541
+ }
542
+
543
+ @Component({
544
+ standalone: false,
545
+ template: `
546
+ <owl-date-time-calendar [selectMode]="selectMode"
547
+ [pickerMoment]="pickerMoment"
548
+ [minDate]="minDate"
549
+ [maxDate]="maxDate"></owl-date-time-calendar>
550
+ `
551
+ })
552
+ class CalendarWithMinMaxComponent {
553
+ selectMode = 'single';
554
+ startAt: Date;
555
+ minDate = new Date(2016, JAN, 1);
556
+ maxDate = new Date(2019, JAN, 1);
557
+ pickerMoment = new Date(2018, JAN, 31);
558
+ }
559
+
560
+ @Component({
561
+ standalone: false,
562
+ template: `
563
+ <owl-date-time-calendar [selectMode]="selectMode"
564
+ [pickerMoment]="pickerMoment"
565
+ [showCalendarWeeks]="showCalendarWeeks"></owl-date-time-calendar>
566
+ `
567
+ })
568
+ class CalendarWithCalendarWeeks {
569
+ selectMode = 'single';
570
+ startAt: Date;
571
+ showCalendarWeeks = false;
572
+ pickerMoment = new Date(2018, JAN, 31);
573
+ }
574
+
575
+ @Component({
576
+ standalone: false,
577
+ template: `
578
+ <owl-date-time-calendar [(selected)]="selected"
579
+ [selectMode]="selectMode"
580
+ [pickerMoment]="pickerMoment"
581
+ [dateFilter]="dateFilter"></owl-date-time-calendar>
582
+ `
583
+ })
584
+ class CalendarWithDateFilterComponent {
585
+ selectMode = 'single';
586
+ selected: Date;
587
+ pickerMoment = new Date(2018, JAN, 31);
588
+
589
+ dateFilter(date: Date) {
590
+ return !(date.getDate() % 2) && date.getMonth() !== NOV;
591
+ }
592
+ }