react-resizable-panels 1.0.0-rc.2 → 1.0.0-rc.4

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.
@@ -960,10 +960,6 @@ function debounce(callback, durationMs = 10) {
960
960
  return callable;
961
961
  }
962
962
 
963
- function getPanelElementsForGroup(groupId) {
964
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
965
- }
966
-
967
963
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
968
964
  // or on a browser with cookies/storage disabled.
969
965
  // In either case, this function avoids accessing localStorage until needed,
@@ -1177,6 +1173,7 @@ function PanelGroupWithForwardedRef({
1177
1173
  const groupId = useUniqueId(idFromProps);
1178
1174
  const [dragState, setDragState] = useState(null);
1179
1175
  const [layout, setLayout] = useState([]);
1176
+ useState([]);
1180
1177
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1181
1178
  const panelSizeBeforeCollapseRef = useRef(new Map());
1182
1179
  const prevDeltaRef = useRef(0);
@@ -1191,7 +1188,8 @@ function PanelGroupWithForwardedRef({
1191
1188
  });
1192
1189
  const eagerValuesRef = useRef({
1193
1190
  layout,
1194
- panelDataArray: []
1191
+ panelDataArray: [],
1192
+ panelDataArrayChanged: false
1195
1193
  });
1196
1194
  const devWarningsRef = useRef({
1197
1195
  didLogIdAndOrderWarning: false,
@@ -1332,7 +1330,7 @@ function PanelGroupWithForwardedRef({
1332
1330
  // Store size before collapse;
1333
1331
  // This is the size that gets restored if the expand() API is used.
1334
1332
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1335
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1333
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1336
1334
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1337
1335
  const nextLayout = adjustLayoutByDelta({
1338
1336
  delta,
@@ -1374,7 +1372,7 @@ function PanelGroupWithForwardedRef({
1374
1372
  // Restore this panel to the size it was before it was collapsed, if possible.
1375
1373
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1376
1374
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1377
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1375
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1378
1376
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1379
1377
  const nextLayout = adjustLayoutByDelta({
1380
1378
  delta,
@@ -1413,7 +1411,7 @@ function PanelGroupWithForwardedRef({
1413
1411
  const {
1414
1412
  panelDataArray
1415
1413
  } = eagerValuesRef.current;
1416
- const panelIndex = panelDataArray.indexOf(panelData);
1414
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1417
1415
  return computePanelFlexBoxStyle({
1418
1416
  dragState,
1419
1417
  layout,
@@ -1452,13 +1450,6 @@ function PanelGroupWithForwardedRef({
1452
1450
  }, []);
1453
1451
  const registerPanel = useCallback(panelData => {
1454
1452
  const {
1455
- autoSaveId,
1456
- id: groupId,
1457
- onLayout,
1458
- storage
1459
- } = committedValuesRef.current;
1460
- const {
1461
- layout: prevLayout,
1462
1453
  panelDataArray
1463
1454
  } = eagerValuesRef.current;
1464
1455
  panelDataArray.push(panelData);
@@ -1475,45 +1466,52 @@ function PanelGroupWithForwardedRef({
1475
1466
  return orderA - orderB;
1476
1467
  }
1477
1468
  });
1469
+ eagerValuesRef.current.panelDataArrayChanged = true;
1470
+ }, []);
1478
1471
 
1479
- // Wait until all panels have registered before we try to compute layout;
1480
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1481
- const panelElements = getPanelElementsForGroup(groupId);
1482
- if (panelElements.length !== panelDataArray.length) {
1483
- return;
1484
- }
1485
-
1486
- // If this panel has been configured to persist sizing information,
1487
- // default size should be restored from local storage if possible.
1488
- let unsafeLayout = null;
1489
- if (autoSaveId) {
1490
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1491
- }
1492
- if (unsafeLayout == null) {
1493
- unsafeLayout = calculateUnsafeDefaultLayout({
1472
+ // (Re)calculate group layout whenever panels are registered or unregistered.
1473
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1474
+ useIsomorphicLayoutEffect(() => {
1475
+ if (eagerValuesRef.current.panelDataArrayChanged) {
1476
+ eagerValuesRef.current.panelDataArrayChanged = false;
1477
+ const {
1478
+ autoSaveId,
1479
+ onLayout,
1480
+ storage
1481
+ } = committedValuesRef.current;
1482
+ const {
1483
+ layout: prevLayout,
1494
1484
  panelDataArray
1495
- });
1496
- }
1485
+ } = eagerValuesRef.current;
1497
1486
 
1498
- // Validate even saved layouts in case something has changed since last render
1499
- // e.g. for pixel groups, this could be the size of the window
1500
- const nextLayout = validatePanelGroupLayout({
1501
- layout: unsafeLayout,
1502
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1503
- });
1487
+ // If this panel has been configured to persist sizing information,
1488
+ // default size should be restored from local storage if possible.
1489
+ let unsafeLayout = null;
1490
+ if (autoSaveId) {
1491
+ unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1492
+ }
1493
+ if (unsafeLayout == null) {
1494
+ unsafeLayout = calculateUnsafeDefaultLayout({
1495
+ panelDataArray
1496
+ });
1497
+ }
1504
1498
 
1505
- // Offscreen mode makes this a bit weird;
1506
- // Panels unregister when hidden and re-register when shown again,
1507
- // but the overall layout doesn't change between these two cases.
1508
- setLayout(nextLayout);
1509
- eagerValuesRef.current.layout = nextLayout;
1510
- if (!areEqual(prevLayout, nextLayout)) {
1511
- if (onLayout) {
1512
- onLayout(nextLayout);
1499
+ // Validate even saved layouts in case something has changed since last render
1500
+ // e.g. for pixel groups, this could be the size of the window
1501
+ const nextLayout = validatePanelGroupLayout({
1502
+ layout: unsafeLayout,
1503
+ panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1504
+ });
1505
+ if (!areEqual(prevLayout, nextLayout)) {
1506
+ setLayout(nextLayout);
1507
+ eagerValuesRef.current.layout = nextLayout;
1508
+ if (onLayout) {
1509
+ onLayout(nextLayout);
1510
+ }
1511
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1513
1512
  }
1514
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1515
1513
  }
1516
- }, []);
1514
+ });
1517
1515
  const registerResizeHandle = useCallback(dragHandleId => {
1518
1516
  return function resizeHandler(event) {
1519
1517
  event.preventDefault();
@@ -1602,7 +1600,7 @@ function PanelGroupWithForwardedRef({
1602
1600
  pivotIndices
1603
1601
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1604
1602
  assert(panelSize != null);
1605
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1603
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1606
1604
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1607
1605
  const nextLayout = adjustLayoutByDelta({
1608
1606
  delta,
@@ -1641,79 +1639,21 @@ function PanelGroupWithForwardedRef({
1641
1639
  resetGlobalCursorStyle();
1642
1640
  setDragState(null);
1643
1641
  }, []);
1644
- const unregisterPanelRef = useRef({
1645
- pendingPanelIds: new Set(),
1646
- timeout: null
1647
- });
1648
1642
  const unregisterPanel = useCallback(panelData => {
1649
1643
  const {
1650
- onLayout
1651
- } = committedValuesRef.current;
1652
- const {
1653
- layout: prevLayout,
1654
1644
  panelDataArray
1655
1645
  } = eagerValuesRef.current;
1656
- const index = panelDataArray.indexOf(panelData);
1646
+ const index = findPanelDataIndex(panelDataArray, panelData);
1657
1647
  if (index >= 0) {
1658
1648
  panelDataArray.splice(index, 1);
1659
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1660
- }
1661
- if (unregisterPanelRef.current.timeout != null) {
1662
- clearTimeout(unregisterPanelRef.current.timeout);
1663
- }
1664
-
1665
- // Batch panel unmounts so that we only calculate layout once;
1666
- // This is more efficient and avoids misleading warnings in development mode.
1667
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1668
- unregisterPanelRef.current.timeout = setTimeout(() => {
1669
- const {
1670
- pendingPanelIds
1671
- } = unregisterPanelRef.current;
1672
- const map = panelIdToLastNotifiedSizeMapRef.current;
1673
1649
 
1674
1650
  // TRICKY
1675
- // Strict effects mode
1676
- let unmountDueToStrictMode = false;
1677
- pendingPanelIds.forEach(panelId => {
1678
- pendingPanelIds.delete(panelId);
1679
- if (panelDataArray.find(({
1680
- id
1681
- }) => id === panelId) != null) {
1682
- unmountDueToStrictMode = true;
1683
-
1684
- // TRICKY
1685
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1686
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1687
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1688
- delete map[panelData.id];
1689
- }
1690
- });
1691
- if (!unmountDueToStrictMode) {
1692
- return;
1693
- }
1694
- if (panelDataArray.length === 0) {
1695
- // The group is unmounting; skip layout calculation.
1696
- return;
1697
- }
1698
- let unsafeLayout = calculateUnsafeDefaultLayout({
1699
- panelDataArray
1700
- });
1701
-
1702
- // Validate even saved layouts in case something has changed since last render
1703
- // e.g. for pixel groups, this could be the size of the window
1704
- const nextLayout = validatePanelGroupLayout({
1705
- layout: unsafeLayout,
1706
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1707
- });
1708
- if (!areEqual(prevLayout, nextLayout)) {
1709
- setLayout(nextLayout);
1710
- eagerValuesRef.current.layout = nextLayout;
1711
- if (onLayout) {
1712
- onLayout(nextLayout);
1713
- }
1714
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1715
- }
1716
- }, 0);
1651
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1652
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1653
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1654
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1655
+ eagerValuesRef.current.panelDataArrayChanged = true;
1656
+ }
1717
1657
  }, []);
1718
1658
  const context = useMemo(() => ({
1719
1659
  collapsePanel,
@@ -1761,9 +1701,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1761
1701
  }));
1762
1702
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1763
1703
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1704
+ function findPanelDataIndex(panelDataArray, panelData) {
1705
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1706
+ }
1764
1707
  function panelDataHelper(panelDataArray, panelData, layout) {
1765
1708
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1766
- const panelIndex = panelDataArray.indexOf(panelData);
1709
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1767
1710
  const panelConstraints = panelConstraintsArray[panelIndex];
1768
1711
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1769
1712
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -936,10 +936,6 @@ function debounce(callback, durationMs = 10) {
936
936
  return callable;
937
937
  }
938
938
 
939
- function getPanelElementsForGroup(groupId) {
940
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
941
- }
942
-
943
939
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
944
940
  // or on a browser with cookies/storage disabled.
945
941
  // In either case, this function avoids accessing localStorage until needed,
@@ -1153,6 +1149,7 @@ function PanelGroupWithForwardedRef({
1153
1149
  const groupId = useUniqueId(idFromProps);
1154
1150
  const [dragState, setDragState] = useState(null);
1155
1151
  const [layout, setLayout] = useState([]);
1152
+ useState([]);
1156
1153
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1157
1154
  const panelSizeBeforeCollapseRef = useRef(new Map());
1158
1155
  const prevDeltaRef = useRef(0);
@@ -1167,7 +1164,8 @@ function PanelGroupWithForwardedRef({
1167
1164
  });
1168
1165
  const eagerValuesRef = useRef({
1169
1166
  layout,
1170
- panelDataArray: []
1167
+ panelDataArray: [],
1168
+ panelDataArrayChanged: false
1171
1169
  });
1172
1170
  const devWarningsRef = useRef({
1173
1171
  didLogIdAndOrderWarning: false,
@@ -1308,7 +1306,7 @@ function PanelGroupWithForwardedRef({
1308
1306
  // Store size before collapse;
1309
1307
  // This is the size that gets restored if the expand() API is used.
1310
1308
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1311
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1309
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1312
1310
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1313
1311
  const nextLayout = adjustLayoutByDelta({
1314
1312
  delta,
@@ -1350,7 +1348,7 @@ function PanelGroupWithForwardedRef({
1350
1348
  // Restore this panel to the size it was before it was collapsed, if possible.
1351
1349
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1352
1350
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1353
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1351
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1354
1352
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1355
1353
  const nextLayout = adjustLayoutByDelta({
1356
1354
  delta,
@@ -1389,7 +1387,7 @@ function PanelGroupWithForwardedRef({
1389
1387
  const {
1390
1388
  panelDataArray
1391
1389
  } = eagerValuesRef.current;
1392
- const panelIndex = panelDataArray.indexOf(panelData);
1390
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1393
1391
  return computePanelFlexBoxStyle({
1394
1392
  dragState,
1395
1393
  layout,
@@ -1428,13 +1426,6 @@ function PanelGroupWithForwardedRef({
1428
1426
  }, []);
1429
1427
  const registerPanel = useCallback(panelData => {
1430
1428
  const {
1431
- autoSaveId,
1432
- id: groupId,
1433
- onLayout,
1434
- storage
1435
- } = committedValuesRef.current;
1436
- const {
1437
- layout: prevLayout,
1438
1429
  panelDataArray
1439
1430
  } = eagerValuesRef.current;
1440
1431
  panelDataArray.push(panelData);
@@ -1451,45 +1442,52 @@ function PanelGroupWithForwardedRef({
1451
1442
  return orderA - orderB;
1452
1443
  }
1453
1444
  });
1445
+ eagerValuesRef.current.panelDataArrayChanged = true;
1446
+ }, []);
1454
1447
 
1455
- // Wait until all panels have registered before we try to compute layout;
1456
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1457
- const panelElements = getPanelElementsForGroup(groupId);
1458
- if (panelElements.length !== panelDataArray.length) {
1459
- return;
1460
- }
1461
-
1462
- // If this panel has been configured to persist sizing information,
1463
- // default size should be restored from local storage if possible.
1464
- let unsafeLayout = null;
1465
- if (autoSaveId) {
1466
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1467
- }
1468
- if (unsafeLayout == null) {
1469
- unsafeLayout = calculateUnsafeDefaultLayout({
1448
+ // (Re)calculate group layout whenever panels are registered or unregistered.
1449
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1450
+ useIsomorphicLayoutEffect(() => {
1451
+ if (eagerValuesRef.current.panelDataArrayChanged) {
1452
+ eagerValuesRef.current.panelDataArrayChanged = false;
1453
+ const {
1454
+ autoSaveId,
1455
+ onLayout,
1456
+ storage
1457
+ } = committedValuesRef.current;
1458
+ const {
1459
+ layout: prevLayout,
1470
1460
  panelDataArray
1471
- });
1472
- }
1461
+ } = eagerValuesRef.current;
1473
1462
 
1474
- // Validate even saved layouts in case something has changed since last render
1475
- // e.g. for pixel groups, this could be the size of the window
1476
- const nextLayout = validatePanelGroupLayout({
1477
- layout: unsafeLayout,
1478
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1479
- });
1463
+ // If this panel has been configured to persist sizing information,
1464
+ // default size should be restored from local storage if possible.
1465
+ let unsafeLayout = null;
1466
+ if (autoSaveId) {
1467
+ unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1468
+ }
1469
+ if (unsafeLayout == null) {
1470
+ unsafeLayout = calculateUnsafeDefaultLayout({
1471
+ panelDataArray
1472
+ });
1473
+ }
1480
1474
 
1481
- // Offscreen mode makes this a bit weird;
1482
- // Panels unregister when hidden and re-register when shown again,
1483
- // but the overall layout doesn't change between these two cases.
1484
- setLayout(nextLayout);
1485
- eagerValuesRef.current.layout = nextLayout;
1486
- if (!areEqual(prevLayout, nextLayout)) {
1487
- if (onLayout) {
1488
- onLayout(nextLayout);
1475
+ // Validate even saved layouts in case something has changed since last render
1476
+ // e.g. for pixel groups, this could be the size of the window
1477
+ const nextLayout = validatePanelGroupLayout({
1478
+ layout: unsafeLayout,
1479
+ panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1480
+ });
1481
+ if (!areEqual(prevLayout, nextLayout)) {
1482
+ setLayout(nextLayout);
1483
+ eagerValuesRef.current.layout = nextLayout;
1484
+ if (onLayout) {
1485
+ onLayout(nextLayout);
1486
+ }
1487
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1489
1488
  }
1490
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1491
1489
  }
1492
- }, []);
1490
+ });
1493
1491
  const registerResizeHandle = useCallback(dragHandleId => {
1494
1492
  return function resizeHandler(event) {
1495
1493
  event.preventDefault();
@@ -1578,7 +1576,7 @@ function PanelGroupWithForwardedRef({
1578
1576
  pivotIndices
1579
1577
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1580
1578
  assert(panelSize != null);
1581
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1579
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1582
1580
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1583
1581
  const nextLayout = adjustLayoutByDelta({
1584
1582
  delta,
@@ -1617,79 +1615,21 @@ function PanelGroupWithForwardedRef({
1617
1615
  resetGlobalCursorStyle();
1618
1616
  setDragState(null);
1619
1617
  }, []);
1620
- const unregisterPanelRef = useRef({
1621
- pendingPanelIds: new Set(),
1622
- timeout: null
1623
- });
1624
1618
  const unregisterPanel = useCallback(panelData => {
1625
1619
  const {
1626
- onLayout
1627
- } = committedValuesRef.current;
1628
- const {
1629
- layout: prevLayout,
1630
1620
  panelDataArray
1631
1621
  } = eagerValuesRef.current;
1632
- const index = panelDataArray.indexOf(panelData);
1622
+ const index = findPanelDataIndex(panelDataArray, panelData);
1633
1623
  if (index >= 0) {
1634
1624
  panelDataArray.splice(index, 1);
1635
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1636
- }
1637
- if (unregisterPanelRef.current.timeout != null) {
1638
- clearTimeout(unregisterPanelRef.current.timeout);
1639
- }
1640
-
1641
- // Batch panel unmounts so that we only calculate layout once;
1642
- // This is more efficient and avoids misleading warnings in development mode.
1643
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1644
- unregisterPanelRef.current.timeout = setTimeout(() => {
1645
- const {
1646
- pendingPanelIds
1647
- } = unregisterPanelRef.current;
1648
- const map = panelIdToLastNotifiedSizeMapRef.current;
1649
1625
 
1650
1626
  // TRICKY
1651
- // Strict effects mode
1652
- let unmountDueToStrictMode = false;
1653
- pendingPanelIds.forEach(panelId => {
1654
- pendingPanelIds.delete(panelId);
1655
- if (panelDataArray.find(({
1656
- id
1657
- }) => id === panelId) != null) {
1658
- unmountDueToStrictMode = true;
1659
-
1660
- // TRICKY
1661
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1662
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1663
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1664
- delete map[panelData.id];
1665
- }
1666
- });
1667
- if (!unmountDueToStrictMode) {
1668
- return;
1669
- }
1670
- if (panelDataArray.length === 0) {
1671
- // The group is unmounting; skip layout calculation.
1672
- return;
1673
- }
1674
- let unsafeLayout = calculateUnsafeDefaultLayout({
1675
- panelDataArray
1676
- });
1677
-
1678
- // Validate even saved layouts in case something has changed since last render
1679
- // e.g. for pixel groups, this could be the size of the window
1680
- const nextLayout = validatePanelGroupLayout({
1681
- layout: unsafeLayout,
1682
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1683
- });
1684
- if (!areEqual(prevLayout, nextLayout)) {
1685
- setLayout(nextLayout);
1686
- eagerValuesRef.current.layout = nextLayout;
1687
- if (onLayout) {
1688
- onLayout(nextLayout);
1689
- }
1690
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1691
- }
1692
- }, 0);
1627
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1628
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1629
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1630
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1631
+ eagerValuesRef.current.panelDataArrayChanged = true;
1632
+ }
1693
1633
  }, []);
1694
1634
  const context = useMemo(() => ({
1695
1635
  collapsePanel,
@@ -1737,9 +1677,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1737
1677
  }));
1738
1678
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1739
1679
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1680
+ function findPanelDataIndex(panelDataArray, panelData) {
1681
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1682
+ }
1740
1683
  function panelDataHelper(panelDataArray, panelData, layout) {
1741
1684
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1742
- const panelIndex = panelDataArray.indexOf(panelData);
1685
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1743
1686
  const panelConstraints = panelConstraintsArray[panelIndex];
1744
1687
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1745
1688
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];