Skip to content

Commit 528361e

Browse files
author
Tobias Schweizer
committed
feature (MatCalendarHeader): move header in own template
1 parent 702317d commit 528361e

File tree

4 files changed

+73
-72
lines changed

4 files changed

+73
-72
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<div class="mat-calendar-header">
2+
3+
<div class="mat-calendar-controls">
4+
<button mat-button class="mat-calendar-period-button"
5+
(click)="calendar.currentPeriodClicked()" [attr.aria-label]="calendar.periodButtonLabel">
6+
{{calendar.periodButtonText}}
7+
<div class="mat-calendar-arrow" [class.mat-calendar-invert]="calendar.currentView != 'month'"></div>
8+
</button>
9+
10+
<div class="mat-calendar-spacer"></div>
11+
12+
<button mat-icon-button class="mat-calendar-previous-button"
13+
[disabled]="!calendar.previousEnabled()" (click)="calendar.previousClicked()"
14+
[attr.aria-label]="calendar.prevButtonLabel">
15+
</button>
16+
17+
<button mat-icon-button class="mat-calendar-next-button"
18+
[disabled]="!calendar.nextEnabled()" (click)="calendar.nextClicked()"
19+
[attr.aria-label]="calendar.nextButtonLabel">
20+
</button>
21+
</div>
22+
</div>

src/lib/datepicker/calendar.html

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
1-
<div class="mat-calendar-header">
21

3-
<ng-template [cdkPortalOutlet]="_calendarHeaderPortal"></ng-template>
2+
<ng-template [cdkPortalOutlet]="_calendarHeaderPortal"></ng-template>
43

5-
<div class="mat-calendar-controls">
6-
<button mat-button class="mat-calendar-period-button"
7-
(click)="_currentPeriodClicked()" [attr.aria-label]="_periodButtonLabel">
8-
{{_periodButtonText}}
9-
<div class="mat-calendar-arrow" [class.mat-calendar-invert]="_currentView != 'month'"></div>
10-
</button>
11-
12-
<div class="mat-calendar-spacer"></div>
13-
14-
<button mat-icon-button class="mat-calendar-previous-button"
15-
[disabled]="!_previousEnabled()" (click)="_previousClicked()"
16-
[attr.aria-label]="_prevButtonLabel">
17-
</button>
18-
19-
<button mat-icon-button class="mat-calendar-next-button"
20-
[disabled]="!_nextEnabled()" (click)="_nextClicked()"
21-
[attr.aria-label]="_nextButtonLabel">
22-
</button>
23-
</div>
24-
</div>
25-
26-
<div class="mat-calendar-content" [ngSwitch]="_currentView" cdkMonitorSubtreeFocus tabindex="-1">
4+
<div class="mat-calendar-content" [ngSwitch]="currentView" cdkMonitorSubtreeFocus tabindex="-1">
275
<mat-month-view
286
*ngSwitchCase="'month'"
297
[(activeDate)]="_activeDate"

src/lib/datepicker/calendar.spec.ts

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,22 @@ describe('MatCalendar', () => {
6161
});
6262

6363
it('should be in month view with specified month active', () => {
64-
expect(calendarInstance._currentView).toBe('month');
64+
expect(calendarInstance.currentView).toBe('month');
6565
expect(calendarInstance._activeDate).toEqual(new Date(2017, JAN, 31));
6666
});
6767

6868
it('should toggle view when period clicked', () => {
69-
expect(calendarInstance._currentView).toBe('month');
69+
expect(calendarInstance.currentView).toBe('month');
7070

7171
periodButton.click();
7272
fixture.detectChanges();
7373

74-
expect(calendarInstance._currentView).toBe('multi-year');
74+
expect(calendarInstance.currentView).toBe('multi-year');
7575

7676
periodButton.click();
7777
fixture.detectChanges();
7878

79-
expect(calendarInstance._currentView).toBe('month');
79+
expect(calendarInstance.currentView).toBe('month');
8080
});
8181

