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.
@@ -678,47 +678,6 @@ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragSta
678
678
  }
679
679
  }
680
680
 
681
- function calculateUnsafeDefaultLayout({
682
- panelDataArray
683
- }) {
684
- const layout = Array(panelDataArray.length);
685
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
686
- let numPanelsWithSizes = 0;
687
- let remainingSize = 100;
688
-
689
- // Distribute default sizes first
690
- for (let index = 0; index < panelDataArray.length; index++) {
691
- const panelConstraints = panelConstraintsArray[index];
692
- assert(panelConstraints);
693
- const {
694
- defaultSize
695
- } = panelConstraints;
696
- if (defaultSize != null) {
697
- numPanelsWithSizes++;
698
- layout[index] = defaultSize;
699
- remainingSize -= defaultSize;
700
- }
701
- }
702
-
703
- // Remaining size should be distributed evenly between panels without default sizes
704
- for (let index = 0; index < panelDataArray.length; index++) {
705
- const panelConstraints = panelConstraintsArray[index];
706
- assert(panelConstraints);
707
- const {
708
- defaultSize
709
- } = panelConstraints;
710
- if (defaultSize != null) {
711
- continue;
712
- }
713
- const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
714
- const size = remainingSize / numRemainingPanels;
715
- numPanelsWithSizes++;
716
- layout[index] = size;
717
- remainingSize -= size;
718
- }
719
- return layout;
720
- }
721
-
722
681
  // Layout should be pre-converted into percentages
723
682
  function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
724
683
  layout.forEach((size, index) => {
@@ -852,10 +811,6 @@ function debounce(callback, durationMs = 10) {
852
811
  return callable;
853
812
  }
854
813
 
855
- function getPanelElementsForGroup(groupId) {
856
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
857
- }
858
-
859
814
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
860
815
  // or on a browser with cookies/storage disabled.
861
816
  // In either case, this function avoids accessing localStorage until needed,
@@ -911,15 +866,6 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
911
866
  } catch (error) {}
912
867
  return null;
913
868
  }
914
- function loadPanelLayout(autoSaveId, panels, storage) {
915
- const state = loadSerializedPanelGroupState(autoSaveId, storage);
916
- if (state) {
917
- var _state$key;
918
- const key = getSerializationKey(panels);
919
- return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
920
- }
921
- return null;
922
- }
923
869
  function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
924
870
  const key = getSerializationKey(panels);
925
871
  const state = loadSerializedPanelGroupState(autoSaveId, storage) || {};
