• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-angular / 12910003674

22 Jan 2025 02:10PM CUT coverage: 91.609% (+0.01%) from 91.597%
12910003674

push

github

web-flow
Merge pull request #15285 from IgniteUI/mvenkov/use-passed-overlay-settings-18.2

Use provided in show method overlay settings - 18.2

12988 of 15222 branches covered (85.32%)

5 of 5 new or added lines in 1 file covered. (100.0%)

46 existing lines in 9 files now uncovered.

26321 of 28732 relevant lines covered (91.61%)

33978.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.25
/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts
1
import {
2
    Component,
3
    HostListener,
4
    ViewChild,
5
    HostBinding,
6
    Input,
7
    ElementRef,
8
    AfterViewInit,
9
    OnDestroy,
10
    OnInit,
11
} from "@angular/core";
12
import { NgIf, NgTemplateOutlet, DatePipe } from "@angular/common";
13
import { NG_VALUE_ACCESSOR } from "@angular/forms";
14

15
import { IgxMonthsViewComponent } from "../months-view/months-view.component";
16
import { IgxYearsViewComponent } from "../years-view/years-view.component";
17
import { IgxDaysViewComponent } from "../days-view/days-view.component";
18
import { IgxIconComponent } from "../../icon/icon.component";
19
import { IgxCalendarView } from "../calendar";
20
import { CalendarDay } from "../common/model";
21
import { IgxCalendarBaseDirective } from "../calendar-base";
22
import { KeyboardNavigationService } from "../calendar.services";
23
import { formatToParts } from "../common/helpers";
24

