react-resizable-panels 1.0.0-rc.1 → 1.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1220,7 +1220,7 @@ function PanelGroupWithForwardedRef({
1220
1220
  // Store size before collapse;
1221
1221
  // This is the size that gets restored if the expand() API is used.
1222
1222
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1223
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1223
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1224
1224
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1225
1225
  const nextLayout = adjustLayoutByDelta({
1226
1226
  delta,
@@ -1262,7 +1262,7 @@ function PanelGroupWithForwardedRef({
1262
1262
  // Restore this panel to the size it was before it was collapsed, if possible.
1263
1263
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1264
1264
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1265
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1265
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1266
1266
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1267
1267
  const nextLayout = adjustLayoutByDelta({
1268
1268
  delta,
@@ -1301,7 +1301,7 @@ function PanelGroupWithForwardedRef({
1301
1301
  const {
1302
1302
  panelDataArray
1303
1303
  } = eagerValuesRef.current;
1304
- const panelIndex = panelDataArray.indexOf(panelData);
1304
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1305
1305
  return computePanelFlexBoxStyle({
1306
1306
  dragState,
1307
1307
  layout,
@@ -1349,6 +1349,19 @@ function PanelGroupWithForwardedRef({
1349
1349
  layout: prevLayout,
1350
1350
  panelDataArray
1351
1351
  } = eagerValuesRef.current;
1352
+
1353
+ // HACK
1354
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1355
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1356
+ const index = findPanelDataIndex(panelDataArray, panelData);
1357
+ if (index >= 0) {
1358
+ if (panelData.idIsFromProps) {
1359
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1360
+ } else {
1361
+ console.warn(`Panel registered twice`);
1362
+ }
1363
+ return;
1364
+ }
1352
1365
  panelDataArray.push(panelData);
1353
1366
  panelDataArray.sort((panelA, panelB) => {
1354
1367
  const orderA = panelA.order;
@@ -1490,7 +1503,7 @@ function PanelGroupWithForwardedRef({
1490
1503
  pivotIndices
1491
1504
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1492
1505
  assert(panelSize != null);
1493
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1506
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1494
1507
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1495
1508
  const nextLayout = adjustLayoutByDelta({
1496
1509
  delta,
@@ -1541,7 +1554,7 @@ function PanelGroupWithForwardedRef({
1541
1554
  layout: prevLayout,
1542
1555
  panelDataArray
1543
1556
  } = eagerValuesRef.current;
1544
- const index = panelDataArray.indexOf(panelData);
1557
+ const index = findPanelDataIndex(panelDataArray, panelData);
1545
1558
  if (index >= 0) {
1546
1559
  panelDataArray.splice(index, 1);
1547
1560
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1557,7 +1570,7 @@ function PanelGroupWithForwardedRef({
1557
1570
  const {
1558
1571
  pendingPanelIds
1559
1572
  } = unregisterPanelRef.current;
1560
- const map = panelIdToLastNotifiedSizeMapRef.current;
1573
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1561
1574
 
1562
1575
  // TRICKY
1563
1576
  // Strict effects mode
@@ -1566,17 +1579,17 @@ function PanelGroupWithForwardedRef({
1566
1579
  pendingPanelIds.delete(panelId);
1567
1580
  if (panelDataArray.find(({
1568
1581
  id
1569
- }) => id === panelId) == null) {
1582
+ }) => id === panelId) != null) {
1570
1583
  unmountDueToStrictMode = true;
1571
-
1584
+ } else {
1572
1585
  // TRICKY
1573
1586
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1574
1587
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1575
1588
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1576
- delete map[panelData.id];
1589
+ delete panelIdToLastNotifiedSizeMap[panelId];
1577
1590
  }
1578
1591
  });
1579
- if (!unmountDueToStrictMode) {
1592
+ if (unmountDueToStrictMode) {
1580
1593
  return;
1581
1594
  }
1582
1595
  if (panelDataArray.length === 0) {
@@ -1649,9 +1662,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1649
1662
  }));
1650
1663
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1651
1664
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1665
+ function findPanelDataIndex(panelDataArray, panelData) {
1666
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1667
+ }
1652
1668
  function panelDataHelper(panelDataArray, panelData, layout) {
1653
1669
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1654
- const panelIndex = panelDataArray.indexOf(panelData);
1670
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1655
1671
  const panelConstraints = panelConstraintsArray[panelIndex];
1656
1672
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1657
1673
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1325,7 +1325,7 @@ function PanelGroupWithForwardedRef({
1325
1325
  // Store size before collapse;
1326
1326
  // This is the size that gets restored if the expand() API is used.
1327
1327
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1328
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1328
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1329
1329
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1330
1330
  const nextLayout = adjustLayoutByDelta({
1331
1331
  delta,
@@ -1367,7 +1367,7 @@ function PanelGroupWithForwardedRef({
1367
1367
  // Restore this panel to the size it was before it was collapsed, if possible.
1368
1368
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1369
1369
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1370
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1370
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1371
1371
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1372
1372
  const nextLayout = adjustLayoutByDelta({
1373
1373
  delta,
@@ -1406,7 +1406,7 @@ function PanelGroupWithForwardedRef({
1406
1406
  const {
1407
1407
  panelDataArray
1408
1408
  } = eagerValuesRef.current;
1409
- const panelIndex = panelDataArray.indexOf(panelData);
1409
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1410
1410
  return computePanelFlexBoxStyle({
1411
1411
  dragState,
1412
1412
  layout,
@@ -1454,6 +1454,19 @@ function PanelGroupWithForwardedRef({
1454
1454
  layout: prevLayout,
1455
1455
  panelDataArray
1456
1456
  } = eagerValuesRef.current;
1457
+
1458
+ // HACK
1459
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1460
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1461
+ const index = findPanelDataIndex(panelDataArray, panelData);
1462
+ if (index >= 0) {
1463
+ if (panelData.idIsFromProps) {
1464
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1465
+ } else {
1466
+ console.warn(`Panel registered twice`);
1467
+ }
1468
+ return;
1469
+ }
1457
1470
  panelDataArray.push(panelData);
1458
1471
  panelDataArray.sort((panelA, panelB) => {
1459
1472
  const orderA = panelA.order;
@@ -1595,7 +1608,7 @@ function PanelGroupWithForwardedRef({
1595
1608
  pivotIndices
1596
1609
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1597
1610
  assert(panelSize != null);
1598
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1611
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1599
1612
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1600
1613
  const nextLayout = adjustLayoutByDelta({
1601
1614
  delta,
@@ -1646,7 +1659,7 @@ function PanelGroupWithForwardedRef({
1646
1659
  layout: prevLayout,
1647
1660
  panelDataArray
1648
1661
  } = eagerValuesRef.current;
1649
- const index = panelDataArray.indexOf(panelData);
1662
+ const index = findPanelDataIndex(panelDataArray, panelData);
1650
1663
  if (index >= 0) {
1651
1664
  panelDataArray.splice(index, 1);
1652
1665
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1662,7 +1675,7 @@ function PanelGroupWithForwardedRef({
1662
1675
  const {
1663
1676
  pendingPanelIds
1664
1677
  } = unregisterPanelRef.current;
1665
- const map = panelIdToLastNotifiedSizeMapRef.current;
1678
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1666
1679
 
1667
1680
  // TRICKY
1668
1681
  // Strict effects mode
@@ -1671,17 +1684,17 @@ function PanelGroupWithForwardedRef({
1671
1684
  pendingPanelIds.delete(panelId);
1672
1685
  if (panelDataArray.find(({
1673
1686
  id
1674
- }) => id === panelId) == null) {
1687
+ }) => id === panelId) != null) {
1675
1688
  unmountDueToStrictMode = true;
1676
-
1689
+ } else {
1677
1690
  // TRICKY
1678
1691
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1679
1692
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1680
1693
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1681
- delete map[panelData.id];
1694
+ delete panelIdToLastNotifiedSizeMap[panelId];
1682
1695
  }
1683
1696
  });
1684
- if (!unmountDueToStrictMode) {
1697
+ if (unmountDueToStrictMode) {
1685
1698
  return;
1686
1699
  }
1687
1700
  if (panelDataArray.length === 0) {
@@ -1754,9 +1767,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1754
1767
  }));
1755
1768
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1756
1769
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1770
+ function findPanelDataIndex(panelDataArray, panelData) {
1771
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1772
+ }
1757
1773
  function panelDataHelper(panelDataArray, panelData, layout) {
1758
1774
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1759
- const panelIndex = panelDataArray.indexOf(panelData);
1775
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1760
1776
  const panelConstraints = panelConstraintsArray[panelIndex];
1761
1777
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1762
1778
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1301,7 +1301,7 @@ function PanelGroupWithForwardedRef({
1301
1301
  // Store size before collapse;
1302
1302
  // This is the size that gets restored if the expand() API is used.
1303
1303
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1304
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1304
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1305
1305
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1306
1306
  const nextLayout = adjustLayoutByDelta({
1307
1307
  delta,
@@ -1343,7 +1343,7 @@ function PanelGroupWithForwardedRef({
1343
1343
  // Restore this panel to the size it was before it was collapsed, if possible.
1344
1344
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1345
1345
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1346
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1346
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1347
1347
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1348
1348
  const nextLayout = adjustLayoutByDelta({
1349
1349
  delta,
@@ -1382,7 +1382,7 @@ function PanelGroupWithForwardedRef({
1382
1382
  const {
1383
1383
  panelDataArray
1384
1384
  } = eagerValuesRef.current;
1385
- const panelIndex = panelDataArray.indexOf(panelData);
1385
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1386
1386
  return computePanelFlexBoxStyle({
1387
1387
  dragState,
1388
1388
  layout,
@@ -1430,6 +1430,19 @@ function PanelGroupWithForwardedRef({
1430
1430
  layout: prevLayout,
1431
1431
  panelDataArray
1432
1432
  } = eagerValuesRef.current;
1433
+
1434
+ // HACK
1435
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1436
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1437
+ const index = findPanelDataIndex(panelDataArray, panelData);
1438
+ if (index >= 0) {
1439
+ if (panelData.idIsFromProps) {
1440
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1441
+ } else {
1442
+ console.warn(`Panel registered twice`);
1443
+ }
1444
+ return;
1445
+ }
1433
1446
  panelDataArray.push(panelData);
1434
1447
  panelDataArray.sort((panelA, panelB) => {
1435
1448
  const orderA = panelA.order;
@@ -1571,7 +1584,7 @@ function PanelGroupWithForwardedRef({
1571
1584
  pivotIndices
1572
1585
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1573
1586
  assert(panelSize != null);
1574
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1587
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1575
1588
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1576
1589
  const nextLayout = adjustLayoutByDelta({
1577
1590
  delta,
@@ -1622,7 +1635,7 @@ function PanelGroupWithForwardedRef({
1622
1635
  layout: prevLayout,
1623
1636
  panelDataArray
1624
1637
  } = eagerValuesRef.current;
1625
- const index = panelDataArray.indexOf(panelData);
1638
+ const index = findPanelDataIndex(panelDataArray, panelData);
1626
1639
  if (index >= 0) {
1627
1640
  panelDataArray.splice(index, 1);
1628
1641
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1638,7 +1651,7 @@ function PanelGroupWithForwardedRef({
1638
1651
  const {
1639
1652
  pendingPanelIds
1640
1653
  } = unregisterPanelRef.current;
1641
- const map = panelIdToLastNotifiedSizeMapRef.current;
1654
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1642
1655
 
1643
1656
  // TRICKY
1644
1657
  // Strict effects mode
@@ -1647,17 +1660,17 @@ function PanelGroupWithForwardedRef({
1647
1660
  pendingPanelIds.delete(panelId);
1648
1661
  if (panelDataArray.find(({
1649
1662
  id
1650
- }) => id === panelId) == null) {
1663
+ }) => id === panelId) != null) {
1651
1664
  unmountDueToStrictMode = true;
1652
-
1665
+ } else {
1653
1666
  // TRICKY
1654
1667
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1655
1668
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1656
1669
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1657
- delete map[panelData.id];
1670
+ delete panelIdToLastNotifiedSizeMap[panelId];
1658
1671
  }
1659
1672
  });
1660
- if (!unmountDueToStrictMode) {
1673
+ if (unmountDueToStrictMode) {
1661
1674
  return;
1662
1675
  }
1663
1676
  if (panelDataArray.length === 0) {
@@ -1730,9 +1743,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1730
1743
  }));
1731
1744
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1732
1745
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1746
+ function findPanelDataIndex(panelDataArray, panelData) {
1747
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1748
+ }
1733
1749
  function panelDataHelper(panelDataArray, panelData, layout) {
1734
1750
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1735
- const panelIndex = panelDataArray.indexOf(panelData);
1751
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1736
1752
  const panelConstraints = panelConstraintsArray[panelIndex];
1737
1753
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1738
1754
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1196,7 +1196,7 @@ function PanelGroupWithForwardedRef({
1196
1196
  // Store size before collapse;
1197
1197
  // This is the size that gets restored if the expand() API is used.
1198
1198
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1199
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1199
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1200
1200
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1201
1201
  const nextLayout = adjustLayoutByDelta({
1202
1202
  delta,
@@ -1238,7 +1238,7 @@ function PanelGroupWithForwardedRef({
1238
1238
  // Restore this panel to the size it was before it was collapsed, if possible.
1239
1239
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1240
1240
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1241
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1241
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1242
1242
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1243
1243
  const nextLayout = adjustLayoutByDelta({
1244
1244
  delta,
@@ -1277,7 +1277,7 @@ function PanelGroupWithForwardedRef({
1277
1277
  const {
1278
1278
  panelDataArray
1279
1279
  } = eagerValuesRef.current;
1280
- const panelIndex = panelDataArray.indexOf(panelData);
1280
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1281
1281
  return computePanelFlexBoxStyle({
1282
1282
  dragState,
1283
1283
  layout,
@@ -1325,6 +1325,19 @@ function PanelGroupWithForwardedRef({
1325
1325
  layout: prevLayout,
1326
1326
  panelDataArray
1327
1327
  } = eagerValuesRef.current;
1328
+
1329
+ // HACK
1330
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1331
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1332
+ const index = findPanelDataIndex(panelDataArray, panelData);
1333
+ if (index >= 0) {
1334
+ if (panelData.idIsFromProps) {
1335
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1336
+ } else {
1337
+ console.warn(`Panel registered twice`);
1338
+ }
1339
+ return;
1340
+ }
1328
1341
  panelDataArray.push(panelData);
1329
1342
  panelDataArray.sort((panelA, panelB) => {
1330
1343
  const orderA = panelA.order;
@@ -1466,7 +1479,7 @@ function PanelGroupWithForwardedRef({
1466
1479
  pivotIndices
1467
1480
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1468
1481
  assert(panelSize != null);
1469
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1482
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1470
1483
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1471
1484
  const nextLayout = adjustLayoutByDelta({
1472
1485
  delta,
@@ -1517,7 +1530,7 @@ function PanelGroupWithForwardedRef({
1517
1530
  layout: prevLayout,
1518
1531
  panelDataArray
1519
1532
  } = eagerValuesRef.current;
1520
- const index = panelDataArray.indexOf(panelData);
1533
+ const index = findPanelDataIndex(panelDataArray, panelData);
1521
1534
  if (index >= 0) {
1522
1535
  panelDataArray.splice(index, 1);
1523
1536
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1533,7 +1546,7 @@ function PanelGroupWithForwardedRef({
1533
1546
  const {
1534
1547
  pendingPanelIds
1535
1548
  } = unregisterPanelRef.current;
1536
- const map = panelIdToLastNotifiedSizeMapRef.current;
1549
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1537
1550
 
1538
1551
  // TRICKY
1539
1552
  // Strict effects mode
@@ -1542,17 +1555,17 @@ function PanelGroupWithForwardedRef({
1542
1555
  pendingPanelIds.delete(panelId);
1543
1556
  if (panelDataArray.find(({
1544
1557
  id
1545
- }) => id === panelId) == null) {
1558
+ }) => id === panelId) != null) {
1546
1559
  unmountDueToStrictMode = true;
1547
-
1560
+ } else {
1548
1561
  // TRICKY
1549
1562
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1550
1563
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1551
1564
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1552
- delete map[panelData.id];
1565
+ delete panelIdToLastNotifiedSizeMap[panelId];
1553
1566
  }
1554
1567
  });
1555
- if (!unmountDueToStrictMode) {
1568
+ if (unmountDueToStrictMode) {
1556
1569
  return;
1557
1570
  }
1558
1571
  if (panelDataArray.length === 0) {
@@ -1625,9 +1638,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1625
1638
  }));
1626
1639
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1627
1640
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1641
+ function findPanelDataIndex(panelDataArray, panelData) {
1642
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1643
+ }
1628
1644
  function panelDataHelper(panelDataArray, panelData, layout) {
1629
1645
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1630
- const panelIndex = panelDataArray.indexOf(panelData);
1646
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1631
1647
  const panelConstraints = panelConstraintsArray[panelIndex];
1632
1648
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1633
1649
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1222,7 +1222,7 @@ function PanelGroupWithForwardedRef({
1222
1222
  // Store size before collapse;
1223
1223
  // This is the size that gets restored if the expand() API is used.
1224
1224
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1225
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1225
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1226
1226
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1227
1227
  const nextLayout = adjustLayoutByDelta({
1228
1228
  delta,
@@ -1264,7 +1264,7 @@ function PanelGroupWithForwardedRef({
1264
1264
  // Restore this panel to the size it was before it was collapsed, if possible.
1265
1265
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1266
1266
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1267
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1267
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1268
1268
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1269
1269
  const nextLayout = adjustLayoutByDelta({
1270
1270
  delta,
@@ -1303,7 +1303,7 @@ function PanelGroupWithForwardedRef({
1303
1303
  const {
1304
1304
  panelDataArray
1305
1305
  } = eagerValuesRef.current;
1306
- const panelIndex = panelDataArray.indexOf(panelData);
1306
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1307
1307
  return computePanelFlexBoxStyle({
1308
1308
  dragState,
1309
1309
  layout,
@@ -1351,6 +1351,19 @@ function PanelGroupWithForwardedRef({
1351
1351
  layout: prevLayout,
1352
1352
  panelDataArray
1353
1353
  } = eagerValuesRef.current;
1354
+
1355
+ // HACK
1356
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1357
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1358
+ const index = findPanelDataIndex(panelDataArray, panelData);
1359
+ if (index >= 0) {
1360
+ if (panelData.idIsFromProps) {
1361
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1362
+ } else {
1363
+ console.warn(`Panel registered twice`);
1364
+ }
1365
+ return;
1366
+ }
1354
1367
  panelDataArray.push(panelData);
1355
1368
  panelDataArray.sort((panelA, panelB) => {
1356
1369
  const orderA = panelA.order;
@@ -1492,7 +1505,7 @@ function PanelGroupWithForwardedRef({
1492
1505
  pivotIndices
1493
1506
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1494
1507
  assert(panelSize != null);
1495
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1508
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1496
1509
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1497
1510
  const nextLayout = adjustLayoutByDelta({
1498
1511
  delta,
@@ -1543,7 +1556,7 @@ function PanelGroupWithForwardedRef({
1543
1556
  layout: prevLayout,
1544
1557
  panelDataArray
1545
1558
  } = eagerValuesRef.current;
1546
- const index = panelDataArray.indexOf(panelData);
1559
+ const index = findPanelDataIndex(panelDataArray, panelData);
1547
1560
  if (index >= 0) {
1548
1561
  panelDataArray.splice(index, 1);
1549
1562
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1559,7 +1572,7 @@ function PanelGroupWithForwardedRef({
1559
1572
  const {
1560
1573
  pendingPanelIds
1561
1574
  } = unregisterPanelRef.current;
1562
- const map = panelIdToLastNotifiedSizeMapRef.current;
1575
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1563
1576
 
1564
1577
  // TRICKY
1565
1578
  // Strict effects mode
@@ -1568,17 +1581,17 @@ function PanelGroupWithForwardedRef({
1568
1581
  pendingPanelIds.delete(panelId);
1569
1582
  if (panelDataArray.find(({
1570
1583
  id
1571
- }) => id === panelId) == null) {
1584
+ }) => id === panelId) != null) {
1572
1585
  unmountDueToStrictMode = true;
1573
-
1586
+ } else {
1574
1587
  // TRICKY
1575
1588
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1576
1589
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1577
1590
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1578
- delete map[panelData.id];
1591
+ delete panelIdToLastNotifiedSizeMap[panelId];
1579
1592
  }
1580
1593
  });
1581
- if (!unmountDueToStrictMode) {
1594
+ if (unmountDueToStrictMode) {
1582
1595
  return;
1583
1596
  }
1584
1597
  if (panelDataArray.length === 0) {
@@ -1651,9 +1664,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1651
1664
  }));
1652
1665
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1653
1666
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1667
+ function findPanelDataIndex(panelDataArray, panelData) {
1668
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1669
+ }
1654
1670
  function panelDataHelper(panelDataArray, panelData, layout) {
1655
1671
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1656
- const panelIndex = panelDataArray.indexOf(panelData);
1672
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1657
1673
  const panelConstraints = panelConstraintsArray[panelIndex];
1658
1674
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1659
1675
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1332,7 +1332,7 @@ function PanelGroupWithForwardedRef({
1332
1332
  // Store size before collapse;
1333
1333
  // This is the size that gets restored if the expand() API is used.
1334
1334
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1335
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1335
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1336
1336
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1337
1337
  const nextLayout = adjustLayoutByDelta({
1338
1338
  delta,
@@ -1374,7 +1374,7 @@ function PanelGroupWithForwardedRef({
1374
1374
  // Restore this panel to the size it was before it was collapsed, if possible.
1375
1375
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1376
1376
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1377
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1377
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1378
1378
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1379
1379
  const nextLayout = adjustLayoutByDelta({
1380
1380
  delta,
@@ -1413,7 +1413,7 @@ function PanelGroupWithForwardedRef({
1413
1413
  const {
1414
1414
  panelDataArray
1415
1415
  } = eagerValuesRef.current;
1416
- const panelIndex = panelDataArray.indexOf(panelData);
1416
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1417
1417
  return computePanelFlexBoxStyle({
1418
1418
  dragState,
1419
1419
  layout,
@@ -1461,6 +1461,19 @@ function PanelGroupWithForwardedRef({
1461
1461
  layout: prevLayout,
1462
1462
  panelDataArray
1463
1463
  } = eagerValuesRef.current;
1464
+
1465
+ // HACK
1466
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1467
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1468
+ const index = findPanelDataIndex(panelDataArray, panelData);
1469
+ if (index >= 0) {
1470
+ if (panelData.idIsFromProps) {
1471
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1472
+ } else {
1473
+ console.warn(`Panel registered twice`);
1474
+ }
1475
+ return;
1476
+ }
1464
1477
  panelDataArray.push(panelData);
1465
1478
  panelDataArray.sort((panelA, panelB) => {
1466
1479
  const orderA = panelA.order;
@@ -1602,7 +1615,7 @@ function PanelGroupWithForwardedRef({
1602
1615
  pivotIndices
1603
1616
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1604
1617
  assert(panelSize != null);
1605
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1618
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1606
1619
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1607
1620
  const nextLayout = adjustLayoutByDelta({
1608
1621
  delta,
@@ -1653,7 +1666,7 @@ function PanelGroupWithForwardedRef({
1653
1666
  layout: prevLayout,
1654
1667
  panelDataArray
1655
1668
  } = eagerValuesRef.current;
1656
- const index = panelDataArray.indexOf(panelData);
1669
+ const index = findPanelDataIndex(panelDataArray, panelData);
1657
1670
  if (index >= 0) {
1658
1671
  panelDataArray.splice(index, 1);
1659
1672
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1669,7 +1682,7 @@ function PanelGroupWithForwardedRef({
1669
1682
  const {
1670
1683
  pendingPanelIds
1671
1684
  } = unregisterPanelRef.current;
1672
- const map = panelIdToLastNotifiedSizeMapRef.current;
1685
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1673
1686
 
1674
1687
  // TRICKY
1675
1688
  // Strict effects mode
@@ -1678,17 +1691,17 @@ function PanelGroupWithForwardedRef({
1678
1691
  pendingPanelIds.delete(panelId);
1679
1692
  if (panelDataArray.find(({
1680
1693
  id
1681
- }) => id === panelId) == null) {
1694
+ }) => id === panelId) != null) {
1682
1695
  unmountDueToStrictMode = true;
1683
-
1696
+ } else {
1684
1697
  // TRICKY
1685
1698
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1686
1699
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1687
1700
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1688
- delete map[panelData.id];
1701
+ delete panelIdToLastNotifiedSizeMap[panelId];
1689
1702
  }
1690
1703
  });
1691
- if (!unmountDueToStrictMode) {
1704
+ if (unmountDueToStrictMode) {
1692
1705
  return;
1693
1706
  }
1694
1707
  if (panelDataArray.length === 0) {
@@ -1761,9 +1774,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1761
1774
  }));
1762
1775
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1763
1776
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1777
+ function findPanelDataIndex(panelDataArray, panelData) {
1778
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1779
+ }
1764
1780
  function panelDataHelper(panelDataArray, panelData, layout) {
1765
1781
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1766
- const panelIndex = panelDataArray.indexOf(panelData);
1782
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1767
1783
  const panelConstraints = panelConstraintsArray[panelIndex];
1768
1784
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1769
1785
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];