docs(datepicker): add docs for custom calendar header (#10543)

* docs(datepicker): add docs for custom calendar header

* fix error

* fix error in example module generation
This commit is contained in:
mmalerba
2018-04-10 10:54:27 -07:00
committed by tinayuangao
parent 0a501586a5
commit b472330659
9 changed files with 186 additions and 25 deletions
+16 -6
View File
@@ -1,7 +1,17 @@
<div class="custom-header">
<button mat-icon-button (click)="previousClicked('year')">&lt;&lt;</button>
<button mat-icon-button (click)="previousClicked('month')">&lt;</button>
<span class="custom-header-label">{{periodLabel}}</span>
<button mat-icon-button (click)="nextClicked('month')">&gt;</button>
<button mat-icon-button (click)="nextClicked('year')">&gt;&gt;</button>
<div class="demo-calendar-header">
<button mat-icon-button class="demo-double-arrow" (click)="previousClicked('year')">
<mat-icon>keyboard_arrow_left</mat-icon>
<mat-icon>keyboard_arrow_left</mat-icon>
</button>
<button mat-icon-button (click)="previousClicked('month')">
<mat-icon>keyboard_arrow_left</mat-icon>
</button>
<span class="demo-calendar-header-label">{{periodLabel}}</span>
<button mat-icon-button (click)="nextClicked('month')">
<mat-icon>keyboard_arrow_right</mat-icon>
</button>
<button mat-icon-button class="demo-double-arrow" (click)="nextClicked('year')">
<mat-icon>keyboard_arrow_right</mat-icon>
<mat-icon>keyboard_arrow_right</mat-icon>
</button>
</div>
+9 -3
View File
@@ -1,10 +1,16 @@
.custom-header {
padding: 1em 1.5em;
.demo-calendar-header {
display: flex;
align-items: center;
padding: 0.5em;
}
.custom-header-label {
.demo-calendar-header-label {
flex: 1;
height: 1em;
font-weight: bold;
text-align: center;
}
.demo-double-arrow .mat-icon {
margin: -22%;
}
+3 -4
View File
@@ -149,9 +149,8 @@
<p>
<mat-form-field>
<mat-label>Custom calendar header</mat-label>
<input matInput [matDatepicker]="customCalendarHeaderPicker"
[disabled]="inputDisabled">
<mat-datepicker-toggle matSuffix [for]="customCalendarHeaderPicker"></mat-datepicker-toggle>
<mat-datepicker #customCalendarHeaderPicker [touchUi]="touch" [disabled]="datepickerDisabled" [calendarHeaderComponent]="customHeader"></mat-datepicker>
<input matInput [matDatepicker]="customHeaderPicker">
<mat-datepicker-toggle matSuffix [for]="customHeaderPicker"></mat-datepicker-toggle>
<mat-datepicker #customHeaderPicker [calendarHeaderComponent]="customHeader"></mat-datepicker>
</mat-form-field>
</p>
+33 -11
View File
@@ -6,11 +6,20 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ChangeDetectionStrategy, Component, Host} from '@angular/core';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Host,
Inject,
OnDestroy
} from '@angular/core';
import {FormControl} from '@angular/forms';
import {DateAdapter, ThemePalette} from '@angular/material/core';
import {MatCalendar, MatDatepickerInputEvent} from '@angular/material/datepicker';
import {MatCalendar} from '@angular/material';
import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats, ThemePalette} from '@angular/material/core';
import {MatDatepickerInputEvent} from '@angular/material/datepicker';
import {Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
@Component({
moduleId: module.id,
@@ -53,25 +62,38 @@ export class DatepickerDemo {
styleUrls: ['custom-header.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomHeader<D> {
export class CustomHeader<D> implements OnDestroy {
private _destroyed = new Subject<void>();
constructor(@Host() private _calendar: MatCalendar<D>,
private _dateAdapter: DateAdapter<D>) {}
private _dateAdapter: DateAdapter<D>,
@Inject(MAT_DATE_FORMATS) private _dateFormats: MatDateFormats,
cdr: ChangeDetectorRef) {
_calendar.stateChanges
.pipe(takeUntil(this._destroyed))
.subscribe(() => cdr.markForCheck());
}
ngOnDestroy() {
this._destroyed.next();
this._destroyed.complete();
}
get periodLabel() {
const year = this._dateAdapter.getYearName(this._calendar.activeDate);
const month = (this._dateAdapter.getMonth(this._calendar.activeDate) + 1);
return `${month}/${year}`;
return this._dateAdapter
.format(this._calendar.activeDate, this._dateFormats.display.monthYearLabel)
.toLocaleUpperCase();
}
previousClicked(mode: 'month' | 'year') {
this._calendar.activeDate = mode == 'month' ?
this._dateAdapter.addCalendarMonths(this._calendar.activeDate, -1) :
this._dateAdapter.addCalendarYears(this._calendar.activeDate, -1);
this._dateAdapter.addCalendarYears(this._calendar.activeDate, -1);
}
nextClicked(mode: 'month' | 'year') {
this._calendar.activeDate = mode == 'month' ?
this._dateAdapter.addCalendarMonths(this._calendar.activeDate, 1) :
this._dateAdapter.addCalendarYears(this._calendar.activeDate, 1);
this._dateAdapter.addCalendarYears(this._calendar.activeDate, 1);
}
}
+14
View File
@@ -287,6 +287,20 @@ export class MyApp {}
<!-- example(datepicker-formats) -->
#### Customizing the calendar header
The header section of the calendar (the part containing the view switcher and previous and next
buttons) can be replaced with a custom component if desired. This is accomplished using the
`calendarHeaderComponent` property of `<mat-datepicker>`. It takes a component class and constructs
an instance of the component to use as the header.
In order to interact with the calendar in your custom header component, you can inject the parent
`MatCalendar` in the constructor. To make sure your header stays in sync with the calendar,
subscribe to the `stateChanges` observable of the calendar and mark your header component for change
detection.
<!-- example(datepicker-custom-header) -->
#### Localizing labels and messages
The various text strings used by the datepicker are provided through `MatDatepickerIntl`.
@@ -0,0 +1,16 @@
.example-header {
display: flex;
align-items: center;
padding: 0.5em;
}
.example-header-label {
flex: 1;
height: 1em;
font-weight: bold;
text-align: center;
}
.example-double-arrow .mat-icon {
margin: -22%;
}
@@ -0,0 +1,6 @@
<mat-form-field>
<mat-label>Custom calendar header</mat-label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker [calendarHeaderComponent]="exampleHeader"></mat-datepicker>
</mat-form-field>
@@ -0,0 +1,86 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Host,
Inject,
OnDestroy,
ViewEncapsulation
} from '@angular/core';
import {MatCalendar} from '@angular/material';
import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats} from '@angular/material/core';
import {Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
/** @title Datepicker with custom calendar header */
@Component({
selector: 'datepicker-custom-header-example',
templateUrl: 'datepicker-custom-header-example.html',
styleUrls: ['datepicker-custom-header-example.css'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DatepickerCustomHeaderExample {
exampleHeader = ExampleHeader;
}
/** Custom header component for datepicker. */
@Component({
selector: 'example-header',
template: `
<div class="example-header">
<button mat-icon-button class="example-double-arrow" (click)="previousClicked('year')">
<mat-icon>keyboard_arrow_left</mat-icon>
<mat-icon>keyboard_arrow_left</mat-icon>
</button>
<button mat-icon-button (click)="previousClicked('month')">
<mat-icon>keyboard_arrow_left</mat-icon>
</button>
<span class="example-header-label">{{periodLabel}}</span>
<button mat-icon-button (click)="nextClicked('month')">
<mat-icon>keyboard_arrow_right</mat-icon>
</button>
<button mat-icon-button class="example-double-arrow" (click)="nextClicked('year')">
<mat-icon>keyboard_arrow_right</mat-icon>
<mat-icon>keyboard_arrow_right</mat-icon>
</button>
</div>
`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ExampleHeader<D> implements OnDestroy {
private destroyed = new Subject<void>();
constructor(@Host() private calendar: MatCalendar<D>,
private dateAdapter: DateAdapter<D>,
@Inject(MAT_DATE_FORMATS) private dateFormats: MatDateFormats,
cdr: ChangeDetectorRef) {
calendar.stateChanges
.pipe(takeUntil(this.destroyed))
.subscribe(() => cdr.markForCheck());
}
ngOnDestroy() {
this.destroyed.next();
this.destroyed.complete();
}
get periodLabel() {
return this.dateAdapter
.format(this.calendar.activeDate, this.dateFormats.display.monthYearLabel)
.toLocaleUpperCase();
}
previousClicked(mode: 'month' | 'year') {
this.calendar.activeDate = mode == 'month' ?
this.dateAdapter.addCalendarMonths(this.calendar.activeDate, -1) :
this.dateAdapter.addCalendarYears(this.calendar.activeDate, -1);
}
nextClicked(mode: 'month' | 'year') {
this.calendar.activeDate = mode == 'month' ?
this.dateAdapter.addCalendarMonths(this.calendar.activeDate, 1) :
this.dateAdapter.addCalendarYears(this.calendar.activeDate, 1);
}
}
+3 -1
View File
@@ -226,7 +226,9 @@ task('build-examples-module', () => {
for (const meta of secondaryComponents) {
example.additionalComponents.push(meta.component);
example.additionalFiles.push(meta.templateUrl);
if (meta.templateUrl) {
example.additionalFiles.push(meta.templateUrl);
}
example.selectorName.push(meta.component);
}
}