bug(aria/combobox): keys pressed back to back are lost; only the last one reaches the popup
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 78/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- angular, typescript
- Domaine
- accessibility, frontend
Piste de recherche
Commencez dans l’implémentation de la combobox ARIA d’Angular, au niveau de ComboboxPattern, où, d’après l’issue, keyboardEventRelay est défini puis redispatché vers la cible du contrôle du popup. Suivez le gestionnaire de touches et l’effet de relais, puis ajoutez ou mettez à jour un test unitaire couvrant plusieurs événements ArrowDown consécutifs. Le travail est terminé lorsque chaque événement est traité dans l’ordre et que trois pressions font avancer de trois options.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
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, typingitem-3with no delay between keys lands onitem; with 60 ms between keys it lands onitem-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
- Langage dominant
- TypeScript
- Étoiles
- 25k
- Forks
- 6.8k
- Merge moyen
- 1 j 5 h
- PR mergées (30 j)
- 67
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de angular/components
-
bug(aria/combobox): ComboboxPopup throws NG0950 when destroyed before its first change detectionOuvertearea: aria/combobox gemini-triaged
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
angular/components#33972 ·
Les mainteneurs répondent en général sous 1 jour
-
bug(material/sort): hover hint arrow on an unsorted header shows the active sort direction, not the resulting direction after click.Peut-être pris @lekhmanrus l’a pris il y a 11 jours. Ouvertearea: material/sort P3
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
angular/components#33933 ·
Les mainteneurs répondent en général sous 1 jour
-
bug(mat-date-picker): month shown twice in date pickerPeut-être pris @PreethiPantangi l’a pris il y a 29 jours. Ouvertearea: material/datepicker P4
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
angular/components#33763 · 2 commentaires · 3 réactions ·
Les mainteneurs répondent en général sous 1 jour
-
Bug in table.scss footer cell height: unset instead of footer row height unsetPeut-être pris @minwookshin l’a pris il y a 15 jours. Ouvertearea: material/table P4
Difficulté 1/5 Moins d'une heure Accessibilité débutants 88/100
angular/components#33709 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
docs-bug(Table): Add example with `rowspan`Peut-être pris @BHUVANSH855 l’a pris il y a 96 jours. Ouvertearea: material/table docs P4
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
angular/components#33455 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de angular/components
Issues similaires
-
bug priority: P2
Difficulté 1/5 1-3 heures Accessibilité débutants 84/100
Les mainteneurs répondent en général sous 1 jour
-
[bug] status, list and push crash with an uncaught NotInitializedError stack trace when teamai is not initializedPeut-être pris @jay23606 l’a pris aujourd’hui. Ouvertebug good first issue help wanted
Difficulté 2/5 1-3 heures Accessibilité débutants 84/100
Tencent/teamai-cli#1227 ·
Les mainteneurs répondent en général sous 1 jour
-
[Tool]: YapOuverte
Difficulté 1/5 1-3 heures Accessibilité débutants 62/100
withkarann/aifoxx#417 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 86/100
sindresorhus/eslint-plugin-unicorn#3921 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 66/100
Les mainteneurs répondent en général sous 1 jour