8282
it('should go to next and previous month', () => {
@@ -97,13 +97,13 @@ describe('MatCalendar', () => {
9797
periodButton.click();
9898
fixture.detectChanges();
9999

100-
expect(calendarInstance._currentView).toBe('multi-year');
100+
expect(calendarInstance.currentView).toBe('multi-year');
101101
expect(calendarInstance._activeDate).toEqual(new Date(2017, JAN, 31));
102102

103103
(calendarElement.querySelector('.mat-calendar-body-active') as HTMLElement).click();
104104
fixture.detectChanges();
105105

106-
expect(calendarInstance._currentView).toBe('year');
106+
expect(calendarInstance.currentView).toBe('year');
107107

108108
nextButton.click();
109109
fixture.detectChanges();
@@ -120,7 +120,7 @@ describe('MatCalendar', () => {
120120
periodButton.click();
121121
fixture.detectChanges();
122122

123-
expect(calendarInstance._currentView).toBe('multi-year');
123+
expect(calendarInstance.currentView).toBe('multi-year');
124124
expect(calendarInstance._activeDate).toEqual(new Date(2017, JAN, 31));
125125

126126
nextButton.click();
@@ -138,21 +138,21 @@ describe('MatCalendar', () => {
138138
periodButton.click();
139139
fixture.detectChanges();
140140

141-
expect(calendarInstance._currentView).toBe('multi-year');
141+
expect(calendarInstance.currentView).toBe('multi-year');
142142
expect(calendarInstance._activeDate).toEqual(new Date(2017, JAN, 31));
143143

144144
let yearCells = calendarElement.querySelectorAll('.mat-calendar-body-cell');
145145
(yearCells[0] as HTMLElement).click();
146146
fixture.detectChanges();
147147

148-
expect(calendarInstance._currentView).toBe('year');
148+
expect(calendarInstance.currentView).toBe('year');
149149
expect(calendarInstance._activeDate).toEqual(new Date(2016, JAN, 31));
150150

151151
let monthCells = calendarElement.querySelectorAll('.mat-calendar-body-cell');
152152
(monthCells[monthCells.length - 1] as HTMLElement).click();
153153
fixture.detectChanges();
154154

155-
expect(calendarInstance._currentView).toBe('month');
155+
expect(calendarInstance.currentView).toBe('month');
156156
expect(calendarInstance._activeDate).toEqual(new Date(2016, DEC, 31));
157157
expect(testComponent.selected).toBeFalsy('no date should be selected yet');
158158
});
@@ -162,22 +162,22 @@ describe('MatCalendar', () => {
162162
(monthCells[monthCells.length - 1] as HTMLElement).click();
163163
fixture.detectChanges();
164164

165-
expect(calendarInstance._currentView).toBe('month');
165+
expect(calendarInstance.currentView).toBe('month');
166166
expect(testComponent.selected).toEqual(new Date(2017, JAN, 31));
167167
});
168168

169169
it('should emit the selected month on cell clicked in year view', () => {
170170
periodButton.click();
171171
fixture.detectChanges();
172172

173-
expect(calendarInstance._currentView).toBe('multi-year');
173+
expect(calendarInstance.currentView).toBe('multi-year');
174174
expect(calendarInstance._activeDate).toEqual(new Date(2017, JAN, 31));
175175

176176
(calendarElement.querySelector('.mat-calendar-body-active') as HTMLElement).click();
177177

178178
fixture.detectChanges();
179179

180-
expect(calendarInstance._currentView).toBe('year');
180+
expect(calendarInstance.currentView).toBe('year');
181181

182182
(calendarElement.querySelector('.mat-calendar-body-active') as HTMLElement).click();
183183

@@ -189,7 +189,7 @@ describe('MatCalendar', () => {
189189
periodButton.click();
190190
fixture.detectChanges();
191191

192-
expect(calendarInstance._currentView).toBe('multi-year');
192+
expect(calendarInstance.currentView).toBe('multi-year');
193193
expect(calendarInstance._activeDate).toEqual(new Date(2017, JAN, 31));
194194

195195
(calendarElement.querySelector('.mat-calendar-body-active') as HTMLElement).click();
@@ -239,12 +239,12 @@ describe('MatCalendar', () => {
239239
dispatchMouseEvent(periodButton, 'click');
240240
fixture.detectChanges();
241241

242-
expect(calendarInstance._currentView).toBe('multi-year');
242+
expect(calendarInstance.currentView).toBe('multi-year');
243243

244244
(calendarBodyEl.querySelector('.mat-calendar-body-active') as HTMLElement).click();
245245
fixture.detectChanges();
246246

247-
expect(calendarInstance._currentView).toBe('year');
247+
expect(calendarInstance.currentView).toBe('year');
248248
});
249249

250250
it('should return to month view on enter', () => {
@@ -256,7 +256,7 @@ describe('MatCalendar', () => {
256256
dispatchKeyboardEvent(tableBodyEl, 'keydown', ENTER);
257257
fixture.detectChanges();
258258

259-
expect(calendarInstance._currentView).toBe('month');
259+
expect(calendarInstance.currentView).toBe('month');
260260
expect(calendarInstance._activeDate).toEqual(new Date(2017, FEB, 28));
261261
expect(testComponent.selected).toBeUndefined();
262262
});
@@ -267,7 +267,7 @@ describe('MatCalendar', () => {
267267
dispatchMouseEvent(periodButton, 'click');
268268
fixture.detectChanges();
269269

270-
expect(calendarInstance._currentView).toBe('multi-year');
270+
expect(calendarInstance.currentView).toBe('multi-year');
271271
});
272272

273273
it('should go to year view on enter', () => {
@@ -279,7 +279,7 @@ describe('MatCalendar', () => {
279279
dispatchKeyboardEvent(tableBodyEl, 'keydown', ENTER);
280280
fixture.detectChanges();
281281

282-
expect(calendarInstance._currentView).toBe('year');
282+
expect(calendarInstance.currentView).toBe('year');
283283
expect(calendarInstance._activeDate).toEqual(new Date(2018, JAN, 31));
284284
expect(testComponent.selected).toBeUndefined();
285285
});
@@ -491,7 +491,7 @@ describe('MatCalendar', () => {
491491
});
492492

493493
it('should not allow selection of disabled date in month view', () => {
494-
expect(calendarInstance._currentView).toBe('month');
494+
expect(calendarInstance.currentView).toBe('month');
495495
expect(calendarInstance._activeDate).toEqual(new Date(2017, JAN, 1));
496496

497497
dispatchKeyboardEvent(tableBodyEl, 'keydown', ENTER);
@@ -512,13 +512,13 @@ describe('MatCalendar', () => {
512512
calendarInstance._activeDate = new Date(2017, NOV, 1);
513513
fixture.detectChanges();
514514

515-
expect(calendarInstance._currentView).toBe('year');
515+
expect(calendarInstance.currentView).toBe('year');
516516

517517
tableBodyEl = calendarElement.querySelector('.mat-calendar-body') as HTMLElement;
518518
dispatchKeyboardEvent(tableBodyEl, 'keydown', ENTER);
519519
fixture.detectChanges();
520520

521-
expect(calendarInstance._currentView).toBe('month');
521+
expect(calendarInstance.currentView).toBe('month');
522522
expect(testComponent.selected).toBeUndefined();
523523
});
524524
});

src/lib/datepicker/calendar.ts

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ChangeDetectorRef,
1313
Component,
1414
EventEmitter,
15+
Host,
1516
Inject,
1617
Input,
1718
OnChanges,
@@ -35,13 +36,13 @@ import {ComponentPortal, ComponentType, Portal} from '@angular/cdk/portal';
3536
@Component({
3637
moduleId: module.id,
3738
selector: 'mat-calendar-header',
38-
template: '',
39+
templateUrl: 'calendar-header.html',
3940
encapsulation: ViewEncapsulation.None,
4041
preserveWhitespaces: false,
4142
changeDetection: ChangeDetectionStrategy.OnPush,
4243
})
4344
export class MatCalendarHeader {
44-
constructor() {
45+
constructor(@Host() public calendar: MatCalendar<any>) {
4546

4647
}
4748
}
@@ -149,15 +150,15 @@ export class MatCalendar<D> implements AfterContentInit, OnDestroy, OnChanges {
149150
private _clampedActiveDate: D;
150151

151152
/** Whether the calendar is in month view. */
152-
_currentView: 'month' | 'year' | 'multi-year';
153+
currentView: 'month' | 'year' | 'multi-year';
153154

154155
/** The label for the current calendar view. */
155-
get _periodButtonText(): string {
156-
if (this._currentView == 'month') {
156+
get periodButtonText(): string {
157+
if (this.currentView == 'month') {
157158
return this._dateAdapter.format(this._activeDate, this._dateFormats.display.monthYearLabel)
158159
.toLocaleUpperCase();
159160
}
160-
if (this._currentView == 'year') {
161+
if (this.currentView == 'year') {
161162
return this._dateAdapter.getYearName(this._activeDate);
162163
}
163164
const activeYear = this._dateAdapter.getYear(this._activeDate);
@@ -168,27 +169,27 @@ export class MatCalendar<D> implements AfterContentInit, OnDestroy, OnChanges {
168169
return `${firstYearInView} \u2013 ${lastYearInView}`;
169170
}
170171

171-
get _periodButtonLabel(): string {
172-
return this._currentView == 'month' ?
172+
get periodButtonLabel(): string {
173+
return this.currentView == 'month' ?
173174
this._intl.switchToMultiYearViewLabel : this._intl.switchToMonthViewLabel;
174175
}
175176

176177
/** The label for the the previous button. */
177-
get _prevButtonLabel(): string {
178+
get prevButtonLabel(): string {
178179
return {
179180
'month': this._intl.prevMonthLabel,
180181
'year': this._intl.prevYearLabel,
181182
'multi-year': this._intl.prevMultiYearLabel
182-
}[this._currentView];
183+
}[this.currentView];
183184
}
184185

185186
/** The label for the the next button. */
186-
get _nextButtonLabel(): string {
187+
get nextButtonLabel(): string {
187188
return {
188189
'month': this._intl.nextMonthLabel,
189190
'year': this._intl.nextYearLabel,
190191
'multi-year': this._intl.nextMultiYearLabel
191-
}[this._currentView];
192+
}[this.currentView];
192193
}
193194

194195
constructor(private _intl: MatDatepickerIntl,
@@ -212,7 +213,7 @@ export class MatCalendar<D> implements AfterContentInit, OnDestroy, OnChanges {
212213
this._calendarHeaderPortal = new ComponentPortal(this.headerComponent || MatCalendarHeader);
213214

214215
this._activeDate = this.startAt || this._dateAdapter.today();
215-
this._currentView = this.startView;
216+
this.currentView = this.startView;
216217
}
217218

218219
ngOnDestroy() {
@@ -255,50 +256,50 @@ export class MatCalendar<D> implements AfterContentInit, OnDestroy, OnChanges {
255256
/** Handles year/month selection in the multi-year/year views. */
256257
_goToDateInView(date: D, view: 'month' | 'year' | 'multi-year'): void {
257258
this._activeDate = date;
258-
this._currentView = view;
259+
this.currentView = view;
259260
}
260261

261262
/** Handles user clicks on the period label. */
262-
_currentPeriodClicked(): void {
263-
this._currentView = this._currentView == 'month' ? 'multi-year' : 'month';
263+
currentPeriodClicked(): void {
264+
this.currentView = this.currentView == 'month' ? 'multi-year' : 'month';
264265
}
265266

266267
/** Handles user clicks on the previous button. */
267-
_previousClicked(): void {
268-
this._activeDate = this._currentView == 'month' ?
268+
previousClicked(): void {
269+
this._activeDate = this.currentView == 'month' ?
269270
this._dateAdapter.addCalendarMonths(this._activeDate, -1) :
270271
this._dateAdapter.addCalendarYears(
271-
this._activeDate, this._currentView == 'year' ? -1 : -yearsPerPage);
272+
this._activeDate, this.currentView == 'year' ? -1 : -yearsPerPage);
272273
}
273274

274275
/** Handles user clicks on the next button. */
275-
_nextClicked(): void {
276-
this._activeDate = this._currentView == 'month' ?
276+
nextClicked(): void {
277+
this._activeDate = this.currentView == 'month' ?
277278
this._dateAdapter.addCalendarMonths(this._activeDate, 1) :
278279
this._dateAdapter.addCalendarYears(
279-
this._activeDate, this._currentView == 'year' ? 1 : yearsPerPage);
280+
this._activeDate, this.currentView == 'year' ? 1 : yearsPerPage);
280281
}
281282

282283
/** Whether the previous period button is enabled. */
283-
_previousEnabled(): boolean {
284+
previousEnabled(): boolean {
284285
if (!this.minDate) {
285286
return true;
286287
}
287288
return !this.minDate || !this._isSameView(this._activeDate, this.minDate);
288289
}
289290

290291
/** Whether the next period button is enabled. */
291-
_nextEnabled(): boolean {
292+
nextEnabled(): boolean {
292293
return !this.maxDate || !this._isSameView(this._activeDate, this.maxDate);
293294
}
294295

295296
/** Whether the two dates represent the same view in the current view mode (month or year). */
296297
private _isSameView(date1: D, date2: D): boolean {
297-
if (this._currentView == 'month') {
298+
if (this.currentView == 'month') {
298299
return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2) &&
299300
this._dateAdapter.getMonth(date1) == this._dateAdapter.getMonth(date2);
300301
}
301-
if (this._currentView == 'year') {
302+
if (this.currentView == 'year') {
302303
return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2);
303304
}
304305
// Otherwise we are in 'multi-year' view.

0 commit comments

Comments
 (0)