From ce7588ecf2c358cf1df27097a47d6dc5cd00fafd Mon Sep 17 00:00:00 2001 From: mmalerba Date: Wed, 19 Apr 2017 08:45:31 -0700 Subject: [PATCH] refactor(datepicker): move weekdays into table header (#4129) * fix broken tests * md-calendar-table --> [md-calendar-body] * move md-calendar-body to tbody element * move weekdays into table header * finishing touches * fix year view padding * add some comments --- src/lib/datepicker/_datepicker-theme.scss | 34 +++++----- src/lib/datepicker/calendar-body.html | 24 +++++++ src/lib/datepicker/calendar-body.scss | 64 ++++++++++++++++++ .../{calendar-table.ts => calendar-body.ts} | 11 +-- src/lib/datepicker/calendar-table.html | 26 ------- src/lib/datepicker/calendar-table.scss | 67 ------------------- src/lib/datepicker/calendar-table.spec.ts | 54 ++++++++------- src/lib/datepicker/calendar.html | 6 +- src/lib/datepicker/calendar.scss | 47 ++++++++----- src/lib/datepicker/calendar.spec.ts | 34 +++++----- src/lib/datepicker/calendar.ts | 8 +-- src/lib/datepicker/datepicker.spec.ts | 2 +- src/lib/datepicker/datepicker.ts | 2 +- src/lib/datepicker/index.ts | 6 +- src/lib/datepicker/month-view.html | 23 ++++--- src/lib/datepicker/month-view.spec.ts | 26 +++---- src/lib/datepicker/month-view.ts | 11 ++- src/lib/datepicker/year-view.html | 24 ++++--- src/lib/datepicker/year-view.spec.ts | 26 +++---- src/lib/datepicker/year-view.ts | 2 +- 20 files changed, 263 insertions(+), 234 deletions(-) create mode 100644 src/lib/datepicker/calendar-body.html create mode 100644 src/lib/datepicker/calendar-body.scss rename src/lib/datepicker/{calendar-table.ts => calendar-body.ts} (92%) delete mode 100644 src/lib/datepicker/calendar-table.html delete mode 100644 src/lib/datepicker/calendar-table.scss diff --git a/src/lib/datepicker/_datepicker-theme.scss b/src/lib/datepicker/_datepicker-theme.scss index bd3d1a56726e..4eea688f7003 100644 --- a/src/lib/datepicker/_datepicker-theme.scss +++ b/src/lib/datepicker/_datepicker-theme.scss @@ -15,10 +15,6 @@ background-color: mat-color($background, card); } - .mat-calendar-header { - border-color: mat-color($foreground, divider); - } - .mat-calendar-arrow { border-top-color: mat-color($foreground, icon); } @@ -28,52 +24,56 @@ color: mat-color($foreground, icon); } - .mat-calendar-weekday-table { + .mat-calendar-table-header { color: mat-color($foreground, hint-text); } - .mat-calendar-table-label { + .mat-calendar-table-header-divider::after { + background: mat-color($foreground, divider); + } + + .mat-calendar-body-label { color: mat-color($foreground, secondary-text); } - .mat-calendar-table-cell-content { + .mat-calendar-body-cell-content { color: mat-color($foreground, text); border-color: transparent; - .mat-calendar-table-disabled > &:not(.mat-calendar-table-selected) { + .mat-calendar-body-disabled > &:not(.mat-calendar-body-selected) { color: mat-color($foreground, disabled-text); } } - :not(.mat-calendar-table-disabled):hover, - .cdk-keyboard-focused .mat-calendar-table-active { - & > .mat-calendar-table-cell-content:not(.mat-calendar-table-selected) { + :not(.mat-calendar-body-disabled):hover, + .cdk-keyboard-focused .mat-calendar-body-active { + & > .mat-calendar-body-cell-content:not(.mat-calendar-body-selected) { background-color: mat-color($background, hover); } } - .mat-calendar-table-selected { + .mat-calendar-body-selected { background-color: mat-color($primary); color: mat-color($primary, default-contrast); - .mat-calendar-table-disabled > & { + .mat-calendar-body-disabled > & { background-color: fade-out(mat-color($primary), $mat-datepicker-selected-fade-amount); } } - .mat-calendar-table-today { - &:not(.mat-calendar-table-selected) { + .mat-calendar-body-today { + &:not(.mat-calendar-body-selected) { // Note: though it's not text, the border is a hint about the fact that this is today's date, // so we use the hint color. border-color: mat-color($foreground, hint-text); - .mat-calendar-table-disabled > & { + .mat-calendar-body-disabled > & { border-color: fade-out(mat-color($foreground, hint-text), $mat-datepicker-today-fade-amount); } } - &.mat-calendar-table-selected { + &.mat-calendar-body-selected { box-shadow: inset 0 0 0 $mat-datepicker-selected-today-box-shadow-width mat-color($primary, default-contrast); } diff --git a/src/lib/datepicker/calendar-body.html b/src/lib/datepicker/calendar-body.html new file mode 100644 index 000000000000..22782713288b --- /dev/null +++ b/src/lib/datepicker/calendar-body.html @@ -0,0 +1,24 @@ + + + {{label}} + + + + + + {{_firstRowOffset >= labelMinRequiredCells ? label : ''}} + + +
+ {{item.displayValue}} +
+ + diff --git a/src/lib/datepicker/calendar-body.scss b/src/lib/datepicker/calendar-body.scss new file mode 100644 index 000000000000..39b1d22cbd9d --- /dev/null +++ b/src/lib/datepicker/calendar-body.scss @@ -0,0 +1,64 @@ +$mat-calendar-body-font-size: 13px !default; +$mat-calendar-body-header-font-size: 14px !default; +$mat-calendar-body-label-padding-start: 5% !default; +$mat-calendar-body-label-translation: -6px !default; +$mat-calendar-body-cell-min-size: 32px !default; +$mat-calendar-body-cell-size: 100% / 7 !default; +$mat-calendar-body-cell-content-margin: 5% !default; +$mat-calendar-body-cell-content-border-width: 1px !default; + +$mat-calendar-body-min-size: 7 * $mat-calendar-body-cell-min-size !default; +$mat-calendar-body-cell-padding: $mat-calendar-body-cell-size / 2 !default; +$mat-calendar-body-cell-content-size: 100% - $mat-calendar-body-cell-content-margin * 2 !default; + + +.mat-calendar-body { + font-size: $mat-calendar-body-font-size; + min-width: $mat-calendar-body-min-size; +} + +.mat-calendar-body-label { + padding: $mat-calendar-body-cell-padding 0 + $mat-calendar-body-cell-padding $mat-calendar-body-cell-padding; + height: 0; + line-height: 0; + transform: translateX($mat-calendar-body-label-translation); + text-align: left; + font-size: $mat-calendar-body-header-font-size; + font-weight: bold; +} + +.mat-calendar-body-cell { + position: relative; + width: $mat-calendar-body-cell-size; + height: 0; + line-height: 0; + padding: $mat-calendar-body-cell-padding 0; + text-align: center; +} + +.mat-calendar-body-cell-content { + position: absolute; + top: $mat-calendar-body-cell-content-margin; + left: $mat-calendar-body-cell-content-margin; + + display: flex; + align-items: center; + justify-content: center; + + box-sizing: border-box; + width: $mat-calendar-body-cell-content-size; + height: $mat-calendar-body-cell-content-size; + + border-width: $mat-calendar-body-cell-content-border-width; + border-style: solid; + border-radius: 50%; +} + +[dir='rtl'] { + .mat-calendar-body-label { + padding: 0 $mat-calendar-body-cell-padding 0 0; + transform: translateX(-$mat-calendar-body-label-translation); + text-align: right; + } +} diff --git a/src/lib/datepicker/calendar-table.ts b/src/lib/datepicker/calendar-body.ts similarity index 92% rename from src/lib/datepicker/calendar-table.ts rename to src/lib/datepicker/calendar-body.ts index a9195f71cd8d..b20376a95604 100644 --- a/src/lib/datepicker/calendar-table.ts +++ b/src/lib/datepicker/calendar-body.ts @@ -23,13 +23,16 @@ export class MdCalendarCell { */ @Component({ moduleId: module.id, - selector: 'md-calendar-table', - templateUrl: 'calendar-table.html', - styleUrls: ['calendar-table.css'], + selector: '[md-calendar-body]', + templateUrl: 'calendar-body.html', + styleUrls: ['calendar-body.css'], + host: { + 'class': 'mat-calendar-body', + }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MdCalendarTable { +export class MdCalendarBody { /** The label for the table. (e.g. "Jan 2017"). */ @Input() label: string; diff --git a/src/lib/datepicker/calendar-table.html b/src/lib/datepicker/calendar-table.html deleted file mode 100644 index af00052cfc34..000000000000 --- a/src/lib/datepicker/calendar-table.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - -
{{label}}
- {{_firstRowOffset >= labelMinRequiredCells ? label : ''}} - -
- {{item.displayValue}} -
-
diff --git a/src/lib/datepicker/calendar-table.scss b/src/lib/datepicker/calendar-table.scss deleted file mode 100644 index c96189cd84ac..000000000000 --- a/src/lib/datepicker/calendar-table.scss +++ /dev/null @@ -1,67 +0,0 @@ -$mat-calendar-table-font-size: 13px !default; -$mat-calendar-table-header-font-size: 14px !default; -$mat-calendar-table-label-padding-start: 5% !default; -$mat-calendar-table-label-translation: -6px !default; -$mat-calendar-table-cell-min-size: 32px !default; -$mat-calendar-table-cell-size: 100% / 7 !default; -$mat-calendar-table-cell-content-margin: 5% !default; -$mat-calendar-table-cell-content-border-width: 1px !default; - -$mat-calendar-table-min-size: 7 * $mat-calendar-table-cell-min-size !default; -$mat-calendar-table-cell-padding: $mat-calendar-table-cell-size / 2 !default; -$mat-calendar-table-cell-content-size: 100% - $mat-calendar-table-cell-content-margin * 2 !default; - - -.mat-calendar-table-table { - border-spacing: 0; - border-collapse: collapse; - font-size: $mat-calendar-table-font-size; - min-width: $mat-calendar-table-min-size; - width: 100%; -} - -.mat-calendar-table-label { - padding: $mat-calendar-table-cell-padding 0 - $mat-calendar-table-cell-padding $mat-calendar-table-cell-padding; - height: 0; - line-height: 0; - transform: translateX($mat-calendar-table-label-translation); - text-align: left; - font-size: $mat-calendar-table-header-font-size; - font-weight: bold; -} - -.mat-calendar-table-cell { - position: relative; - width: $mat-calendar-table-cell-size; - height: 0; - line-height: 0; - padding: $mat-calendar-table-cell-padding 0; - text-align: center; -} - -.mat-calendar-table-cell-content { - position: absolute; - top: $mat-calendar-table-cell-content-margin; - left: $mat-calendar-table-cell-content-margin; - - display: flex; - align-items: center; - justify-content: center; - - box-sizing: border-box; - width: $mat-calendar-table-cell-content-size; - height: $mat-calendar-table-cell-content-size; - - border-width: $mat-calendar-table-cell-content-border-width; - border-style: solid; - border-radius: 50%; -} - -[dir='rtl'] { - .mat-calendar-table-label { - padding: 0 $mat-calendar-table-cell-padding 0 0; - transform: translateX(-$mat-calendar-table-label-translation); - text-align: right; - } -} diff --git a/src/lib/datepicker/calendar-table.spec.ts b/src/lib/datepicker/calendar-table.spec.ts index fa314a3d9af8..a0fea7c9c430 100644 --- a/src/lib/datepicker/calendar-table.spec.ts +++ b/src/lib/datepicker/calendar-table.spec.ts @@ -1,6 +1,6 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {Component} from '@angular/core'; -import {MdCalendarCell, MdCalendarTable} from './calendar-table'; +import {MdCalendarCell, MdCalendarBody} from './calendar-body'; import {By} from '@angular/platform-browser'; import {SimpleDate} from '../core/datetime/simple-date'; @@ -9,7 +9,7 @@ describe('MdCalendarTable', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ - MdCalendarTable, + MdCalendarBody, // Test components. StandardCalendarTable, @@ -30,15 +30,15 @@ describe('MdCalendarTable', () => { let refreshElementLists = () => { rowEls = calendarTableNativeElement.querySelectorAll('tr'); - labelEls = calendarTableNativeElement.querySelectorAll('.mat-calendar-table-label'); - cellEls = calendarTableNativeElement.querySelectorAll('.mat-calendar-table-cell'); + labelEls = calendarTableNativeElement.querySelectorAll('.mat-calendar-body-label'); + cellEls = calendarTableNativeElement.querySelectorAll('.mat-calendar-body-cell'); }; beforeEach(() => { fixture = TestBed.createComponent(StandardCalendarTable); fixture.detectChanges(); - let calendarTableDebugElement = fixture.debugElement.query(By.directive(MdCalendarTable)); + let calendarTableDebugElement = fixture.debugElement.query(By.directive(MdCalendarBody)); calendarTableNativeElement = calendarTableDebugElement.nativeElement; testComponent = fixture.componentInstance; @@ -52,13 +52,13 @@ describe('MdCalendarTable', () => { }); it('highlights today', () => { - let todayCell = calendarTableNativeElement.querySelector('.mat-calendar-table-today'); + let todayCell = calendarTableNativeElement.querySelector('.mat-calendar-body-today'); expect(todayCell).not.toBeNull(); expect(todayCell.innerHTML.trim()).toBe('3'); }); it('highlights selected', () => { - let selectedCell = calendarTableNativeElement.querySelector('.mat-calendar-table-selected'); + let selectedCell = calendarTableNativeElement.querySelector('.mat-calendar-body-selected'); expect(selectedCell).not.toBeNull(); expect(selectedCell.innerHTML.trim()).toBe('4'); }); @@ -73,23 +73,23 @@ describe('MdCalendarTable', () => { expect(labelEls.length).toBe(1); expect(cellEls.length).toBe(11); expect(rowEls[0].firstElementChild.classList) - .toContain('mat-calendar-table-label', 'first cell should be the label'); + .toContain('mat-calendar-body-label', 'first cell should be the label'); expect(labelEls[0].getAttribute('colspan')).toBe('3'); }); it('cell should be selected on click', () => { let todayElement = - calendarTableNativeElement.querySelector('.mat-calendar-table-today') as HTMLElement; + calendarTableNativeElement.querySelector('.mat-calendar-body-today') as HTMLElement; todayElement.click(); fixture.detectChanges(); expect(todayElement.classList) - .toContain('mat-calendar-table-selected', 'today should be selected'); + .toContain('mat-calendar-body-selected', 'today should be selected'); }); it('should mark active date', () => { expect((cellEls[10] as HTMLElement).innerText.trim()).toBe('11'); - expect(cellEls[10].classList).toContain('mat-calendar-table-active'); + expect(cellEls[10].classList).toContain('mat-calendar-body-active'); }); }); @@ -103,10 +103,10 @@ describe('MdCalendarTable', () => { fixture = TestBed.createComponent(CalendarTableWithDisabledCells); fixture.detectChanges(); - let calendarTableDebugElement = fixture.debugElement.query(By.directive(MdCalendarTable)); + let calendarTableDebugElement = fixture.debugElement.query(By.directive(MdCalendarBody)); calendarTableNativeElement = calendarTableDebugElement.nativeElement; testComponent = fixture.componentInstance; - cellEls = calendarTableNativeElement.querySelectorAll('.mat-calendar-table-cell'); + cellEls = calendarTableNativeElement.querySelectorAll('.mat-calendar-body-cell'); }); it('should only allow selection of disabled cells when allowDisabledSelection is true', () => { @@ -128,15 +128,16 @@ describe('MdCalendarTable', () => { @Component({ - template: ` - `, + template: ` +
`, }) class StandardCalendarTable { label = 'Jan 2017'; @@ -153,10 +154,11 @@ class StandardCalendarTable { @Component({ - template: ` - ` + template: ` +
` }) class CalendarTableWithDisabledCells { rows = [[1, 2, 3, 4]].map(r => r.map(d => { diff --git a/src/lib/datepicker/calendar.html b/src/lib/datepicker/calendar.html index 96de7d3e7b24..a9a23b3ff788 100644 --- a/src/lib/datepicker/calendar.html +++ b/src/lib/datepicker/calendar.html @@ -13,13 +13,9 @@ (click)="_nextClicked()" [attr.aria-label]="_nextButtonLabel"> - - - -
{{day}}
-
svg { - vertical-align: middle; -} - .mat-calendar-arrow { display: inline-block; width: 0; @@ -71,12 +65,6 @@ $mat-calendar-next-icon-transform: translateX(-2px) rotate(45deg); } } -.mat-calendar-weekday-table { - width: 100%; - text-align: center; - font-size: $mat-calendar-weekday-table-font-size; -} - .mat-calendar-previous-button, .mat-calendar-next-button { position: relative; @@ -103,3 +91,32 @@ $mat-calendar-next-icon-transform: translateX(-2px) rotate(45deg); border-right-width: $mat-calendar-prev-next-icon-border-width; transform: $mat-calendar-next-icon-transform; } + +.mat-calendar-table { + border-spacing: 0; + border-collapse: collapse; + width: 100%; +} + +.mat-calendar-table-header th { + text-align: center; + font-size: $mat-calendar-weekday-table-font-size; + font-weight: normal; + padding: 0 0 $mat-calendar-padding 0; +} + +.mat-calendar-table-header-divider { + position: relative; + height: $mat-calendar-header-divider-width; + + // We use an absolutely positioned pseudo-element as the divider line for the table header so we + // can extend it all the way to the edge of the calendar. + &::after { + content: ''; + position: absolute; + top: 0; + left: -$mat-calendar-padding; + right: -$mat-calendar-padding; + height: $mat-calendar-header-divider-width; + } +} diff --git a/src/lib/datepicker/calendar.spec.ts b/src/lib/datepicker/calendar.spec.ts index 29f484bbdb9a..60e2ce027817 100644 --- a/src/lib/datepicker/calendar.spec.ts +++ b/src/lib/datepicker/calendar.spec.ts @@ -5,10 +5,11 @@ import {MdCalendar} from './calendar'; import {By} from '@angular/platform-browser'; import {MdMonthView} from './month-view'; import {MdYearView} from './year-view'; -import {MdCalendarTable} from './calendar-table'; +import {MdCalendarBody} from './calendar-body'; import {DatetimeModule} from '../core/datetime/index'; import { - dispatchFakeEvent, dispatchKeyboardEvent, + dispatchFakeEvent, + dispatchKeyboardEvent, dispatchMouseEvent } from '../core/testing/dispatch-events'; import { @@ -32,7 +33,7 @@ describe('MdCalendar', () => { ], declarations: [ MdCalendar, - MdCalendarTable, + MdCalendarBody, MdMonthView, MdYearView, @@ -127,7 +128,7 @@ describe('MdCalendar', () => { expect(calendarInstance._monthView).toBe(false, 'should be in year view'); expect(calendarInstance._activeDate).toEqual(new SimpleDate(2017, 0, 31)); - let monthCells = calendarElement.querySelectorAll('.mat-calendar-table-cell'); + let monthCells = calendarElement.querySelectorAll('.mat-calendar-body-cell'); (monthCells[monthCells.length - 1] as HTMLElement).click(); fixture.detectChanges(); @@ -137,7 +138,7 @@ describe('MdCalendar', () => { }); it('should select date in month view', () => { - let monthCells = calendarElement.querySelectorAll('.mat-calendar-table-cell'); + let monthCells = calendarElement.querySelectorAll('.mat-calendar-body-cell'); (monthCells[monthCells.length - 1] as HTMLElement).click(); fixture.detectChanges(); @@ -150,7 +151,7 @@ describe('MdCalendar', () => { let calendarBodyEl: HTMLElement; beforeEach(() => { - calendarBodyEl = calendarElement.querySelector('.mat-calendar-body') as HTMLElement; + calendarBodyEl = calendarElement.querySelector('.mat-calendar-content') as HTMLElement; expect(calendarBodyEl).not.toBeNull(); dispatchFakeEvent(calendarBodyEl, 'focus'); @@ -434,8 +435,8 @@ describe('MdCalendar', () => { let fixture: ComponentFixture; let testComponent: CalendarWithMinMax; let calendarElement: HTMLElement; - let prevButton: HTMLElement; - let nextButton: HTMLElement; + let prevButton: HTMLButtonElement; + let nextButton: HTMLButtonElement; let calendarInstance: MdCalendar; beforeEach(() => { @@ -443,8 +444,9 @@ describe('MdCalendar', () => { let calendarDebugElement = fixture.debugElement.query(By.directive(MdCalendar)); calendarElement = calendarDebugElement.nativeElement; - prevButton = calendarElement.querySelector('.mat-calendar-previous-button') as HTMLElement; - nextButton = calendarElement.querySelector('.mat-calendar-next-button') as HTMLElement; + prevButton = + calendarElement.querySelector('.mat-calendar-previous-button') as HTMLButtonElement; + nextButton = calendarElement.querySelector('.mat-calendar-next-button') as HTMLButtonElement; calendarInstance = calendarDebugElement.componentInstance; testComponent = fixture.componentInstance; }); @@ -467,13 +469,13 @@ describe('MdCalendar', () => { testComponent.startAt = new SimpleDate(2016, 1, 1); fixture.detectChanges(); - expect(prevButton.classList).not.toContain('mat-calendar-disabled'); + expect(prevButton.disabled).toBe(false, 'previous button should not be disabled'); expect(calendarInstance._activeDate).toEqual(new SimpleDate(2016, 1, 1)); prevButton.click(); fixture.detectChanges(); - expect(prevButton.classList).toContain('mat-calendar-disabled'); + expect(prevButton.disabled).toBe(true, 'previous button should be disabled'); expect(calendarInstance._activeDate).toEqual(new SimpleDate(2016, 0, 1)); prevButton.click(); @@ -486,13 +488,13 @@ describe('MdCalendar', () => { testComponent.startAt = new SimpleDate(2017, 11, 1); fixture.detectChanges(); - expect(nextButton.classList).not.toContain('mat-calendar-disabled'); + expect(nextButton.disabled).toBe(false, 'next button should not be disabled'); expect(calendarInstance._activeDate).toEqual(new SimpleDate(2017, 11, 1)); nextButton.click(); fixture.detectChanges(); - expect(nextButton.classList).toContain('mat-calendar-disabled'); + expect(nextButton.disabled).toBe(true, 'next button should be disabled'); expect(calendarInstance._activeDate).toEqual(new SimpleDate(2018, 0, 1)); nextButton.click(); @@ -519,7 +521,7 @@ describe('MdCalendar', () => { }); it('should disable and prevent selection of filtered dates', () => { - let cells = calendarElement.querySelectorAll('.mat-calendar-table-cell'); + let cells = calendarElement.querySelectorAll('.mat-calendar-body-cell'); (cells[0] as HTMLElement).click(); fixture.detectChanges(); @@ -535,7 +537,7 @@ describe('MdCalendar', () => { let calendarBodyEl: HTMLElement; beforeEach(() => { - calendarBodyEl = calendarElement.querySelector('.mat-calendar-body') as HTMLElement; + calendarBodyEl = calendarElement.querySelector('.mat-calendar-content') as HTMLElement; expect(calendarBodyEl).not.toBeNull(); dispatchFakeEvent(calendarBodyEl, 'focus'); diff --git a/src/lib/datepicker/calendar.ts b/src/lib/datepicker/calendar.ts index 9543b9027e82..78007f3fa427 100644 --- a/src/lib/datepicker/calendar.ts +++ b/src/lib/datepicker/calendar.ts @@ -91,9 +91,6 @@ export class MdCalendar implements AfterContentInit { /** Whether the calendar is in month view. */ _monthView: boolean; - /** The names of the weekdays. */ - _weekdays: string[]; - /** The label for the current calendar view. */ get _periodButtonText(): string { return this._monthView ? @@ -117,10 +114,7 @@ export class MdCalendar implements AfterContentInit { return this._monthView ? this._locale.nextMonthLabel : this._locale.nextYearLabel; } - constructor(private _locale: CalendarLocale) { - this._weekdays = this._locale.narrowDays.slice(this._locale.firstDayOfWeek) - .concat(this._locale.narrowDays.slice(0, this._locale.firstDayOfWeek)); - } + constructor(private _locale: CalendarLocale) {} ngAfterContentInit() { this._activeDate = this.startAt || SimpleDate.today(); diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index 9dee866200ef..455a7761b4ff 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -117,7 +117,7 @@ describe('MdDatepicker', () => { expect(document.querySelector('md-dialog-container')).not.toBeNull(); expect(testComponent.datepickerInput.value).toEqual(new SimpleDate(2020, 0, 1)); - let cells = document.querySelectorAll('.mat-calendar-table-cell'); + let cells = document.querySelectorAll('.mat-calendar-body-cell'); dispatchMouseEvent(cells[1], 'click'); fixture.detectChanges(); diff --git a/src/lib/datepicker/datepicker.ts b/src/lib/datepicker/datepicker.ts index 3c3f0c990aae..63153fdc4762 100644 --- a/src/lib/datepicker/datepicker.ts +++ b/src/lib/datepicker/datepicker.ts @@ -62,7 +62,7 @@ export class MdDatepickerContent implements AfterContentInit { constructor(private _elementRef: ElementRef) {} ngAfterContentInit() { - this._elementRef.nativeElement.querySelector('.mat-calendar-body').focus(); + this._elementRef.nativeElement.querySelector('.mat-calendar-content').focus(); } } diff --git a/src/lib/datepicker/index.ts b/src/lib/datepicker/index.ts index 2571620c0340..8526e5f8cd0e 100644 --- a/src/lib/datepicker/index.ts +++ b/src/lib/datepicker/index.ts @@ -1,7 +1,7 @@ import {NgModule} from '@angular/core'; import {MdMonthView} from './month-view'; import {CommonModule} from '@angular/common'; -import {MdCalendarTable} from './calendar-table'; +import {MdCalendarBody} from './calendar-body'; import {MdYearView} from './year-view'; import {DatetimeModule} from '../core/datetime/index'; import {OverlayModule} from '../core/overlay/overlay-directives'; @@ -15,7 +15,7 @@ import {MdButtonModule} from '../button/index'; export * from './calendar'; -export * from './calendar-table'; +export * from './calendar-body'; export * from './datepicker'; export * from './datepicker-input'; export * from './month-view'; @@ -39,7 +39,7 @@ export * from './year-view'; ], declarations: [ MdCalendar, - MdCalendarTable, + MdCalendarBody, MdDatepicker, MdDatepickerContent, MdDatepickerInput, diff --git a/src/lib/datepicker/month-view.html b/src/lib/datepicker/month-view.html index af76b0a61a4e..a572c8ded789 100644 --- a/src/lib/datepicker/month-view.html +++ b/src/lib/datepicker/month-view.html @@ -1,8 +1,15 @@ - - + + + + + + + +
{{day}}
diff --git a/src/lib/datepicker/month-view.spec.ts b/src/lib/datepicker/month-view.spec.ts index d7fdefc1e985..ee544470a8a3 100644 --- a/src/lib/datepicker/month-view.spec.ts +++ b/src/lib/datepicker/month-view.spec.ts @@ -3,7 +3,7 @@ import {Component} from '@angular/core'; import {By} from '@angular/platform-browser'; import {MdMonthView} from './month-view'; import {SimpleDate} from '../core/datetime/simple-date'; -import {MdCalendarTable} from './calendar-table'; +import {MdCalendarBody} from './calendar-body'; import {DatetimeModule} from '../core/datetime/index'; @@ -14,7 +14,7 @@ describe('MdMonthView', () => { DatetimeModule, ], declarations: [ - MdCalendarTable, + MdCalendarBody, MdMonthView, // Test components. @@ -41,17 +41,17 @@ describe('MdMonthView', () => { }); it('has correct month label', () => { - let labelEl = monthViewNativeElement.querySelector('.mat-calendar-table-label'); + let labelEl = monthViewNativeElement.querySelector('.mat-calendar-body-label'); expect(labelEl.innerHTML.trim()).toBe('JAN'); }); it('has 31 days', () => { - let cellEls = monthViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); + let cellEls = monthViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); expect(cellEls.length).toBe(31); }); it('shows selected date if in same month', () => { - let selectedEl = monthViewNativeElement.querySelector('.mat-calendar-table-selected'); + let selectedEl = monthViewNativeElement.querySelector('.mat-calendar-body-selected'); expect(selectedEl.innerHTML.trim()).toBe('10'); }); @@ -59,23 +59,23 @@ describe('MdMonthView', () => { testComponent.selected = new SimpleDate(2017, 2, 10); fixture.detectChanges(); - let selectedEl = monthViewNativeElement.querySelector('.mat-calendar-table-selected'); + let selectedEl = monthViewNativeElement.querySelector('.mat-calendar-body-selected'); expect(selectedEl).toBeNull(); }); it('fires selected change event on cell clicked', () => { - let cellEls = monthViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); + let cellEls = monthViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); (cellEls[cellEls.length - 1] as HTMLElement).click(); fixture.detectChanges(); - let selectedEl = monthViewNativeElement.querySelector('.mat-calendar-table-selected'); + let selectedEl = monthViewNativeElement.querySelector('.mat-calendar-body-selected'); expect(selectedEl.innerHTML.trim()).toBe('31'); }); it('should mark active date', () => { - let cellEls = monthViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); + let cellEls = monthViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); expect((cellEls[4] as HTMLElement).innerText.trim()).toBe('5'); - expect(cellEls[4].classList).toContain('mat-calendar-table-active'); + expect(cellEls[4].classList).toContain('mat-calendar-body-active'); }); }); @@ -94,9 +94,9 @@ describe('MdMonthView', () => { }); it('should disable filtered dates', () => { - let cells = monthViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); - expect(cells[0].classList).toContain('mat-calendar-table-disabled'); - expect(cells[1].classList).not.toContain('mat-calendar-table-disabled'); + let cells = monthViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); + expect(cells[0].classList).toContain('mat-calendar-body-disabled'); + expect(cells[1].classList).not.toContain('mat-calendar-body-disabled'); }); }); }); diff --git a/src/lib/datepicker/month-view.ts b/src/lib/datepicker/month-view.ts index 411405f9ef96..94ea70d7fc18 100644 --- a/src/lib/datepicker/month-view.ts +++ b/src/lib/datepicker/month-view.ts @@ -7,7 +7,7 @@ import { Output, AfterContentInit } from '@angular/core'; -import {MdCalendarCell} from './calendar-table'; +import {MdCalendarCell} from './calendar-body'; import {CalendarLocale} from '../core/datetime/calendar-locale'; import {SimpleDate} from '../core/datetime/simple-date'; @@ -74,7 +74,14 @@ export class MdMonthView implements AfterContentInit { /** The date of the month that today falls on. Null if today is in another month. */ _todayDate: number; - constructor(private _locale: CalendarLocale) {} + /** The names of the weekdays. */ + _weekdays: string[]; + + constructor(private _locale: CalendarLocale) { + // Rotate the labels for days of the week based on the configured first day of the week. + this._weekdays = this._locale.narrowDays.slice(this._locale.firstDayOfWeek) + .concat(this._locale.narrowDays.slice(0, this._locale.firstDayOfWeek)); + } ngAfterContentInit(): void { this._init(); diff --git a/src/lib/datepicker/year-view.html b/src/lib/datepicker/year-view.html index 3ec753e219cc..d8a7b447cb89 100644 --- a/src/lib/datepicker/year-view.html +++ b/src/lib/datepicker/year-view.html @@ -1,9 +1,15 @@ - - + + + + + + +
diff --git a/src/lib/datepicker/year-view.spec.ts b/src/lib/datepicker/year-view.spec.ts index 66674cba4c25..5511aafac9b4 100644 --- a/src/lib/datepicker/year-view.spec.ts +++ b/src/lib/datepicker/year-view.spec.ts @@ -3,7 +3,7 @@ import {Component} from '@angular/core'; import {By} from '@angular/platform-browser'; import {MdYearView} from './year-view'; import {SimpleDate} from '../core/datetime/simple-date'; -import {MdCalendarTable} from './calendar-table'; +import {MdCalendarBody} from './calendar-body'; import {DatetimeModule} from '../core/datetime/index'; @@ -14,7 +14,7 @@ describe('MdYearView', () => { DatetimeModule, ], declarations: [ - MdCalendarTable, + MdCalendarBody, MdYearView, // Test components. @@ -41,17 +41,17 @@ describe('MdYearView', () => { }); it('has correct year label', () => { - let labelEl = yearViewNativeElement.querySelector('.mat-calendar-table-label'); + let labelEl = yearViewNativeElement.querySelector('.mat-calendar-body-label'); expect(labelEl.innerHTML.trim()).toBe('2017'); }); it('has 12 months', () => { - let cellEls = yearViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); + let cellEls = yearViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); expect(cellEls.length).toBe(12); }); it('shows selected month if in same year', () => { - let selectedEl = yearViewNativeElement.querySelector('.mat-calendar-table-selected'); + let selectedEl = yearViewNativeElement.querySelector('.mat-calendar-body-selected'); expect(selectedEl.innerHTML.trim()).toBe('MAR'); }); @@ -59,23 +59,23 @@ describe('MdYearView', () => { testComponent.selected = new SimpleDate(2016, 2, 10); fixture.detectChanges(); - let selectedEl = yearViewNativeElement.querySelector('.mat-calendar-table-selected'); + let selectedEl = yearViewNativeElement.querySelector('.mat-calendar-body-selected'); expect(selectedEl).toBeNull(); }); it('fires selected change event on cell clicked', () => { - let cellEls = yearViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); + let cellEls = yearViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); (cellEls[cellEls.length - 1] as HTMLElement).click(); fixture.detectChanges(); - let selectedEl = yearViewNativeElement.querySelector('.mat-calendar-table-selected'); + let selectedEl = yearViewNativeElement.querySelector('.mat-calendar-body-selected'); expect(selectedEl.innerHTML.trim()).toBe('DEC'); }); it('should mark active date', () => { - let cellEls = yearViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); + let cellEls = yearViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); expect((cellEls[0] as HTMLElement).innerText.trim()).toBe('JAN'); - expect(cellEls[0].classList).toContain('mat-calendar-table-active'); + expect(cellEls[0].classList).toContain('mat-calendar-body-active'); }); }); @@ -94,9 +94,9 @@ describe('MdYearView', () => { }); it('should disabled months with no enabled days', () => { - let cells = yearViewNativeElement.querySelectorAll('.mat-calendar-table-cell'); - expect(cells[0].classList).not.toContain('mat-calendar-table-disabled'); - expect(cells[1].classList).toContain('mat-calendar-table-disabled'); + let cells = yearViewNativeElement.querySelectorAll('.mat-calendar-body-cell'); + expect(cells[0].classList).not.toContain('mat-calendar-body-disabled'); + expect(cells[1].classList).toContain('mat-calendar-body-disabled'); }); }); }); diff --git a/src/lib/datepicker/year-view.ts b/src/lib/datepicker/year-view.ts index 39ce2a1600ec..a9bc7616988a 100644 --- a/src/lib/datepicker/year-view.ts +++ b/src/lib/datepicker/year-view.ts @@ -7,7 +7,7 @@ import { Output, EventEmitter } from '@angular/core'; -import {MdCalendarCell} from './calendar-table'; +import {MdCalendarCell} from './calendar-body'; import {CalendarLocale} from '../core/datetime/calendar-locale'; import {SimpleDate} from '../core/datetime/simple-date';