diff --git a/src/lib/datepicker/datepicker-input.ts b/src/lib/datepicker/datepicker-input.ts index 1eccd662f09..3e736041e3d 100644 --- a/src/lib/datepicker/datepicker-input.ts +++ b/src/lib/datepicker/datepicker-input.ts @@ -311,7 +311,9 @@ export class MatDatepickerInput implements ControlValueAccessor, OnDestroy, V } _onKeydown(event: KeyboardEvent) { - if (this._datepicker && event.altKey && event.keyCode === DOWN_ARROW) { + const isAltDownArrow = event.altKey && event.keyCode === DOWN_ARROW; + + if (this._datepicker && isAltDownArrow && !this._elementRef.nativeElement.readOnly) { this._datepicker.open(); event.preventDefault(); } diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index 96044bda37e..a69becfce94 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -454,7 +454,7 @@ describe('MatDatepicker', () => { expect(testComponent.datepicker.opened).toBe(false); })); - it('should open the datpeicker using ALT + DOWN_ARROW', fakeAsync(() => { + it('should open the datepicker using ALT + DOWN_ARROW', fakeAsync(() => { expect(testComponent.datepicker.opened).toBe(false); const event = createKeyboardEvent('keydown', DOWN_ARROW); @@ -468,6 +468,24 @@ describe('MatDatepicker', () => { expect(event.defaultPrevented).toBe(true); })); + it('should not open for ALT + DOWN_ARROW on readonly input', fakeAsync(() => { + const input = fixture.nativeElement.querySelector('input'); + + expect(testComponent.datepicker.opened).toBe(false); + + input.setAttribute('readonly', 'true'); + + const event = createKeyboardEvent('keydown', DOWN_ARROW); + Object.defineProperty(event, 'altKey', {get: () => true}); + + dispatchEvent(input, event); + fixture.detectChanges(); + flush(); + + expect(testComponent.datepicker.opened).toBe(false); + expect(event.defaultPrevented).toBe(false); + })); + }); describe('datepicker with too many inputs', () => {