25
let NEXT_ID = 0;
2✔
26
@Component({
27
    providers: [
28
        {
29
            multi: true,
30
            provide: NG_VALUE_ACCESSOR,
31
            useExisting: IgxMonthPickerComponent,
32
        },
33
        {
34
            multi: false,
35
            provide: KeyboardNavigationService
36
        },
37
    ],
38
    selector: "igx-month-picker",
39
    templateUrl: "month-picker.component.html",
40
    standalone: true,
41
    imports: [
42
        NgIf,
43
        NgTemplateOutlet,
44
        DatePipe,
45
        IgxIconComponent,
46
        IgxMonthsViewComponent,
47
        IgxYearsViewComponent,
48
    ],
49
})
50
export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements OnInit, AfterViewInit, OnDestroy {
2✔
51
    /**
52
     * Sets/gets the `id` of the month picker.
53
     * If not set, the `id` will have value `"igx-month-picker-0"`.
54
     */
55
    @HostBinding("attr.id")
56
    @Input()
57
    public id = `igx-month-picker-${NEXT_ID++}`;
21✔
58

59
    /**
60
     * @hidden
61
     * @internal
62
     */
63
    private _activeDescendant: number;
64

65
    /**
66
     * @hidden
67
     * @internal
68
     */
69
    @ViewChild("wrapper")
70
    public wrapper: ElementRef;
71

72
    /**
73
     * The default css class applied to the component.
74
     *
75
     * @hidden
76
     */
77
    @HostBinding("class.igx-month-picker")
78
    public styleClass = true;
21✔
79

80
    /**
81
     * @hidden
82
     */
83
    @ViewChild("months", { read: IgxMonthsViewComponent })
84
    public monthsView: IgxMonthsViewComponent;
85

86
    /**
87
     * @hidden
88
     */
89
    @ViewChild("decade", { read: IgxYearsViewComponent })
90
    public dacadeView: IgxYearsViewComponent;
91

92
    /**
93
     * @hidden
94
     */
95
    @ViewChild("days", { read: IgxDaysViewComponent })
96
    public daysView: IgxDaysViewComponent;
97

98
    /**
99
     * @hidden
100
     */
101
    @ViewChild("yearsBtn")
102
    public yearsBtn: ElementRef;
103

104
    /**
105
     * @hidden
106
     */
107
    @HostListener("keydown.pageup", ["$event"])
108
    public previousPage(event?: KeyboardEvent) {
109
        event?.preventDefault();
6✔
110
        this.previousViewDate = this.viewDate;
6✔
111

112
        if (this.isDefaultView) {
6✔
113
            this.viewDate = CalendarDay.from(this.viewDate).add('year', -1).native;
5✔
114
        }
115

116
        if (this.isDecadeView) {
6✔
117
            this.viewDate = CalendarDay.from(this.viewDate).add('year', -15).native;
1✔
118
        }
119

120
        this.viewDateChanged.emit({
6✔
121
            previousValue: this.previousViewDate,
122
            currentValue: this.viewDate,
123
        });
124
    }
125

126
    /**
127
     * @hidden
128
     */
129
    @HostListener("keydown.pagedown", ["$event"])
130
    public nextPage(event?: KeyboardEvent) {
131
        event?.preventDefault();
11✔
132
        this.previousViewDate = this.viewDate;
11✔
133

134
        if (this.isDefaultView) {
11✔
135
            this.viewDate = CalendarDay.from(this.viewDate).add('year', 1).native;
10✔
136
        }
137

138
        if (this.isDecadeView) {
11✔
139
            this.viewDate = CalendarDay.from(this.viewDate).add('year', 15).native;
1✔
140
        }
141

142
        this.viewDateChanged.emit({
11✔
143
            previousValue: this.previousViewDate,
144
            currentValue: this.viewDate,
145
        });
146
    }
147

148
        /**
149
         * @hidden
150
         * @internal
151
         */
152
        public onActiveViewDecadeKB(date: Date, event: KeyboardEvent, activeViewIdx: number) {
UNCOV
153
                super.activeViewDecadeKB(event, activeViewIdx);
×
154

UNCOV
155
                if (this.platform.isActivationKey(event)) {
×
156
            this.viewDate = date;
×
157
            this.wrapper.nativeElement.focus();
×
158
                }
159
        }
160

161
        /**
162
         * @hidden
163
         * @internal
164
         */
165
        public onActiveViewDecade(event: MouseEvent, date: Date, activeViewIdx: number): void {
166
        event.preventDefault();
5✔
167

168
                super.activeViewDecade(activeViewIdx);
5✔
169
        this.viewDate = date;
5✔
170
        }
171

172
    /**
173
     * @hidden
174
     */
175
    public override activeViewDecadeKB(event: KeyboardEvent) {
UNCOV
176
        super.activeViewDecadeKB(event);
×
177

UNCOV
178
        if (event.key === this.platform.KEYMAP.ARROW_RIGHT) {
×
179
            this.nextPage(event);
×
180
        }
181

UNCOV
182
        if (event.key === this.platform.KEYMAP.ARROW_LEFT) {
×
183
            this.previousPage(event);
×
184
        }
185
    }
186

187
    /**
188
     * @hidden
189
     */
190
    public override activeViewDecade() {
UNCOV
191
        super.activeViewDecade();
×
192

UNCOV
193
        requestAnimationFrame(() => {
×
194
            this.dacadeView.el.nativeElement.focus();
×
195
        });
196
    }
197

198
    /**
199
     * @hidden
200
     */
201
    public changePageKB(event: KeyboardEvent, next = true) {
4✔
202
        if (this.platform.isActivationKey(event)) {
6✔
203
            event.stopPropagation();
6✔
204

205
            if (next) {
6✔
206
                this.nextPage();
4✔
207
            } else {
208
                this.previousPage();
2✔
209
            }
210
        }
211
    }
212

213
    /**
214
     * @hidden
215
     */
216
    public selectYear(event: Date) {
217
        this.previousViewDate = this.viewDate;
4✔
218

219
        this.viewDate = new Date(
4✔
220
            event.getFullYear(),
221
            event.getMonth(),
222
            event.getDate(),
223
        );
224

225
        this.activeView = IgxCalendarView.Year;
4✔
226
        this.wrapper.nativeElement.focus();
4✔
227
    }
228

229
    /**
230
     * @hidden
231
     */
232
    public selectMonth(event: Date) {
233
        this.selectDate(event);
3✔
234
        this.selected.emit(this.selectedDates);
3✔
235
    }
236

237
    /**
238
     * Selects a date.
239
     * ```typescript
240
     *  this.monthPicker.selectDate(new Date(`2018-06-12`));
241
     * ```
242
     */
243
    public override selectDate(value: Date) {
244
        if (!value) {
26!
UNCOV
245
            return new Date();
×
246
        }
247

248
        super.selectDate(value);
26✔
249
        this.viewDate = value;
26✔
250
    }
251

252
    /**
253
     * @hidden
254
     */
255
    public getNextYear() {
UNCOV
256
        return CalendarDay.from(this.viewDate).add('year', 1).year;
×
257
    }
258

259
    /**
260
     * @hidden
261
     */
262
    public getPreviousYear() {
UNCOV
263
        return CalendarDay.from(this.viewDate).add('year', -1).year;
×
264
    }
265

266
    /**
267
     * @hidden
268
     */
269
    public updateDate(date: Date) {
270
        this.previousViewDate = this.viewDate;
2✔
271
        this.viewDate = CalendarDay.from(date).add('year', -this.activeViewIdx).native;
2✔
272

273
        if (this.isDefaultView) {
2✔
274
            this.viewDateChanged.emit({
2✔
275
                previousValue: this.previousViewDate,
276
                currentValue: this.viewDate,
277
            });
278
        }
279
    }
280

281
    @HostListener('mousedown', ['$event'])
282
    protected onMouseDown(event: MouseEvent) {
283
        event.stopPropagation();
19✔
284
        this.wrapper.nativeElement.focus();
19✔
285
    }
286

287
    private _showActiveDay: boolean;
288

289
        /**
290
         * @hidden
291
         * @internal
292
         */
293
    protected set showActiveDay(value: boolean) {
294
        this._showActiveDay = value;
24✔
295
        this.cdr.detectChanges();
24✔
296
    }
297

298
    protected get showActiveDay() {
299
        return this._showActiveDay;
136✔
300
    }
301

302
    protected get activeDescendant(): number {
303
        if (this.activeView === 'month') {
136!
UNCOV
304
            return (this.value as Date)?.getTime();
×
305
        }
306

307
        return this._activeDescendant ?? this.viewDate.getTime();
136✔
308
    }
309

310
    protected set activeDescendant(date: Date) {
UNCOV
311
        this._activeDescendant = date.getTime();
×
312
    }
313

314
    public override get isDefaultView(): boolean {
315
        return this.activeView === IgxCalendarView.Year;
299✔
316
    }
317

318
    public ngOnInit() {
319
        this.activeView = IgxCalendarView.Year;
21✔
320
    }
321

322
    public ngAfterViewInit() {
323
        this.keyboardNavigation
21✔
324
            .attachKeyboardHandlers(this.wrapper, this)
325
            .set("ArrowUp", this.onArrowUp)
326
            .set("ArrowDown", this.onArrowDown)
327
            .set("ArrowLeft", this.onArrowLeft)
328
            .set("ArrowRight", this.onArrowRight)
329
            .set("Enter", this.onEnter)
330
            .set(" ", this.onEnter)
331
            .set("Home", this.onHome)
332
            .set("End", this.onEnd)
333
            .set("PageUp", this.handlePageUp)
334
            .set("PageDown", this.handlePageDown);
335

336
        this.wrapper.nativeElement.addEventListener('focus', (event: FocusEvent) => this.onWrapperFocus(event));
21✔
337
        this.wrapper.nativeElement.addEventListener('blur', (event: FocusEvent) => this.onWrapperBlur(event));
21✔
338

339
        this.activeView$.subscribe((view) => {
21✔
340
            this.activeViewChanged.emit(view);
11✔
341

342
            this.viewDateChanged.emit({
11✔
343
                previousValue: this.previousViewDate,
344
                currentValue: this.viewDate
345
            });
346
        });
347
    }
348

349
    private onWrapperFocus(event: FocusEvent) {
350
        event.stopPropagation();
12✔
351
        this.showActiveDay = true;
12✔
352
    }
353

354
    private onWrapperBlur(event: FocusEvent) {
355
        event.stopPropagation();
12✔
356

357
        this.showActiveDay = false;
12✔
358
        this._onTouchedCallback();
12✔
359
    }
360

361
    private handlePageUpDown(event: KeyboardEvent, delta: number) {
UNCOV
362
        event.preventDefault();
×
363
        event.stopPropagation();
×
364

UNCOV
365
        if (this.isDefaultView && event.shiftKey) {
×
366
            this.viewDate = CalendarDay.from(this.viewDate).add('year', delta).native;
×
367
            this.cdr.detectChanges();
×
368
        } else {
UNCOV
369
            delta > 0 ? this.nextPage() : this.previousPage();
×
370
        }
371
    }
372

373
    private handlePageUp(event: KeyboardEvent) {
UNCOV
374
        this.handlePageUpDown(event, -1);
×
375
    }
376

377
    private handlePageDown(event: KeyboardEvent) {
UNCOV
378
        this.handlePageUpDown(event, 1);
×
379
    }
380

381
    private onArrowUp(event: KeyboardEvent) {
382
        if (this.isDefaultView) {
2!
UNCOV
383
            this.monthsView.onKeydownArrowUp(event);
×
384
        }
385

386
        if (this.isDecadeView) {
2✔
387
            this.dacadeView.onKeydownArrowUp(event);
2✔
388
        }
389
    }
390

391
    private onArrowDown(event: KeyboardEvent) {
392
        if (this.isDefaultView) {
1!
UNCOV
393
            this.monthsView.onKeydownArrowDown(event);
×
394
        }
395

396
        if (this.isDecadeView) {
1✔
397
            this.dacadeView.onKeydownArrowDown(event);
1✔
398
        }
399
    }
400

401
    private onArrowLeft(event: KeyboardEvent) {
402
        if (this.isDefaultView) {
1!
UNCOV
403
            this.monthsView.onKeydownArrowLeft(event);
×
404
        }
405

406
        if (this.isDecadeView) {
1✔
407
            this.dacadeView.onKeydownArrowLeft(event);
1✔
408
        }
409
    }
410

411
    private onArrowRight(event: KeyboardEvent) {
412
        if (this.isDefaultView) {
1✔
413
            this.monthsView.onKeydownArrowRight(event);
1✔
414
        }
415

416
        if (this.isDecadeView) {
1!
UNCOV
417
            this.dacadeView.onKeydownArrowRight(event);
×
418
        }
419
    }
420

421
    private onEnter(event: KeyboardEvent) {
422
        event.stopPropagation();
3✔
423

424
        if (this.isDefaultView) {
3✔
425
            this.monthsView.onKeydownEnter(event);
1✔
426
        }
427

428
        if (this.isDecadeView) {
3✔
429
            this.dacadeView.onKeydownEnter(event);
2✔
430
        }
431
    }
432

433
    private onHome(event: KeyboardEvent) {
UNCOV
434
        event.stopPropagation();
×
435
        if (this.isDefaultView) {
×
436
            this.monthsView.onKeydownHome(event);
×
437
        }
438

UNCOV
439
        if (this.isDecadeView) {
×
440
            this.dacadeView.onKeydownHome(event);
×
441
        }
442
    }
443

444
    private onEnd(event: KeyboardEvent) {
UNCOV
445
        event.stopPropagation();
×
446
        if (this.isDefaultView) {
×
447
            this.monthsView.onKeydownEnd(event);
×
448
        }
449

UNCOV
450
        if (this.isDecadeView) {
×
451
            this.dacadeView.onKeydownEnd(event);
×
452
        }
453
    }
454

455
        /**
456
         * @hidden
457
         * @internal
458
         */
459
        public ngOnDestroy(): void {
460
        this.keyboardNavigation.detachKeyboardHandlers();
21✔
461
        this.wrapper?.nativeElement.removeEventListener('focus', this.onWrapperFocus);
21✔
462
        this.wrapper?.nativeElement.removeEventListener('blur', this.onWrapperBlur);
21✔
463
        }
464

465
        /**
466
         * @hidden
467
         * @internal
468
         */
469
        public getPrevYearDate(date: Date): Date {
470
                return CalendarDay.from(date).add('year', -1).native;
136✔
471
        }
472

473
        /**
474
         * @hidden
475
         * @internal
476
         */
477
        public getNextYearDate(date: Date): Date {
478
        return CalendarDay.from(date).add('year', 1).native;
136✔
479
        }
480

481
        /**
482
         * Getter for the context object inside the calendar templates.
483
         *
484
         * @hidden
485
         * @internal
486
         */
487
        public getContext(i: number) {
488
        const date = CalendarDay.from(this.viewDate).add('month', i).native;
107✔
489
                return this.generateContext(date, i);
107✔
490
        }
491

492
        /**
493
         * Helper method building and returning the context object inside the calendar templates.
494
         *
495
         * @hidden
496
         * @internal
497
         */
498
        private generateContext(value: Date | Date[], i?: number) {
499
        const construct = (date: Date, index: number) => ({
107✔
500
            index: index,
501
            date,
502
            ...formatToParts(date, this.locale, this.formatOptions, [
503
                "era",
504
                "year",
505
                "month",
506
                "day",
507
                "weekday",
508
            ]),
509
        });
510

511
        const formatObject = Array.isArray(value)
107!
UNCOV
512
            ? value.map((date, index) => construct(date, index))
×
513
            : construct(value, i);
514

515
        return { $implicit: formatObject };
107✔
516
        }
517
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc