fix(dropdown): handle activeDescendant aria attribute manually in virtual dropdown - #17374
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes NG0100 ExpressionChangedAfterItHasBeenCheckedError for virtualized IgxDropDownComponent in zoneless Angular by stabilizing the aria-activedescendant computation during virtual scroll updates.
Changes:
- Cached
aria-activedescendant(_activeDescendantId) for virtualized DropDown instead of computing it via livechildrenlookups during CD. - Updated the cache on virtual chunk loads and key navigation paths.
- Added a zoneless regression test for “select item → scroll” in the virtualized DropDown suite.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.ts | Introduces cached active-descendant id for virtual mode; updates cache on chunk load/navigation to avoid NG0100 in zoneless CD. |
| projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.spec.ts | Adds a zoneless regression test covering select + scroll scenario. |
| projects/igniteui-angular/combo/src/combo/combo-dropdown.component.ts | Removes redundant local _activeDescendantId field now that base DropDown provides it. |
| this.skipHeader(direction); | ||
| }); | ||
| } else { | ||
| this._activeDescendantId = this.children.find(e => e.index === index)?.id ?? null; | ||
| this.skipHeader(direction); |
| dropdown = fixture.componentInstance.dropdown; | ||
| scroll = fixture.componentInstance.virtualScroll; | ||
| }); | ||
| it('should not throw when scrolling after selecting an item', async () => { |
There was a problem hiding this comment.
The test covers the original ExpressionChangedAfterItHasBeenChecked regression during manual virtual scrolling. Would it make sense to also add a small virtual keyboard-navigation case that verifies the actual aria-activedescendant value, ideally across a chunk boundary? At the moment, removing the _activeDescendantId update from the keyboard-navigation path still leaves the test passing, so that part of the change may not be covered.
There was a problem hiding this comment.
I`ve added two tests since there are two branches that come across when navigating - when new chunk is loading and when the navigated item is in view
…igation with scroll in virtualized dropdown
Closes #17322
Description
Fixes ExpressionChangedAfterItHasBeenChecked errors in the virtualized
IgxDropDownComponentwhen running in zoneless Angular applications.Motivation / Context
aria-activedescendantwas computed on-the-fly via a@HostBindinggetter. For virtual scroll, thefocusedItemgetter performed a livechildren.find(...)DOM query. When a virtual scroll chunk updated (either via keyboard navigation or manual scrollbar scroll), the childrenQueryListchanged during a CD pass, causing the getter to return a different value between Angular's main pass and the dev-mode stability check. In zoneless mode — where each CD pass is independent and strict — this reliably throws. In zone-based mode, NgZone coalesces async mutations so the error is masked.Type of Change (check all that apply):
Component(s) / Area(s) Affected:
How Has This Been Tested?
Test Configuration:
Screenshots / Recordings
Checklist:
feature/README.MDupdates for the feature docsREADME.MDCHANGELOG.MDupdates for newly added functionalityng updatemigrations for the breaking changes (migrations guidelines)