@samitouri / QOS-React-2 / commits / 1724e9ce0a

[DOM] Blur focused descendants in Fragment refs (#37125)

## Summary `FragmentInstance.blur()` only matched the active element against the first level of host children. If the focused element was nested inside one of those children, `focus()` could reach it but `blur()` would leave it focused. This treats an active element contained by a Fragment host child as part of the Fragment and blurs the active element itself. It also adds regression coverage for a nested input. Fixes #37124. ## How did you test this change? - `yarn test ReactDOMFragmentRefs-test --runInBand` (65 tests passed) - `yarn test --prod ReactDOMFragmentRefs-test --runInBand` (65 tests passed) - `yarn prettier` - `yarn linc` - `yarn flow dom-node`

Minh Vu committed Jul 29, 2026 at 18:21 UTC 1724e9ce0aa1db99bcbe2633304b6a0fee2e4e1e
2 files changed +32 -2
packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
+2 -2
@@ -3262,9 +3262,9 @@ function blurActiveElementWithinFragment(
3262 return false;
3263 }
3264 const instance = getInstanceFromHostFiber<Instance>(child);
3265 - if (instance === activeElement) {
3265 + if (instance === activeElement || instance.contains(activeElement)) {
3266 // $FlowFixMe[prop-missing]
3267 - instance.blur();
3267 + activeElement.blur();
3268 return true;
3269 }
3270 return false;
packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js
+30
@@ -454,6 +454,36 @@ describe('FragmentRefs', () => {
454 expect(document.activeElement).toEqual(document.body);
455 });
456
457 + // @gate enableFragmentRefs
458 + it('removes focus from a nested element inside of the Fragment', async () => {
459 + const fragmentRef = React.createRef();
460 + const root = ReactDOMClient.createRoot(container);
461 +
462 + function Test() {
463 + return (
464 + <Fragment ref={fragmentRef}>
465 + <div>
466 + <input id="nested-input" />
467 + </div>
468 + </Fragment>
469 + );
470 + }
471 +
472 + await act(() => {
473 + root.render(<Test />);
474 + });
475 +
476 + await act(() => {
477 + fragmentRef.current.focus();
478 + });
479 + expect(document.activeElement.id).toEqual('nested-input');
480 +
481 + await act(() => {
482 + fragmentRef.current.blur();
483 + });
484 + expect(document.activeElement).toEqual(document.body);
485 + });
486 +
487 // @gate enableFragmentRefs
488 it('does not remove focus from elements outside of the Fragment', async () => {
489 const fragmentRefA = React.createRef();