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.
@@ -929,10 +929,6 @@ function debounce(callback, durationMs = 10) {
929
929
  return callable;
930
930
  }
931
931
 
932
- function getPanelElementsForGroup(groupId) {
933
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
934
- }
935
-
936
932
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
937
933
  // or on a browser with cookies/storage disabled.
938
934
  // In either case, this function avoids accessing localStorage until needed,
@@ -1146,6 +1142,7 @@ function PanelGroupWithForwardedRef({
1146
1142
  const groupId = useUniqueId(idFromProps);
1147
1143
  const [dragState, setDragState] = useState(null);
1148
1144
  const [layout, setLayout] = useState([]);
1145
+ useState([]);
1149
1146
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1150
1147
  const panelSizeBeforeCollapseRef = useRef(new Map());
1151
1148
  const prevDeltaRef = useRef(0);
@@ -1160,7 +1157,8 @@ function PanelGroupWithForwardedRef({
1160
1157
  });
1161
1158
  const eagerValuesRef = useRef({
1162
1159
  layout,
1163
- panelDataArray: []
1160
+ panelDataArray: [],
1161
+ panelDataArrayChanged: false
1164
1162
  });
1165
1163
  const devWarningsRef = useRef({
1166
1164
  didLogIdAndOrderWarning: false,
@@ -1301,7 +1299,7 @@ function PanelGroupWithForwardedRef({
1301
1299
  // Store size before collapse;
1302
1300
  // This is the size that gets restored if the expand() API is used.
1303
1301
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1304
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1302
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1305
1303
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1306
1304
  const nextLayout = adjustLayoutByDelta({
1307
1305
  delta,
@@ -1343,7 +1341,7 @@ function PanelGroupWithForwardedRef({
1343
1341
  // Restore this panel to the size it was before it was collapsed, if possible.
1344
1342
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1345
1343
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1346
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1344
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1347
1345
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1348
1346
  const nextLayout = adjustLayoutByDelta({
1349
1347
  delta,
@@ -1382,7 +1380,7 @@ function PanelGroupWithForwardedRef({
1382
1380
  const {
1383
1381
  panelDataArray
1384
1382
  } = eagerValuesRef.current;
1385
- const panelIndex = panelDataArray.indexOf(panelData);
1383
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1386
1384
  return computePanelFlexBoxStyle({
1387
1385
  dragState,
1388
1386
  layout,
@@ -1421,13 +1419,6 @@ function PanelGroupWithForwardedRef({
1421
1419
  }, []);
1422
1420
  const registerPanel = useCallback(panelData => {
1423
1421
  const {
1424
- autoSaveId,
1425
- id: groupId,
1426
- onLayout,
1427
- storage
1428
- } = committedValuesRef.current;
1429
- const {
1430
- layout: prevLayout,
1431
1422
  panelDataArray
1432
1423
  } = eagerValuesRef.current;
1433
1424
  panelDataArray.push(panelData);
@@ -1444,45 +1435,52 @@ function PanelGroupWithForwardedRef({
1444
1435
  return orderA - orderB;
1445
1436
  }
1446
1437
  });
1438
+ eagerValuesRef.current.panelDataArrayChanged = true;
1439
+ }, []);
1447
1440
 
1448
- // Wait until all panels have registered before we try to compute layout;
1449
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1450
- const panelElements = getPanelElementsForGroup(groupId);
1451
- if (panelElements.length !== panelDataArray.length) {
1452
- return;
1453
- }
1454
-
1455
- // If this panel has been configured to persist sizing information,
1456
- // default size should be restored from local storage if possible.
1457
- let unsafeLayout = null;
1458
- if (autoSaveId) {
1459
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1460
- }
1461
- if (unsafeLayout == null) {
1462
- unsafeLayout = calculateUnsafeDefaultLayout({
1441
+ // (Re)calculate group layout whenever panels are registered or unregistered.
1442
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1443
+ useIsomorphicLayoutEffect(() => {
1444
+ if (eagerValuesRef.current.panelDataArrayChanged) {
1445
+ eagerValuesRef.current.panelDataArrayChanged = false;
1446
+ const {
1447
+ autoSaveId,
1448
+ onLayout,
1449
+ storage
1450
+ } = committedValuesRef.current;
1451
+ const {
1452
+ layout: prevLayout,
1463
1453
  panelDataArray
1464
- });
1465
- }
1454
+ } = eagerValuesRef.current;
1466
1455
 
1467
- // Validate even saved layouts in case something has changed since last render
1468
- // e.g. for pixel groups, this could be the size of the window
1469
- const nextLayout = validatePanelGroupLayout({
1470
- layout: unsafeLayout,
1471
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1472
- });
1456
+ // If this panel has been configured to persist sizing information,
1457
+ // default size should be restored from local storage if possible.
1458
+ let unsafeLayout = null;
1459
+ if (autoSaveId) {
1460
+ unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1461
+ }
1462
+ if (unsafeLayout == null) {
1463
+ unsafeLayout = calculateUnsafeDefaultLayout({
1464
+ panelDataArray
1465
+ });
1466
+ }
1473
1467
 
1474
- // Offscreen mode makes this a bit weird;
1475
- // Panels unregister when hidden and re-register when shown again,
1476
- // but the overall layout doesn't change between these two cases.
1477
- setLayout(nextLayout);
1478
- eagerValuesRef.current.layout = nextLayout;
1479
- if (!areEqual(prevLayout, nextLayout)) {
1480
- if (onLayout) {
1481
- onLayout(nextLayout);
1468
+ // Validate even saved layouts in case something has changed since last render
1469
+ // e.g. for pixel groups, this could be the size of the window
1470
+ const nextLayout = validatePanelGroupLayout({
1471
+ layout: unsafeLayout,
1472
+ panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1473
+ });
1474
+ if (!areEqual(prevLayout, nextLayout)) {
1475
+ setLayout(nextLayout);
1476
+ eagerValuesRef.current.layout = nextLayout;
1477
+ if (onLayout) {
1478
+ onLayout(nextLayout);
1479
+ }
1480
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1482
1481
  }
1483
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1484
1482
  }
1485
- }, []);
1483
+ });
1486
1484
  const registerResizeHandle = useCallback(dragHandleId => {
1487
1485
  return function resizeHandler(event) {
1488
1486
  event.preventDefault();
@@ -1571,7 +1569,7 @@ function PanelGroupWithForwardedRef({
1571
1569
  pivotIndices
1572
1570
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1573
1571
  assert(panelSize != null);
1574
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1572
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1575
1573
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1576
1574
  const nextLayout = adjustLayoutByDelta({
1577
1575
  delta,
@@ -1610,79 +1608,21 @@ function PanelGroupWithForwardedRef({
1610
1608
  resetGlobalCursorStyle();
1611
1609
  setDragState(null);
1612
1610
  }, []);
1613
- const unregisterPanelRef = useRef({
1614
- pendingPanelIds: new Set(),
1615
- timeout: null
1616
- });
1617
1611
  const unregisterPanel = useCallback(panelData => {
1618
1612
  const {
1619
- onLayout
1620
- } = committedValuesRef.current;
1621
- const {
1622
- layout: prevLayout,
1623
1613
  panelDataArray
1624
1614
  } = eagerValuesRef.current;
1625
- const index = panelDataArray.indexOf(panelData);
1615
+ const index = findPanelDataIndex(panelDataArray, panelData);
1626
1616
  if (index >= 0) {
1627
1617
  panelDataArray.splice(index, 1);
1628
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1629
- }
1630
- if (unregisterPanelRef.current.timeout != null) {
1631
- clearTimeout(unregisterPanelRef.current.timeout);
1632
- }
1633
-
1634
- // Batch panel unmounts so that we only calculate layout once;
1635
- // This is more efficient and avoids misleading warnings in development mode.
1636
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1637
- unregisterPanelRef.current.timeout = setTimeout(() => {
1638
- const {
1639
- pendingPanelIds
1640
- } = unregisterPanelRef.current;
1641
- const map = panelIdToLastNotifiedSizeMapRef.current;
1642
1618
 
1643
1619
  // TRICKY
1644
- // Strict effects mode
1645
- let unmountDueToStrictMode = false;
1646
- pendingPanelIds.forEach(panelId => {
1647
- pendingPanelIds.delete(panelId);
1648
- if (panelDataArray.find(({
1649
- id
1650
- }) => id === panelId) != null) {
1651
- unmountDueToStrictMode = true;
1652
-
1653
- // TRICKY
1654
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1655
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1656
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1657
- delete map[panelData.id];
1658
- }
1659
- });
1660
- if (!unmountDueToStrictMode) {
1661
- return;
1662
- }
1663
- if (panelDataArray.length === 0) {
1664
- // The group is unmounting; skip layout calculation.
1665
- return;
1666
- }
1667
- let unsafeLayout = calculateUnsafeDefaultLayout({
1668
- panelDataArray
1669
- });
1670
-
1671
- // Validate even saved layouts in case something has changed since last render
1672
- // e.g. for pixel groups, this could be the size of the window
1673
- const nextLayout = validatePanelGroupLayout({
1674
- layout: unsafeLayout,
1675
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1676
- });
1677
- if (!areEqual(prevLayout, nextLayout)) {
1678
- setLayout(nextLayout);
1679
- eagerValuesRef.current.layout = nextLayout;
1680
- if (onLayout) {
1681
- onLayout(nextLayout);
1682
- }
1683
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1684
- }
1685
- }, 0);
1620
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1621
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1622
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1623
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1624
+ eagerValuesRef.current.panelDataArrayChanged = true;
1625
+ }
1686
1626
  }, []);
1687
1627
  const context = useMemo(() => ({
1688
1628
  collapsePanel,
@@ -1730,9 +1670,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1730
1670
  }));
1731
1671
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1732
1672
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1673
+ function findPanelDataIndex(panelDataArray, panelData) {
1674
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1675
+ }
1733
1676
  function panelDataHelper(panelDataArray, panelData, layout) {
1734
1677
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1735
- const panelIndex = panelDataArray.indexOf(panelData);
1678
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1736
1679
  const panelConstraints = panelConstraintsArray[panelIndex];
1737
1680
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1738
1681
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -913,10 +913,6 @@ function debounce(callback, durationMs = 10) {
913
913
  return callable;
914
914
  }
915
915
 
916
- function getPanelElementsForGroup(groupId) {
917
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
918
- }
919
-
920
916
  // PanelGroup might be rendering in a server-side environment where localStorage is not available
921
917
  // or on a browser with cookies/storage disabled.
922
918
  // In either case, this function avoids accessing localStorage until needed,
@@ -1083,6 +1079,7 @@ function PanelGroupWithForwardedRef({
1083
1079
  const groupId = useUniqueId(idFromProps);
1084
1080
  const [dragState, setDragState] = useState(null);
1085
1081
  const [layout, setLayout] = useState([]);
1082
+ useState([]);
1086
1083
  const panelIdToLastNotifiedSizeMapRef = useRef({});
1087
1084
  const panelSizeBeforeCollapseRef = useRef(new Map());
1088
1085
  const prevDeltaRef = useRef(0);
@@ -1097,7 +1094,8 @@ function PanelGroupWithForwardedRef({
1097
1094
  });
1098
1095
  const eagerValuesRef = useRef({
1099
1096
  layout,
1100
- panelDataArray: []
1097
+ panelDataArray: [],
1098
+ panelDataArrayChanged: false
1101
1099
  });
1102
1100
  useRef({
1103
1101
  didLogIdAndOrderWarning: false,
@@ -1196,7 +1194,7 @@ function PanelGroupWithForwardedRef({
1196
1194
  // Store size before collapse;
1197
1195
  // This is the size that gets restored if the expand() API is used.
1198
1196
  panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1199
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1197
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1200
1198
  const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1201
1199
  const nextLayout = adjustLayoutByDelta({
1202
1200
  delta,
@@ -1238,7 +1236,7 @@ function PanelGroupWithForwardedRef({
1238
1236
  // Restore this panel to the size it was before it was collapsed, if possible.
1239
1237
  const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1240
1238
  const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1241
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1239
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1242
1240
  const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1243
1241
  const nextLayout = adjustLayoutByDelta({
1244
1242
  delta,
@@ -1277,7 +1275,7 @@ function PanelGroupWithForwardedRef({
1277
1275
  const {
1278
1276
  panelDataArray
1279
1277
  } = eagerValuesRef.current;
1280
- const panelIndex = panelDataArray.indexOf(panelData);
1278
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1281
1279
  return computePanelFlexBoxStyle({
1282
1280
  dragState,
1283
1281
  layout,
@@ -1316,13 +1314,6 @@ function PanelGroupWithForwardedRef({
1316
1314
  }, []);
1317
1315
  const registerPanel = useCallback(panelData => {
1318
1316
  const {
1319
- autoSaveId,
1320
- id: groupId,
1321
- onLayout,
1322
- storage
1323
- } = committedValuesRef.current;
1324
- const {
1325
- layout: prevLayout,
1326
1317
  panelDataArray
1327
1318
  } = eagerValuesRef.current;
1328
1319
  panelDataArray.push(panelData);
@@ -1339,45 +1330,52 @@ function PanelGroupWithForwardedRef({
1339
1330
  return orderA - orderB;
1340
1331
  }
1341
1332
  });
1333
+ eagerValuesRef.current.panelDataArrayChanged = true;
1334
+ }, []);
1342
1335
 
1343
- // Wait until all panels have registered before we try to compute layout;
1344
- // doing it earlier is both wasteful and may trigger misleading warnings in development mode.
1345
- const panelElements = getPanelElementsForGroup(groupId);
1346
- if (panelElements.length !== panelDataArray.length) {
1347
- return;
1348
- }
1349
-
1350
- // If this panel has been configured to persist sizing information,
1351
- // default size should be restored from local storage if possible.
1352
- let unsafeLayout = null;
1353
- if (autoSaveId) {
1354
- unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1355
- }
1356
- if (unsafeLayout == null) {
1357
- unsafeLayout = calculateUnsafeDefaultLayout({
1336
+ // (Re)calculate group layout whenever panels are registered or unregistered.
1337
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1338
+ useIsomorphicLayoutEffect(() => {
1339
+ if (eagerValuesRef.current.panelDataArrayChanged) {
1340
+ eagerValuesRef.current.panelDataArrayChanged = false;
1341
+ const {
1342
+ autoSaveId,
1343
+ onLayout,
1344
+ storage
1345
+ } = committedValuesRef.current;
1346
+ const {
1347
+ layout: prevLayout,
1358
1348
  panelDataArray
1359
- });
1360
- }
1349
+ } = eagerValuesRef.current;
1361
1350
 
1362
- // Validate even saved layouts in case something has changed since last render
1363
- // e.g. for pixel groups, this could be the size of the window
1364
- const nextLayout = validatePanelGroupLayout({
1365
- layout: unsafeLayout,
1366
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1367
- });
1351
+ // If this panel has been configured to persist sizing information,
1352
+ // default size should be restored from local storage if possible.
1353
+ let unsafeLayout = null;
1354
+ if (autoSaveId) {
1355
+ unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1356
+ }
1357
+ if (unsafeLayout == null) {
1358
+ unsafeLayout = calculateUnsafeDefaultLayout({
1359
+ panelDataArray
1360
+ });
1361
+ }
1368
1362
 
1369
- // Offscreen mode makes this a bit weird;
1370
- // Panels unregister when hidden and re-register when shown again,
1371
- // but the overall layout doesn't change between these two cases.
1372
- setLayout(nextLayout);
1373
- eagerValuesRef.current.layout = nextLayout;
1374
- if (!areEqual(prevLayout, nextLayout)) {
1375
- if (onLayout) {
1376
- onLayout(nextLayout);
1363
+ // Validate even saved layouts in case something has changed since last render
1364
+ // e.g. for pixel groups, this could be the size of the window
1365
+ const nextLayout = validatePanelGroupLayout({
1366
+ layout: unsafeLayout,
1367
+ panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1368
+ });
1369
+ if (!areEqual(prevLayout, nextLayout)) {
1370
+ setLayout(nextLayout);
1371
+ eagerValuesRef.current.layout = nextLayout;
1372
+ if (onLayout) {
1373
+ onLayout(nextLayout);
1374
+ }
1375
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1377
1376
  }
1378
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1379
1377
  }
1380
- }, []);
1378
+ });
1381
1379
  const registerResizeHandle = useCallback(dragHandleId => {
1382
1380
  return function resizeHandler(event) {
1383
1381
  event.preventDefault();
@@ -1466,7 +1464,7 @@ function PanelGroupWithForwardedRef({
1466
1464
  pivotIndices
1467
1465
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1468
1466
  assert(panelSize != null);
1469
- const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1467
+ const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1470
1468
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1471
1469
  const nextLayout = adjustLayoutByDelta({
1472
1470
  delta,
@@ -1505,79 +1503,21 @@ function PanelGroupWithForwardedRef({
1505
1503
  resetGlobalCursorStyle();
1506
1504
  setDragState(null);
1507
1505
  }, []);
1508
- const unregisterPanelRef = useRef({
1509
- pendingPanelIds: new Set(),
1510
- timeout: null
1511
- });
1512
1506
  const unregisterPanel = useCallback(panelData => {
1513
1507
  const {
1514
- onLayout
1515
- } = committedValuesRef.current;
1516
- const {
1517
- layout: prevLayout,
1518
1508
  panelDataArray
1519
1509
  } = eagerValuesRef.current;
1520
- const index = panelDataArray.indexOf(panelData);
1510
+ const index = findPanelDataIndex(panelDataArray, panelData);
1521
1511
  if (index >= 0) {
1522
1512
  panelDataArray.splice(index, 1);
1523
- unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
1524
- }
1525
- if (unregisterPanelRef.current.timeout != null) {
1526
- clearTimeout(unregisterPanelRef.current.timeout);
1527
- }
1528
-
1529
- // Batch panel unmounts so that we only calculate layout once;
1530
- // This is more efficient and avoids misleading warnings in development mode.
1531
- // We can't check the DOM to detect this because Panel elements have not yet been removed.
1532
- unregisterPanelRef.current.timeout = setTimeout(() => {
1533
- const {
1534
- pendingPanelIds
1535
- } = unregisterPanelRef.current;
1536
- const map = panelIdToLastNotifiedSizeMapRef.current;
1537
1513
 
1538
1514
  // TRICKY
1539
- // Strict effects mode
1540
- let unmountDueToStrictMode = false;
1541
- pendingPanelIds.forEach(panelId => {
1542
- pendingPanelIds.delete(panelId);
1543
- if (panelDataArray.find(({
1544
- id
1545
- }) => id === panelId) != null) {
1546
- unmountDueToStrictMode = true;
1547
-
1548
- // TRICKY
1549
- // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1550
- // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1551
- // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1552
- delete map[panelData.id];
1553
- }
1554
- });
1555
- if (!unmountDueToStrictMode) {
1556
- return;
1557
- }
1558
- if (panelDataArray.length === 0) {
1559
- // The group is unmounting; skip layout calculation.
1560
- return;
1561
- }
1562
- let unsafeLayout = calculateUnsafeDefaultLayout({
1563
- panelDataArray
1564
- });
1565
-
1566
- // Validate even saved layouts in case something has changed since last render
1567
- // e.g. for pixel groups, this could be the size of the window
1568
- const nextLayout = validatePanelGroupLayout({
1569
- layout: unsafeLayout,
1570
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1571
- });
1572
- if (!areEqual(prevLayout, nextLayout)) {
1573
- setLayout(nextLayout);
1574
- eagerValuesRef.current.layout = nextLayout;
1575
- if (onLayout) {
1576
- onLayout(nextLayout);
1577
- }
1578
- callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1579
- }
1580
- }, 0);
1515
+ // When a panel is removed from the group, we should delete the most recent prev-size entry for it.
1516
+ // If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
1517
+ // Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
1518
+ delete panelIdToLastNotifiedSizeMapRef.current[panelData.id];
1519
+ eagerValuesRef.current.panelDataArrayChanged = true;
1520
+ }
1581
1521
  }, []);
1582
1522
  const context = useMemo(() => ({
1583
1523
  collapsePanel,
@@ -1625,9 +1565,12 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1625
1565
  }));
1626
1566
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1627
1567
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1568
+ function findPanelDataIndex(panelDataArray, panelData) {
1569
+ return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1570
+ }
1628
1571
  function panelDataHelper(panelDataArray, panelData, layout) {
1629
1572
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1630
- const panelIndex = panelDataArray.indexOf(panelData);
1573
+ const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1631
1574
  const panelConstraints = panelConstraintsArray[panelIndex];
1632
1575
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1633
1576
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
@@ -1,89 +1,2 @@
1
- import { CSSProperties, ElementType, HTMLAttributes, PropsWithChildren } from "react";
2
- export type PanelOnCollapse = () => void;
3
- export type PanelOnExpand = () => void;
4
- export type PanelOnResize = (size: number, prevSize: number | undefined) => void;
5
- export type ImperativePanelHandle = {
6
- collapse: () => void;
7
- expand: () => void;
8
- getId(): string;
9
- getSize(): number;
10
- isCollapsed: () => boolean;
11
- isExpanded: () => boolean;
12
- resize: (size: number) => void;
13
- };
14
- export type PanelProps = Omit<HTMLAttributes<ElementType>, "id" | "onResize"> & PropsWithChildren<{
15
- className?: string;
16
- collapsedSize?: number | undefined;
17
- collapsible?: boolean | undefined;
18
- defaultSize?: number | undefined;
19
- id?: string;
20
- maxSize?: number | undefined;
21
- minSize?: number | undefined;
22
- onCollapse?: PanelOnCollapse;
23
- onExpand?: PanelOnExpand;
24
- onResize?: PanelOnResize;
25
- order?: number;
26
- style?: object;
27
- tagName?: ElementType;
28
- }>;
29
- export declare namespace PanelWithForwardedRef {
30
- var displayName: string;
31
- }
32
- export const Panel: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<ElementType>, "id" | "onResize"> & {
33
- className?: string | undefined;
34
- collapsedSize?: number | undefined;
35
- collapsible?: boolean | undefined;
36
- defaultSize?: number | undefined;
37
- id?: string | undefined;
38
- maxSize?: number | undefined;
39
- minSize?: number | undefined;
40
- onCollapse?: PanelOnCollapse | undefined;
41
- onExpand?: PanelOnExpand | undefined;
42
- onResize?: PanelOnResize | undefined;
43
- order?: number | undefined;
44
- style?: object | undefined;
45
- tagName?: ElementType | undefined;
46
- } & {
47
- children?: import("react").ReactNode;
48
- } & import("react").RefAttributes<ImperativePanelHandle>>;
49
- type Direction = "horizontal" | "vertical";
50
- export function assert(expectedCondition: any, message?: string): asserts expectedCondition;
51
- export type ImperativePanelGroupHandle = {
52
- getId: () => string;
53
- getLayout: () => number[];
54
- setLayout: (layout: number[]) => void;
55
- };
56
- export type PanelGroupStorage = {
57
- getItem(name: string): string | null;
58
- setItem(name: string, value: string): void;
59
- };
60
- export type PanelGroupOnLayout = (layout: number[]) => void;
61
- export type PanelGroupProps = Omit<HTMLAttributes<ElementType>, "id"> & PropsWithChildren<{
62
- autoSaveId?: string | null;
63
- className?: string;
64
- direction: Direction;
65
- id?: string | null;
66
- keyboardResizeBy?: number | null;
67
- onLayout?: PanelGroupOnLayout | null;
68
- storage?: PanelGroupStorage;
69
- style?: CSSProperties;
70
- tagName?: ElementType;
71
- }>;
72
- export const PanelGroup: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<ElementType>, "id"> & {
73
- autoSaveId?: string | null | undefined;
74
- className?: string | undefined;
75
- direction: Direction;
76
- id?: string | null | undefined;
77
- keyboardResizeBy?: number | null | undefined;
78
- onLayout?: PanelGroupOnLayout | null | undefined;
79
- storage?: PanelGroupStorage | undefined;
80
- style?: CSSProperties | undefined;
81
- tagName?: ElementType | undefined;
82
- } & {
83
- children?: import("react").ReactNode;
84
- } & import("react").RefAttributes<ImperativePanelGroupHandle>>;
85
- export declare namespace PanelResizeHandle {
86
- var displayName: string;
87
- }
88
-
1
+ export * from "./declarations/src/index";
89
2
  //# sourceMappingURL=react-resizable-panels.cjs.d.ts.map
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/react-resizable-panels/src/src/vendor/react.ts","packages/react-resizable-panels/src/src/PanelGroupContext.ts","packages/react-resizable-panels/src/src/hooks/useIsomorphicEffect.ts","packages/react-resizable-panels/src/src/hooks/useUniqueId.ts","packages/react-resizable-panels/src/src/Panel.ts","packages/react-resizable-panels/src/src/types.ts","packages/react-resizable-panels/src/src/utils/assert.ts","packages/react-resizable-panels/src/src/constants.ts","packages/react-resizable-panels/src/src/utils/numbers/fuzzyCompareNumbers.ts","packages/react-resizable-panels/src/src/utils/numbers/fuzzyNumbersEqual.ts","packages/react-resizable-panels/src/src/utils/resizePanel.ts","packages/react-resizable-panels/src/src/utils/adjustLayoutByDelta.ts","packages/react-resizable-panels/src/src/utils/calculateAriaValues.ts","packages/react-resizable-panels/src/src/utils/dom/getResizeHandleElementsForGroup.ts","packages/react-resizable-panels/src/src/utils/dom/getResizeHandleElementIndex.ts","packages/react-resizable-panels/src/src/utils/determinePivotIndices.ts","packages/react-resizable-panels/src/src/utils/dom/getPanelGroupElement.ts","packages/react-resizable-panels/src/src/utils/dom/getResizeHandleElement.ts","packages/react-resizable-panels/src/src/utils/dom/getResizeHandlePanelIds.ts","packages/react-resizable-panels/src/src/hooks/useWindowSplitterPanelGroupBehavior.ts","packages/react-resizable-panels/src/src/utils/arrays.ts","packages/react-resizable-panels/src/src/utils/events.ts","packages/react-resizable-panels/src/src/utils/getResizeEventCursorPosition.ts","packages/react-resizable-panels/src/src/utils/calculateDragOffsetPercentage.ts","packages/react-resizable-panels/src/src/utils/calculateDeltaPercentage.ts","packages/react-resizable-panels/src/src/utils/calculateUnsafeDefaultLayout.ts","packages/react-resizable-panels/src/src/utils/callPanelCallbacks.ts","packages/react-resizable-panels/src/src/utils/compareLayouts.ts","packages/react-resizable-panels/src/src/utils/computePanelFlexBoxStyle.ts","packages/react-resizable-panels/src/src/utils/cursor.ts","packages/react-resizable-panels/src/src/utils/debounce.ts","packages/react-resizable-panels/src/src/utils/dom/getPanelElementsForGroup.ts","packages/react-resizable-panels/src/src/utils/initializeDefaultStorage.ts","packages/react-resizable-panels/src/src/utils/serialization.ts","packages/react-resizable-panels/src/src/utils/validatePanelConstraints.ts","packages/react-resizable-panels/src/src/utils/validatePanelGroupLayout.ts","packages/react-resizable-panels/src/src/PanelGroup.ts","packages/react-resizable-panels/src/src/hooks/useWindowSplitterBehavior.ts","packages/react-resizable-panels/src/src/PanelResizeHandle.ts","packages/react-resizable-panels/src/src/index.ts","packages/react-resizable-panels/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"import { Panel } from \"./Panel\";\nimport { PanelGroup } from \"./PanelGroup\";\nimport { PanelResizeHandle } from \"./PanelResizeHandle\";\nimport { assert } from \"./utils/assert\";\n\nimport type {\n ImperativePanelHandle,\n PanelOnCollapse,\n PanelOnExpand,\n PanelOnResize,\n PanelProps,\n} from \"./Panel\";\nimport type {\n ImperativePanelGroupHandle,\n PanelGroupOnLayout,\n PanelGroupProps,\n PanelGroupStorage,\n} from \"./PanelGroup\";\nimport type {\n PanelResizeHandleOnDragging,\n PanelResizeHandleProps,\n} from \"./PanelResizeHandle\";\n\nexport {\n // TypeScript types\n ImperativePanelGroupHandle,\n ImperativePanelHandle,\n PanelGroupOnLayout,\n PanelGroupProps,\n PanelGroupStorage,\n PanelOnCollapse,\n PanelOnExpand,\n PanelOnResize,\n PanelProps,\n PanelResizeHandleOnDragging,\n PanelResizeHandleProps,\n\n // Utiltiy methods\n assert,\n\n // React components\n Panel,\n PanelGroup,\n PanelResizeHandle,\n};\n"],"names":[],"version":3,"file":"react-resizable-panels.cjs.d.ts.map","sourceRoot":"../../../"}
1
+ {"version":3,"file":"react-resizable-panels.cjs.d.ts","sourceRoot":"","sources":["./declarations/src/index.d.ts"],"names":[],"mappings":"AAAA"}