Skip to content

Fix Autocomplete focus styles when clicking the input after virtual focus#9767

Open
hanityx wants to merge 2 commits intoadobe:mainfrom
hanityx:codex/fix-autocomplete-focus-recovery
Open

Fix Autocomplete focus styles when clicking the input after virtual focus#9767
hanityx wants to merge 2 commits intoadobe:mainfrom
hanityx:codex/fix-autocomplete-focus-recovery

Conversation

@hanityx
Copy link

@hanityx hanityx commented Mar 9, 2026

Closes #8198

Fixes the Autocomplete case where virtual focus moves to an option and clicking the already-focused input does not restore the input's focused state. This adds a small fix, regression tests, and a storybook repro for manual verification. No documentation changes seem necessary for this behavior fix.

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

Automated:

  • yarn jest packages/react-aria-components/test/Autocomplete.test.tsx --runInBand
  • yarn jest packages/@react-aria/autocomplete/test/useSearchAutocomplete.test.js --runInBand
  • yarn jest packages/react-aria-components/test/ComboBox.test.js --runInBand
  • yarn jest packages/@react-aria/combobox/test/useComboBox.test.js --runInBand
  • yarn eslint packages/@react-aria/autocomplete/src/useAutocomplete.ts packages/react-aria-components/test/Autocomplete.test.tsx packages/react-aria-components/stories/Autocomplete.stories.tsx
  • yarn check-types

Manual:

  1. Run storybook with yarn start.
  2. Open React Aria Components/Autocomplete.
  3. Open Autocomplete focus recovery after virtual focus.
  4. Focus the input, then either hover an option or move focus with the keyboard.
  5. Click the input again.
  6. Verify that the input regains its focused styling and the active descendant is cleared.

🧢 Your Project:

Copilot AI review requested due to automatic review settings March 9, 2026 17:05
@github-actions github-actions bot added the RAC label Mar 9, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an Autocomplete virtual-focus edge case where clicking an already-focused input doesn’t restore the input’s focused styling (and doesn’t clear aria-activedescendant) after virtual focus has moved to an option.

Changes:

  • Clear virtual focus on pointerdown when the input is already the active element (excluding touch), so focused styling is restored on click.
  • Add regression tests covering hover-driven and keyboard-driven virtual focus recovery scenarios.
  • Add a Storybook repro story for manual verification of focus recovery behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
packages/@react-aria/autocomplete/src/useAutocomplete.ts Adds an onPointerDown handler (virtual-focus mode) to clear virtual focus when clicking an already-focused input.
packages/react-aria-components/test/Autocomplete.test.tsx Adds regression tests ensuring focused styles and aria-activedescendant are restored/cleared when clicking the input after virtual focus moves to options.
packages/react-aria-components/stories/Autocomplete.stories.tsx Adds a Storybook scenario to manually reproduce and validate focus recovery after virtual focus.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@hanityx hanityx closed this Mar 9, 2026
@hanityx hanityx reopened this Mar 9, 2026
@hanityx hanityx closed this Mar 9, 2026
@hanityx hanityx reopened this Mar 9, 2026
Copy link
Member

@snowystinger snowystinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. One oddity about this, the mouse shouldn't actually cause a visible focus ring usually. There should probably be a "data-focus-visible" condition to the css as well.

let menu = getByRole('menu');
let options = within(menu).getAllByRole('menuitem');
await user.hover(options[1]);
options = within(menu).getAllByRole('menuitem');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
options = within(menu).getAllByRole('menuitem');

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also removed that extra re-fetch.

return;
}

if (getEventTarget(e) === inputRef.current && getActiveElement(getOwnerDocument(inputRef.current)) === inputRef.current) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the check for activeElement? I was trying out the change in https://react-aria.adobe.com/Autocomplete (though my local copy of yarn start:s2-docs and if I mouse over an option, then click outside the menu/input but still inside the dialog (so it doesn't dismiss), then I see that clicking on the input after that won't get the focus ring.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were right here. I removed the activeElement check, added a regression test for the outside-click case, and switched the starter input ring to data-focus-visible.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Autocomplete input focus is inconsistent

3 participants