Skip to content

Commit

Permalink
feat(datepicker): add keyboard support to calendar (#3655)
Browse files Browse the repository at this point in the history
* add active cell support to calendar-table, month-view, and year-view

* stop normalizing the active date in calendar since we now care about the
exact active date

* add some key handlers

* add keyboard support, break some tests

* add tests

* some finishing touches

* fix tabindex

* fix rxjs import

* addressed some comments

* refactor handleKeydown

* fix commas
  • Loading branch information
mmalerba committed Apr 20, 2017
1 parent 278f1fc commit bda87c0
Show file tree
Hide file tree
Showing 15 changed files with 635 additions and 84 deletions.
3 changes: 2 additions & 1 deletion src/lib/datepicker/_datepicker-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
}
}

:not(.mat-calendar-table-disabled):hover {
:not(.mat-calendar-table-disabled):hover,
.cdk-keyboard-focused .mat-calendar-table-active {
& > .mat-calendar-table-cell-content:not(.mat-calendar-table-selected) {
background-color: mat-color($background, hover);
}
Expand Down
7 changes: 4 additions & 3 deletions src/lib/datepicker/calendar-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
</tr>

<!-- Create the first row separately so we can include a special spacer cell. -->
<tr *ngFor="let row of rows; let i = index">
<td *ngIf="i === 0 && _firstRowOffset"
<tr *ngFor="let row of rows; let rowIndex = index">
<td *ngIf="rowIndex === 0 && _firstRowOffset"
class="mat-calendar-table-label"
[attr.colspan]="_firstRowOffset">
{{_firstRowOffset >= labelMinRequiredCells ? label : ''}}
</td>
<td *ngFor="let item of row"
<td *ngFor="let item of row; let colIndex = index"
class="mat-calendar-table-cell"
[class.mat-calendar-table-disabled]="!item.enabled"
[class.mat-calendar-table-active]="_isActiveCell(rowIndex, colIndex)"
(click)="_cellClicked(item)">
<div class="mat-calendar-table-cell-content"
[class.mat-calendar-table-selected]="selectedValue === item.value"
Expand Down
6 changes: 6 additions & 0 deletions src/lib/datepicker/calendar-table.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ describe('MdCalendarTable', () => {
expect(todayElement.classList)
.toContain('mat-calendar-table-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');
});
});

describe('calendar table with disabled cells', () => {
Expand Down Expand Up @@ -129,6 +134,7 @@ describe('MdCalendarTable', () => {
[selectedValue]="selectedValue"
[labelMinRequiredCells]="labelMinRequiredCells"
[numCols]="numCols"
[activeCell]="10"
(selectedValueChange)="onSelect($event)">
</md-calendar-table>`,
})
Expand Down
18 changes: 16 additions & 2 deletions src/lib/datepicker/calendar-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,33 @@ export class MdCalendarTable {
/** Whether to allow selection of disabled cells. */
@Input() allowDisabledSelection = false;

/** The cell number of the active cell in the table. */
@Input() activeCell = 0;

/** Emits when a new value is selected. */
@Output() selectedValueChange = new EventEmitter<number>();

_cellClicked(cell: MdCalendarCell) {
_cellClicked(cell: MdCalendarCell): void {
if (!this.allowDisabledSelection && !cell.enabled) {
return;
}
this.selectedValueChange.emit(cell.value);
}

/** The number of blank cells to put at the beginning for the first row. */
get _firstRowOffset() {
get _firstRowOffset(): number {
return this.rows && this.rows.length && this.rows[0].length ?
this.numCols - this.rows[0].length : 0;
}

_isActiveCell(rowIndex: number, colIndex: number): boolean {
let cellNumber = rowIndex * this.numCols + colIndex;

// Account for the fact that the first row may not have as many cells.
if (rowIndex) {
cellNumber -= this._firstRowOffset;
}

return cellNumber == this.activeCell;
}
}
7 changes: 4 additions & 3 deletions src/lib/datepicker/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@
</table>
</div>

<div class="mat-calendar-body">
<div class="mat-calendar-body" tabindex="0" (keydown)="_handleCalendarBodyKeydown($event)"
cdkMonitorSubtreeFocus>
<md-month-view
*ngIf="_monthView"
[date]="_currentPeriod"
[activeDate]="_activeDate"
[selected]="selected"
[dateFilter]="_dateFilterForViews"
(selectedChange)="_dateSelected($event)">
</md-month-view>

<md-year-view
*ngIf="!_monthView"
[date]="_currentPeriod"
[activeDate]="_activeDate"
[selected]="selected"
[dateFilter]="_dateFilterForViews"
(selectedChange)="_monthSelected($event)">
Expand Down
Loading

0 comments on commit bda87c0

Please sign in to comment.