Is this a regression?
The previous version in which this bug was not present was
No response
Description
Setting the combobox's expanded model to true programmatically (e.g. open-on-focus) does not keep the popup open under Zone.js change detection: expanded is immediately reset to
false, so the popup never becomes visible. The same code works correctly under provideZonelessChangeDetection().
Keyboard-driven opening (ArrowDown) works fine under Zone.js — only programmatically setting expanded fails.
This looks like the same class of Zone.js afterRenderEffect scheduling issue fixed for the keyboard relay in #33453 (commit e87216c), but applied only to keyboardEventRelayEffect. In
src/aria/combobox/combobox.ts the sibling effects are still registered in the default phase:
afterRenderEffect({write: ()=>this._pattern.keyboardEventRelayEffect()});// fixed in #33453 (https://github.com/angular/components/pull/33453)afterRenderEffect(()=>this._pattern.closePopupOnBlurEffect());// still default phaseafterRenderEffect(()=>{this.contentVisible.set(this._pattern.isExpanded());});// still default phaseclosePopupOnBlurEffect() does:
if(expanded&&!alwaysExpanded&&!comboboxFocused&&!popupFocused){this.inputs.expanded.set(false);}Under Zone.js, when expanded is set in a focus handler, this effect observes isFocused() as still false and resets expanded. alwaysExpanded is the only way to keep the popup
open, but it permanently forces isExpanded() true, disabling Escape-to-close and ArrowUp/Down-to-open.
Reproduction
StackBlitz link: https://stackblitz.com/edit/components-issue-starter-vhdrsdal?file=src%2Fmain.ts
Steps to reproduce:
Minimal editable combobox, bootstrapped with provideZoneChangeDetection():
<inputngCombobox#cb="ngCombobox" [(expanded)]="expanded" (focus)="expanded.set(true)" /><ng-templatengComboboxPopup[combobox]="cb"><divngListboxngComboboxWidget><divngOptionvalue="a">A</div></div></ng-template>
- Focus the input.
- Popup briefly opens then closes;
expanded reads false in devtools. - Switch to
provideZonelessChangeDetection() → works as expected.
Expected
Setting expanded = true (while the input is focused) keeps the popup open under Zone.js, matching zoneless behaviour.
Actual
expanded is reset to false by closePopupOnBlurEffect before the focus state settles; popup does not stay open.
Expected Behavior
Setting expanded = true (while the input is focused) keeps the popup open under Zone.js, matching zoneless behaviour.
Actual Behavior
expanded is reset to false by closePopupOnBlurEffect before the focus state settles; popup does not stay open.
Environment
@angular/aria, @angular/cdk, @angular/core: 22.0.3- Zone.js: enabled (
provideZoneChangeDetection()) - Repro also expected on
main (effects still default-phase).
Is this a regression?
The previous version in which this bug was not present was
No response
Description
Setting the combobox's
expandedmodel totrueprogrammatically (e.g. open-on-focus) does not keep the popup open under Zone.js change detection:expandedis immediately reset tofalse, so the popup never becomes visible. The same code works correctly underprovideZonelessChangeDetection().Keyboard-driven opening (
ArrowDown) works fine under Zone.js — only programmatically settingexpandedfails.This looks like the same class of Zone.js
afterRenderEffectscheduling issue fixed for the keyboard relay in #33453 (commit e87216c), but applied only tokeyboardEventRelayEffect. Insrc/aria/combobox/combobox.tsthe sibling effects are still registered in the default phase:closePopupOnBlurEffect()does:Under Zone.js, when
expandedis set in afocushandler, this effect observesisFocused()as stillfalseand resetsexpanded.alwaysExpandedis the only way to keep the popupopen, but it permanently forces
isExpanded()true, disablingEscape-to-close andArrowUp/Down-to-open.Reproduction
StackBlitz link: https://stackblitz.com/edit/components-issue-starter-vhdrsdal?file=src%2Fmain.ts
Steps to reproduce:
Minimal editable combobox, bootstrapped with
provideZoneChangeDetection():expandedreadsfalsein devtools.provideZonelessChangeDetection()→ works as expected.Expected
Setting
expanded = true(while the input is focused) keeps the popup open under Zone.js, matching zoneless behaviour.Actual
expandedis reset tofalsebyclosePopupOnBlurEffectbefore the focus state settles; popup does not stay open.Expected Behavior
Setting
expanded = true(while the input is focused) keeps the popup open under Zone.js, matching zoneless behaviour.Actual Behavior
expandedis reset tofalsebyclosePopupOnBlurEffectbefore the focus state settles; popup does not stay open.Environment
@angular/aria,@angular/cdk,@angular/core: 22.0.3provideZoneChangeDetection())main(effects still default-phase).