-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(datepicker): Add Custom Header to DatePicker #9639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mmalerba
merged 64 commits into
angular:master
from
dhlab-basel:tobiasschweizer/calendar-header-comp
Mar 22, 2018
Merged
Changes from all commits
Commits
Show all changes
64 commits
Select commit
Hold shift + click to select a range
6251e1e
feature (add custom header to mat-calendar)
8d30140
refactor (define custom header component)
81c89fa
refactor (remove useless text)
737a563
refactor (pass custom header component type as input)
998be7c
refactor (add header as component portal)
a14dbd4
refactor (custom header as component portal)
585407f
refactor (switch for custom header component)
6668ae6
refactor (define entry components)
f9628a8
fix (correct entry point)
050904b
refactor (custom header component): add test function to custom heade…
a2db283
refactor (some code formatting)
7f071ec
refactor (set indentation to two spaces)
5c9f662
refactor (formatting)
3467c0a
refactor (custom header for mat-calendar): renaming and code improvem…
014777a
refactor (calendarHeaderComponent) rename input of MatDatepicker
179c9af
refactor (calendarHeaderComponent): make a demo for custom header
b6938f2
refactor (calendar header): make calendar header portal variable public
0faefc4
refactor (calendar header): formatting
aa8f837
Merge branch 'master' into tobiasschweizer/calendar-header-comp
2b4d4d2
Merge branch 'master' into tobiasschweizer/calendar-header-comp
b238107
Merge branch 'master' into tobiasschweizer/calendar-header-comp
46b2c9d
Merge branch 'master' into tobiasschweizer/calendar-header-comp
a45f3ee
tests (MatCalendar): fix tests
f8c4c5b
tests (calendar): fix import issue
b6b50cc
tests (MatCalendar): remove unused import
ca7a0db
tests (MatCalendar): import MatDatepickerModule without redeclaration
2058afb
tests (MatCalendar): fix imports
f6f19e8
refactor (MatCalendar): default header comes with empty template
702317d
refactor (MatCalendar): remove useless newline
528361e
feature (MatCalendarHeader): move header in own template
e36dc71
Merge branch 'master' into tobiasschweizer/calendar-header-comp
a7975d2
refactor (MatCalendar): some code reformatting
02b5604
fix (MatCalendar): add missin change detection for MatCalendarHeader
57bd12c
refactor (MatCalendar): fix indentation
a88fecb
fix (MatCalendar): clean stream up after component destruction
4c66467
fix (MatCalendar): fix change detection for MatCalendarHeader
258929a
Merge branch 'master' into tobiasschweizer/calendar-header-comp
81147f1
refactor (MatCalendarHeader): add dateadapter to constructor
586d5da
refactor (MatCalendarHeader): move methods to calendar header (ongoing)
a9d4c58
refactor (MatCalendarHeader): move label getter methods to MatCalenda…
9bba08f
refactor (MatCalendarHeader): move MatCalendarHeader component in a s…
1ff7e45
tests (MatCalendarHeader): move header related tests from MatCalendar…
5196ee7
refactor (MatCalendar): linting
4cee00c
Merge branch 'master' into tobiasschweizer/calendar-header-comp
da49938
refactor (MatCalendarHeader): move MatCalendarHeader component back t…
70ff16f
refactor (MatCalendarHeader): move header related methods
533739e
feature (MatCalendarHeader): add sample custom header controls to dem…
c287495
Merge branch 'master' into tobiasschweizer/calendar-header-comp
6d0a4d2
refactor (MatCalendarHeader): fix some styling issues
a33b70c
refactor (MatCalendarHeader): fix indentation
c7f21bf
refactor (MatCalendarHeader): make calendar private for custom header
715e413
refactor (MatCalendarHeader): use type parameter for header (generics)
5f4b0fc
refactor (MatCalendarHeader): make template file for custom header on…
3057f9d
Merge branch 'master' into tobiasschweizer/calendar-header-comp
d81db60
refactor (MatCalendarHeader): separate section own demo page
94c825a
refactor (MatCalendarHeader): style custom header
b6fc003
refactor (MatCalendarHeader): fix styling issue
796cbf2
refactor (package-lock.json): revert changes to version on master branch
abf1c62
refactor (package-lock.json): revert to commit 6f63fd283eeb643523a9e3…
1fdb1c3
Merge branch 'master' into tobiasschweizer/calendar-header-comp
822dd56
fix (MatCalendarHeader): correct forward reference to MatCalendar
ba4e839
Merge branch 'master' into tobiasschweizer/calendar-header-comp
1ee0f93
Add `stateChanges` to `MatCalendar`
mmalerba aff641d
fix nits
mmalerba File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<div class="custom-header"> | ||
<button mat-icon-button (click)="previousClicked('year')"><<</button> | ||
<button mat-icon-button (click)="previousClicked('month')"><</button> | ||
<span class="custom-header-label">{{periodLabel}}</span> | ||
<button mat-icon-button (click)="nextClicked('month')">></button> | ||
<button mat-icon-button (click)="nextClicked('year')">>></button> | ||
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.custom-header { | ||
padding: 1em 1.5em; | ||
display: flex; | ||
align-items: center; | ||
} | ||
|
||
.custom-header-label { | ||
flex: 1; | ||
text-align: center; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<div class="mat-calendar-header"> | ||
<div class="mat-calendar-controls"> | ||
<button mat-button class="mat-calendar-period-button" | ||
(click)="currentPeriodClicked()" [attr.aria-label]="periodButtonLabel"> | ||
{{periodButtonText}} | ||
<div class="mat-calendar-arrow" [class.mat-calendar-invert]="calendar.currentView != 'month'"></div> | ||
</button> | ||
|
||
<div class="mat-calendar-spacer"></div> | ||
|
||
<button mat-icon-button class="mat-calendar-previous-button" | ||
[disabled]="!previousEnabled()" (click)="previousClicked()" | ||
[attr.aria-label]="prevButtonLabel"> | ||
</button> | ||
|
||
<button mat-icon-button class="mat-calendar-next-button" | ||
[disabled]="!nextEnabled()" (click)="nextClicked()" | ||
[attr.aria-label]="nextButtonLabel"> | ||
</button> | ||
</div> | ||
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import {Direction, Directionality} from '@angular/cdk/bidi'; | ||
import {MatDatepickerModule} from './datepicker-module'; | ||
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; | ||
import {MatDatepickerIntl} from './datepicker-intl'; | ||
import {DEC, FEB, JAN, MatNativeDateModule} from '@angular/material/core'; | ||
import {Component} from '@angular/core'; | ||
import {MatCalendar} from './calendar'; | ||
import {By} from '@angular/platform-browser'; | ||
import {yearsPerPage} from './multi-year-view'; | ||
|
||
describe('MatCalendarHeader', () => { | ||
let dir: { value: Direction }; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [ | ||
MatNativeDateModule, | ||
MatDatepickerModule, | ||
], | ||
declarations: [ | ||
// Test components. | ||
StandardCalendar, | ||
], | ||
providers: [ | ||
MatDatepickerIntl, | ||
{provide: Directionality, useFactory: () => dir = {value: 'ltr'}} | ||
], | ||
}); | ||
|
||
TestBed.compileComponents(); | ||
})); | ||
|
||
describe('standard calendar', () => { | ||
let fixture: ComponentFixture<StandardCalendar>; | ||
let testComponent: StandardCalendar; | ||
let calendarElement: HTMLElement; | ||
let periodButton: HTMLElement; | ||
let prevButton: HTMLElement; | ||
let nextButton: HTMLElement; | ||
let calendarInstance: MatCalendar<Date>; | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(StandardCalendar); | ||
fixture.detectChanges(); | ||
|
||
let calendarDebugElement = fixture.debugElement.query(By.directive(MatCalendar)); | ||
calendarElement = calendarDebugElement.nativeElement; | ||
periodButton = calendarElement.querySelector('.mat-calendar-period-button') as HTMLElement; | ||
prevButton = calendarElement.querySelector('.mat-calendar-previous-button') as HTMLElement; | ||
nextButton = calendarElement.querySelector('.mat-calendar-next-button') as HTMLElement; | ||
|
||
calendarInstance = calendarDebugElement.componentInstance; | ||
testComponent = fixture.componentInstance; | ||
}); | ||
|
||
it('should be in month view with specified month active', () => { | ||
expect(calendarInstance.currentView).toBe('month'); | ||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 31)); | ||
}); | ||
|
||
it('should toggle view when period clicked', () => { | ||
expect(calendarInstance.currentView).toBe('month'); | ||
|
||
periodButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('multi-year'); | ||
|
||
periodButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('month'); | ||
}); | ||
|
||
it('should go to next and previous month', () => { | ||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 31)); | ||
|
||
nextButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.activeDate).toEqual(new Date(2017, FEB, 28)); | ||
|
||
prevButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 28)); | ||
}); | ||
|
||
it('should go to previous and next year', () => { | ||
periodButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('multi-year'); | ||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 31)); | ||
|
||
(calendarElement.querySelector('.mat-calendar-body-active') as HTMLElement).click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('year'); | ||
|
||
nextButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.activeDate).toEqual(new Date(2018, JAN, 31)); | ||
|
||
prevButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 31)); | ||
}); | ||
|
||
it('should go to previous and next multi-year range', () => { | ||
periodButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('multi-year'); | ||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 31)); | ||
|
||
nextButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.activeDate).toEqual(new Date(2017 + yearsPerPage, JAN, 31)); | ||
|
||
prevButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 31)); | ||
}); | ||
|
||
it('should go back to month view after selecting year and month', () => { | ||
periodButton.click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('multi-year'); | ||
expect(calendarInstance.activeDate).toEqual(new Date(2017, JAN, 31)); | ||
|
||
let yearCells = calendarElement.querySelectorAll('.mat-calendar-body-cell'); | ||
(yearCells[0] as HTMLElement).click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('year'); | ||
expect(calendarInstance.activeDate).toEqual(new Date(2016, JAN, 31)); | ||
|
||
let monthCells = calendarElement.querySelectorAll('.mat-calendar-body-cell'); | ||
(monthCells[monthCells.length - 1] as HTMLElement).click(); | ||
fixture.detectChanges(); | ||
|
||
expect(calendarInstance.currentView).toBe('month'); | ||
expect(calendarInstance.activeDate).toEqual(new Date(2016, DEC, 31)); | ||
expect(testComponent.selected).toBeFalsy('no date should be selected yet'); | ||
}); | ||
|
||
}); | ||
}); | ||
|
||
@Component({ | ||
template: ` | ||
<mat-calendar | ||
[startAt]="startDate" | ||
[(selected)]="selected" | ||
(yearSelected)="selectedYear=$event" | ||
(monthSelected)="selectedMonth=$event"> | ||
</mat-calendar>` | ||
}) | ||
class StandardCalendar { | ||
selected: Date; | ||
selectedYear: Date; | ||
selectedMonth: Date; | ||
startDate = new Date(2017, JAN, 31); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: normal indentation = 2 spaces, continuation lines can be indented 4 or align the attributes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in a7975d2