[autocomplete] Fix item removal when it receives focus from VoiceOver before using Backspace#48572
Conversation
Deploy previewhttps://deploy-preview-48572--material-ui.netlify.app/ Bundle size
Check out the code infra dashboard for more information about this PR. |
There was a problem hiding this comment.
Pull request overview
This PR addresses an accessibility-related Autocomplete (multiple) regression where VoiceOver-driven focus/backspace interactions could cause extra chip removals by syncing focused chip state on focus and attempting to suppress a VoiceOver-specific synthetic Backspace.
Changes:
- Add
onFocusto tag/chip props to keepfocusedItemin sync when focus comes from non-keyboard sources (e.g. VoiceOver navigation). - Add a
ignoreNextBackspaceRefmechanism intended to suppress a synthetic Backspace event that VoiceOver dispatches to the input after chip deletion. - Update existing tag-navigation tests to use
user.keyboardand add new tests to validate focused-chip removal behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/mui-material/src/useAutocomplete/useAutocomplete.js | Adds focused chip sync on focus and introduces a ref-based suppression for VoiceOver’s extra Backspace event. |
| packages/mui-material/src/Autocomplete/Autocomplete.test.js | Migrates relevant tests to user.keyboard and adds assertions for removing only the focused chip. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (ignoreNextBackspaceRef.current) { | ||
| ignoreNextBackspaceRef.current = false; | ||
| break; |
There was a problem hiding this comment.
Found an issue with the ignoreNextBackspaceRef logic, reproducible here: https://deploy-preview-48572--material-ui.netlify.app/material-ui/react-autocomplete/#limit-tags
Steps:
- Click the input to focus it (popup opens)
- ArrowLeft once, the "The Empire Strikes Back" chip becomes focused
- Backspace once, the chip is removed
- Backspace again, nothing happens; I expected the next chip to be deleted
There was a problem hiding this comment.
I've been trying to avoid this logic but somehow I could not find any alternative. Will continue to dig into it.
mj12albert
left a comment
There was a problem hiding this comment.
Looks good, tested the fix with VO+Chrome/Safari
When focus on the selected items, in a multiple selection autocomplete, comes from a non native keyboard event, we are not updating the state with the focused item. In the issue case, the focus comes from VoiceOver navigation. Also, VoiceOver is sending another Backspace event on the
inputimmediately after it sent one to theChip.Consequently, instead of deleting the one focused item, we were deleting 3 items: focused one (actually a Chip delete handler), and 2 from the end, one because focusedItem was -1 (not updating according to VoiceOver focus) and one because of the extra
inputbackspace event.Fixes:
inputhappens, exit and restore the ref info. This is not ideal, but I can't figure anything better.Added tests for the focusedItem sync only. The second case, related to VoiceOver sending another Backspace event on top of the Chip one, is impossible to unit test.
Fixes #44936