diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index ea86763a5722..2667b9b16fbe 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -102,7 +102,7 @@ export function getMatAutocompleteMissingPanelError(): Error { '[attr.autocomplete]': 'autocompleteAttribute', '[attr.role]': 'autocompleteDisabled ? null : "combobox"', '[attr.aria-autocomplete]': 'autocompleteDisabled ? null : "list"', - '[attr.aria-activedescendant]': 'activeOption?.id', + '[attr.aria-activedescendant]': '(panelOpen && activeOption) ? activeOption.id : null', '[attr.aria-expanded]': 'autocompleteDisabled ? null : panelOpen.toString()', '[attr.aria-owns]': '(autocompleteDisabled || !panelOpen) ? null : autocomplete?.id', // Note: we use `focusin`, as opposed to `focus`, in order to open the panel diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index 143ea70c8f00..d7f2c71f5491 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -1644,6 +1644,29 @@ describe('MatAutocomplete', () => { .toContain('mat-active', 'Expected first option to be highlighted.'); })); + it('should remove aria-activedescendant when panel is closed with autoActiveFirstOption', + fakeAsync(() => { + const input: HTMLElement = fixture.nativeElement.querySelector('input'); + + expect(input.hasAttribute('aria-activedescendant')) + .toBe(false, 'Expected no active descendant on init.'); + + fixture.componentInstance.trigger.autocomplete.autoActiveFirstOption = true; + fixture.componentInstance.trigger.openPanel(); + fixture.detectChanges(); + zone.simulateZoneExit(); + fixture.detectChanges(); + + expect(input.getAttribute('aria-activedescendant')) + .toBeTruthy('Expected active descendant while open.'); + + fixture.componentInstance.trigger.closePanel(); + fixture.detectChanges(); + + expect(input.hasAttribute('aria-activedescendant')) + .toBe(false, 'Expected no active descendant when closed.'); + })); + it('should be able to configure preselecting the first option globally', fakeAsync(() => { overlayContainer.ngOnDestroy(); fixture.destroy();