Skip to content

Commit b1d4b42

Browse files
crisbetovivian-hu-zz
authored andcommittedNov 10, 2018
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.
1 parent 26d63ee commit b1d4b42

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed
 

‎src/lib/datepicker/datepicker-toggle.html

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<button
2+
#button
23
mat-icon-button
34
type="button"
45
aria-haspopup="true"

‎src/lib/datepicker/datepicker-toggle.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import {
2020
OnDestroy,
2121
SimpleChanges,
2222
ViewEncapsulation,
23+
ViewChild,
2324
} from '@angular/core';
25+
import {MatButton} from '@angular/material/button';
2426
import {merge, of as observableOf, Subscription} from 'rxjs';
2527
import {MatDatepicker} from './datepicker';
2628
import {MatDatepickerIntl} from './datepicker-intl';
@@ -40,11 +42,13 @@ export class MatDatepickerToggleIcon {}
4042
styleUrls: ['datepicker-toggle.css'],
4143
host: {
4244
'class': 'mat-datepicker-toggle',
43-
// Clear out the native tabindex here since we forward it to the underlying button
44-
'[attr.tabindex]': 'null',
45+
// Always set the tabindex to -1 so that it doesn't overlap with any custom tabindex the
46+
// consumer may have provided, while still being able to receive focus.
47+
'[attr.tabindex]': '-1',
4548
'[class.mat-datepicker-toggle-active]': 'datepicker && datepicker.opened',
4649
'[class.mat-accent]': 'datepicker && datepicker.color === "accent"',
4750
'[class.mat-warn]': 'datepicker && datepicker.color === "warn"',
51+
'(focus)': '_button.focus()',
4852
},
4953
exportAs: 'matDatepickerToggle',
5054
encapsulation: ViewEncapsulation.None,
@@ -75,6 +79,9 @@ export class MatDatepickerToggle<D> implements AfterContentInit, OnChanges, OnDe
7579
/** Custom icon set by the consumer. */
7680
@ContentChild(MatDatepickerToggleIcon) _customIcon: MatDatepickerToggleIcon;
7781

82+
/** Underlying button element. */
83+
@ViewChild('button') _button: MatButton;
84+
7885
constructor(
7986
public _intl: MatDatepickerIntl,
8087
private _changeDetectorRef: ChangeDetectorRef,

‎src/lib/datepicker/datepicker.spec.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1043,8 +1043,23 @@ describe('MatDatepicker', () => {
10431043

10441044
const host = fixture.nativeElement.querySelector('.mat-datepicker-toggle');
10451045

1046-
expect(host.hasAttribute('tabindex')).toBe(false);
1046+
expect(host.getAttribute('tabindex')).toBe('-1');
10471047
});
1048+
1049+
it('should forward focus to the underlying button when the host is focused', () => {
1050+
const fixture = createComponent(DatepickerWithTabindexOnToggle, [MatNativeDateModule]);
1051+
fixture.detectChanges();
1052+
1053+
const host = fixture.nativeElement.querySelector('.mat-datepicker-toggle');
1054+
const button = host.querySelector('button');
1055+
1056+
expect(document.activeElement).not.toBe(button);
1057+
1058+
host.focus();
1059+
1060+
expect(document.activeElement).toBe(button);
1061+
});
1062+
10481063
});
10491064

10501065
describe('datepicker inside mat-form-field', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.