@@ -1069,6 +1015,7 @@ function PanelGroupWithForwardedRef({
1069
1015
  const groupId = useUniqueId(idFromProps);
1070
1016
  const [dragState, setDragState] = useState(null);
1071
1017
  const [layout, setLayout] = useState([]);
1018
+ useState([]);
1072
1019
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1073
1020
  const panelSizeBeforeCollapseRef = useRef(new Map());
1074
1021
  const prevDeltaRef = useRef(0);
@@ -1083,7 +1030,8 @@ function PanelGroupWithForwardedRef({
1083
1030
  });
1084
1031
  const eagerValuesRef = useRef({
1085
1032
  layout,
1086
- panelDataArray: []
1033
+ panelDataArray: [],
1034
+ panelDataArrayChanged: false
1087
1035
  });
1088
1036
  const devWarningsRef = useRef({
1089
1037
  didLogIdAndOrderWarning: false,
@@ -1216,7 +1164,7 @@ function PanelGroupWithForwardedRef({
1216
1164
  // Store size before collapse;
1217
1165
  // This is the size that gets restored if the expand() API is used.
1218
1166
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1219
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1167
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1220
1168
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1221
1169
  const nextLayout = adjustLayoutByDelta({
1222
1170
  delta,
@@ -1258,7 +1206,7 @@ function PanelGroupWithForwardedRef({
1258
1206
  // Restore this panel to the size it was before it was collapsed, if possible.
1259
1207
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1260
1208
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1261
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1209
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1262
1210
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1263
1211
  const nextLayout = adjustLayoutByDelta({
1264
1212
  delta,
@@ -1297,7 +1245,7 @@ function PanelGroupWithForwardedRef({
1297
1245
  const {
1298
1246
  panelDataArray
1299
1247
  } = eagerValuesRef.current;
1300
- const panelIndex = panelDataArray.indexOf(panelData);
1248
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1301
1249
  return computePanelFlexBoxStyle({
1302
1250
  dragState,
1303
1251
  layout,
@@ -1336,13 +1284,6 @@ function PanelGroupWithForwardedRef({
1336
1284
  }, []);
1337
1285
  const registerPanel = useCallback(panelData => {
1338
1286
  const {
1339
- autoSaveId,
1340
- id: groupId,
1341
- onLayout,
1342
- storage
1343
- } = committedValuesRef.current;
1344
- const {
1345
- layout: prevLayout,
1346
1287
  panelDataArray
1347
1288
  } = eagerValuesRef.current;
1348
1289
  panelDataArray.push(panelData);
@@ -1359,44 +1300,7 @@ function PanelGroupWithForwardedRef({
1359
1300
  return orderA - orderB;
1360
1301
  }
1361
1302
  });
1362
-
1363
- // Wait until all panels have registered before we try to compute layout;
1364
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1365
- const panelElements = getPanelElementsForGroup(groupId);
1366
- if (panelElements.length !== panelDataArray.length) {
1367
- return;
1368
- }
1369
-
1370
- // If this panel has been configured to persist sizing information,
1371
- // default size should be restored from local storage if possible.
1372
- let unsafeLayout = null;
1373
- if (autoSaveId) {
1374
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1375
- }
1376
- if (unsafeLayout == null) {
1377
- unsafeLayout = calculateUnsafeDefaultLayout({
1378
- panelDataArray
1379
- });
1380
- }
1381
-
1382
- // Validate even saved layouts in case something has changed since last render
1383
- // e.g. for pixel groups, this could be the size of the window
1384
- const nextLayout = validatePanelGroupLayout({
1385
- layout: unsafeLayout,
1386
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1387
- });
1388
-
1389
- // Offscreen mode makes this a bit weird;
1390
- // Panels unregister when hidden and re-register when shown again,
1391
- // but the overall layout doesn't change between these two cases.
1392
- setLayout(nextLayout);
1393
- eagerValuesRef.current.layout = nextLayout;
1394
- if (!areEqual(prevLayout, nextLayout)) {
1395
- if (onLayout) {
1396
- onLayout(nextLayout);
1397
- }
1398
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1399
- }
1303
+ eagerValuesRef.current.panelDataArrayChanged = true;
1400
1304
  }, []);
1401
1305
  const registerResizeHandle = useCallback(dragHandleId => {
1402
1306
  return function resizeHandler(event) {
@@ -1486,7 +1390,7 @@ function PanelGroupWithForwardedRef({
1486
1390
  pivotIndices
1487
1391
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1488
1392
  assert(panelSize != null);
1489
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1393
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1490
1394
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1491
1395
  const nextLayout = adjustLayoutByDelta({
1492
1396
  delta,
@@ -1525,79 +1429,21 @@ function PanelGroupWithForwardedRef({
1525
1429
  resetGlobalCursorStyle();
1526
1430
  setDragState(null);
1527
1431
  }, []);
1528
- const unregisterPanelRef = useRef({
1529
- pendingPanelIds: new Set(),
1530
- timeout: null
1531
- });
1532
1432
  const unregisterPanel = useCallback(panelData => {
1533
1433
  const {
1534
- onLayout
1535
- } = committedValuesRef.current;
1536
- const {
1537
- layout: prevLayout,
1538
1434
  panelDataArray
1539
1435
  } = eagerValuesRef.current;
1540
- const index = panelDataArray.indexOf(panelData);
1436
+ const index = findPanelDataIndex(panelDataArray, panelData);
1541
1437
  if (index >= 0) {
1542
1438
  panelDataArray.splice(index, 1);
1543
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1544
- }
1545
- if (unregisterPanelRef.current.timeout != null) {
1546
- clearTimeout(unregisterPanelRef.current.timeout);
1547
- }
1548
-
1549
- // Batch panel unmounts so that we only calculate layout once;
1550
- // This is more efficient and avoids misleading warnings in development mode.
1551
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1552
- unregisterPanelRef.current.timeout = setTimeout(() => {
1553
- const {
1554
- pendingPanelIds
1555
- } = unregisterPanelRef.current;
1556
- const map = panelIdToLastNotifiedSizeMapRef.current;
1557
1439
 
1558
1440
  // TRICKY
1559
- // Strict effects mode
1560
- let unmountDueToStrictMode = false;
1561
- pendingPanelIds.forEach(panelId => {
1562
- pendingPanelIds.delete(panelId);
1563
- if (panelDataArray.find(({
1564
- id
1565
- }) => id === panelId) != null) {
1566
- unmountDueToStrictMode = true;
1567
-
1568
- // TRICKY
1569
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1570
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1571
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1572
- delete map[panelData.id];
1573
- }
1574
- });
1575
- if (!unmountDueToStrictMode) {
1576
- return;
1577
- }
1578
- if (panelDataArray.length === 0) {
1579
- // The group is unmounting; skip layout calculation.
1580
- return;
1581
- }
1582
- let unsafeLayout = calculateUnsafeDefaultLayout({
1583
- panelDataArray
1584
- });
1585
-
1586
- // Validate even saved layouts in case something has changed since last render
1587
- // e.g. for pixel groups, this could be the size of the window
1588
- const nextLayout = validatePanelGroupLayout({
1589
- layout: unsafeLayout,
1590
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1591
- });
1592
- if (!areEqual(prevLayout, nextLayout)) {
1593
- setLayout(nextLayout);
1594
- eagerValuesRef.current.layout = nextLayout;
1595
- if (onLayout) {
1596
- onLayout(nextLayout);
1597
- }
1598
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1599
- }
1600
- }, 0);
1441
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1442
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1443
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1444
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1445
+ eagerValuesRef.current.panelDataArrayChanged = true;
1446
+ }
1601
1447
  }, []);
1602
1448
  const context = useMemo(() => ({
1603
1449
  collapsePanel,
@@ -1645,9 +1491,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1645
1491
  }));
1646
1492
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1647
1493
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1494
+ function findPanelDataIndex(panelDataArray, panelData) {
1495
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1496
+ }
1648
1497
  function panelDataHelper(panelDataArray, panelData, layout) {
1649
1498
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1650
- const panelIndex = panelDataArray.indexOf(panelData);
1499
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1651
1500
  const panelConstraints = panelConstraintsArray[panelIndex];
1652
1501
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1653
1502
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -654,47 +654,6 @@ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragSta
654
654
  }
655
655
  }
656
656
 
657
- function calculateUnsafeDefaultLayout({
658
- panelDataArray
659
- }) {
660
- const layout = Array(panelDataArray.length);
661
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
662
- let numPanelsWithSizes = 0;
663
- let remainingSize = 100;
664
-
665
- // Distribute default sizes first
666
- for (let index = 0; index < panelDataArray.length; index++) {
667
- const panelConstraints = panelConstraintsArray[index];
668
- assert(panelConstraints);
669
- const {
670
- defaultSize
671
- } = panelConstraints;
672
- if (defaultSize != null) {
673
- numPanelsWithSizes++;
674
- layout[index] = defaultSize;
675
- remainingSize -= defaultSize;
676
- }
677
- }
678
-
679
- // Remaining size should be distributed evenly between panels without default sizes
680
- for (let index = 0; index < panelDataArray.length; index++) {
681
- const panelConstraints = panelConstraintsArray[index];
682
- assert(panelConstraints);
683
- const {
684
- defaultSize
685
- } = panelConstraints;
686
- if (defaultSize != null) {
687
- continue;
688
- }
689
- const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
690
- const size = remainingSize / numRemainingPanels;
691
- numPanelsWithSizes++;
692
- layout[index] = size;
693
- remainingSize -= size;
694
- }
695
- return layout;
696
- }
697
-
698
657
  // Layout should be pre-converted into percentages
699
658
  function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
700
659
  layout.forEach((size, index) => {
@@ -828,10 +787,6 @@ function debounce(callback, durationMs = 10) {
828
787
  return callable;
829
788
  }
830
789
 
831
- function getPanelElementsForGroup(groupId) {
832
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
833
- }
834
-
835
790
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
836
791
  // or on a browser with cookies/storage disabled.
837
792
  // In either case, this function avoids accessing localStorage until needed,
@@ -887,15 +842,6 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
887
842
  } catch (error) {}
888
843
  return null;
889
844
  }
890
- function loadPanelLayout(autoSaveId, panels, storage) {
891
- const state = loadSerializedPanelGroupState(autoSaveId, storage);
892
- if (state) {
893
- var _state$key;
894
- const key = getSerializationKey(panels);
895
- return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
896
- }
897
- return null;
898
- }
899
845
  function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
900
846
  const key = getSerializationKey(panels);
901
847
  const state = loadSerializedPanelGroupState(autoSaveId, storage) || {};
@@ -1045,6 +991,7 @@ function PanelGroupWithForwardedRef({
1045
991
  const groupId = useUniqueId(idFromProps);
1046
992
  const [dragState, setDragState] = useState(null);
1047
993
  const [layout, setLayout] = useState([]);
994
+ useState([]);
1048
995
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1049
996
  const panelSizeBeforeCollapseRef = useRef(new Map());
1050
997
  const prevDeltaRef = useRef(0);
@@ -1059,7 +1006,8 @@ function PanelGroupWithForwardedRef({
1059
1006
  });
1060
1007
  const eagerValuesRef = useRef({
1061
1008
  layout,
1062
- panelDataArray: []
1009
+ panelDataArray: [],
1010
+ panelDataArrayChanged: false
1063
1011
  });
1064
1012
  const devWarningsRef = useRef({
1065
1013
  didLogIdAndOrderWarning: false,
@@ -1192,7 +1140,7 @@ function PanelGroupWithForwardedRef({
1192
1140
  // Store size before collapse;
1193
1141
  // This is the size that gets restored if the expand() API is used.
1194
1142
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1195
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1143
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1196
1144
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1197
1145
  const nextLayout = adjustLayoutByDelta({
1198
1146
  delta,
@@ -1234,7 +1182,7 @@ function PanelGroupWithForwardedRef({
1234
1182
  // Restore this panel to the size it was before it was collapsed, if possible.
1235
1183
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1236
1184
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1237
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1185
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1238
1186
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1239
1187
  const nextLayout = adjustLayoutByDelta({
1240
1188
  delta,
@@ -1273,7 +1221,7 @@ function PanelGroupWithForwardedRef({
1273
1221
  const {
1274
1222
  panelDataArray
1275
1223
  } = eagerValuesRef.current;
1276
- const panelIndex = panelDataArray.indexOf(panelData);
1224
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1277
1225
  return computePanelFlexBoxStyle({
1278
1226
  dragState,
1279
1227
  layout,
@@ -1312,13 +1260,6 @@ function PanelGroupWithForwardedRef({
1312
1260
  }, []);
1313
1261
  const registerPanel = useCallback(panelData => {
1314
1262
  const {
1315
- autoSaveId,
1316
- id: groupId,
1317
- onLayout,
1318
- storage
1319
- } = committedValuesRef.current;
1320
- const {
1321
- layout: prevLayout,
1322
1263
  panelDataArray
1323
1264
  } = eagerValuesRef.current;
1324
1265
  panelDataArray.push(panelData);
@@ -1335,44 +1276,7 @@ function PanelGroupWithForwardedRef({
1335
1276
  return orderA - orderB;
1336
1277
  }
1337
1278
  });
1338
-
1339
- // Wait until all panels have registered before we try to compute layout;
1340
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1341
- const panelElements = getPanelElementsForGroup(groupId);
1342
- if (panelElements.length !== panelDataArray.length) {
1343
- return;
1344
- }
1345
-
1346
- // If this panel has been configured to persist sizing information,
1347
- // default size should be restored from local storage if possible.
1348
- let unsafeLayout = null;
1349
- if (autoSaveId) {
1350
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1351
- }
1352
- if (unsafeLayout == null) {
1353
- unsafeLayout = calculateUnsafeDefaultLayout({
1354
- panelDataArray
1355
- });
1356
- }
1357
-
1358
- // Validate even saved layouts in case something has changed since last render
1359
- // e.g. for pixel groups, this could be the size of the window
1360
- const nextLayout = validatePanelGroupLayout({
1361
- layout: unsafeLayout,
1362
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1363
- });
1364
-
1365
- // Offscreen mode makes this a bit weird;
1366
- // Panels unregister when hidden and re-register when shown again,
1367
- // but the overall layout doesn't change between these two cases.
1368
- setLayout(nextLayout);
1369
- eagerValuesRef.current.layout = nextLayout;
1370
- if (!areEqual(prevLayout, nextLayout)) {
1371
- if (onLayout) {
1372
- onLayout(nextLayout);
1373
- }
1374
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1375
- }
1279
+ eagerValuesRef.current.panelDataArrayChanged = true;
1376
1280
  }, []);
1377
1281
  const registerResizeHandle = useCallback(dragHandleId => {
1378
1282
  return function resizeHandler(event) {
@@ -1462,7 +1366,7 @@ function PanelGroupWithForwardedRef({
1462
1366
  pivotIndices
1463
1367
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1464
1368
  assert(panelSize != null);
1465
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1369
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1466
1370
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1467
1371
  const nextLayout = adjustLayoutByDelta({
1468
1372
  delta,
@@ -1501,79 +1405,21 @@ function PanelGroupWithForwardedRef({
1501
1405
  resetGlobalCursorStyle();
1502
1406
  setDragState(null);
1503
1407
  }, []);
1504
- const unregisterPanelRef = useRef({
1505
- pendingPanelIds: new Set(),
1506
- timeout: null
1507
- });
1508
1408
  const unregisterPanel = useCallback(panelData => {
1509
1409
  const {
1510
- onLayout
1511
- } = committedValuesRef.current;
1512
- const {
1513
- layout: prevLayout,
1514
1410
  panelDataArray
1515
1411
  } = eagerValuesRef.current;
1516
- const index = panelDataArray.indexOf(panelData);
1412
+ const index = findPanelDataIndex(panelDataArray, panelData);
1517
1413
  if (index >= 0) {
1518
1414
  panelDataArray.splice(index, 1);
1519
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1520
- }
1521
- if (unregisterPanelRef.current.timeout != null) {
1522
- clearTimeout(unregisterPanelRef.current.timeout);
1523
- }
1524
-
1525
- // Batch panel unmounts so that we only calculate layout once;
1526
- // This is more efficient and avoids misleading warnings in development mode.
1527
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1528
- unregisterPanelRef.current.timeout = setTimeout(() => {
1529
- const {
1530
- pendingPanelIds
1531
- } = unregisterPanelRef.current;
1532
- const map = panelIdToLastNotifiedSizeMapRef.current;
1533
1415
 
1534
1416
  // TRICKY
1535
- // Strict effects mode
1536
- let unmountDueToStrictMode = false;
1537
- pendingPanelIds.forEach(panelId => {
1538
- pendingPanelIds.delete(panelId);
1539
- if (panelDataArray.find(({
1540
- id
1541
- }) => id === panelId) != null) {
1542
- unmountDueToStrictMode = true;
1543
-
1544
- // TRICKY
1545
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1546
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1547
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1548
- delete map[panelData.id];
1549
- }
1550
- });
1551
- if (!unmountDueToStrictMode) {
1552
- return;
1553
- }
1554
- if (panelDataArray.length === 0) {
1555
- // The group is unmounting; skip layout calculation.
1556
- return;
1557
- }
1558
- let unsafeLayout = calculateUnsafeDefaultLayout({
1559
- panelDataArray
1560
- });
1561
-
1562
- // Validate even saved layouts in case something has changed since last render
1563
- // e.g. for pixel groups, this could be the size of the window
1564
- const nextLayout = validatePanelGroupLayout({
1565
- layout: unsafeLayout,
1566
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1567
- });
1568
- if (!areEqual(prevLayout, nextLayout)) {
1569
- setLayout(nextLayout);
1570
- eagerValuesRef.current.layout = nextLayout;
1571
- if (onLayout) {
1572
- onLayout(nextLayout);
1573
- }
1574
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1575
- }
1576
- }, 0);
1417
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1418
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1419
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1420
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1421
+ eagerValuesRef.current.panelDataArrayChanged = true;
1422
+ }
1577
1423
  }, []);
1578
1424
  const context = useMemo(() => ({
1579
1425
  collapsePanel,
@@ -1621,9 +1467,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1621
1467
  }));
1622
1468
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1623
1469
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1470
+ function findPanelDataIndex(panelDataArray, panelData) {
1471
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1472
+ }
1624
1473
  function panelDataHelper(panelDataArray, panelData, layout) {
1625
1474
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1626
- const panelIndex = panelDataArray.indexOf(panelData);
1475
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1627
1476
  const panelConstraints = panelConstraintsArray[panelIndex];
1628
1477
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1629
1478
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];