react-resizable-panels 0.0.59 → 0.0.60
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.
- package/CHANGELOG.md +6 -0
- package/dist/declarations/src/PanelGroup.d.ts +2 -2
- package/dist/react-resizable-panels.browser.cjs.js +177 -143
- package/dist/react-resizable-panels.browser.development.cjs.js +180 -146
- package/dist/react-resizable-panels.browser.development.esm.js +180 -146
- package/dist/react-resizable-panels.browser.esm.js +177 -143
- package/dist/react-resizable-panels.cjs.js +177 -143
- package/dist/react-resizable-panels.cjs.js.map +1 -1
- package/dist/react-resizable-panels.development.cjs.js +180 -146
- package/dist/react-resizable-panels.development.esm.js +180 -146
- package/dist/react-resizable-panels.development.node.cjs.js +226 -66
- package/dist/react-resizable-panels.development.node.esm.js +226 -66
- package/dist/react-resizable-panels.esm.js +177 -143
- package/dist/react-resizable-panels.esm.js.map +1 -1
- package/dist/react-resizable-panels.node.cjs.js +223 -63
- package/dist/react-resizable-panels.node.esm.js +223 -63
- package/package.json +1 -1
- package/src/Panel.ts +2 -0
- package/src/PanelGroup.ts +219 -177
- package/src/utils/dom/getPanelElementsForGroup.ts +5 -0
|
@@ -67,6 +67,7 @@ function PanelWithForwardedRef({
|
|
|
67
67
|
expandPanel,
|
|
68
68
|
getPanelSize,
|
|
69
69
|
getPanelStyle,
|
|
70
|
+
groupId,
|
|
70
71
|
isPanelCollapsed,
|
|
71
72
|
registerPanel,
|
|
72
73
|
resizePanel,
|
|
@@ -132,6 +133,7 @@ function PanelWithForwardedRef({
|
|
|
132
133
|
// CSS selectors
|
|
133
134
|
"data-panel": "",
|
|
134
135
|
"data-panel-id": panelId,
|
|
136
|
+
"data-panel-group-id": groupId,
|
|
135
137
|
// e2e test attributes
|
|
136
138
|
"data-panel-collapsible": undefined,
|
|
137
139
|
"data-panel-size": undefined
|
|
@@ -772,6 +774,44 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
|
|
|
772
774
|
}
|
|
773
775
|
}
|
|
774
776
|
|
|
777
|
+
function calculateUnsafeDefaultLayout({
|
|
778
|
+
groupSizePixels,
|
|
779
|
+
panelDataArray
|
|
780
|
+
}) {
|
|
781
|
+
const layout = Array(panelDataArray.length);
|
|
782
|
+
const panelDataConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
783
|
+
let numPanelsWithSizes = 0;
|
|
784
|
+
let remainingSize = 100;
|
|
785
|
+
|
|
786
|
+
// Distribute default sizes first
|
|
787
|
+
for (let index = 0; index < panelDataArray.length; index++) {
|
|
788
|
+
const {
|
|
789
|
+
defaultSizePercentage
|
|
790
|
+
} = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
|
|
791
|
+
if (defaultSizePercentage != null) {
|
|
792
|
+
numPanelsWithSizes++;
|
|
793
|
+
layout[index] = defaultSizePercentage;
|
|
794
|
+
remainingSize -= defaultSizePercentage;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// Remaining size should be distributed evenly between panels without default sizes
|
|
799
|
+
for (let index = 0; index < panelDataArray.length; index++) {
|
|
800
|
+
const {
|
|
801
|
+
defaultSizePercentage
|
|
802
|
+
} = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
|
|
803
|
+
if (defaultSizePercentage != null) {
|
|
804
|
+
continue;
|
|
805
|
+
}
|
|
806
|
+
const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
|
|
807
|
+
const size = remainingSize / numRemainingPanels;
|
|
808
|
+
numPanelsWithSizes++;
|
|
809
|
+
layout[index] = size;
|
|
810
|
+
remainingSize -= size;
|
|
811
|
+
}
|
|
812
|
+
return layout;
|
|
813
|
+
}
|
|
814
|
+
|
|
775
815
|
function convertPercentageToPixels(percentage, groupSizePixels) {
|
|
776
816
|
return percentage / 100 * groupSizePixels;
|
|
777
817
|
}
|
|
@@ -922,6 +962,10 @@ function debounce(callback, durationMs = 10) {
|
|
|
922
962
|
return callable;
|
|
923
963
|
}
|
|
924
964
|
|
|
965
|
+
function getPanelElementsForGroup(groupId) {
|
|
966
|
+
return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
967
|
+
}
|
|
968
|
+
|
|
925
969
|
// PanelGroup might be rendering in a server-side environment where localStorage is not available
|
|
926
970
|
// or on a browser with cookies/storage disabled.
|
|
927
971
|
// In either case, this function avoids accessing localStorage until needed,
|
|
@@ -977,6 +1021,15 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
977
1021
|
} catch (error) {}
|
|
978
1022
|
return null;
|
|
979
1023
|
}
|
|
1024
|
+
function loadPanelLayout(autoSaveId, panels, storage) {
|
|
1025
|
+
const state = loadSerializedPanelGroupState(autoSaveId, storage);
|
|
1026
|
+
if (state) {
|
|
1027
|
+
var _state$key;
|
|
1028
|
+
const key = getSerializationKey(panels);
|
|
1029
|
+
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
1030
|
+
}
|
|
1031
|
+
return null;
|
|
1032
|
+
}
|
|
980
1033
|
function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
981
1034
|
const key = getSerializationKey(panels);
|
|
982
1035
|
const state = loadSerializedPanelGroupState(autoSaveId, storage) || {};
|
|
@@ -988,6 +1041,12 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
|
988
1041
|
}
|
|
989
1042
|
}
|
|
990
1043
|
|
|
1044
|
+
function shouldMonitorPixelBasedConstraints(constraints) {
|
|
1045
|
+
return constraints.some(constraints => {
|
|
1046
|
+
return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
|
|
991
1050
|
// All units must be in percentages; pixel values should be pre-converted
|
|
992
1051
|
function validatePanelGroupLayout({
|
|
993
1052
|
groupSizePixels,
|
|
@@ -1056,7 +1115,7 @@ const defaultStorage = {
|
|
|
1056
1115
|
};
|
|
1057
1116
|
const debounceMap = {};
|
|
1058
1117
|
function PanelGroupWithForwardedRef({
|
|
1059
|
-
autoSaveId,
|
|
1118
|
+
autoSaveId = null,
|
|
1060
1119
|
children,
|
|
1061
1120
|
className: classNameFromProps = "",
|
|
1062
1121
|
dataAttributes,
|
|
@@ -1073,12 +1132,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1073
1132
|
const groupId = useUniqueId(idFromProps);
|
|
1074
1133
|
const [dragState, setDragState] = useState(null);
|
|
1075
1134
|
const [layout, setLayout] = useState([]);
|
|
1076
|
-
const [panelDataArray, setPanelDataArray] = useState([]);
|
|
1077
1135
|
const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
|
|
1078
1136
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1079
1137
|
const prevDeltaRef = useRef(0);
|
|
1080
|
-
const [imperativeApiQueue, setImperativeApiQueue] = useState([]);
|
|
1081
1138
|
const committedValuesRef = useRef({
|
|
1139
|
+
autoSaveId,
|
|
1082
1140
|
direction,
|
|
1083
1141
|
dragState,
|
|
1084
1142
|
id: groupId,
|
|
@@ -1086,7 +1144,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1086
1144
|
keyboardResizeByPixels,
|
|
1087
1145
|
layout,
|
|
1088
1146
|
onLayout,
|
|
1089
|
-
panelDataArray
|
|
1147
|
+
panelDataArray: [],
|
|
1148
|
+
storage
|
|
1090
1149
|
});
|
|
1091
1150
|
useRef({
|
|
1092
1151
|
didLogIdAndOrderWarning: false,
|
|
@@ -1124,6 +1183,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1124
1183
|
});
|
|
1125
1184
|
if (!areEqual(prevLayout, safeLayout)) {
|
|
1126
1185
|
setLayout(safeLayout);
|
|
1186
|
+
committedValuesRef.current.layout = safeLayout;
|
|
1127
1187
|
if (onLayout) {
|
|
1128
1188
|
onLayout(safeLayout.map(sizePercentage => ({
|
|
1129
1189
|
sizePercentage,
|
|
@@ -1134,14 +1194,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1134
1194
|
}
|
|
1135
1195
|
}
|
|
1136
1196
|
}), []);
|
|
1197
|
+
|
|
1137
1198
|
useWindowSplitterPanelGroupBehavior({
|
|
1138
1199
|
committedValuesRef,
|
|
1139
1200
|
groupId,
|
|
1140
1201
|
layout,
|
|
1141
|
-
panelDataArray,
|
|
1202
|
+
panelDataArray: committedValuesRef.current.panelDataArray,
|
|
1142
1203
|
setLayout
|
|
1143
1204
|
});
|
|
1144
1205
|
useEffect(() => {
|
|
1206
|
+
const {
|
|
1207
|
+
panelDataArray
|
|
1208
|
+
} = committedValuesRef.current;
|
|
1209
|
+
|
|
1145
1210
|
// If this panel has been configured to persist sizing information, save sizes to local storage.
|
|
1146
1211
|
if (autoSaveId) {
|
|
1147
1212
|
if (layout.length === 0 || layout.length !== panelDataArray.length) {
|
|
@@ -1154,7 +1219,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1154
1219
|
}
|
|
1155
1220
|
debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
|
|
1156
1221
|
}
|
|
1157
|
-
}, [autoSaveId, layout,
|
|
1222
|
+
}, [autoSaveId, layout, storage]);
|
|
1158
1223
|
|
|
1159
1224
|
// DEV warnings
|
|
1160
1225
|
useEffect(() => {
|
|
@@ -1167,17 +1232,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1167
1232
|
onLayout,
|
|
1168
1233
|
panelDataArray
|
|
1169
1234
|
} = committedValuesRef.current;
|
|
1170
|
-
|
|
1171
|
-
// See issues/211
|
|
1172
|
-
if (panelDataArray.find(({
|
|
1173
|
-
id
|
|
1174
|
-
}) => id === panelData.id) == null) {
|
|
1175
|
-
setImperativeApiQueue(prev => [...prev, {
|
|
1176
|
-
panelData,
|
|
1177
|
-
type: "collapse"
|
|
1178
|
-
}]);
|
|
1179
|
-
return;
|
|
1180
|
-
}
|
|
1181
1235
|
if (panelData.constraints.collapsible) {
|
|
1182
1236
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1183
1237
|
const {
|
|
@@ -1202,6 +1256,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1202
1256
|
});
|
|
1203
1257
|
if (!compareLayouts(prevLayout, nextLayout)) {
|
|
1204
1258
|
setLayout(nextLayout);
|
|
1259
|
+
committedValuesRef.current.layout = nextLayout;
|
|
1205
1260
|
if (onLayout) {
|
|
1206
1261
|
onLayout(nextLayout.map(sizePercentage => ({
|
|
1207
1262
|
sizePercentage,
|
|
@@ -1221,17 +1276,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1221
1276
|
onLayout,
|
|
1222
1277
|
panelDataArray
|
|
1223
1278
|
} = committedValuesRef.current;
|
|
1224
|
-
|
|
1225
|
-
// See issues/211
|
|
1226
|
-
if (panelDataArray.find(({
|
|
1227
|
-
id
|
|
1228
|
-
}) => id === panelData.id) == null) {
|
|
1229
|
-
setImperativeApiQueue(prev => [...prev, {
|
|
1230
|
-
panelData,
|
|
1231
|
-
type: "expand"
|
|
1232
|
-
}]);
|
|
1233
|
-
return;
|
|
1234
|
-
}
|
|
1235
1279
|
if (panelData.constraints.collapsible) {
|
|
1236
1280
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1237
1281
|
const {
|
|
@@ -1257,6 +1301,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1257
1301
|
});
|
|
1258
1302
|
if (!compareLayouts(prevLayout, nextLayout)) {
|
|
1259
1303
|
setLayout(nextLayout);
|
|
1304
|
+
committedValuesRef.current.layout = nextLayout;
|
|
1260
1305
|
if (onLayout) {
|
|
1261
1306
|
onLayout(nextLayout.map(sizePercentage => ({
|
|
1262
1307
|
sizePercentage,
|
|
@@ -1287,6 +1332,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1287
1332
|
|
|
1288
1333
|
// This API should never read from committedValuesRef
|
|
1289
1334
|
const getPanelStyle = useCallback(panelData => {
|
|
1335
|
+
const {
|
|
1336
|
+
panelDataArray
|
|
1337
|
+
} = committedValuesRef.current;
|
|
1290
1338
|
const panelIndex = panelDataArray.indexOf(panelData);
|
|
1291
1339
|
return computePanelFlexBoxStyle({
|
|
1292
1340
|
dragState,
|
|
@@ -1294,7 +1342,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1294
1342
|
panelData: panelDataArray,
|
|
1295
1343
|
panelIndex
|
|
1296
1344
|
});
|
|
1297
|
-
}, [dragState, layout
|
|
1345
|
+
}, [dragState, layout]);
|
|
1298
1346
|
|
|
1299
1347
|
// External APIs are safe to memoize via committed values ref
|
|
1300
1348
|
const isPanelCollapsed = useCallback(panelData => {
|
|
@@ -1324,22 +1372,76 @@ function PanelGroupWithForwardedRef({
|
|
|
1324
1372
|
return !collapsible || panelSizePercentage > collapsedSizePercentage;
|
|
1325
1373
|
}, [groupId]);
|
|
1326
1374
|
const registerPanel = useCallback(panelData => {
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1375
|
+
const {
|
|
1376
|
+
autoSaveId,
|
|
1377
|
+
id: groupId,
|
|
1378
|
+
layout: prevLayout,
|
|
1379
|
+
onLayout,
|
|
1380
|
+
panelDataArray,
|
|
1381
|
+
storage
|
|
1382
|
+
} = committedValuesRef.current;
|
|
1383
|
+
panelDataArray.push(panelData);
|
|
1384
|
+
panelDataArray.sort((panelA, panelB) => {
|
|
1385
|
+
const orderA = panelA.order;
|
|
1386
|
+
const orderB = panelB.order;
|
|
1387
|
+
if (orderA == null && orderB == null) {
|
|
1388
|
+
return 0;
|
|
1389
|
+
} else if (orderA == null) {
|
|
1390
|
+
return -1;
|
|
1391
|
+
} else if (orderB == null) {
|
|
1392
|
+
return 1;
|
|
1393
|
+
} else {
|
|
1394
|
+
return orderA - orderB;
|
|
1395
|
+
}
|
|
1396
|
+
});
|
|
1397
|
+
|
|
1398
|
+
// Wait until all panels have registered before we try to compute layout;
|
|
1399
|
+
// doing it earlier is both wasteful and may trigger misleading warnings in development mode.
|
|
1400
|
+
const panelElements = getPanelElementsForGroup(groupId);
|
|
1401
|
+
if (panelElements.length !== panelDataArray.length) {
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
// If this panel has been configured to persist sizing information,
|
|
1406
|
+
// default size should be restored from local storage if possible.
|
|
1407
|
+
let unsafeLayout = null;
|
|
1408
|
+
if (autoSaveId) {
|
|
1409
|
+
unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
|
|
1410
|
+
}
|
|
1411
|
+
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1412
|
+
if (groupSizePixels <= 0) {
|
|
1413
|
+
if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
|
|
1414
|
+
constraints
|
|
1415
|
+
}) => constraints))) {
|
|
1416
|
+
// Wait until the group has rendered a non-zero size before computing layout.
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
if (unsafeLayout == null) {
|
|
1421
|
+
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1422
|
+
groupSizePixels,
|
|
1423
|
+
panelDataArray
|
|
1341
1424
|
});
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
// Validate even saved layouts in case something has changed since last render
|
|
1428
|
+
// e.g. for pixel groups, this could be the size of the window
|
|
1429
|
+
const nextLayout = validatePanelGroupLayout({
|
|
1430
|
+
groupSizePixels,
|
|
1431
|
+
layout: unsafeLayout,
|
|
1432
|
+
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1342
1433
|
});
|
|
1434
|
+
if (!areEqual(prevLayout, nextLayout)) {
|
|
1435
|
+
setLayout(nextLayout);
|
|
1436
|
+
committedValuesRef.current.layout = nextLayout;
|
|
1437
|
+
if (onLayout) {
|
|
1438
|
+
onLayout(nextLayout.map(sizePercentage => ({
|
|
1439
|
+
sizePercentage,
|
|
1440
|
+
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1441
|
+
})));
|
|
1442
|
+
}
|
|
1443
|
+
callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
|
|
1444
|
+
}
|
|
1343
1445
|
}, []);
|
|
1344
1446
|
const registerResizeHandle = useCallback(dragHandleId => {
|
|
1345
1447
|
return function resizeHandler(event) {
|
|
@@ -1409,6 +1511,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1409
1511
|
}
|
|
1410
1512
|
if (layoutChanged) {
|
|
1411
1513
|
setLayout(nextLayout);
|
|
1514
|
+
committedValuesRef.current.layout = nextLayout;
|
|
1412
1515
|
if (onLayout) {
|
|
1413
1516
|
onLayout(nextLayout.map(sizePercentage => ({
|
|
1414
1517
|
sizePercentage,
|
|
@@ -1427,18 +1530,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1427
1530
|
onLayout,
|
|
1428
1531
|
panelDataArray
|
|
1429
1532
|
} = committedValuesRef.current;
|
|
1430
|
-
|
|
1431
|
-
// See issues/211
|
|
1432
|
-
if (panelDataArray.find(({
|
|
1433
|
-
id
|
|
1434
|
-
}) => id === panelData.id) == null) {
|
|
1435
|
-
setImperativeApiQueue(prev => [...prev, {
|
|
1436
|
-
panelData,
|
|
1437
|
-
mixedSizes,
|
|
1438
|
-
type: "resize"
|
|
1439
|
-
}]);
|
|
1440
|
-
return;
|
|
1441
|
-
}
|
|
1442
1533
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1443
1534
|
const {
|
|
1444
1535
|
groupSizePixels,
|
|
@@ -1458,6 +1549,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1458
1549
|
});
|
|
1459
1550
|
if (!compareLayouts(prevLayout, nextLayout)) {
|
|
1460
1551
|
setLayout(nextLayout);
|
|
1552
|
+
committedValuesRef.current.layout = nextLayout;
|
|
1461
1553
|
if (onLayout) {
|
|
1462
1554
|
onLayout(nextLayout.map(sizePercentage => ({
|
|
1463
1555
|
sizePercentage,
|
|
@@ -1485,16 +1577,84 @@ function PanelGroupWithForwardedRef({
|
|
|
1485
1577
|
resetGlobalCursorStyle();
|
|
1486
1578
|
setDragState(null);
|
|
1487
1579
|
}, []);
|
|
1580
|
+
const unregisterPanelRef = useRef({
|
|
1581
|
+
pendingPanelIds: new Set(),
|
|
1582
|
+
timeout: null
|
|
1583
|
+
});
|
|
1488
1584
|
const unregisterPanel = useCallback(panelData => {
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1585
|
+
const {
|
|
1586
|
+
id: groupId,
|
|
1587
|
+
layout: prevLayout,
|
|
1588
|
+
onLayout,
|
|
1589
|
+
panelDataArray
|
|
1590
|
+
} = committedValuesRef.current;
|
|
1591
|
+
const index = panelDataArray.indexOf(panelData);
|
|
1592
|
+
if (index >= 0) {
|
|
1593
|
+
panelDataArray.splice(index, 1);
|
|
1594
|
+
unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
|
|
1595
|
+
}
|
|
1596
|
+
if (unregisterPanelRef.current.timeout != null) {
|
|
1597
|
+
clearTimeout(unregisterPanelRef.current.timeout);
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
// Batch panel unmounts so that we only calculate layout once;
|
|
1601
|
+
// This is more efficient and avoids misleading warnings in development mode.
|
|
1602
|
+
// We can't check the DOM to detect this because Panel elements have not yet been removed.
|
|
1603
|
+
unregisterPanelRef.current.timeout = setTimeout(() => {
|
|
1604
|
+
const {
|
|
1605
|
+
pendingPanelIds
|
|
1606
|
+
} = unregisterPanelRef.current;
|
|
1607
|
+
panelIdToLastNotifiedMixedSizesMapRef.current;
|
|
1608
|
+
|
|
1609
|
+
// TRICKY
|
|
1610
|
+
// Strict effects mode
|
|
1611
|
+
let unmountDueToStrictMode = false;
|
|
1612
|
+
pendingPanelIds.forEach(panelId => {
|
|
1613
|
+
pendingPanelIds.delete(panelId);
|
|
1614
|
+
if (panelDataArray.find(({
|
|
1615
|
+
id
|
|
1616
|
+
}) => id === panelId) == null) {
|
|
1617
|
+
unmountDueToStrictMode = true;
|
|
1618
|
+
|
|
1619
|
+
// TRICKY
|
|
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 panelIdToLastNotifiedMixedSizesMapRef.current[panelData.id];
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
if (!unmountDueToStrictMode) {
|
|
1627
|
+
return;
|
|
1495
1628
|
}
|
|
1496
|
-
|
|
1497
|
-
|
|
1629
|
+
if (panelDataArray.length === 0) {
|
|
1630
|
+
// The group is unmounting; skip layout calculation.
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1634
|
+
let unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1635
|
+
groupSizePixels,
|
|
1636
|
+
panelDataArray
|
|
1637
|
+
});
|
|
1638
|
+
|
|
1639
|
+
// Validate even saved layouts in case something has changed since last render
|
|
1640
|
+
// e.g. for pixel groups, this could be the size of the window
|
|
1641
|
+
const nextLayout = validatePanelGroupLayout({
|
|
1642
|
+
groupSizePixels,
|
|
1643
|
+
layout: unsafeLayout,
|
|
1644
|
+
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1645
|
+
});
|
|
1646
|
+
if (!areEqual(prevLayout, nextLayout)) {
|
|
1647
|
+
setLayout(nextLayout);
|
|
1648
|
+
committedValuesRef.current.layout = nextLayout;
|
|
1649
|
+
if (onLayout) {
|
|
1650
|
+
onLayout(nextLayout.map(sizePercentage => ({
|
|
1651
|
+
sizePercentage,
|
|
1652
|
+
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1653
|
+
})));
|
|
1654
|
+
}
|
|
1655
|
+
callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
|
|
1656
|
+
}
|
|
1657
|
+
}, 0);
|
|
1498
1658
|
}, []);
|
|
1499
1659
|
const context = useMemo(() => ({
|
|
1500
1660
|
collapsePanel,
|
package/package.json
CHANGED
package/src/Panel.ts
CHANGED
|
@@ -115,6 +115,7 @@ export function PanelWithForwardedRef({
|
|
|
115
115
|
expandPanel,
|
|
116
116
|
getPanelSize,
|
|
117
117
|
getPanelStyle,
|
|
118
|
+
groupId,
|
|
118
119
|
isPanelCollapsed,
|
|
119
120
|
registerPanel,
|
|
120
121
|
resizePanel,
|
|
@@ -250,6 +251,7 @@ export function PanelWithForwardedRef({
|
|
|
250
251
|
// CSS selectors
|
|
251
252
|
"data-panel": "",
|
|
252
253
|
"data-panel-id": panelId,
|
|
254
|
+
"data-panel-group-id": groupId,
|
|
253
255
|
|
|
254
256
|
// e2e test attributes
|
|
255
257
|
"data-panel-collapsible": isDevelopment
|