Skip to content

fix(aria/combobox): empty aria-controls when the popup widget has no id - #33635

Merged
crisbeto merged 3 commits into
angular:mainfrom
lazerg:fix/issue-70082-combobox-empty-aria-controls
Aug 7, 2026
Merged

fix(aria/combobox): empty aria-controls when the popup widget has no id#33635
crisbeto merged 3 commits into
angular:mainfrom
lazerg:fix/issue-70082-combobox-empty-aria-controls

Conversation

@lazerg

Copy link
Copy Markdown
Contributor

ngComboboxWidget reads its ID off the host element, so a popup whose widget doesn't set one (for example the dialog popup in the docs, where the widget is a plain div) leaves the combobox with aria-controls="", which Axe flags. The same happened when the ID came from a host binding such as ngListbox, since it isn't on the element yet when the widget reads it.

The widget now generates an ID after the first render if the element still doesn't have one, and re-reads the ID at that point so binding-provided ones are picked up.

Fixes#33640.

@angular-robotangular-robotBot added area: aria/combobox area: docs Related to the documentation labels Aug 5, 2026
@lazerg
lazergforce-pushed the fix/issue-70082-combobox-empty-aria-controls branch from 1cef0e3 to 70a1084CompareAugust 5, 2026 08:32
@crisbeto
crisbeto requested a review from ok7saiAugust 5, 2026 20:01

@ok7saiok7sai left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix! Overall looks good.

Comment threadsrc/aria/combobox/combobox.spec.ts Outdated
});
});

describe('with Dialog', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest restructure the test group to something like

describe('ComboboxWidget', () => {
it('should auto-generate an ID on widget when none is provided', async () => {
// Tests plain widget without id -> receives 'ng-combobox-widget-X'
});
it('should preserve an explicit ID on the widget element', async () => {
// Tests <div ngComboboxWidget id="custom-id"> -> uses 'custom-id'
});
it('should prioritize sibling directive IDs over generated IDs', async () => {
// Tests <div ngComboboxWidget ngListbox> -> uses 'ng-listbox-X'
});
});

For better describing the wanted behaviors.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in da624a1. Two of the three fail on main; the explicit-id one passes there and guards against a regression.

@ok7saiok7sai added action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release labels Aug 6, 2026
@crisbeto
crisbeto merged commit c87e3a5 into angular:mainAug 7, 2026
35 checks passed
@crisbeto

Copy link
Copy Markdown
Member

This PR was merged into the repository. The changes were merged into the following branches:

crisbeto pushed a commit that referenced this pull request Aug 7, 2026
…id (#33635)
* fix(aria/combobox): empty aria-controls when the popup widget has no id
* docs(aria/combobox): explain the imperative id assignment
* test(aria/combobox): describe the widget id behaviors individually
(cherry picked from commit c87e3a5)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: mergeThe PR is ready for merge by the caretakerarea: aria/comboboxarea: docsRelated to the documentationtarget: patchThis PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Combobox sets an empty aria-controls attribute when using a dialog popup

3 participants

@lazerg@crisbeto@ok7sai