From 09302b6ba0dae23232a1820dc131f7b90bd4e0d6 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 24 Aug 2018 16:57:28 +0200 Subject: [PATCH] fix(datepicker-toggle): forward tabindex to underlying button (#12461) Forwards the tabindex of a `mat-button-toggle` to its underlying `button` and clears it from the host element. Fixes #12456. --- src/lib/datepicker/datepicker-toggle.html | 1 + src/lib/datepicker/datepicker-toggle.ts | 15 ++++++++++- src/lib/datepicker/datepicker.spec.ts | 33 +++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/lib/datepicker/datepicker-toggle.html b/src/lib/datepicker/datepicker-toggle.html index da7e836f7500..cd4a9c71cb46 100644 --- a/src/lib/datepicker/datepicker-toggle.html +++ b/src/lib/datepicker/datepicker-toggle.html @@ -3,6 +3,7 @@ type="button" aria-haspopup="true" [attr.aria-label]="_intl.openCalendarLabel" + [attr.tabindex]="disabled ? -1 : tabIndex" [disabled]="disabled" (click)="_open($event)"> diff --git a/src/lib/datepicker/datepicker-toggle.ts b/src/lib/datepicker/datepicker-toggle.ts index 51c2ac16f367..5cfc79555c88 100644 --- a/src/lib/datepicker/datepicker-toggle.ts +++ b/src/lib/datepicker/datepicker-toggle.ts @@ -9,6 +9,7 @@ import {coerceBooleanProperty} from '@angular/cdk/coercion'; import { AfterContentInit, + Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -39,6 +40,8 @@ export class MatDatepickerToggleIcon {} styleUrls: ['datepicker-toggle.css'], host: { 'class': 'mat-datepicker-toggle', + // Clear out the native tabindex here since we forward it to the underlying button + '[attr.tabindex]': 'null', '[class.mat-datepicker-toggle-active]': 'datepicker && datepicker.opened', '[class.mat-accent]': 'datepicker && datepicker.color === "accent"', '[class.mat-warn]': 'datepicker && datepicker.color === "warn"', @@ -53,6 +56,9 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe /** Datepicker instance that the button will toggle. */ @Input('for') datepicker: MatDatepicker; + /** Tabindex for the toggle. */ + @Input() tabIndex: number | null; + /** Whether the toggle button is disabled. */ @Input() get disabled(): boolean { @@ -66,7 +72,14 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe /** Custom icon set by the consumer. */ @ContentChild(MatDatepickerToggleIcon) _customIcon: MatDatepickerToggleIcon; - constructor(public _intl: MatDatepickerIntl, private _changeDetectorRef: ChangeDetectorRef) {} + constructor( + public _intl: MatDatepickerIntl, + private _changeDetectorRef: ChangeDetectorRef, + @Attribute('tabindex') defaultTabIndex: string) { + + const parsedTabIndex = Number(defaultTabIndex); + this.tabIndex = (parsedTabIndex || parsedTabIndex === 0) ? parsedTabIndex : null; + } ngOnChanges(changes: SimpleChanges) { if (changes.datepicker) { diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index 9471394b52b8..02a99f12ecad 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -1008,6 +1008,26 @@ describe('MatDatepicker', () => { })); }); + describe('datepicker with tabindex on mat-datepicker-toggle', () => { + it('should forward the tabindex to the underlying button', () => { + const fixture = createComponent(DatepickerWithTabindexOnToggle, [MatNativeDateModule]); + fixture.detectChanges(); + + const button = fixture.nativeElement.querySelector('.mat-datepicker-toggle button'); + + expect(button.getAttribute('tabindex')).toBe('7'); + }); + + it('should clear the tabindex from the mat-datepicker-toggle host', () => { + const fixture = createComponent(DatepickerWithTabindexOnToggle, [MatNativeDateModule]); + fixture.detectChanges(); + + const host = fixture.nativeElement.querySelector('.mat-datepicker-toggle'); + + expect(host.hasAttribute('tabindex')).toBe(false); + }); + }); + describe('datepicker inside mat-form-field', () => { let fixture: ComponentFixture; let testComponent: FormFieldDatepicker; @@ -1875,3 +1895,16 @@ class DelayedDatepicker { date: Date | null; assignedDatepicker: MatDatepicker; } + + + +@Component({ + template: ` + + +
+
+ + `, +}) +class DatepickerWithTabindexOnToggle {}