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

IgniteUI / igniteui-angular / 13416727049

19 Feb 2025 03:51PM CUT coverage: 91.602% (-0.003%) from 91.605%
13416727049

Pull #15247

github

web-flow
Merge 6c8542ad5 into b165899e8
Pull Request #15247: fix(excel-export): Get correct grid column collection from row island…

12995 of 15232 branches covered (85.31%)

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

118 existing lines in 20 files now uncovered.

26341 of 28756 relevant lines covered (91.6%)

34063.14 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
    imports: [
41
        NgIf,
42
        NgTemplateOutlet,
43
        DatePipe,
44
        IgxIconComponent,
45
        IgxMonthsViewComponent,
46
        IgxYearsViewComponent,
47
    ]
48
})
49
export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements OnInit, AfterViewInit, OnDestroy {
2✔
50
    /**
51
     * Sets/gets the `id` of the month picker.
52
     * If not set, the `id` will have value `"igx-month-picker-0"`.
53
     */
54
    @HostBinding("attr.id")
55
    @Input()
56
    public id = `igx-month-picker-${NEXT_ID++}`;
21✔
57

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

286
    private _showActiveDay: boolean;
287

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

514
        return { $implicit: formatObject };
107✔
515
        }
516
}
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