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.
@@ -1308,7 +1308,7 @@ function PanelGroupWithForwardedRef({
1308
1308
  // Store size before collapse;
1309
1309
  // This is the size that gets restored if the expand() API is used.
1310
1310
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1311
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1311
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1312
1312
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1313
1313
  const nextLayout = adjustLayoutByDelta({
1314
1314
  delta,
@@ -1350,7 +1350,7 @@ function PanelGroupWithForwardedRef({
1350
1350
  // Restore this panel to the size it was before it was collapsed, if possible.
1351
1351
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1352
1352
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1353
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1353
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1354
1354
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1355
1355
  const nextLayout = adjustLayoutByDelta({
1356
1356
  delta,
@@ -1389,7 +1389,7 @@ function PanelGroupWithForwardedRef({
1389
1389
  const {
1390
1390
  panelDataArray
1391
1391
  } = eagerValuesRef.current;
1392
- const panelIndex = panelDataArray.indexOf(panelData);
1392
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1393
1393
  return computePanelFlexBoxStyle({
1394
1394
  dragState,
1395
1395
  layout,
@@ -1437,6 +1437,19 @@ function PanelGroupWithForwardedRef({
1437
1437
  layout: prevLayout,
1438
1438
  panelDataArray
1439
1439
  } = eagerValuesRef.current;
1440
+
1441
+ // HACK
1442
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1443
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1444
+ const index = findPanelDataIndex(panelDataArray, panelData);
1445
+ if (index >= 0) {
1446
+ if (panelData.idIsFromProps) {
1447
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1448
+ } else {
1449
+ console.warn(`Panel registered twice`);
1450
+ }
1451
+ return;
1452
+ }
1440
1453
  panelDataArray.push(panelData);
1441
1454
  panelDataArray.sort((panelA, panelB) => {
1442
1455
  const orderA = panelA.order;
@@ -1578,7 +1591,7 @@ function PanelGroupWithForwardedRef({
1578
1591
  pivotIndices
1579
1592
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1580
1593
  assert(panelSize != null);
1581
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1594
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1582
1595
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1583
1596
  const nextLayout = adjustLayoutByDelta({
1584
1597
  delta,
@@ -1629,7 +1642,7 @@ function PanelGroupWithForwardedRef({
1629
1642
  layout: prevLayout,
1630
1643
  panelDataArray
1631
1644
  } = eagerValuesRef.current;
1632
- const index = panelDataArray.indexOf(panelData);
1645
+ const index = findPanelDataIndex(panelDataArray, panelData);
1633
1646
  if (index >= 0) {
1634
1647
  panelDataArray.splice(index, 1);
1635
1648
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1645,7 +1658,7 @@ function PanelGroupWithForwardedRef({
1645
1658
  const {
1646
1659
  pendingPanelIds
1647
1660
  } = unregisterPanelRef.current;
1648
- const map = panelIdToLastNotifiedSizeMapRef.current;
1661
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1649
1662
 
1650
1663
  // TRICKY
1651
1664
  // Strict effects mode
@@ -1654,17 +1667,17 @@ function PanelGroupWithForwardedRef({
1654
1667
  pendingPanelIds.delete(panelId);
1655
1668
  if (panelDataArray.find(({
1656
1669
  id
1657
- }) => id === panelId) == null) {
1670
+ }) => id === panelId) != null) {
1658
1671
  unmountDueToStrictMode = true;
1659
-
1672
+ } else {
1660
1673
  // TRICKY
1661
1674
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1662
1675
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1663
1676
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1664
- delete map[panelData.id];
1677
+ delete panelIdToLastNotifiedSizeMap[panelId];
1665
1678
  }
1666
1679
  });
1667
- if (!unmountDueToStrictMode) {
1680
+ if (unmountDueToStrictMode) {
1668
1681
  return;
1669
1682
  }
1670
1683
  if (panelDataArray.length === 0) {
@@ -1737,9 +1750,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1737
1750
  }));
1738
1751
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1739
1752
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1753
+ function findPanelDataIndex(panelDataArray, panelData) {
1754
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1755
+ }
1740
1756
  function panelDataHelper(panelDataArray, panelData, layout) {
1741
1757
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1742
- const panelIndex = panelDataArray.indexOf(panelData);
1758
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1743
1759
  const panelConstraints = panelConstraintsArray[panelIndex];
1744
1760
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1745
1761
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1216,7 +1216,7 @@ function PanelGroupWithForwardedRef({
1216
1216
  // Store size before collapse;
1217
1217
  // This is the size that gets restored if the expand() API is used.
1218
1218
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1219
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1219
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1220
1220
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1221
1221
  const nextLayout = adjustLayoutByDelta({
1222
1222
  delta,
@@ -1258,7 +1258,7 @@ function PanelGroupWithForwardedRef({
1258
1258
  // Restore this panel to the size it was before it was collapsed, if possible.
1259
1259
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1260
1260
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1261
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1261
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1262
1262
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1263
1263
  const nextLayout = adjustLayoutByDelta({
1264
1264
  delta,
@@ -1297,7 +1297,7 @@ function PanelGroupWithForwardedRef({
1297
1297
  const {
1298
1298
  panelDataArray
1299
1299
  } = eagerValuesRef.current;
1300
- const panelIndex = panelDataArray.indexOf(panelData);
1300
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1301
1301
  return computePanelFlexBoxStyle({
1302
1302
  dragState,
1303
1303
  layout,
@@ -1345,6 +1345,19 @@ function PanelGroupWithForwardedRef({
1345
1345
  layout: prevLayout,
1346
1346
  panelDataArray
1347
1347
  } = eagerValuesRef.current;
1348
+
1349
+ // HACK
1350
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1351
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1352
+ const index = findPanelDataIndex(panelDataArray, panelData);
1353
+ if (index >= 0) {
1354
+ if (panelData.idIsFromProps) {
1355
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1356
+ } else {
1357
+ console.warn(`Panel registered twice`);
1358
+ }
1359
+ return;
1360
+ }
1348
1361
  panelDataArray.push(panelData);
1349
1362
  panelDataArray.sort((panelA, panelB) => {
1350
1363
  const orderA = panelA.order;
@@ -1486,7 +1499,7 @@ function PanelGroupWithForwardedRef({
1486
1499
  pivotIndices
1487
1500
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1488
1501
  assert(panelSize != null);
1489
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1502
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1490
1503
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1491
1504
  const nextLayout = adjustLayoutByDelta({
1492
1505
  delta,
@@ -1537,7 +1550,7 @@ function PanelGroupWithForwardedRef({
1537
1550
  layout: prevLayout,
1538
1551
  panelDataArray
1539
1552
  } = eagerValuesRef.current;
1540
- const index = panelDataArray.indexOf(panelData);
1553
+ const index = findPanelDataIndex(panelDataArray, panelData);
1541
1554
  if (index >= 0) {
1542
1555
  panelDataArray.splice(index, 1);
1543
1556
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1553,7 +1566,7 @@ function PanelGroupWithForwardedRef({
1553
1566
  const {
1554
1567
  pendingPanelIds
1555
1568
  } = unregisterPanelRef.current;
1556
- const map = panelIdToLastNotifiedSizeMapRef.current;
1569
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1557
1570
 
1558
1571
  // TRICKY
1559
1572
  // Strict effects mode
@@ -1562,17 +1575,17 @@ function PanelGroupWithForwardedRef({
1562
1575
  pendingPanelIds.delete(panelId);
1563
1576
  if (panelDataArray.find(({
1564
1577
  id
1565
- }) => id === panelId) == null) {
1578
+ }) => id === panelId) != null) {
1566
1579
  unmountDueToStrictMode = true;
1567
-
1580
+ } else {
1568
1581
  // TRICKY
1569
1582
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1570
1583
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1571
1584
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1572
- delete map[panelData.id];
1585
+ delete panelIdToLastNotifiedSizeMap[panelId];
1573
1586
  }
1574
1587
  });
1575
- if (!unmountDueToStrictMode) {
1588
+ if (unmountDueToStrictMode) {
1576
1589
  return;
1577
1590
  }
1578
1591
  if (panelDataArray.length === 0) {
@@ -1645,9 +1658,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1645
1658
  }));
1646
1659
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1647
1660
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1661
+ function findPanelDataIndex(panelDataArray, panelData) {
1662
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1663
+ }
1648
1664
  function panelDataHelper(panelDataArray, panelData, layout) {
1649
1665
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1650
- const panelIndex = panelDataArray.indexOf(panelData);
1666
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1651
1667
  const panelConstraints = panelConstraintsArray[panelIndex];
1652
1668
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1653
1669
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1192,7 +1192,7 @@ function PanelGroupWithForwardedRef({
1192
1192
  // Store size before collapse;
1193
1193
  // This is the size that gets restored if the expand() API is used.
1194
1194
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1195
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1195
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1196
1196
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1197
1197
  const nextLayout = adjustLayoutByDelta({
1198
1198
  delta,
@@ -1234,7 +1234,7 @@ function PanelGroupWithForwardedRef({
1234
1234
  // Restore this panel to the size it was before it was collapsed, if possible.
1235
1235
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1236
1236
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1237
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1237
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1238
1238
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1239
1239
  const nextLayout = adjustLayoutByDelta({
1240
1240
  delta,
@@ -1273,7 +1273,7 @@ function PanelGroupWithForwardedRef({
1273
1273
  const {
1274
1274
  panelDataArray
1275
1275
  } = eagerValuesRef.current;
1276
- const panelIndex = panelDataArray.indexOf(panelData);
1276
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1277
1277
  return computePanelFlexBoxStyle({
1278
1278
  dragState,
1279
1279
  layout,
@@ -1321,6 +1321,19 @@ function PanelGroupWithForwardedRef({
1321
1321
  layout: prevLayout,
1322
1322
  panelDataArray
1323
1323
  } = eagerValuesRef.current;
1324
+
1325
+ // HACK
1326
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1327
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1328
+ const index = findPanelDataIndex(panelDataArray, panelData);
1329
+ if (index >= 0) {
1330
+ if (panelData.idIsFromProps) {
1331
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1332
+ } else {
1333
+ console.warn(`Panel registered twice`);
1334
+ }
1335
+ return;
1336
+ }
1324
1337
  panelDataArray.push(panelData);
1325
1338
  panelDataArray.sort((panelA, panelB) => {
1326
1339
  const orderA = panelA.order;
@@ -1462,7 +1475,7 @@ function PanelGroupWithForwardedRef({
1462
1475
  pivotIndices
1463
1476
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1464
1477
  assert(panelSize != null);
1465
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1478
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1466
1479
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1467
1480
  const nextLayout = adjustLayoutByDelta({
1468
1481
  delta,
@@ -1513,7 +1526,7 @@ function PanelGroupWithForwardedRef({
1513
1526
  layout: prevLayout,
1514
1527
  panelDataArray
1515
1528
  } = eagerValuesRef.current;
1516
- const index = panelDataArray.indexOf(panelData);
1529
+ const index = findPanelDataIndex(panelDataArray, panelData);
1517
1530
  if (index >= 0) {
1518
1531
  panelDataArray.splice(index, 1);
1519
1532
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1529,7 +1542,7 @@ function PanelGroupWithForwardedRef({
1529
1542
  const {
1530
1543
  pendingPanelIds
1531
1544
  } = unregisterPanelRef.current;
1532
- const map = panelIdToLastNotifiedSizeMapRef.current;
1545
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1533
1546
 
1534
1547
  // TRICKY
1535
1548
  // Strict effects mode
@@ -1538,17 +1551,17 @@ function PanelGroupWithForwardedRef({
1538
1551
  pendingPanelIds.delete(panelId);
1539
1552
  if (panelDataArray.find(({
1540
1553
  id
1541
- }) => id === panelId) == null) {
1554
+ }) => id === panelId) != null) {
1542
1555
  unmountDueToStrictMode = true;
1543
-
1556
+ } else {
1544
1557
  // TRICKY
1545
1558
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1546
1559
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1547
1560
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1548
- delete map[panelData.id];
1561
+ delete panelIdToLastNotifiedSizeMap[panelId];
1549
1562
  }
1550
1563
  });
1551
- if (!unmountDueToStrictMode) {
1564
+ if (unmountDueToStrictMode) {
1552
1565
  return;
1553
1566
  }
1554
1567
  if (panelDataArray.length === 0) {
@@ -1621,9 +1634,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1621
1634
  }));
1622
1635
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1623
1636
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1637
+ function findPanelDataIndex(panelDataArray, panelData) {
1638
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1639
+ }
1624
1640
  function panelDataHelper(panelDataArray, panelData, layout) {
1625
1641
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1626
- const panelIndex = panelDataArray.indexOf(panelData);
1642
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1627
1643
  const panelConstraints = panelConstraintsArray[panelIndex];
1628
1644
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1629
1645
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1198,7 +1198,7 @@ function PanelGroupWithForwardedRef({
1198
1198
  // Store size before collapse;
1199
1199
  // This is the size that gets restored if the expand() API is used.
1200
1200
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1201
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1201
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1202
1202
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1203
1203
  const nextLayout = adjustLayoutByDelta({
1204
1204
  delta,
@@ -1240,7 +1240,7 @@ function PanelGroupWithForwardedRef({
1240
1240
  // Restore this panel to the size it was before it was collapsed, if possible.
1241
1241
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1242
1242
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1243
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1243
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1244
1244
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1245
1245
  const nextLayout = adjustLayoutByDelta({
1246
1246
  delta,
@@ -1279,7 +1279,7 @@ function PanelGroupWithForwardedRef({
1279
1279
  const {
1280
1280
  panelDataArray
1281
1281
  } = eagerValuesRef.current;
1282
- const panelIndex = panelDataArray.indexOf(panelData);
1282
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1283
1283
  return computePanelFlexBoxStyle({
1284
1284
  dragState,
1285
1285
  layout,
@@ -1327,6 +1327,19 @@ function PanelGroupWithForwardedRef({
1327
1327
  layout: prevLayout,
1328
1328
  panelDataArray
1329
1329
  } = eagerValuesRef.current;
1330
+
1331
+ // HACK
1332
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1333
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1334
+ const index = findPanelDataIndex(panelDataArray, panelData);
1335
+ if (index >= 0) {
1336
+ if (panelData.idIsFromProps) {
1337
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1338
+ } else {
1339
+ console.warn(`Panel registered twice`);
1340
+ }
1341
+ return;
1342
+ }
1330
1343
  panelDataArray.push(panelData);
1331
1344
  panelDataArray.sort((panelA, panelB) => {
1332
1345
  const orderA = panelA.order;
@@ -1468,7 +1481,7 @@ function PanelGroupWithForwardedRef({
1468
1481
  pivotIndices
1469
1482
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1470
1483
  assert(panelSize != null);
1471
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1484
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1472
1485
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1473
1486
  const nextLayout = adjustLayoutByDelta({
1474
1487
  delta,
@@ -1519,7 +1532,7 @@ function PanelGroupWithForwardedRef({
1519
1532
  layout: prevLayout,
1520
1533
  panelDataArray
1521
1534
  } = eagerValuesRef.current;
1522
- const index = panelDataArray.indexOf(panelData);
1535
+ const index = findPanelDataIndex(panelDataArray, panelData);
1523
1536
  if (index >= 0) {
1524
1537
  panelDataArray.splice(index, 1);
1525
1538
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1535,7 +1548,7 @@ function PanelGroupWithForwardedRef({
1535
1548
  const {
1536
1549
  pendingPanelIds
1537
1550
  } = unregisterPanelRef.current;
1538
- const map = panelIdToLastNotifiedSizeMapRef.current;
1551
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1539
1552
 
1540
1553
  // TRICKY
1541
1554
  // Strict effects mode
@@ -1544,17 +1557,17 @@ function PanelGroupWithForwardedRef({
1544
1557
  pendingPanelIds.delete(panelId);
1545
1558
  if (panelDataArray.find(({
1546
1559
  id
1547
- }) => id === panelId) == null) {
1560
+ }) => id === panelId) != null) {
1548
1561
  unmountDueToStrictMode = true;
1549
-
1562
+ } else {
1550
1563
  // TRICKY
1551
1564
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1552
1565
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1553
1566
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1554
- delete map[panelData.id];
1567
+ delete panelIdToLastNotifiedSizeMap[panelId];
1555
1568
  }
1556
1569
  });
1557
- if (!unmountDueToStrictMode) {
1570
+ if (unmountDueToStrictMode) {
1558
1571
  return;
1559
1572
  }
1560
1573
  if (panelDataArray.length === 0) {
@@ -1627,9 +1640,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1627
1640
  }));
1628
1641
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1629
1642
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1643
+ function findPanelDataIndex(panelDataArray, panelData) {
1644
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1645
+ }
1630
1646
  function panelDataHelper(panelDataArray, panelData, layout) {
1631
1647
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1632
- const panelIndex = panelDataArray.indexOf(panelData);
1648
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1633
1649
  const panelConstraints = panelConstraintsArray[panelIndex];
1634
1650
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1635
1651
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1116,7 +1116,7 @@ function PanelGroupWithForwardedRef({
1116
1116
  // Store size before collapse;
1117
1117
  // This is the size that gets restored if the expand() API is used.
1118
1118
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1119
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1119
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1120
1120
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1121
1121
  const nextLayout = adjustLayoutByDelta({
1122
1122
  delta,
@@ -1158,7 +1158,7 @@ function PanelGroupWithForwardedRef({
1158
1158
  // Restore this panel to the size it was before it was collapsed, if possible.
1159
1159
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1160
1160
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1161
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1161
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1162
1162
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1163
1163
  const nextLayout = adjustLayoutByDelta({
1164
1164
  delta,
@@ -1197,7 +1197,7 @@ function PanelGroupWithForwardedRef({
1197
1197
  const {
1198
1198
  panelDataArray
1199
1199
  } = eagerValuesRef.current;
1200
- const panelIndex = panelDataArray.indexOf(panelData);
1200
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1201
1201
  return computePanelFlexBoxStyle({
1202
1202
  dragState,
1203
1203
  layout,
@@ -1245,6 +1245,19 @@ function PanelGroupWithForwardedRef({
1245
1245
  layout: prevLayout,
1246
1246
  panelDataArray
1247
1247
  } = eagerValuesRef.current;
1248
+
1249
+ // HACK
1250
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1251
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1252
+ const index = findPanelDataIndex(panelDataArray, panelData);
1253
+ if (index >= 0) {
1254
+ if (panelData.idIsFromProps) {
1255
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1256
+ } else {
1257
+ console.warn(`Panel registered twice`);
1258
+ }
1259
+ return;
1260
+ }
1248
1261
  panelDataArray.push(panelData);
1249
1262
  panelDataArray.sort((panelA, panelB) => {
1250
1263
  const orderA = panelA.order;
@@ -1386,7 +1399,7 @@ function PanelGroupWithForwardedRef({
1386
1399
  pivotIndices
1387
1400
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1388
1401
  assert(panelSize != null);
1389
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1402
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1390
1403
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1391
1404
  const nextLayout = adjustLayoutByDelta({
1392
1405
  delta,
@@ -1437,7 +1450,7 @@ function PanelGroupWithForwardedRef({
1437
1450
  layout: prevLayout,
1438
1451
  panelDataArray
1439
1452
  } = eagerValuesRef.current;
1440
- const index = panelDataArray.indexOf(panelData);
1453
+ const index = findPanelDataIndex(panelDataArray, panelData);
1441
1454
  if (index >= 0) {
1442
1455
  panelDataArray.splice(index, 1);
1443
1456
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1453,7 +1466,7 @@ function PanelGroupWithForwardedRef({
1453
1466
  const {
1454
1467
  pendingPanelIds
1455
1468
  } = unregisterPanelRef.current;
1456
- const map = panelIdToLastNotifiedSizeMapRef.current;
1469
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1457
1470
 
1458
1471
  // TRICKY
1459
1472
  // Strict effects mode
@@ -1462,17 +1475,17 @@ function PanelGroupWithForwardedRef({
1462
1475
  pendingPanelIds.delete(panelId);
1463
1476
  if (panelDataArray.find(({
1464
1477
  id
1465
- }) => id === panelId) == null) {
1478
+ }) => id === panelId) != null) {
1466
1479
  unmountDueToStrictMode = true;
1467
-
1480
+ } else {
1468
1481
  // TRICKY
1469
1482
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1470
1483
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1471
1484
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1472
- delete map[panelData.id];
1485
+ delete panelIdToLastNotifiedSizeMap[panelId];
1473
1486
  }
1474
1487
  });
1475
- if (!unmountDueToStrictMode) {
1488
+ if (unmountDueToStrictMode) {
1476
1489
  return;
1477
1490
  }
1478
1491
  if (panelDataArray.length === 0) {
@@ -1545,9 +1558,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1545
1558
  }));
1546
1559
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1547
1560
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1561
+ function findPanelDataIndex(panelDataArray, panelData) {
1562
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1563
+ }
1548
1564
  function panelDataHelper(panelDataArray, panelData, layout) {
1549
1565
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1550
- const panelIndex = panelDataArray.indexOf(panelData);
1566
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1551
1567
  const panelConstraints = panelConstraintsArray[panelIndex];
1552
1568
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1553
1569
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1092,7 +1092,7 @@ function PanelGroupWithForwardedRef({
1092
1092
  // Store size before collapse;
1093
1093
  // This is the size that gets restored if the expand() API is used.
1094
1094
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1095
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1095
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1096
1096
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1097
1097
  const nextLayout = adjustLayoutByDelta({
1098
1098
  delta,
@@ -1134,7 +1134,7 @@ function PanelGroupWithForwardedRef({
1134
1134
  // Restore this panel to the size it was before it was collapsed, if possible.
1135
1135
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1136
1136
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1137
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1137
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1138
1138
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1139
1139
  const nextLayout = adjustLayoutByDelta({
1140
1140
  delta,
@@ -1173,7 +1173,7 @@ function PanelGroupWithForwardedRef({
1173
1173
  const {
1174
1174
  panelDataArray
1175
1175
  } = eagerValuesRef.current;
1176
- const panelIndex = panelDataArray.indexOf(panelData);
1176
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1177
1177
  return computePanelFlexBoxStyle({
1178
1178
  dragState,
1179
1179
  layout,
@@ -1221,6 +1221,19 @@ function PanelGroupWithForwardedRef({
1221
1221
  layout: prevLayout,
1222
1222
  panelDataArray
1223
1223
  } = eagerValuesRef.current;
1224
+
1225
+ // HACK
1226
+ // This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
1227
+ // see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
1228
+ const index = findPanelDataIndex(panelDataArray, panelData);
1229
+ if (index >= 0) {
1230
+ if (panelData.idIsFromProps) {
1231
+ console.warn(`Panel with id "${panelData.id}" registered twice`);
1232
+ } else {
1233
+ console.warn(`Panel registered twice`);
1234
+ }
1235
+ return;
1236
+ }
1224
1237
  panelDataArray.push(panelData);
1225
1238
  panelDataArray.sort((panelA, panelB) => {
1226
1239
  const orderA = panelA.order;
@@ -1362,7 +1375,7 @@ function PanelGroupWithForwardedRef({
1362
1375
  pivotIndices
1363
1376
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1364
1377
  assert(panelSize != null);
1365
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1378
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1366
1379
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1367
1380
  const nextLayout = adjustLayoutByDelta({
1368
1381
  delta,
@@ -1413,7 +1426,7 @@ function PanelGroupWithForwardedRef({
1413
1426
  layout: prevLayout,
1414
1427
  panelDataArray
1415
1428
  } = eagerValuesRef.current;
1416
- const index = panelDataArray.indexOf(panelData);
1429
+ const index = findPanelDataIndex(panelDataArray, panelData);
1417
1430
  if (index >= 0) {
1418
1431
  panelDataArray.splice(index, 1);
1419
1432
  unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
@@ -1429,7 +1442,7 @@ function PanelGroupWithForwardedRef({
1429
1442
  const {
1430
1443
  pendingPanelIds
1431
1444
  } = unregisterPanelRef.current;
1432
- const map = panelIdToLastNotifiedSizeMapRef.current;
1445
+ const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
1433
1446
 
1434
1447
  // TRICKY
1435
1448
  // Strict effects mode
@@ -1438,17 +1451,17 @@ function PanelGroupWithForwardedRef({
1438
1451
  pendingPanelIds.delete(panelId);
1439
1452
  if (panelDataArray.find(({
1440
1453
  id
1441
- }) => id === panelId) == null) {
1454
+ }) => id === panelId) != null) {
1442
1455
  unmountDueToStrictMode = true;
1443
-
1456
+ } else {
1444
1457
  // TRICKY
1445
1458
  // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1446
1459
  // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1447
1460
  // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1448
- delete map[panelData.id];
1461
+ delete panelIdToLastNotifiedSizeMap[panelId];
1449
1462
  }
1450
1463
  });
1451
- if (!unmountDueToStrictMode) {
1464
+ if (unmountDueToStrictMode) {
1452
1465
  return;
1453
1466
  }
1454
1467
  if (panelDataArray.length === 0) {
@@ -1521,9 +1534,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1521
1534
  }));
1522
1535
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1523
1536
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1537
+ function findPanelDataIndex(panelDataArray, panelData) {
1538
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1539
+ }
1524
1540
  function panelDataHelper(panelDataArray, panelData, layout) {
1525
1541
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1526
- const panelIndex = panelDataArray.indexOf(panelData);
1542
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1527
1543
  const panelConstraints = panelConstraintsArray[panelIndex];
1528
1544
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1529
1545
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-resizable-panels",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.3",
4
4
  "description": "React components for resizable panel groups/layouts",
5
5
  "author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
6
6
  "license": "MIT",