react-resizable-panels 1.0.2 → 1.0.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.
- package/CHANGELOG.md +9 -1
- package/dist/react-resizable-panels.browser.cjs.js +34 -22
- package/dist/react-resizable-panels.browser.development.cjs.js +34 -22
- package/dist/react-resizable-panels.browser.development.esm.js +34 -22
- package/dist/react-resizable-panels.browser.esm.js +34 -22
- package/dist/react-resizable-panels.cjs.js +34 -22
- package/dist/react-resizable-panels.development.cjs.js +34 -22
- package/dist/react-resizable-panels.development.esm.js +34 -22
- package/dist/react-resizable-panels.development.node.cjs.js +24 -13
- package/dist/react-resizable-panels.development.node.esm.js +24 -13
- package/dist/react-resizable-panels.esm.js +34 -22
- package/dist/react-resizable-panels.node.cjs.js +24 -13
- package/dist/react-resizable-panels.node.esm.js +24 -13
- package/package.json +1 -1
- package/src/Panel.test.tsx +12 -0
- package/src/PanelGroup.ts +31 -13
- package/src/utils/serialization.ts +33 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.4
|
|
4
|
+
|
|
5
|
+
- Edge case bug fix for `isCollapsed` panel method
|
|
6
|
+
|
|
7
|
+
## 1.0.3
|
|
8
|
+
|
|
9
|
+
- Remember most recently expanded panel size in local storage (#234)
|
|
10
|
+
|
|
3
11
|
## 1.0.2
|
|
4
12
|
|
|
5
|
-
- Change local storage key for persisted sizes to avoid restoring pixel-based sizes (
|
|
13
|
+
- Change local storage key for persisted sizes to avoid restoring pixel-based sizes (#233)
|
|
6
14
|
|
|
7
15
|
## 1.0.1
|
|
8
16
|
|
|
@@ -961,11 +961,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
961
961
|
}
|
|
962
962
|
}
|
|
963
963
|
|
|
964
|
+
function getPanelGroupKey(autoSaveId) {
|
|
965
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
966
|
+
}
|
|
967
|
+
|
|
964
968
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
965
969
|
// so they should not be used as part of the serialization key.
|
|
966
970
|
// Using the min/max size attributes should work well enough as a backup.
|
|
967
971
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
968
|
-
function
|
|
972
|
+
function getPanelKey(panels) {
|
|
969
973
|
return panels.map(panel => {
|
|
970
974
|
const {
|
|
971
975
|
constraints,
|
|
@@ -982,7 +986,8 @@ function getSerializationKey(panels) {
|
|
|
982
986
|
}
|
|
983
987
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
984
988
|
try {
|
|
985
|
-
const
|
|
989
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
990
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
986
991
|
if (serialized) {
|
|
987
992
|
const parsed = JSON.parse(serialized);
|
|
988
993
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -992,21 +997,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
992
997
|
} catch (error) {}
|
|
993
998
|
return null;
|
|
994
999
|
}
|
|
995
|
-
function
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
1001
|
-
}
|
|
1002
|
-
return null;
|
|
1000
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
1001
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
1002
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
1003
|
+
const panelKey = getPanelKey(panels);
|
|
1004
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
1003
1005
|
}
|
|
1004
|
-
function
|
|
1005
|
-
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1006
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
1007
|
+
var _loadSerializedPanelG2;
|
|
1008
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1009
|
+
const panelKey = getPanelKey(panels);
|
|
1010
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
1011
|
+
state[panelKey] = {
|
|
1012
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
1013
|
+
layout: sizes
|
|
1014
|
+
};
|
|
1008
1015
|
try {
|
|
1009
|
-
storage.setItem(
|
|
1016
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
1010
1017
|
} catch (error) {
|
|
1011
1018
|
console.error(error);
|
|
1012
1019
|
}
|
|
@@ -1103,7 +1110,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1103
1110
|
const groupId = useUniqueId(idFromProps);
|
|
1104
1111
|
const [dragState, setDragState] = useState(null);
|
|
1105
1112
|
const [layout, setLayout] = useState([]);
|
|
1106
|
-
useState([]);
|
|
1107
1113
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1108
1114
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1109
1115
|
const prevDeltaRef = useRef(0);
|
|
@@ -1186,13 +1192,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1186
1192
|
|
|
1187
1193
|
// Limit the frequency of localStorage updates.
|
|
1188
1194
|
if (debouncedSave == null) {
|
|
1189
|
-
debouncedSave = debounce(
|
|
1195
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1190
1196
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1191
1197
|
}
|
|
1192
1198
|
|
|
1193
|
-
// Clone
|
|
1194
|
-
//
|
|
1195
|
-
|
|
1199
|
+
// Clone mutable data before passing to the debounced function,
|
|
1200
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1201
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1202
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1203
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1196
1204
|
}
|
|
1197
1205
|
}, [autoSaveId, layout, storage]);
|
|
1198
1206
|
|
|
@@ -1318,7 +1326,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1318
1326
|
panelDataArray
|
|
1319
1327
|
} = eagerValuesRef.current;
|
|
1320
1328
|
const {
|
|
1321
|
-
collapsedSize,
|
|
1329
|
+
collapsedSize = 0,
|
|
1322
1330
|
collapsible,
|
|
1323
1331
|
panelSize
|
|
1324
1332
|
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
@@ -1379,7 +1387,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1379
1387
|
// default size should be restored from local storage if possible.
|
|
1380
1388
|
let unsafeLayout = null;
|
|
1381
1389
|
if (autoSaveId) {
|
|
1382
|
-
|
|
1390
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1391
|
+
if (state) {
|
|
1392
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1393
|
+
unsafeLayout = state.layout;
|
|
1394
|
+
}
|
|
1383
1395
|
}
|
|
1384
1396
|
if (unsafeLayout == null) {
|
|
1385
1397
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -977,11 +977,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
977
977
|
}
|
|
978
978
|
}
|
|
979
979
|
|
|
980
|
+
function getPanelGroupKey(autoSaveId) {
|
|
981
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
982
|
+
}
|
|
983
|
+
|
|
980
984
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
981
985
|
// so they should not be used as part of the serialization key.
|
|
982
986
|
// Using the min/max size attributes should work well enough as a backup.
|
|
983
987
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
984
|
-
function
|
|
988
|
+
function getPanelKey(panels) {
|
|
985
989
|
return panels.map(panel => {
|
|
986
990
|
const {
|
|
987
991
|
constraints,
|
|
@@ -998,7 +1002,8 @@ function getSerializationKey(panels) {
|
|
|
998
1002
|
}
|
|
999
1003
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
1000
1004
|
try {
|
|
1001
|
-
const
|
|
1005
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1006
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
1002
1007
|
if (serialized) {
|
|
1003
1008
|
const parsed = JSON.parse(serialized);
|
|
1004
1009
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -1008,21 +1013,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
1008
1013
|
} catch (error) {}
|
|
1009
1014
|
return null;
|
|
1010
1015
|
}
|
|
1011
|
-
function
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
1017
|
-
}
|
|
1018
|
-
return null;
|
|
1016
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
1017
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
1018
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
1019
|
+
const panelKey = getPanelKey(panels);
|
|
1020
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
1019
1021
|
}
|
|
1020
|
-
function
|
|
1021
|
-
|
|
1022
|
-
const
|
|
1023
|
-
|
|
1022
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
1023
|
+
var _loadSerializedPanelG2;
|
|
1024
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1025
|
+
const panelKey = getPanelKey(panels);
|
|
1026
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
1027
|
+
state[panelKey] = {
|
|
1028
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
1029
|
+
layout: sizes
|
|
1030
|
+
};
|
|
1024
1031
|
try {
|
|
1025
|
-
storage.setItem(
|
|
1032
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
1026
1033
|
} catch (error) {
|
|
1027
1034
|
console.error(error);
|
|
1028
1035
|
}
|
|
@@ -1166,7 +1173,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1166
1173
|
const groupId = useUniqueId(idFromProps);
|
|
1167
1174
|
const [dragState, setDragState] = useState(null);
|
|
1168
1175
|
const [layout, setLayout] = useState([]);
|
|
1169
|
-
useState([]);
|
|
1170
1176
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1171
1177
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1172
1178
|
const prevDeltaRef = useRef(0);
|
|
@@ -1249,13 +1255,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1249
1255
|
|
|
1250
1256
|
// Limit the frequency of localStorage updates.
|
|
1251
1257
|
if (debouncedSave == null) {
|
|
1252
|
-
debouncedSave = debounce(
|
|
1258
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1253
1259
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1254
1260
|
}
|
|
1255
1261
|
|
|
1256
|
-
// Clone
|
|
1257
|
-
//
|
|
1258
|
-
|
|
1262
|
+
// Clone mutable data before passing to the debounced function,
|
|
1263
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1264
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1265
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1266
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1259
1267
|
}
|
|
1260
1268
|
}, [autoSaveId, layout, storage]);
|
|
1261
1269
|
|
|
@@ -1423,7 +1431,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1423
1431
|
panelDataArray
|
|
1424
1432
|
} = eagerValuesRef.current;
|
|
1425
1433
|
const {
|
|
1426
|
-
collapsedSize,
|
|
1434
|
+
collapsedSize = 0,
|
|
1427
1435
|
collapsible,
|
|
1428
1436
|
panelSize
|
|
1429
1437
|
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
@@ -1484,7 +1492,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1484
1492
|
// default size should be restored from local storage if possible.
|
|
1485
1493
|
let unsafeLayout = null;
|
|
1486
1494
|
if (autoSaveId) {
|
|
1487
|
-
|
|
1495
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1496
|
+
if (state) {
|
|
1497
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1498
|
+
unsafeLayout = state.layout;
|
|
1499
|
+
}
|
|
1488
1500
|
}
|
|
1489
1501
|
if (unsafeLayout == null) {
|
|
1490
1502
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -953,11 +953,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
953
953
|
}
|
|
954
954
|
}
|
|
955
955
|
|
|
956
|
+
function getPanelGroupKey(autoSaveId) {
|
|
957
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
958
|
+
}
|
|
959
|
+
|
|
956
960
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
957
961
|
// so they should not be used as part of the serialization key.
|
|
958
962
|
// Using the min/max size attributes should work well enough as a backup.
|
|
959
963
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
960
|
-
function
|
|
964
|
+
function getPanelKey(panels) {
|
|
961
965
|
return panels.map(panel => {
|
|
962
966
|
const {
|
|
963
967
|
constraints,
|
|
@@ -974,7 +978,8 @@ function getSerializationKey(panels) {
|
|
|
974
978
|
}
|
|
975
979
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
976
980
|
try {
|
|
977
|
-
const
|
|
981
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
982
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
978
983
|
if (serialized) {
|
|
979
984
|
const parsed = JSON.parse(serialized);
|
|
980
985
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -984,21 +989,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
984
989
|
} catch (error) {}
|
|
985
990
|
return null;
|
|
986
991
|
}
|
|
987
|
-
function
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
993
|
-
}
|
|
994
|
-
return null;
|
|
992
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
993
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
994
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
995
|
+
const panelKey = getPanelKey(panels);
|
|
996
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
995
997
|
}
|
|
996
|
-
function
|
|
997
|
-
|
|
998
|
-
const
|
|
999
|
-
|
|
998
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
999
|
+
var _loadSerializedPanelG2;
|
|
1000
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1001
|
+
const panelKey = getPanelKey(panels);
|
|
1002
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
1003
|
+
state[panelKey] = {
|
|
1004
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
1005
|
+
layout: sizes
|
|
1006
|
+
};
|
|
1000
1007
|
try {
|
|
1001
|
-
storage.setItem(
|
|
1008
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
1002
1009
|
} catch (error) {
|
|
1003
1010
|
console.error(error);
|
|
1004
1011
|
}
|
|
@@ -1142,7 +1149,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1142
1149
|
const groupId = useUniqueId(idFromProps);
|
|
1143
1150
|
const [dragState, setDragState] = useState(null);
|
|
1144
1151
|
const [layout, setLayout] = useState([]);
|
|
1145
|
-
useState([]);
|
|
1146
1152
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1147
1153
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1148
1154
|
const prevDeltaRef = useRef(0);
|
|
@@ -1225,13 +1231,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1225
1231
|
|
|
1226
1232
|
// Limit the frequency of localStorage updates.
|
|
1227
1233
|
if (debouncedSave == null) {
|
|
1228
|
-
debouncedSave = debounce(
|
|
1234
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1229
1235
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1230
1236
|
}
|
|
1231
1237
|
|
|
1232
|
-
// Clone
|
|
1233
|
-
//
|
|
1234
|
-
|
|
1238
|
+
// Clone mutable data before passing to the debounced function,
|
|
1239
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1240
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1241
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1242
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1235
1243
|
}
|
|
1236
1244
|
}, [autoSaveId, layout, storage]);
|
|
1237
1245
|
|
|
@@ -1399,7 +1407,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1399
1407
|
panelDataArray
|
|
1400
1408
|
} = eagerValuesRef.current;
|
|
1401
1409
|
const {
|
|
1402
|
-
collapsedSize,
|
|
1410
|
+
collapsedSize = 0,
|
|
1403
1411
|
collapsible,
|
|
1404
1412
|
panelSize
|
|
1405
1413
|
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
@@ -1460,7 +1468,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1460
1468
|
// default size should be restored from local storage if possible.
|
|
1461
1469
|
let unsafeLayout = null;
|
|
1462
1470
|
if (autoSaveId) {
|
|
1463
|
-
|
|
1471
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1472
|
+
if (state) {
|
|
1473
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1474
|
+
unsafeLayout = state.layout;
|
|
1475
|
+
}
|
|
1464
1476
|
}
|
|
1465
1477
|
if (unsafeLayout == null) {
|
|
1466
1478
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -937,11 +937,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
937
937
|
}
|
|
938
938
|
}
|
|
939
939
|
|
|
940
|
+
function getPanelGroupKey(autoSaveId) {
|
|
941
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
942
|
+
}
|
|
943
|
+
|
|
940
944
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
941
945
|
// so they should not be used as part of the serialization key.
|
|
942
946
|
// Using the min/max size attributes should work well enough as a backup.
|
|
943
947
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
944
|
-
function
|
|
948
|
+
function getPanelKey(panels) {
|
|
945
949
|
return panels.map(panel => {
|
|
946
950
|
const {
|
|
947
951
|
constraints,
|
|
@@ -958,7 +962,8 @@ function getSerializationKey(panels) {
|
|
|
958
962
|
}
|
|
959
963
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
960
964
|
try {
|
|
961
|
-
const
|
|
965
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
966
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
962
967
|
if (serialized) {
|
|
963
968
|
const parsed = JSON.parse(serialized);
|
|
964
969
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -968,21 +973,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
968
973
|
} catch (error) {}
|
|
969
974
|
return null;
|
|
970
975
|
}
|
|
971
|
-
function
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
977
|
-
}
|
|
978
|
-
return null;
|
|
976
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
977
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
978
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
979
|
+
const panelKey = getPanelKey(panels);
|
|
980
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
979
981
|
}
|
|
980
|
-
function
|
|
981
|
-
|
|
982
|
-
const
|
|
983
|
-
|
|
982
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
983
|
+
var _loadSerializedPanelG2;
|
|
984
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
985
|
+
const panelKey = getPanelKey(panels);
|
|
986
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
987
|
+
state[panelKey] = {
|
|
988
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
989
|
+
layout: sizes
|
|
990
|
+
};
|
|
984
991
|
try {
|
|
985
|
-
storage.setItem(
|
|
992
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
986
993
|
} catch (error) {
|
|
987
994
|
console.error(error);
|
|
988
995
|
}
|
|
@@ -1079,7 +1086,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1079
1086
|
const groupId = useUniqueId(idFromProps);
|
|
1080
1087
|
const [dragState, setDragState] = useState(null);
|
|
1081
1088
|
const [layout, setLayout] = useState([]);
|
|
1082
|
-
useState([]);
|
|
1083
1089
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1084
1090
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1085
1091
|
const prevDeltaRef = useRef(0);
|
|
@@ -1162,13 +1168,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1162
1168
|
|
|
1163
1169
|
// Limit the frequency of localStorage updates.
|
|
1164
1170
|
if (debouncedSave == null) {
|
|
1165
|
-
debouncedSave = debounce(
|
|
1171
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1166
1172
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1167
1173
|
}
|
|
1168
1174
|
|
|
1169
|
-
// Clone
|
|
1170
|
-
//
|
|
1171
|
-
|
|
1175
|
+
// Clone mutable data before passing to the debounced function,
|
|
1176
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1177
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1178
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1179
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1172
1180
|
}
|
|
1173
1181
|
}, [autoSaveId, layout, storage]);
|
|
1174
1182
|
|
|
@@ -1294,7 +1302,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1294
1302
|
panelDataArray
|
|
1295
1303
|
} = eagerValuesRef.current;
|
|
1296
1304
|
const {
|
|
1297
|
-
collapsedSize,
|
|
1305
|
+
collapsedSize = 0,
|
|
1298
1306
|
collapsible,
|
|
1299
1307
|
panelSize
|
|
1300
1308
|
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
@@ -1355,7 +1363,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1355
1363
|
// default size should be restored from local storage if possible.
|
|
1356
1364
|
let unsafeLayout = null;
|
|
1357
1365
|
if (autoSaveId) {
|
|
1358
|
-
|
|
1366
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1367
|
+
if (state) {
|
|
1368
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1369
|
+
unsafeLayout = state.layout;
|
|
1370
|
+
}
|
|
1359
1371
|
}
|
|
1360
1372
|
if (unsafeLayout == null) {
|
|
1361
1373
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -963,11 +963,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
963
963
|
}
|
|
964
964
|
}
|
|
965
965
|
|
|
966
|
+
function getPanelGroupKey(autoSaveId) {
|
|
967
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
968
|
+
}
|
|
969
|
+
|
|
966
970
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
967
971
|
// so they should not be used as part of the serialization key.
|
|
968
972
|
// Using the min/max size attributes should work well enough as a backup.
|
|
969
973
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
970
|
-
function
|
|
974
|
+
function getPanelKey(panels) {
|
|
971
975
|
return panels.map(panel => {
|
|
972
976
|
const {
|
|
973
977
|
constraints,
|
|
@@ -984,7 +988,8 @@ function getSerializationKey(panels) {
|
|
|
984
988
|
}
|
|
985
989
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
986
990
|
try {
|
|
987
|
-
const
|
|
991
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
992
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
988
993
|
if (serialized) {
|
|
989
994
|
const parsed = JSON.parse(serialized);
|
|
990
995
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -994,21 +999,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
994
999
|
} catch (error) {}
|
|
995
1000
|
return null;
|
|
996
1001
|
}
|
|
997
|
-
function
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
1003
|
-
}
|
|
1004
|
-
return null;
|
|
1002
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
1003
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
1004
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
1005
|
+
const panelKey = getPanelKey(panels);
|
|
1006
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
1005
1007
|
}
|
|
1006
|
-
function
|
|
1007
|
-
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1008
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
1009
|
+
var _loadSerializedPanelG2;
|
|
1010
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1011
|
+
const panelKey = getPanelKey(panels);
|
|
1012
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
1013
|
+
state[panelKey] = {
|
|
1014
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
1015
|
+
layout: sizes
|
|
1016
|
+
};
|
|
1010
1017
|
try {
|
|
1011
|
-
storage.setItem(
|
|
1018
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
1012
1019
|
} catch (error) {
|
|
1013
1020
|
console.error(error);
|
|
1014
1021
|
}
|
|
@@ -1105,7 +1112,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1105
1112
|
const groupId = useUniqueId(idFromProps);
|
|
1106
1113
|
const [dragState, setDragState] = useState(null);
|
|
1107
1114
|
const [layout, setLayout] = useState([]);
|
|
1108
|
-
useState([]);
|
|
1109
1115
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1110
1116
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1111
1117
|
const prevDeltaRef = useRef(0);
|
|
@@ -1188,13 +1194,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1188
1194
|
|
|
1189
1195
|
// Limit the frequency of localStorage updates.
|
|
1190
1196
|
if (debouncedSave == null) {
|
|
1191
|
-
debouncedSave = debounce(
|
|
1197
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1192
1198
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1193
1199
|
}
|
|
1194
1200
|
|
|
1195
|
-
// Clone
|
|
1196
|
-
//
|
|
1197
|
-
|
|
1201
|
+
// Clone mutable data before passing to the debounced function,
|
|
1202
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1203
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1204
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1205
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1198
1206
|
}
|
|
1199
1207
|
}, [autoSaveId, layout, storage]);
|
|
1200
1208
|
|
|
@@ -1320,7 +1328,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1320
1328
|
panelDataArray
|
|
1321
1329
|
} = eagerValuesRef.current;
|
|
1322
1330
|
const {
|
|
1323
|
-
collapsedSize,
|
|
1331
|
+
collapsedSize = 0,
|
|
1324
1332
|
collapsible,
|
|
1325
1333
|
panelSize
|
|
1326
1334
|
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
@@ -1381,7 +1389,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1381
1389
|
// default size should be restored from local storage if possible.
|
|
1382
1390
|
let unsafeLayout = null;
|
|
1383
1391
|
if (autoSaveId) {
|
|
1384
|
-
|
|
1392
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1393
|
+
if (state) {
|
|
1394
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1395
|
+
unsafeLayout = state.layout;
|
|
1396
|
+
}
|
|
1385
1397
|
}
|
|
1386
1398
|
if (unsafeLayout == null) {
|
|
1387
1399
|
unsafeLayout = calculateUnsafeDefaultLayout({
|