-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Bug description:
When typeahead shows autocomplete list and an item in the list is active aria-activedescendant is not set on the input component.
Plunker/StackBlitz that reproduces the issue:
No special setup is needed, it can be observed for any example right on the documentation website https://valor-software.com/ngx-bootstrap/#/components/typeahead?tab=overview. Do inspect on the input, type something to trigger autocomplete list and observe that aria-activedescendant is not added on the input as expected.
<input class="form-control ng-valid ng-dirty ng-touched" aria-expanded="true" aria-autocomplete="list" aria-owns="ngb-typeahead-3">
Expected behavior
When item in the autocomplete list is active then input component on which the typeahead directive is used has aria-activedescendant attribute set with the value of the attribute being the id of the active item:
<input class="form-control ng-valid ng-dirty ng-touched" aria-expanded="true" aria-autocomplete="list" aria-activedescendant="ngb-typeahead-3-3" aria-owns="ngb-typeahead-3">
Upon investigation of the code, found the following:
- typeahead directive sets the attribute when activeChangeEvent is fired from the list container
this._container.activeChangeEvent.subscribe((activeId: string) => { this.activeDescendant = activeId; this.changeDetection.markForCheck(); }); - The typeahead container fires the event on the
activesetter:
set active(active: TypeaheadMatch | undefined) {
this._active = active;
this.activeChanged();
}
This setter however is not being utilized and the logic instead uses setActive when change occurs:
protected setActive(value?: TypeaheadMatch): void {
this._active = value;
let preview;
if (!(this._active == null || this._active.isHeader())) {
preview = value;
}
this.parent?.typeaheadOnPreview.emit(preview);
}
Firing the event inside setActive appear to fix the issue when testing locally and can be a potential fix.
protected setActive(value?: TypeaheadMatch): void {
this._active = value;
let preview;
if (!(this._active == null || this._active.isHeader())) {
preview = value;
}
this.parent?.typeaheadOnPreview.emit(preview);
this.activeChanged(); <--- Added
}