Skip to content

Commit 2cbc95a

Browse files
authored
refactor(month-picker): rework keyboard nav to be inline with the calendar (#14178)
1 parent 0814c80 commit 2cbc95a

File tree

3 files changed

+453
-164
lines changed

3 files changed

+453
-164
lines changed
Lines changed: 132 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,159 @@
1-
<!-- Picker Info -->
1+
<!-- Previous arrow icon -->
2+
<ng-template #prevArrow let-obj>
3+
<igx-icon aria-hidden="true">keyboard_arrow_left</igx-icon>
4+
</ng-template>
5+
6+
<!-- Next arrow icon -->
7+
<ng-template #nextArrow let-obj>
8+
<igx-icon aria-hidden="true">keyboard_arrow_right</igx-icon>
9+
</ng-template>
10+
11+
<!-- Previous picker button -->
12+
<ng-template #prevPageButton let-obj>
13+
<div
14+
#prevPageBtn
15+
tabindex="0"
16+
class="igx-calendar-picker__prev"
17+
role="button"
18+
[attr.aria-label]="prevNavLabel((getPrevYearDate(viewDate) | date: 'YYYY'))"
19+
data-action="prev"
20+
igxCalendarScrollPage
21+
(mousedown)="previousPage()"
22+
(keydown)="changePageKB($event, false)"
23+
>
24+
<ng-container *ngTemplateOutlet="prevArrow"></ng-container>
25+
</div>
26+
</ng-template>
227

3-
<!-- Month -->
4-
<ng-template #defaultMonth>
28+
<!-- Next picker button -->
29+
<ng-template #nextPageButton let-obj>
30+
<div
31+
#nextPageBtn
32+
tabindex="0"
33+
class="igx-calendar-picker__next"
34+
role="button"
35+
[attr.aria-label]="nextNavLabel((getNextYearDate(viewDate) | date: 'YYYY'))"
36+
data-action="next"
37+
igxCalendarScrollPage
38+
(mousedown)="nextPage()"
39+
(keydown)="changePageKB($event)"
40+
>
41+
<ng-container *ngTemplateOutlet="nextArrow"></ng-container>
42+
</div>
43+
</ng-template>
44+
45+
<!-- Year -->
46+
<ng-template #defaultYear let-obj>
47+
<span *ngIf="activeView === 'year'" class="igx-calendar__aria-off-screen" aria-live="polite">{{ formattedYear(obj.date) }}</span>
548
<span
649
#yearsBtn
750
tabindex="0"
8-
aria-live="polite"
9-
class="igx-calendar-picker__date"
10-
(keydown)="activeViewDecadeKB($event)"
11-
(click)="activeViewDecade()"
12-
>
13-
{{ formattedYear(viewDate) }}
51+
role="button"
52+
[attr.aria-label]="(obj.date | date: 'yyyy') + ', ' + resourceStrings.igx_calendar_select_year"
53+
(keydown)="onActiveViewDecadeKB(obj.date, $event, obj.index)"
54+
(mousedown)="onActiveViewDecade($event, obj.date, obj.index)"
55+
class="igx-calendar-picker__date">
56+
{{ formattedYear(obj.date) }}
1457
</span>
1558
</ng-template>
1659

17-
<!-- Years -->
18-
<ng-template #defaultYears>
19-
<span>{{ getDecadeRange().start }}</span>
20-
<span>&nbsp;-&nbsp;</span>
21-
<span>{{ getDecadeRange().end }}</span>
60+
<!-- Decade -->
61+
<ng-template #defaultDecade>
62+
<span>{{ getDecadeRange().start }} - {{ getDecadeRange().end }}</span>
2263
</ng-template>
2364

24-
<!-- Picker Arrows -->
25-
26-
<!-- Months -->
27-
<ng-template #calendarMonthPicker>
65+
<!-- PICKER IN MONTHS -->
66+
<ng-template #calendarYearPicker>
2867
<section class="igx-calendar-picker">
29-
<div [style.width.%]="100">
30-
<ng-container *ngTemplateOutlet="defaultMonth"></ng-container>
68+
<div class="igx-calendar-picker__dates">
69+
<ng-container
70+
*ngTemplateOutlet="defaultYear; context: getContext(0)">
71+
</ng-container>
3172
</div>
3273
<div class="igx-calendar-picker__nav">
33-
<div
34-
role="button"
35-
tabindex="0"
36-
class="igx-calendar-picker__prev"
37-
[attr.aria-label]="'Previous Year ' + getPreviousYear()"
38-
(click)="previousPage()"
39-
(keydown)="changePageKB($event, false)"
40-
data-action="prev"
41-
>
42-
<igx-icon>keyboard_arrow_left</igx-icon>
43-
</div>
44-
<div
45-
role="button"
46-
tabindex="0"
47-
class="igx-calendar-picker__next"
48-
[attr.aria-label]="'Next Year ' + getNextYear()"
49-
(click)="nextPage()"
50-
(keydown)="changePageKB($event)"
51-
data-action="next"
52-
>
53-
<igx-icon>keyboard_arrow_right</igx-icon>
54-
</div>
74+
<ng-container *ngTemplateOutlet="prevPageButton"></ng-container>
75+
<ng-container *ngTemplateOutlet="nextPageButton"></ng-container>
5576
</div>
5677
</section>
5778
</ng-template>
5879

59-
<!-- Years -->
60-
<ng-template #calendarYearsPicker>
80+
<!-- PICKER IN YEARS -->
81+
<ng-template #calendarDecadePicker>
6182
<section class="igx-calendar-picker">
62-
<div [style.width.%]="100">
63-
<ng-container *ngTemplateOutlet="defaultYears"></ng-container>
83+
<div class="igx-calendar-picker__dates" aria-live="polite">
84+
<ng-container
85+
*ngTemplateOutlet="defaultDecade;">
86+
</ng-container>
6487
</div>
6588
<div class="igx-calendar-picker__nav">
66-
<div
67-
tabindex="0"
68-
class="igx-calendar-picker__prev"
69-
role="button"
70-
data-action="prev"
71-
(click)="previousPage()"
72-
(keydown)="changePageKB($event, false)"
73-
data-action="prev"
74-
>
75-
<igx-icon aria-hidden="true">keyboard_arrow_left</igx-icon>
76-
</div>
77-
<div
78-
tabindex="0"
79-
class="igx-calendar-picker__next"
80-
role="button"
81-
data-action="next"
82-
(click)="nextPage()"
83-
(keydown)="changePageKB($event)"
84-
data-action="next"
85-
>
86-
<igx-icon aria-hidden="true">keyboard_arrow_right</igx-icon>
87-
</div>
89+
<ng-container *ngTemplateOutlet="prevPageButton"></ng-container>
90+
<ng-container *ngTemplateOutlet="nextPageButton"></ng-container>
8891
</div>
8992
</section>
9093
</ng-template>
9194

92-
<!-- Outlets -->
93-
94-
<!-- Months -->
9595
<div
96-
*ngIf="isDefaultView"
97-
class="igx-months-view__body"
98-
(swiperight)="previousPage()"
99-
(swipeleft)="nextPage()"
100-
>
101-
<ng-container *ngTemplateOutlet="calendarMonthPicker"></ng-container>
102-
<igx-months-view
103-
#months
104-
[date]="viewDate"
105-
[locale]="locale"
106-
[formatView]="formatViews.month"
107-
[monthFormat]="formatOptions.month"
108-
(selected)="selectMonth($event)"
109-
(pageChanged)="updateDate($event)"
96+
#wrapper
97+
[tabIndex]="0"
98+
class="igx-calendar__wrapper"
99+
[attr.aria-activedescendant]="activeDescendant"
100+
[attr.aria-multiselectable]="selection !== 'single'"
101+
aria-labelledby="calendar-desc"
102+
role="grid"
110103
>
111-
</igx-months-view>
112-
</div>
104+
<caption id="calendar-desc" tabindex="-1" class="igx-calendar__aria-off-screen">
105+
{{ resourceStrings.igx_calendar_singular_single_selection}}
106+
</caption>
113107

114-
<!-- Years -->
115-
<div *ngIf="isDecadeView">
116-
<ng-container *ngTemplateOutlet="calendarYearsPicker"></ng-container>
117-
<igx-years-view
118-
#decade
119-
*ngIf="isDecadeView"
120-
[date]="viewDate"
121-
[locale]="locale"
122-
[formatView]="formatViews.year"
123-
[yearFormat]="formatOptions.year"
124-
(selected)="selectYear($event)"
125-
(pageChanged)="updateDate($event)"
126-
>
127-
</igx-years-view>
108+
<section class="igx-calendar__pickers">
109+
<ng-container *ngIf="isDefaultView">
110+
<ng-container *ngTemplateOutlet="calendarYearPicker"></ng-container>
111+
</ng-container>
112+
113+
<ng-container *ngIf="isDecadeView">
114+
<ng-container *ngTemplateOutlet="calendarDecadePicker"></ng-container>
115+
</ng-container>
116+
</section>
117+
118+
<section class="igx-calendar__body">
119+
<ng-container *ngIf="isDefaultView">
120+
<igx-months-view
121+
#months
122+
role="rowgroup"
123+
[tabIndex]="-1"
124+
[date]="viewDate"
125+
[locale]="locale"
126+
[formatView]="formatViews.month"
127+
[monthFormat]="formatOptions.month"
128+
[showActive]="showActiveDay"
129+
[standalone]="false"
130+
(swiperight)="previousPage()"
131+
(swipeleft)="nextPage()"
132+
(selected)="selectMonth($event)"
133+
(pageChanged)="updateDate($event)"
134+
(mousedown)="$event.preventDefault()">
135+
>
136+
</igx-months-view>
137+
</ng-container>
138+
139+
<ng-container *ngIf="isDecadeView">
140+
<igx-years-view
141+
#decade
142+
role="rowgroup"
143+
[tabIndex]="-1"
144+
[date]="viewDate"
145+
[locale]="locale"
146+
[formatView]="formatViews.year"
147+
[yearFormat]="formatOptions.year"
148+
[showActive]="showActiveDay"
149+
[standalone]="false"
150+
(swiperight)="previousPage()"
151+
(swipeleft)="nextPage()"
152+
(selected)="selectYear($event)"
153+
(pageChanged)="updateDate($event)"
154+
(mousedown)="$event.preventDefault()"
155+
>
156+
</igx-years-view>
157+
</ng-container>
158+
</section>
128159
</div>

0 commit comments

Comments
 (0)