1197
1198
function Test() {
1199
return (
1200
- <div ref={containerRef}>
1201
- <div ref={beforeRef} />
1200
+ <div ref={containerRef} id="container">
1201
+ <div ref={beforeRef} id="before" />
1202
<React.Fragment ref={fragmentRef}>
1203
- <div ref={firstChildRef} />
1204
- <div ref={middleChildRef} />
1205
- <div ref={lastChildRef} />
1203
+ <div ref={firstChildRef} id="first" />
1204
+ <div ref={middleChildRef} id="middle" />
1205
+ <div ref={lastChildRef} id="last" />
1206
</React.Fragment>
1207
- <div ref={afterRef} />
1207
+ <div ref={afterRef} id="after" />
1208
</div>
1209
);
1210
}
1289
},
1290
);
1291
1292
- // containerRef preceds and contains the fragment
1292
+ // containerRef precedes and contains the fragment
1293
expectPosition(
1294
fragmentRef.current.compareDocumentPosition(containerRef.current),
1295
{
1328
function Test() {
1329
return (
1330
<div id="container" ref={containerRef}>
1331
- <div>
1331
+ <div id="innercontainer">
1332
<div ref={beforeRef} id="before" />
1333
<React.Fragment ref={fragmentRef}>
1334
<div ref={onlyChildRef} id="within" />
1491
);
1492
});
1493
1494
+ // @gate enableFragmentRefs
1495
+ it('handles nested children', async () => {
1496
+ const fragmentRef = React.createRef();
1497
+ const nestedFragmentRef = React.createRef();
1498
+ const childARef = React.createRef();
1499
+ const childBRef = React.createRef();
1500
+ const childCRef = React.createRef();
1501
+ document.body.appendChild(container);
1502
+ const root = ReactDOMClient.createRoot(container);
1503
+
1504
+ function Child() {
1505
+ return (
1506
+ <div ref={childCRef} id="C">
1507
+ C
1508
+ </div>
1509
+ );
1510
+ }
1511
+
1512
+ function Test() {
1513
+ return (
1514
+ <React.Fragment ref={fragmentRef}>
1515
+ <div ref={childARef} id="A">
1516
+ A
1517
+ </div>
1518
+ <React.Fragment ref={nestedFragmentRef}>
1519
+ <div ref={childBRef} id="B">
1520
+ B
1521
+ </div>
1522
+ </React.Fragment>
1523
+ <Child />
1524
+ </React.Fragment>
1525
+ );
1526
+ }
1527
+
1528
+ await act(() => root.render(<Test />));
1529
+
1530
+ expectPosition(
1531
+ fragmentRef.current.compareDocumentPosition(childARef.current),
1532
+ {
1533
+ preceding: false,
1534
+ following: false,
1535
+ contains: false,
1536
+ containedBy: true,
1537
+ disconnected: false,
1538
+ implementationSpecific: false,
1539
+ },
1540
+ );
1541
+ expectPosition(
1542
+ fragmentRef.current.compareDocumentPosition(childBRef.current),
1543
+ {
1544
+ preceding: false,
1545
+ following: false,
1546
+ contains: false,
1547
+ containedBy: true,
1548
+ disconnected: false,
1549
+ implementationSpecific: false,
1550
+ },
1551
+ );
1552
+ expectPosition(
1553
+ fragmentRef.current.compareDocumentPosition(childCRef.current),
1554
+ {
1555
+ preceding: false,
1556
+ following: false,
1557
+ contains: false,
1558
+ containedBy: true,
1559
+ disconnected: false,
1560
+ implementationSpecific: false,
1561
+ },
1562
+ );
1563
+ });
1564
+
1565
// @gate enableFragmentRefs
1566
it('returns disconnected for comparison with an unmounted fragment instance', async () => {
1567
const fragmentRef = React.createRef();
1622
1623
function Test() {
1624
return (
1554
- <div>
1555
- {createPortal(<div ref={portaledSiblingRef} />, document.body)}
1625
+ <div id="wrapper">
1626
+ {createPortal(<div ref={portaledSiblingRef} id="A" />, container)}
1627
<Fragment ref={fragmentRef}>
1557
- {createPortal(<div ref={portaledChildRef} />, document.body)}
1558
- <div />
1628
+ {createPortal(<div ref={portaledChildRef} id="B" />, container)}
1629
+ <div id="C" />
1630
</Fragment>
1631
</div>
1632
);
1671
const childARef = React.createRef();
1672
const childBRef = React.createRef();
1673
const childCRef = React.createRef();
1674
+ const childDRef = React.createRef();
1675
+ const childERef = React.createRef();
1676
1677
function Test() {
1678
const [c, setC] = React.useState(false);
1685
{createPortal(
1686
<Fragment ref={fragmentRef}>
1687
<div id="A" ref={childARef} />
1615
- {c ? <div id="C" ref={childCRef} /> : null}
1688
+ {c ? (
1689
+ <div id="C" ref={childCRef}>
1690
+ <div id="D" ref={childDRef} />
1691
+ </div>
1692
+ ) : null}
1693
</Fragment>,
1694
document.body,
1695
)}
1696
{createPortal(<p id="B" ref={childBRef} />, document.body)}
1697
+ <div id="E" ref={childERef} />
1698
</>
1699
);
1700
}
1701
1702
await act(() => root.render(<Test />));
1703
1626
- // Due to effect, order is A->B->C
1627
- expect(document.body.innerHTML).toBe(
1628
- '<div></div>' +
1704
+ // Due to effect, order is E / A->B->C->D
1705
+ expect(document.body.outerHTML).toBe(
1706
+ '<body>' +
1707
+ '<div><div id="E"></div></div>' +
1708
'<div id="A"></div>' +
1709
'<p id="B"></p>' +
1631
- '<div id="C"></div>',
1710
+ '<div id="C"><div id="D"></div></div>' +
1711
+ '</body>',
1712
);
1713
1714
expectPosition(
1722
implementationSpecific: false,
1723
},
1724
);
1645
-
1725
expectPosition(
1726
fragmentRef.current.compareDocumentPosition(childARef.current),
1727
{
1733
implementationSpecific: false,
1734
},
1735
);
1736
+ // Contained by in DOM, but following in React tree
1737
expectPosition(
1738
fragmentRef.current.compareDocumentPosition(childBRef.current),
1739
{
1756
implementationSpecific: false,
1757
},
1758
);
1759
+ expectPosition(
1760
+ fragmentRef.current.compareDocumentPosition(childDRef.current),
1761
+ {
1762
+ preceding: false,
1763
+ following: false,
1764
+ contains: false,
1765
+ containedBy: true,
1766
+ disconnected: false,
1767
+ implementationSpecific: false,
1768
+ },
1769
+ );
1770
+ // Preceding DOM but following in React tree
1771
+ expectPosition(
1772
+ fragmentRef.current.compareDocumentPosition(childERef.current),
1773
+ {
1774
+ preceding: false,
1775
+ following: false,
1776
+ contains: false,
1777
+ containedBy: false,
1778
+ disconnected: false,
1779
+ implementationSpecific: true,
1780
+ },
1781
+ );
1782
});
1783
1784
// @gate enableFragmentRefs