Skip to content

fix(dropdown): handle activeDescendant aria attribute manually in virtual dropdown - #17374

Merged
ChronosSF merged 7 commits into
masterfrom
mdragnev/fix-dropdown-zoneless
Jul 16, 2026
Merged

fix(dropdown): handle activeDescendant aria attribute manually in virtual dropdown#17374
ChronosSF merged 7 commits into
masterfrom
mdragnev/fix-dropdown-zoneless

Conversation

@mddragnev

@mddragnev mddragnev commented Jul 2, 2026

Copy link
Copy Markdown
Member

Closes #17322

Description

Fixes ExpressionChangedAfterItHasBeenChecked errors in the virtualized IgxDropDownComponent when running in zoneless Angular applications.

Motivation / Context

aria-activedescendant was computed on-the-fly via a @HostBinding getter. For virtual scroll, the focusedItem getter performed a live children.find(...) DOM query. When a virtual scroll chunk updated (either via keyboard navigation or manual scrollbar scroll), the children QueryList changed 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):

  • Bug fix
  • New functionality
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactoring (no functional changes)
  • Documentation
  • Demos
  • CI/CD
  • Tests
  • Changelog
  • Skills/Agents

Component(s) / Area(s) Affected:

How Has This Been Tested?

  • Unit tests
  • Manual testing
  • Automated e2e tests

Test Configuration:

  • Angular version:
  • Browser(s):
  • OS:

Screenshots / Recordings

Checklist:

  • All relevant tags have been applied to this PR
  • This PR includes unit tests covering all the new code (test guidelines)
  • This PR includes API docs for newly added methods/properties (api docs guidelines)
  • This PR includes feature/README.MD updates for the feature docs
  • This PR includes general feature table updates in the root README.MD
  • This PR includes CHANGELOG.MD updates for newly added functionality
  • This PR contains breaking changes
  • This PR includes ng update migrations for the breaking changes (migrations guidelines)
  • This PR includes behavioral changes and the feature specification has been updated with them
  • Accessibility (ARIA, keyboard navigation, focus management) has been verified

@mddragnev
mddragnev marked this pull request as ready for review July 2, 2026 12:48
@mddragnev
mddragnev requested review from Copilot and rkaraivanov July 2, 2026 12:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 live children lookups 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.

Comment thread projects/igniteui-angular/drop-down/src/drop-down/drop-down.component.spec.ts Outdated
Comment on lines 344 to 348
this.skipHeader(direction);
});
} else {
this._activeDescendantId = this.children.find(e => e.index === index)?.id ?? null;
this.skipHeader(direction);
@mddragnev mddragnev changed the title test(dropdown): Add zoneless test for virtual dropdown fix(dropdown): handle activeDescendant aria attribute manually Jul 6, 2026
@mddragnev mddragnev changed the title fix(dropdown): handle activeDescendant aria attribute manually fix(dropdown): handle activeDescendant aria attribute manually in virtual dropdown Jul 6, 2026
dropdown = fixture.componentInstance.dropdown;
scroll = fixture.componentInstance.virtualScroll;
});
it('should not throw when scrolling after selecting an item', async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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

@viktorkombov viktorkombov added 💥 status: in-test PRs currently being tested ✅ status: verified Applies to PRs that have passed manual verification and removed 💥 status: in-test PRs currently being tested labels Jul 13, 2026
@ChronosSF
ChronosSF merged commit b9681be into master Jul 16, 2026
6 checks passed
@ChronosSF
ChronosSF deleted the mdragnev/fix-dropdown-zoneless branch July 16, 2026 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dropdown version: 22.1.x ✅ status: verified Applies to PRs that have passed manual verification zoneless

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zoneless: DropDown throws ExpressionChangedAfterItHasBeenCheckedError when aria-activedescendant changes after check

4 participants