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.
@@ -937,10 +937,6 @@ function debounce(callback, durationMs = 10) {
937
937
  return callable;
938
938
  }
939
939
 
940
- function getPanelElementsForGroup(groupId) {
941
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
942
- }
943
-
944
940
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
945
941
  // or on a browser with cookies/storage disabled.
946
942
  // In either case, this function avoids accessing localStorage until needed,
@@ -1107,6 +1103,7 @@ function PanelGroupWithForwardedRef({
1107
1103
  const groupId = useUniqueId(idFromProps);
1108
1104
  const [dragState, setDragState] = useState(null);
1109
1105
  const [layout, setLayout] = useState([]);
1106
+ useState([]);
1110
1107
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1111
1108
  const panelSizeBeforeCollapseRef = useRef(new Map());
1112
1109
  const prevDeltaRef = useRef(0);
@@ -1121,7 +1118,8 @@ function PanelGroupWithForwardedRef({
1121
1118
  });
1122
1119
  const eagerValuesRef = useRef({
1123
1120
  layout,
1124
- panelDataArray: []
1121
+ panelDataArray: [],
1122
+ panelDataArrayChanged: false
1125
1123
  });
1126
1124
  useRef({
1127
1125
  didLogIdAndOrderWarning: false,
@@ -1220,7 +1218,7 @@ function PanelGroupWithForwardedRef({
1220
1218
  // Store size before collapse;
1221
1219
  // This is the size that gets restored if the expand() API is used.
1222
1220
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1223
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1221
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1224
1222
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1225
1223
  const nextLayout = adjustLayoutByDelta({
1226
1224
  delta,
@@ -1262,7 +1260,7 @@ function PanelGroupWithForwardedRef({
1262
1260
  // Restore this panel to the size it was before it was collapsed, if possible.
1263
1261
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1264
1262
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1265
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1263
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1266
1264
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1267
1265
  const nextLayout = adjustLayoutByDelta({
1268
1266
  delta,
@@ -1301,7 +1299,7 @@ function PanelGroupWithForwardedRef({
1301
1299
  const {
1302
1300
  panelDataArray
1303
1301
  } = eagerValuesRef.current;
1304
- const panelIndex = panelDataArray.indexOf(panelData);
1302
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1305
1303
  return computePanelFlexBoxStyle({
1306
1304
  dragState,
1307
1305
  layout,
@@ -1340,13 +1338,6 @@ function PanelGroupWithForwardedRef({
1340
1338
  }, []);
1341
1339
  const registerPanel = useCallback(panelData => {
1342
1340
  const {
1343
- autoSaveId,
1344
- id: groupId,
1345
- onLayout,
1346
- storage
1347
- } = committedValuesRef.current;
1348
- const {
1349
- layout: prevLayout,
1350
1341
  panelDataArray
1351
1342
  } = eagerValuesRef.current;
1352
1343
  panelDataArray.push(panelData);
@@ -1363,45 +1354,52 @@ function PanelGroupWithForwardedRef({
1363
1354
  return orderA - orderB;
1364
1355
  }
1365
1356
  });
1357
+ eagerValuesRef.current.panelDataArrayChanged = true;
1358
+ }, []);
1366
1359
 
1367
- // Wait until all panels have registered before we try to compute layout;
1368
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1369
- const panelElements = getPanelElementsForGroup(groupId);
1370
- if (panelElements.length !== panelDataArray.length) {
1371
- return;
1372
- }
1373
-
1374
- // If this panel has been configured to persist sizing information,
1375
- // default size should be restored from local storage if possible.
1376
- let unsafeLayout = null;
1377
- if (autoSaveId) {
1378
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1379
- }
1380
- if (unsafeLayout == null) {
1381
- unsafeLayout = calculateUnsafeDefaultLayout({
1360
+ // (Re)calculate group layout whenever panels are registered or unregistered.
1361
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1362
+ useIsomorphicLayoutEffect(() => {
1363
+ if (eagerValuesRef.current.panelDataArrayChanged) {
1364
+ eagerValuesRef.current.panelDataArrayChanged = false;
1365
+ const {
1366
+ autoSaveId,
1367
+ onLayout,
1368
+ storage
1369
+ } = committedValuesRef.current;
1370
+ const {
1371
+ layout: prevLayout,
1382
1372
  panelDataArray
1383
- });
1384
- }
1373
+ } = eagerValuesRef.current;
1385
1374
 
1386
- // Validate even saved layouts in case something has changed since last render
1387
- // e.g. for pixel groups, this could be the size of the window
1388
- const nextLayout = validatePanelGroupLayout({
1389
- layout: unsafeLayout,
1390
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1391
- });
1375
+ // If this panel has been configured to persist sizing information,
1376
+ // default size should be restored from local storage if possible.
1377
+ let unsafeLayout = null;
1378
+ if (autoSaveId) {
1379
+ unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1380
+ }
1381
+ if (unsafeLayout == null) {
1382
+ unsafeLayout = calculateUnsafeDefaultLayout({
1383
+ panelDataArray
1384
+ });
1385
+ }
1392
1386
 
1393
- // Offscreen mode makes this a bit weird;
1394
- // Panels unregister when hidden and re-register when shown again,
1395
- // but the overall layout doesn't change between these two cases.
1396
- setLayout(nextLayout);
1397
- eagerValuesRef.current.layout = nextLayout;
1398
- if (!areEqual(prevLayout, nextLayout)) {
1399
- if (onLayout) {
1400
- onLayout(nextLayout);
1387
+ // Validate even saved layouts in case something has changed since last render
1388
+ // e.g. for pixel groups, this could be the size of the window
1389
+ const nextLayout = validatePanelGroupLayout({
1390
+ layout: unsafeLayout,
1391
+ panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1392
+ });
1393
+ if (!areEqual(prevLayout, nextLayout)) {
1394
+ setLayout(nextLayout);
1395
+ eagerValuesRef.current.layout = nextLayout;
1396
+ if (onLayout) {
1397
+ onLayout(nextLayout);
1398
+ }
1399
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1401
1400
  }
1402
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1403
1401
  }
1404
- }, []);
1402
+ });
1405
1403
  const registerResizeHandle = useCallback(dragHandleId => {
1406
1404
  return function resizeHandler(event) {
1407
1405
  event.preventDefault();
@@ -1490,7 +1488,7 @@ function PanelGroupWithForwardedRef({
1490
1488
  pivotIndices
1491
1489
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1492
1490
  assert(panelSize != null);
1493
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1491
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1494
1492
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1495
1493
  const nextLayout = adjustLayoutByDelta({
1496
1494
  delta,
@@ -1529,79 +1527,21 @@ function PanelGroupWithForwardedRef({
1529
1527
  resetGlobalCursorStyle();
1530
1528
  setDragState(null);
1531
1529
  }, []);
1532
- const unregisterPanelRef = useRef({
1533
- pendingPanelIds: new Set(),
1534
- timeout: null
1535
- });
1536
1530
  const unregisterPanel = useCallback(panelData => {
1537
1531
  const {
1538
- onLayout
1539
- } = committedValuesRef.current;
1540
- const {
1541
- layout: prevLayout,
1542
1532
  panelDataArray
1543
1533
  } = eagerValuesRef.current;
1544
- const index = panelDataArray.indexOf(panelData);
1534
+ const index = findPanelDataIndex(panelDataArray, panelData);
1545
1535
  if (index >= 0) {
1546
1536
  panelDataArray.splice(index, 1);
1547
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1548
- }
1549
- if (unregisterPanelRef.current.timeout != null) {
1550
- clearTimeout(unregisterPanelRef.current.timeout);
1551
- }
1552
-
1553
- // Batch panel unmounts so that we only calculate layout once;
1554
- // This is more efficient and avoids misleading warnings in development mode.
1555
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1556
- unregisterPanelRef.current.timeout = setTimeout(() => {
1557
- const {
1558
- pendingPanelIds
1559
- } = unregisterPanelRef.current;
1560
- const map = panelIdToLastNotifiedSizeMapRef.current;
1561
1537
 
1562
1538
  // TRICKY
1563
- // Strict effects mode
1564
- let unmountDueToStrictMode = false;
1565
- pendingPanelIds.forEach(panelId => {
1566
- pendingPanelIds.delete(panelId);
1567
- if (panelDataArray.find(({
1568
- id
1569
- }) => id === panelId) != null) {
1570
- unmountDueToStrictMode = true;
1571
-
1572
- // TRICKY
1573
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1574
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1575
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1576
- delete map[panelData.id];
1577
- }
1578
- });
1579
- if (!unmountDueToStrictMode) {
1580
- return;
1581
- }
1582
- if (panelDataArray.length === 0) {
1583
- // The group is unmounting; skip layout calculation.
1584
- return;
1585
- }
1586
- let unsafeLayout = calculateUnsafeDefaultLayout({
1587
- panelDataArray
1588
- });
1589
-
1590
- // Validate even saved layouts in case something has changed since last render
1591
- // e.g. for pixel groups, this could be the size of the window
1592
- const nextLayout = validatePanelGroupLayout({
1593
- layout: unsafeLayout,
1594
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1595
- });
1596
- if (!areEqual(prevLayout, nextLayout)) {
1597
- setLayout(nextLayout);
1598
- eagerValuesRef.current.layout = nextLayout;
1599
- if (onLayout) {
1600
- onLayout(nextLayout);
1601
- }
1602
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1603
- }
1604
- }, 0);
1539
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1540
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1541
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1542
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1543
+ eagerValuesRef.current.panelDataArrayChanged = true;
1544
+ }
1605
1545
  }, []);
1606
1546
  const context = useMemo(() => ({
1607
1547
  collapsePanel,
@@ -1649,9 +1589,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1649
1589
  }));
1650
1590
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1651
1591
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1592
+ function findPanelDataIndex(panelDataArray, panelData) {
1593
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1594
+ }
1652
1595
  function panelDataHelper(panelDataArray, panelData, layout) {
1653
1596
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1654
- const panelIndex = panelDataArray.indexOf(panelData);
1597
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1655
1598
  const panelConstraints = panelConstraintsArray[panelIndex];
1656
1599
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1657
1600
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -953,10 +953,6 @@ function debounce(callback, durationMs = 10) {
953
953
  return callable;
954
954
  }
955
955
 
956
- function getPanelElementsForGroup(groupId) {
957
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
958
- }
959
-
960
956
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
961
957
  // or on a browser with cookies/storage disabled.
962
958
  // In either case, this function avoids accessing localStorage until needed,
@@ -1170,6 +1166,7 @@ function PanelGroupWithForwardedRef({
1170
1166
  const groupId = useUniqueId(idFromProps);
1171
1167
  const [dragState, setDragState] = useState(null);
1172
1168
  const [layout, setLayout] = useState([]);
1169
+ useState([]);
1173
1170
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1174
1171
  const panelSizeBeforeCollapseRef = useRef(new Map());
1175
1172
  const prevDeltaRef = useRef(0);
@@ -1184,7 +1181,8 @@ function PanelGroupWithForwardedRef({
1184
1181
  });
1185
1182
  const eagerValuesRef = useRef({
1186
1183
  layout,
1187
- panelDataArray: []
1184
+ panelDataArray: [],
1185
+ panelDataArrayChanged: false
1188
1186
  });
1189
1187
  const devWarningsRef = useRef({
1190
1188
  didLogIdAndOrderWarning: false,
@@ -1325,7 +1323,7 @@ function PanelGroupWithForwardedRef({
1325
1323
  // Store size before collapse;
1326
1324
  // This is the size that gets restored if the expand() API is used.
1327
1325
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1328
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1326
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1329
1327
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1330
1328
  const nextLayout = adjustLayoutByDelta({
1331
1329
  delta,
@@ -1367,7 +1365,7 @@ function PanelGroupWithForwardedRef({
1367
1365
  // Restore this panel to the size it was before it was collapsed, if possible.
1368
1366
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1369
1367
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1370
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1368
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1371
1369
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1372
1370
  const nextLayout = adjustLayoutByDelta({
1373
1371
  delta,
@@ -1406,7 +1404,7 @@ function PanelGroupWithForwardedRef({
1406
1404
  const {
1407
1405
  panelDataArray
1408
1406
  } = eagerValuesRef.current;
1409
- const panelIndex = panelDataArray.indexOf(panelData);
1407
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1410
1408
  return computePanelFlexBoxStyle({
1411
1409
  dragState,
1412
1410
  layout,
@@ -1445,13 +1443,6 @@ function PanelGroupWithForwardedRef({
1445
1443
  }, []);
1446
1444
  const registerPanel = useCallback(panelData => {
1447
1445
  const {
1448
- autoSaveId,
1449
- id: groupId,
1450
- onLayout,
1451
- storage
1452
- } = committedValuesRef.current;
1453
- const {
1454
- layout: prevLayout,
1455
1446
  panelDataArray
1456
1447
  } = eagerValuesRef.current;
1457
1448
  panelDataArray.push(panelData);
@@ -1468,45 +1459,52 @@ function PanelGroupWithForwardedRef({
1468
1459
  return orderA - orderB;
1469
1460
  }
1470
1461
  });
1462
+ eagerValuesRef.current.panelDataArrayChanged = true;
1463
+ }, []);
1471
1464
 
1472
- // Wait until all panels have registered before we try to compute layout;
1473
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1474
- const panelElements = getPanelElementsForGroup(groupId);
1475
- if (panelElements.length !== panelDataArray.length) {
1476
- return;
1477
- }
1478
-
1479
- // If this panel has been configured to persist sizing information,
1480
- // default size should be restored from local storage if possible.
1481
- let unsafeLayout = null;
1482
- if (autoSaveId) {
1483
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1484
- }
1485
- if (unsafeLayout == null) {
1486
- unsafeLayout = calculateUnsafeDefaultLayout({
1465
+ // (Re)calculate group layout whenever panels are registered or unregistered.
1466
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1467
+ useIsomorphicLayoutEffect(() => {
1468
+ if (eagerValuesRef.current.panelDataArrayChanged) {
1469
+ eagerValuesRef.current.panelDataArrayChanged = false;
1470
+ const {
1471
+ autoSaveId,
1472
+ onLayout,
1473
+ storage
1474
+ } = committedValuesRef.current;
1475
+ const {
1476
+ layout: prevLayout,
1487
1477
  panelDataArray
1488
- });
1489
- }
1478
+ } = eagerValuesRef.current;
1490
1479
 
1491
- // Validate even saved layouts in case something has changed since last render
1492
- // e.g. for pixel groups, this could be the size of the window
1493
- const nextLayout = validatePanelGroupLayout({
1494
- layout: unsafeLayout,
1495
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1496
- });
1480
+ // If this panel has been configured to persist sizing information,
1481
+ // default size should be restored from local storage if possible.
1482
+ let unsafeLayout = null;
1483
+ if (autoSaveId) {
1484
+ unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1485
+ }
1486
+ if (unsafeLayout == null) {
1487
+ unsafeLayout = calculateUnsafeDefaultLayout({
1488
+ panelDataArray
1489
+ });
1490
+ }
1497
1491
 
1498
- // Offscreen mode makes this a bit weird;
1499
- // Panels unregister when hidden and re-register when shown again,
1500
- // but the overall layout doesn't change between these two cases.
1501
- setLayout(nextLayout);
1502
- eagerValuesRef.current.layout = nextLayout;
1503
- if (!areEqual(prevLayout, nextLayout)) {
1504
- if (onLayout) {
1505
- onLayout(nextLayout);
1492
+ // Validate even saved layouts in case something has changed since last render
1493
+ // e.g. for pixel groups, this could be the size of the window
1494
+ const nextLayout = validatePanelGroupLayout({
1495
+ layout: unsafeLayout,
1496
+ panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1497
+ });
1498
+ if (!areEqual(prevLayout, nextLayout)) {
1499
+ setLayout(nextLayout);
1500
+ eagerValuesRef.current.layout = nextLayout;
1501
+ if (onLayout) {
1502
+ onLayout(nextLayout);
1503
+ }
1504
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1506
1505
  }
1507
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1508
1506
  }
1509
- }, []);
1507
+ });
1510
1508
  const registerResizeHandle = useCallback(dragHandleId => {
1511
1509
  return function resizeHandler(event) {
1512
1510
  event.preventDefault();
@@ -1595,7 +1593,7 @@ function PanelGroupWithForwardedRef({
1595
1593
  pivotIndices
1596
1594
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1597
1595
  assert(panelSize != null);
1598
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1596
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1599
1597
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1600
1598
  const nextLayout = adjustLayoutByDelta({
1601
1599
  delta,
@@ -1634,79 +1632,21 @@ function PanelGroupWithForwardedRef({
1634
1632
  resetGlobalCursorStyle();
1635
1633
  setDragState(null);
1636
1634
  }, []);
1637
- const unregisterPanelRef = useRef({
1638
- pendingPanelIds: new Set(),
1639
- timeout: null
1640
- });
1641
1635
  const unregisterPanel = useCallback(panelData => {
1642
1636
  const {
1643
- onLayout
1644
- } = committedValuesRef.current;
1645
- const {
1646
- layout: prevLayout,
1647
1637
  panelDataArray
1648
1638
  } = eagerValuesRef.current;
1649
- const index = panelDataArray.indexOf(panelData);
1639
+ const index = findPanelDataIndex(panelDataArray, panelData);
1650
1640
  if (index >= 0) {
1651
1641
  panelDataArray.splice(index, 1);
1652
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1653
- }
1654
- if (unregisterPanelRef.current.timeout != null) {
1655
- clearTimeout(unregisterPanelRef.current.timeout);
1656
- }
1657
-
1658
- // Batch panel unmounts so that we only calculate layout once;
1659
- // This is more efficient and avoids misleading warnings in development mode.
1660
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1661
- unregisterPanelRef.current.timeout = setTimeout(() => {
1662
- const {
1663
- pendingPanelIds
1664
- } = unregisterPanelRef.current;
1665
- const map = panelIdToLastNotifiedSizeMapRef.current;
1666
1642
 
1667
1643
  // TRICKY
1668
- // Strict effects mode
1669
- let unmountDueToStrictMode = false;
1670
- pendingPanelIds.forEach(panelId => {
1671
- pendingPanelIds.delete(panelId);
1672
- if (panelDataArray.find(({
1673
- id
1674
- }) => id === panelId) != null) {
1675
- unmountDueToStrictMode = true;
1676
-
1677
- // TRICKY
1678
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1679
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1680
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1681
- delete map[panelData.id];
1682
- }
1683
- });
1684
- if (!unmountDueToStrictMode) {
1685
- return;
1686
- }
1687
- if (panelDataArray.length === 0) {
1688
- // The group is unmounting; skip layout calculation.
1689
- return;
1690
- }
1691
- let unsafeLayout = calculateUnsafeDefaultLayout({
1692
- panelDataArray
1693
- });
1694
-
1695
- // Validate even saved layouts in case something has changed since last render
1696
- // e.g. for pixel groups, this could be the size of the window
1697
- const nextLayout = validatePanelGroupLayout({
1698
- layout: unsafeLayout,
1699
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1700
- });
1701
- if (!areEqual(prevLayout, nextLayout)) {
1702
- setLayout(nextLayout);
1703
- eagerValuesRef.current.layout = nextLayout;
1704
- if (onLayout) {
1705
- onLayout(nextLayout);
1706
- }
1707
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1708
- }
1709
- }, 0);
1644
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1645
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1646
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1647
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1648
+ eagerValuesRef.current.panelDataArrayChanged = true;
1649
+ }
1710
1650
  }, []);
1711
1651
  const context = useMemo(() => ({
1712
1652
  collapsePanel,
@@ -1754,9 +1694,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1754
1694
  }));
1755
1695
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1756
1696
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1697
+ function findPanelDataIndex(panelDataArray, panelData) {
1698
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1699
+ }
1757
1700
  function panelDataHelper(panelDataArray, panelData, layout) {
1758
1701
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1759
- const panelIndex = panelDataArray.indexOf(panelData);
1702
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1760
1703
  const panelConstraints = panelConstraintsArray[panelIndex];
1761
1704
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1762
1705
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];