Skip to content

fix(material/chips): correct focus management on chip destruction#33329

Open
zsheikh-eng wants to merge 3 commits into
angular:mainfrom
zsheikh-eng:fix-chip-focus-bug
Open

fix(material/chips): correct focus management on chip destruction#33329
zsheikh-eng wants to merge 3 commits into
angular:mainfrom
zsheikh-eng:fix-chip-focus-bug

Conversation

@zsheikh-eng

@zsheikh-eng zsheikh-eng commented Jun 1, 2026

Copy link
Copy Markdown

Fixes #14345

Description

The Bug:
When a chip is removed from MatChipSet or MatChipGrid, keyboard navigation (like using Shift+Tab or arrow keys) breaks upon subsequent interactions. This happens because the internal FocusKeyManager retains a stale reference to the deleted chip if the focus leaves the chip container (e.g., when the list becomes empty or focus returns to the input box). This stale reference traps keyboard focus or causes it to drop to the document body, failing standard focus order requirements (WCAG 2.1 Success Criterion 2.4.3).

The Fix:
The solution is to preserve standard browser focus redirection while explicitly cleaning up staleReferences when focus exits the chip context. This PR:

Un-privatizes the redirection logic (_lastDestroyedFocusedChipIndex and _redirectDestroyedChipFocus) to protected in the base MatChipSet class.

Allows MatChipGrid to override this behavior, call super._redirectDestroyedChipFocus() to preserve deterministic browser focus moves, and perform a silent cleanup using updateActiveItem(-1) when navigation leaves the chip set.

Why this path?

Deterministic Focus: It relies on the superclass redirection to maintain standard browser focus moves (refocusing the input or next chip) that downstream applications and consuming components expect.

Cleanup without Hijacking: The silent cleanup ensures the FocusKeyManager is reset safely without aggressively forcing a browser focus event or stealing focus from adjacent input fields.

Testing:

Added unit tests to chip-grid.spec.ts asserting that focus redirects correctly to the next chip upon deletion, and that the internal state is safely reset when the last focused chip is destroyed.

Un-privatized _redirectDestroyedChipFocus to allow MatChipGrid to override the aggressive focus-stealing behavior with a silent updateActiveItem call, respecting downstream layout stability.

Fixes angular#14345
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CDK: ListKeyManager activeItem has incorrect reference after QueryList changes

1 participant