From 36ed4a74f8a3f6884973e392d10d00d0980193d8 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 9 Mar 2017 14:26:06 -0800 Subject: [PATCH 1/3] add aria-* attrs and keyboard bindings to datepicker input --- src/lib/datepicker/datepicker-input.ts | 14 +++++++++++- src/lib/datepicker/datepicker-trigger.scss | 11 +++++++++ src/lib/datepicker/datepicker-trigger.ts | 26 ++++++++++++++++++++++ src/lib/datepicker/datepicker.html | 1 + src/lib/datepicker/datepicker.ts | 15 +++++++++++++ src/lib/input/input-container.ts | 6 +++++ 6 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/lib/datepicker/datepicker-trigger.scss create mode 100644 src/lib/datepicker/datepicker-trigger.ts diff --git a/src/lib/datepicker/datepicker-input.ts b/src/lib/datepicker/datepicker-input.ts index 12ab3b830c3b..f24dddf04c3d 100644 --- a/src/lib/datepicker/datepicker-input.ts +++ b/src/lib/datepicker/datepicker-input.ts @@ -14,6 +14,7 @@ import {SimpleDate} from '../core/datetime/simple-date'; import {CalendarLocale} from '../core/datetime/calendar-locale'; import {Subscription} from 'rxjs'; import {MdInputContainer} from '../input/input-container'; +import {DOWN_ARROW} from '../core/keyboard/keycodes'; export const MD_DATEPICKER_VALUE_ACCESSOR: any = { @@ -28,8 +29,12 @@ export const MD_DATEPICKER_VALUE_ACCESSOR: any = { selector: 'input[mdDatepicker], input[matDatepicker]', providers: [MD_DATEPICKER_VALUE_ACCESSOR], host: { + '[attr.aria-expanded]': '_datepicker?.opened || "false"', + '[attr.aria-haspopup]': 'true', + '[attr.aria-owns]': '_datepicker?.id', '(input)': '_onChange($event.target.value)', '(blur)': '_onTouched()', + '(keydown)': '_onKeydown($event)', } }) export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor, OnDestroy { @@ -40,7 +45,7 @@ export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor this._datepicker._registerInput(this); } } - private _datepicker: MdDatepicker; + _datepicker: MdDatepicker; @Input() get value(): SimpleDate { @@ -107,4 +112,11 @@ export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor setDisabledState(disabled: boolean): void { this._renderer.setElementProperty(this._elementRef.nativeElement, 'disabled', disabled); } + + _onKeydown(event: KeyboardEvent) { + if (event.altKey && event.keyCode === DOWN_ARROW) { + this._datepicker.open(); + event.preventDefault(); + } + } } diff --git a/src/lib/datepicker/datepicker-trigger.scss b/src/lib/datepicker/datepicker-trigger.scss new file mode 100644 index 000000000000..10c049130d78 --- /dev/null +++ b/src/lib/datepicker/datepicker-trigger.scss @@ -0,0 +1,11 @@ +$mat-datepicker-trigger-icon-size: 24px !default; + + +.mat-datepicker-trigger { + display: inline-block; + background: url('data:image/svg+xml;utf8,') no-repeat; + background-size: contain; + height: $mat-datepicker-trigger-icon-size; + width: $mat-datepicker-trigger-icon-size; + vertical-align: middle; +} diff --git a/src/lib/datepicker/datepicker-trigger.ts b/src/lib/datepicker/datepicker-trigger.ts new file mode 100644 index 000000000000..473dc07fd3dd --- /dev/null +++ b/src/lib/datepicker/datepicker-trigger.ts @@ -0,0 +1,26 @@ +import {ChangeDetectionStrategy, Component, Input, ViewEncapsulation} from '@angular/core'; +import {MdDatepicker} from './datepicker'; + + +@Component({ + moduleId: module.id, + selector: 'md-datepicker-trigger, mat-datepicker-trigger', + template: '', + styleUrls: ['datepicker-trigger.css'], + host: { + '[class.mat-datepicker-trigger]': 'true', + '(click)': '_open($event)', + }, + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class MdDatepickerTrigger { + @Input('for') datepicker: MdDatepicker; + + _open(event: Event): void { + if (this.datepicker) { + this.datepicker.open(); + event.stopPropagation(); + } + } +} diff --git a/src/lib/datepicker/datepicker.html b/src/lib/datepicker/datepicker.html index c7cf5a083d31..bf20f86edd3d 100644 --- a/src/lib/datepicker/datepicker.html +++ b/src/lib/datepicker/datepicker.html @@ -1,5 +1,6 @@