[DOM] Handle blur on Fragments below `Document` (#37062)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sebastian "Sebbie" Silbermann committed
Jul 21, 2026 at 10:26 UTC
862e275a1c150edcefab6d8ba3306192ffd6edfa
2 files changed
+73
-2
packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
+5
-2
@@ -3232,8 +3232,11 @@ FragmentInstance.prototype.blur = function (this: FragmentInstanceType): void {
3232
const parentInstanceOrContainer = getInstanceFromHostFiber<
3233
Instance | Container,
3234
>(parentHostFiber);
3235
- // TODO: Handle parentInstanceOrContainer being a document
3236
- const activeElement = parentInstanceOrContainer.ownerDocument.activeElement;
3235
+ // Instance is included in the Container type for DOM.
3236
+ const ownerDocument = getOwnerDocumentFromRootContainer(
3237
+ parentInstanceOrContainer,
3238
+ );
3239
+ const activeElement = ownerDocument.activeElement;
3240
if (
3241
activeElement === null ||
3242
!parentInstanceOrContainer.contains(activeElement)
packages/react-dom/src/__tests__/ReactDOMFragmentRefsDocument-test.js
new
+68
@@ -0,0 +1,68 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @emails reactcore
8
+ * @jest-environment node
9
+ */
10
+
11
+'use strict';
12
+
13
+let JSDOM;
14
+let React;
15
+let ReactDOMClient;
16
+let act;
17
+let document;
18
+let Fragment;
19
+
20
+describe('FragmentRefs', () => {
21
+ beforeEach(() => {
22
+ jest.resetModules();
23
+ JSDOM = require('jsdom');
24
+ React = require('react');
25
+ Fragment = React.Fragment;
26
+ ReactDOMClient = require('react-dom/client');
27
+ act = require('internal-test-utils').act;
28
+
29
+ const jsdom = new JSDOM.JSDOM('');
30
+ document = jsdom.window.document;
31
+ global.window = jsdom.window;
32
+ global.document = global.window.document;
33
+ });
34
+
35
+ describe('focus methods', () => {
36
+ describe('blur()', () => {
37
+ // @gate enableFragmentRefs
38
+ it('throws when the nearest host parent is a Document container', async () => {
39
+ const fragmentRef = React.createRef();
40
+ const root = ReactDOMClient.createRoot(document);
41
+
42
+ await act(() => {
43
+ root.render(
44
+ <Fragment ref={fragmentRef}>
45
+ <html>
46
+ <body>
47
+ <a id="child-a" href="/">
48
+ A
49
+ </a>
50
+ </body>
51
+ </html>
52
+ </Fragment>,
53
+ );
54
+ });
55
+
56
+ await act(() => {
57
+ fragmentRef.current.focus();
58
+ });
59
+ expect(document.activeElement.id).toEqual('child-a');
60
+
61
+ await act(() => {
62
+ fragmentRef.current.blur();
63
+ });
64
+ expect(document.activeElement).toEqual(document.body);
65
+ });
66
+ });
67
+ });
68
+});