siAutocomplete: active reports the last option when siAutocompleteDefaultIndex is -1
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 85/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- angular, typescript
- Domain
- accessibility, frontend
Research direction
Read projects/element-ng/autocomplete/si-autocomplete-listbox.directive.ts, especially the active getter and setActiveItem(). Check the autocomplete tests for coverage of a default index of -1, then run the relevant test suite. Done means active is null and aria-activedescendant is empty until an option becomes active.
Written by the indexing model from the issue text.
Description
Prerequisites
- I have read the Contributing Guidelines.
- I have not leaked any internal/restricted information like screenshots, videos, code snippets, links etc.
Affected component
siAutocomplete (SiAutocompleteListboxDirective.active), and through it si-typeahead with
typeaheadAutoSelectIndex -1
Summary
With siAutocompleteDefaultIndex -1 (no option active when the list opens), active returns the last option
although none is active. The combobox's aria-activedescendant therefore points at the last option, so a screen reader
announces it as the current one, and SiAutocompleteDirective.active hands it to the consumer.
Version
@siemens/element-ng51.6.0 (also onmain, 46b5bac,
projects/element-ng/autocomplete/si-autocomplete-listbox.directive.ts)- Angular 22,
@angular/cdk22, Chromium
Steps to reproduce
<input [siTypeahead]="options" [typeaheadAutoSelectIndex]="-1" />with a few options.- Type so that the list opens with several suggestions, and do not press an arrow key.
- Look at the input's
aria-activedescendant(or readSiAutocompleteDirective.active).
Code reproduction example
No hosted example; the steps above reproduce it with any typeahead.
What is the current bug behavior
setActiveItem() calls keyManager.setActiveItem(siAutocompleteDefaultIndex()), so with -1 the CDK key manager has
activeItemIndex -1 and activeItem null. The getter only checks for null:
get active(): SiAutocompleteOptionDirective<T> | null {
if (this.keyManager.activeItemIndex === null) {
return null;
}
return this.options().at(this.keyManager.activeItemIndex) ?? null;
}
Array.prototype.at(-1) is the last element, so active is the last option. aria-activedescendant names its id,
while no option has the active class and Enter does not select it (onKeydown correctly uses
keyManager.activeItem).
What is the expected correct behavior
active is null and aria-activedescendant is empty until an option is made active.
Possible fix
--- a/projects/element-ng/autocomplete/si-autocomplete-listbox.directive.ts
+++ b/projects/element-ng/autocomplete/si-autocomplete-listbox.directive.ts
get active(): SiAutocompleteOptionDirective<T> | null {
// NOTE: We must not return `this.keyManager.activeItem` here, because its not updating
// activeItem reference when options change.
- if (this.keyManager.activeItemIndex === null) {
+ const index = this.keyManager.activeItemIndex;
+ if (index === null || index < 0) {
return null;
}
- return this.options().at(this.keyManager.activeItemIndex) ?? null;
+ return this.options()[index] ?? null;
}
Related: #2569 moves this active-option handling to @angular/aria; until then the current directive reports the
wrong option.
- Dominant language
- TypeScript
- Stars
- 85
- Forks
- 28
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 162
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from siemens/element
-
si-tree-view: the label jumps aside while the loading spinner fades out beside the returning chevronOpen
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
modal sizes: add missing modal sizes in UX documentationPossibly taken @panch1739 claimed this 8 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
siemens/element#3101 · 1 comment · 1 assignee ·
Maintainers usually reply within 1 day
-
The copy button in the documentation is brokenPossibly taken @kfenner claimed this 18 days ago. Openbug documentation
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
siemens/element#2997 · 1 comment ·
Maintainers usually reply within 1 day
-
filtered-search: search button does nothing if doSearchOnInputChange is setPossibly taken @spike-rabbit claimed this 29 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
siemens/element#2917 · 4 comments · 1 assignee ·
Maintainers usually reply within 1 day
Similar issues
-
account bug communication lecture
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
area:tui bug platform:macos
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
anthropics/claude-code#109005 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 87/100
openedx/end-to-end-tests#196 ·
Maintainers usually reply within 1 day
-
area:tooling good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
interledger/publisher-tools#1007 ·
Maintainers usually reply within 1 day
-
priority/medium roadmap/v1.1.1 stakeholder/rapr type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
databrickslabs/ontos#1420 ·
Maintainers usually reply within 3 days