fix(datepicker): toggle not forwarding focus to underlying button (#14020)

Fixes the datepicker toggle not being focusable which prevents people from using the focus trap directives, and not forwarding focus to its underlying `button` element.
This commit is contained in:
Kristiyan Kostadinov
2018-11-10 00:16:35 +00:00
committed by vivian-hu
parent 26d63ee10b
commit b1d4b42488
3 changed files with 26 additions and 3 deletions
@@ -1,4 +1,5 @@
<button
#button
mat-icon-button
type="button"
aria-haspopup="true"
+9 -2
View File
@@ -20,7 +20,9 @@ import {
OnDestroy,
SimpleChanges,
ViewEncapsulation,
ViewChild,
} from '@angular/core';
import {MatButton} from '@angular/material/button';
import {merge, of as observableOf, Subscription} from 'rxjs';
import {MatDatepicker} from './datepicker';
import {MatDatepickerIntl} from './datepicker-intl';
@@ -40,11 +42,13 @@ 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',
// Always set the tabindex to -1 so that it doesn't overlap with any custom tabindex the
// consumer may have provided, while still being able to receive focus.
'[attr.tabindex]': '-1',
'[class.mat-datepicker-toggle-active]': 'datepicker && datepicker.opened',
'[class.mat-accent]': 'datepicker && datepicker.color === "accent"',
'[class.mat-warn]': 'datepicker && datepicker.color === "warn"',
'(focus)': '_button.focus()',
},
exportAs: 'matDatepickerToggle',
encapsulation: ViewEncapsulation.None,
@@ -75,6 +79,9 @@ export class MatDatepickerToggle<D> implements AfterContentInit, OnChanges, OnDe
/** Custom icon set by the consumer. */
@ContentChild(MatDatepickerToggleIcon) _customIcon: MatDatepickerToggleIcon;
/** Underlying button element. */
@ViewChild('button') _button: MatButton;
constructor(
public _intl: MatDatepickerIntl,
private _changeDetectorRef: ChangeDetectorRef,
+16 -1
View File
@@ -1043,8 +1043,23 @@ describe('MatDatepicker', () => {
const host = fixture.nativeElement.querySelector('.mat-datepicker-toggle');
expect(host.hasAttribute('tabindex')).toBe(false);
expect(host.getAttribute('tabindex')).toBe('-1');
});
it('should forward focus to the underlying button when the host is focused', () => {
const fixture = createComponent(DatepickerWithTabindexOnToggle, [MatNativeDateModule]);
fixture.detectChanges();
const host = fixture.nativeElement.querySelector('.mat-datepicker-toggle');
const button = host.querySelector('button');
expect(document.activeElement).not.toBe(button);
host.focus();
expect(document.activeElement).toBe(button);
});
});
describe('datepicker inside mat-form-field', () => {