Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

bug(aria/combobox): keys pressed back to back are lost; only the last one reaches the popup

Open Beginner friendly
#33,973 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@drakeo338 is already working on this.

Since Oct 20, 2026.

  • #33975 by @drakeo338 — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
angular, typescript

Research direction

Start in the Angular ARIA combobox implementation at ComboboxPattern, where the issue says keyboardEventRelay is set and later re-dispatched to the popup control target. Trace the key handler and relay effect, then add or update a unit test for several back-to-back ArrowDown events; done means each event is handled in order and three presses move three options.

Written by the indexing model from the issue text.

Description

area: aria/combobox gemini-triaged
Is this a regression?
  • Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was

No response

Description

While the popup is open, ComboboxPattern relays navigation and typeahead keys to the popup through a signal: the key handler does this.keyboardEventRelay.set(e), and an effect later re-dispatches the event on the popup's control target. If a second key arrives before the effect runs, the signal is overwritten and the first key is never relayed.

Effects:

  • Down, Down, Down pressed quickly moves the active option once.
  • Typeahead loses characters: with options item, item-2, item-3, typing item-3 with no delay between keys lands on item; with 60 ms between keys it lands on item-3.
  • Test automation and tools that send keys in a burst (and some assistive technology input) see wrong results. Seen in Chromium through Playwright, and in unit tests.

Related: #33361 (same relay signal, different symptom: a stale event replayed on reopen).

Reproduction
import { Component } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { Combobox, ComboboxPopup, ComboboxWidget } from '@angular/aria/combobox';
import { Listbox, Option } from '@angular/aria/listbox';

@Component({
  imports: [Combobox, ComboboxPopup, ComboboxWidget, Listbox, Option],
  template: `
    <div ngCombobox #combobox="ngCombobox" tabindex="0">Pick one</div>
    <ng-template ngComboboxPopup [combobox]="combobox">
      <div ngListbox ngComboboxWidget #listbox="ngListbox" focusMode="activedescendant"
        [activeDescendant]="listbox.activeDescendant()">
        @for (o of options; track o) {
          <div ngOption [value]="o" [label]="o">{{ o }}</div>
        }
      </div>
    </ng-template>
  `,
})
class Repro {
  options = ['alpha', 'bravo', 'charlie', 'delta'];
}

const key = (el: Element, k: string) =>
  el.dispatchEvent(new KeyboardEvent('keydown', { key: k, bubbles: true }));

it('handles each key pressed back to back', async () => {
  const fixture = TestBed.createComponent(Repro);
  await fixture.whenStable();
  const combobox = fixture.nativeElement.querySelector('[ngCombobox]');
  combobox.focus();
  key(combobox, 'ArrowDown');            // open
  await fixture.whenStable();
  key(combobox, 'Home');
  await fixture.whenStable();
  key(combobox, 'ArrowDown');
  key(combobox, 'ArrowDown');
  key(combobox, 'ArrowDown');
  await fixture.whenStable();
  const id = combobox.getAttribute('aria-activedescendant');
  expect(fixture.nativeElement.querySelector(`[id="${id}"]`).textContent.trim())
    .toBe('delta');                       // actual: 'bravo'
});
Expected Behavior

Each key event is handled, in order. Three Down presses move three options.

Actual Behavior

Only the last key since the effect last ran is relayed. Three Down presses move one option ("bravo" in place of "delta").

A possible fix: relay each event synchronously from the key handler (or queue them), not through a single-value signal.

Environment
  • Angular: 22.2.1
  • CDK/Material: @angular/cdk 22.2.3, @angular/aria 22.2.3 (also in 22.3.0-next.2 and main)
  • Browser(s): Chromium (Playwright); Vitest with happy-dom
  • Operating System (e.g. Windows, macOS, Ubuntu): macOS
Dominant language
TypeScript
Stars
25k
Forks
6.8k
Avg merge
1d 5h
Merged PRs (30d)
67

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from angular/components

All issues in angular/components

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.