react-resizable-panels 1.0.1 → 1.0.3
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 +8 -0
- 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/PanelGroup.ts +26 -8
- package/src/utils/serialization.ts +36 -19
|
@@ -984,11 +984,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
984
984
|
}
|
|
985
985
|
}
|
|
986
986
|
|
|
987
|
+
function getPanelGroupKey(autoSaveId) {
|
|
988
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
989
|
+
}
|
|
990
|
+
|
|
987
991
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
988
992
|
// so they should not be used as part of the serialization key.
|
|
989
993
|
// Using the min/max size attributes should work well enough as a backup.
|
|
990
994
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
991
|
-
function
|
|
995
|
+
function getPanelKey(panels) {
|
|
992
996
|
return panels.map(panel => {
|
|
993
997
|
const {
|
|
994
998
|
constraints,
|
|
@@ -999,13 +1003,14 @@ function getSerializationKey(panels) {
|
|
|
999
1003
|
if (idIsFromProps) {
|
|
1000
1004
|
return id;
|
|
1001
1005
|
} else {
|
|
1002
|
-
return `${order}:${JSON.stringify(constraints)}
|
|
1006
|
+
return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
|
|
1003
1007
|
}
|
|
1004
1008
|
}).sort((a, b) => a.localeCompare(b)).join(",");
|
|
1005
1009
|
}
|
|
1006
1010
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
1007
1011
|
try {
|
|
1008
|
-
const
|
|
1012
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1013
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
1009
1014
|
if (serialized) {
|
|
1010
1015
|
const parsed = JSON.parse(serialized);
|
|
1011
1016
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -1015,21 +1020,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
1015
1020
|
} catch (error) {}
|
|
1016
1021
|
return null;
|
|
1017
1022
|
}
|
|
1018
|
-
function
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
1024
|
-
}
|
|
1025
|
-
return null;
|
|
1023
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
1024
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
1025
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
1026
|
+
const panelKey = getPanelKey(panels);
|
|
1027
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
1026
1028
|
}
|
|
1027
|
-
function
|
|
1028
|
-
|
|
1029
|
-
const
|
|
1030
|
-
|
|
1029
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
1030
|
+
var _loadSerializedPanelG2;
|
|
1031
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1032
|
+
const panelKey = getPanelKey(panels);
|
|
1033
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
1034
|
+
state[panelKey] = {
|
|
1035
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
1036
|
+
layout: sizes
|
|
1037
|
+
};
|
|
1031
1038
|
try {
|
|
1032
|
-
storage.setItem(
|
|
1039
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
1033
1040
|
} catch (error) {
|
|
1034
1041
|
console.error(error);
|
|
1035
1042
|
}
|
|
@@ -1173,7 +1180,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1173
1180
|
const groupId = useUniqueId(idFromProps);
|
|
1174
1181
|
const [dragState, setDragState] = useState(null);
|
|
1175
1182
|
const [layout, setLayout] = useState([]);
|
|
1176
|
-
useState([]);
|
|
1177
1183
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1178
1184
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1179
1185
|
const prevDeltaRef = useRef(0);
|
|
@@ -1256,13 +1262,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1256
1262
|
|
|
1257
1263
|
// Limit the frequency of localStorage updates.
|
|
1258
1264
|
if (debouncedSave == null) {
|
|
1259
|
-
debouncedSave = debounce(
|
|
1265
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1260
1266
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1261
1267
|
}
|
|
1262
1268
|
|
|
1263
|
-
// Clone
|
|
1264
|
-
//
|
|
1265
|
-
|
|
1269
|
+
// Clone mutable data before passing to the debounced function,
|
|
1270
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1271
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1272
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1273
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1266
1274
|
}
|
|
1267
1275
|
}, [autoSaveId, layout, storage]);
|
|
1268
1276
|
|
|
@@ -1491,7 +1499,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1491
1499
|
// default size should be restored from local storage if possible.
|
|
1492
1500
|
let unsafeLayout = null;
|
|
1493
1501
|
if (autoSaveId) {
|
|
1494
|
-
|
|
1502
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1503
|
+
if (state) {
|
|
1504
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1505
|
+
unsafeLayout = state.layout;
|
|
1506
|
+
}
|
|
1495
1507
|
}
|
|
1496
1508
|
if (unsafeLayout == null) {
|
|
1497
1509
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -960,11 +960,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
960
960
|
}
|
|
961
961
|
}
|
|
962
962
|
|
|
963
|
+
function getPanelGroupKey(autoSaveId) {
|
|
964
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
965
|
+
}
|
|
966
|
+
|
|
963
967
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
964
968
|
// so they should not be used as part of the serialization key.
|
|
965
969
|
// Using the min/max size attributes should work well enough as a backup.
|
|
966
970
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
967
|
-
function
|
|
971
|
+
function getPanelKey(panels) {
|
|
968
972
|
return panels.map(panel => {
|
|
969
973
|
const {
|
|
970
974
|
constraints,
|
|
@@ -975,13 +979,14 @@ function getSerializationKey(panels) {
|
|
|
975
979
|
if (idIsFromProps) {
|
|
976
980
|
return id;
|
|
977
981
|
} else {
|
|
978
|
-
return `${order}:${JSON.stringify(constraints)}
|
|
982
|
+
return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
|
|
979
983
|
}
|
|
980
984
|
}).sort((a, b) => a.localeCompare(b)).join(",");
|
|
981
985
|
}
|
|
982
986
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
983
987
|
try {
|
|
984
|
-
const
|
|
988
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
989
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
985
990
|
if (serialized) {
|
|
986
991
|
const parsed = JSON.parse(serialized);
|
|
987
992
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -991,21 +996,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
991
996
|
} catch (error) {}
|
|
992
997
|
return null;
|
|
993
998
|
}
|
|
994
|
-
function
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
1000
|
-
}
|
|
1001
|
-
return null;
|
|
999
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
1000
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
1001
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
1002
|
+
const panelKey = getPanelKey(panels);
|
|
1003
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
1002
1004
|
}
|
|
1003
|
-
function
|
|
1004
|
-
|
|
1005
|
-
const
|
|
1006
|
-
|
|
1005
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
1006
|
+
var _loadSerializedPanelG2;
|
|
1007
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
1008
|
+
const panelKey = getPanelKey(panels);
|
|
1009
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
1010
|
+
state[panelKey] = {
|
|
1011
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
1012
|
+
layout: sizes
|
|
1013
|
+
};
|
|
1007
1014
|
try {
|
|
1008
|
-
storage.setItem(
|
|
1015
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
1009
1016
|
} catch (error) {
|
|
1010
1017
|
console.error(error);
|
|
1011
1018
|
}
|
|
@@ -1149,7 +1156,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1149
1156
|
const groupId = useUniqueId(idFromProps);
|
|
1150
1157
|
const [dragState, setDragState] = useState(null);
|
|
1151
1158
|
const [layout, setLayout] = useState([]);
|
|
1152
|
-
useState([]);
|
|
1153
1159
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1154
1160
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1155
1161
|
const prevDeltaRef = useRef(0);
|
|
@@ -1232,13 +1238,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1232
1238
|
|
|
1233
1239
|
// Limit the frequency of localStorage updates.
|
|
1234
1240
|
if (debouncedSave == null) {
|
|
1235
|
-
debouncedSave = debounce(
|
|
1241
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1236
1242
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1237
1243
|
}
|
|
1238
1244
|
|
|
1239
|
-
// Clone
|
|
1240
|
-
//
|
|
1241
|
-
|
|
1245
|
+
// Clone mutable data before passing to the debounced function,
|
|
1246
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1247
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1248
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1249
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1242
1250
|
}
|
|
1243
1251
|
}, [autoSaveId, layout, storage]);
|
|
1244
1252
|
|
|
@@ -1467,7 +1475,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1467
1475
|
// default size should be restored from local storage if possible.
|
|
1468
1476
|
let unsafeLayout = null;
|
|
1469
1477
|
if (autoSaveId) {
|
|
1470
|
-
|
|
1478
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1479
|
+
if (state) {
|
|
1480
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1481
|
+
unsafeLayout = state.layout;
|
|
1482
|
+
}
|
|
1471
1483
|
}
|
|
1472
1484
|
if (unsafeLayout == null) {
|
|
1473
1485
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -835,11 +835,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
835
835
|
}
|
|
836
836
|
}
|
|
837
837
|
|
|
838
|
+
function getPanelGroupKey(autoSaveId) {
|
|
839
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
840
|
+
}
|
|
841
|
+
|
|
838
842
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
839
843
|
// so they should not be used as part of the serialization key.
|
|
840
844
|
// Using the min/max size attributes should work well enough as a backup.
|
|
841
845
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
842
|
-
function
|
|
846
|
+
function getPanelKey(panels) {
|
|
843
847
|
return panels.map(panel => {
|
|
844
848
|
const {
|
|
845
849
|
constraints,
|
|
@@ -850,13 +854,14 @@ function getSerializationKey(panels) {
|
|
|
850
854
|
if (idIsFromProps) {
|
|
851
855
|
return id;
|
|
852
856
|
} else {
|
|
853
|
-
return `${order}:${JSON.stringify(constraints)}
|
|
857
|
+
return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
|
|
854
858
|
}
|
|
855
859
|
}).sort((a, b) => a.localeCompare(b)).join(",");
|
|
856
860
|
}
|
|
857
861
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
858
862
|
try {
|
|
859
|
-
const
|
|
863
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
864
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
860
865
|
if (serialized) {
|
|
861
866
|
const parsed = JSON.parse(serialized);
|
|
862
867
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -866,12 +871,17 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
866
871
|
} catch (error) {}
|
|
867
872
|
return null;
|
|
868
873
|
}
|
|
869
|
-
function
|
|
870
|
-
|
|
871
|
-
const
|
|
872
|
-
|
|
874
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
875
|
+
var _loadSerializedPanelG2;
|
|
876
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
877
|
+
const panelKey = getPanelKey(panels);
|
|
878
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
879
|
+
state[panelKey] = {
|
|
880
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
881
|
+
layout: sizes
|
|
882
|
+
};
|
|
873
883
|
try {
|
|
874
|
-
storage.setItem(
|
|
884
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
875
885
|
} catch (error) {
|
|
876
886
|
console.error(error);
|
|
877
887
|
}
|
|
@@ -1015,7 +1025,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1015
1025
|
const groupId = useUniqueId(idFromProps);
|
|
1016
1026
|
const [dragState, setDragState] = useState(null);
|
|
1017
1027
|
const [layout, setLayout] = useState([]);
|
|
1018
|
-
useState([]);
|
|
1019
1028
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1020
1029
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1021
1030
|
const prevDeltaRef = useRef(0);
|
|
@@ -1090,13 +1099,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1090
1099
|
|
|
1091
1100
|
// Limit the frequency of localStorage updates.
|
|
1092
1101
|
if (debouncedSave == null) {
|
|
1093
|
-
debouncedSave = debounce(
|
|
1102
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1094
1103
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1095
1104
|
}
|
|
1096
1105
|
|
|
1097
|
-
// Clone
|
|
1098
|
-
//
|
|
1099
|
-
|
|
1106
|
+
// Clone mutable data before passing to the debounced function,
|
|
1107
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1108
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1109
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1110
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1100
1111
|
}
|
|
1101
1112
|
}, [autoSaveId, layout, storage]);
|
|
1102
1113
|
|
|
@@ -811,11 +811,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
811
811
|
}
|
|
812
812
|
}
|
|
813
813
|
|
|
814
|
+
function getPanelGroupKey(autoSaveId) {
|
|
815
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
816
|
+
}
|
|
817
|
+
|
|
814
818
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
815
819
|
// so they should not be used as part of the serialization key.
|
|
816
820
|
// Using the min/max size attributes should work well enough as a backup.
|
|
817
821
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
818
|
-
function
|
|
822
|
+
function getPanelKey(panels) {
|
|
819
823
|
return panels.map(panel => {
|
|
820
824
|
const {
|
|
821
825
|
constraints,
|
|
@@ -826,13 +830,14 @@ function getSerializationKey(panels) {
|
|
|
826
830
|
if (idIsFromProps) {
|
|
827
831
|
return id;
|
|
828
832
|
} else {
|
|
829
|
-
return `${order}:${JSON.stringify(constraints)}
|
|
833
|
+
return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
|
|
830
834
|
}
|
|
831
835
|
}).sort((a, b) => a.localeCompare(b)).join(",");
|
|
832
836
|
}
|
|
833
837
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
834
838
|
try {
|
|
835
|
-
const
|
|
839
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
840
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
836
841
|
if (serialized) {
|
|
837
842
|
const parsed = JSON.parse(serialized);
|
|
838
843
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -842,12 +847,17 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
842
847
|
} catch (error) {}
|
|
843
848
|
return null;
|
|
844
849
|
}
|
|
845
|
-
function
|
|
846
|
-
|
|
847
|
-
const
|
|
848
|
-
|
|
850
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
851
|
+
var _loadSerializedPanelG2;
|
|
852
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
853
|
+
const panelKey = getPanelKey(panels);
|
|
854
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
855
|
+
state[panelKey] = {
|
|
856
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
857
|
+
layout: sizes
|
|
858
|
+
};
|
|
849
859
|
try {
|
|
850
|
-
storage.setItem(
|
|
860
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
851
861
|
} catch (error) {
|
|
852
862
|
console.error(error);
|
|
853
863
|
}
|
|
@@ -991,7 +1001,6 @@ function PanelGroupWithForwardedRef({
|
|
|
991
1001
|
const groupId = useUniqueId(idFromProps);
|
|
992
1002
|
const [dragState, setDragState] = useState(null);
|
|
993
1003
|
const [layout, setLayout] = useState([]);
|
|
994
|
-
useState([]);
|
|
995
1004
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
996
1005
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
997
1006
|
const prevDeltaRef = useRef(0);
|
|
@@ -1066,13 +1075,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1066
1075
|
|
|
1067
1076
|
// Limit the frequency of localStorage updates.
|
|
1068
1077
|
if (debouncedSave == null) {
|
|
1069
|
-
debouncedSave = debounce(
|
|
1078
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1070
1079
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1071
1080
|
}
|
|
1072
1081
|
|
|
1073
|
-
// Clone
|
|
1074
|
-
//
|
|
1075
|
-
|
|
1082
|
+
// Clone mutable data before passing to the debounced function,
|
|
1083
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1084
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1085
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1086
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1076
1087
|
}
|
|
1077
1088
|
}, [autoSaveId, layout, storage]);
|
|
1078
1089
|
|
|
@@ -939,11 +939,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
939
939
|
}
|
|
940
940
|
}
|
|
941
941
|
|
|
942
|
+
function getPanelGroupKey(autoSaveId) {
|
|
943
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
944
|
+
}
|
|
945
|
+
|
|
942
946
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
943
947
|
// so they should not be used as part of the serialization key.
|
|
944
948
|
// Using the min/max size attributes should work well enough as a backup.
|
|
945
949
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
946
|
-
function
|
|
950
|
+
function getPanelKey(panels) {
|
|
947
951
|
return panels.map(panel => {
|
|
948
952
|
const {
|
|
949
953
|
constraints,
|
|
@@ -954,13 +958,14 @@ function getSerializationKey(panels) {
|
|
|
954
958
|
if (idIsFromProps) {
|
|
955
959
|
return id;
|
|
956
960
|
} else {
|
|
957
|
-
return `${order}:${JSON.stringify(constraints)}
|
|
961
|
+
return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
|
|
958
962
|
}
|
|
959
963
|
}).sort((a, b) => a.localeCompare(b)).join(",");
|
|
960
964
|
}
|
|
961
965
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
962
966
|
try {
|
|
963
|
-
const
|
|
967
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
968
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
964
969
|
if (serialized) {
|
|
965
970
|
const parsed = JSON.parse(serialized);
|
|
966
971
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -970,21 +975,23 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
970
975
|
} catch (error) {}
|
|
971
976
|
return null;
|
|
972
977
|
}
|
|
973
|
-
function
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
979
|
-
}
|
|
980
|
-
return null;
|
|
978
|
+
function loadPanelGroupState(autoSaveId, panels, storage) {
|
|
979
|
+
var _loadSerializedPanelG, _state$panelKey;
|
|
980
|
+
const state = (_loadSerializedPanelG = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG !== void 0 ? _loadSerializedPanelG : {};
|
|
981
|
+
const panelKey = getPanelKey(panels);
|
|
982
|
+
return (_state$panelKey = state[panelKey]) !== null && _state$panelKey !== void 0 ? _state$panelKey : null;
|
|
981
983
|
}
|
|
982
|
-
function
|
|
983
|
-
|
|
984
|
-
const
|
|
985
|
-
|
|
984
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
985
|
+
var _loadSerializedPanelG2;
|
|
986
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
987
|
+
const panelKey = getPanelKey(panels);
|
|
988
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
989
|
+
state[panelKey] = {
|
|
990
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
991
|
+
layout: sizes
|
|
992
|
+
};
|
|
986
993
|
try {
|
|
987
|
-
storage.setItem(
|
|
994
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
988
995
|
} catch (error) {
|
|
989
996
|
console.error(error);
|
|
990
997
|
}
|
|
@@ -1081,7 +1088,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1081
1088
|
const groupId = useUniqueId(idFromProps);
|
|
1082
1089
|
const [dragState, setDragState] = useState(null);
|
|
1083
1090
|
const [layout, setLayout] = useState([]);
|
|
1084
|
-
useState([]);
|
|
1085
1091
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1086
1092
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1087
1093
|
const prevDeltaRef = useRef(0);
|
|
@@ -1164,13 +1170,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1164
1170
|
|
|
1165
1171
|
// Limit the frequency of localStorage updates.
|
|
1166
1172
|
if (debouncedSave == null) {
|
|
1167
|
-
debouncedSave = debounce(
|
|
1173
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1168
1174
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1169
1175
|
}
|
|
1170
1176
|
|
|
1171
|
-
// Clone
|
|
1172
|
-
//
|
|
1173
|
-
|
|
1177
|
+
// Clone mutable data before passing to the debounced function,
|
|
1178
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1179
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1180
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1181
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1174
1182
|
}
|
|
1175
1183
|
}, [autoSaveId, layout, storage]);
|
|
1176
1184
|
|
|
@@ -1357,7 +1365,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1357
1365
|
// default size should be restored from local storage if possible.
|
|
1358
1366
|
let unsafeLayout = null;
|
|
1359
1367
|
if (autoSaveId) {
|
|
1360
|
-
|
|
1368
|
+
const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
|
|
1369
|
+
if (state) {
|
|
1370
|
+
panelSizeBeforeCollapseRef.current = new Map(Object.entries(state.expandToSizes));
|
|
1371
|
+
unsafeLayout = state.layout;
|
|
1372
|
+
}
|
|
1361
1373
|
}
|
|
1362
1374
|
if (unsafeLayout == null) {
|
|
1363
1375
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -824,11 +824,15 @@ function initializeDefaultStorage(storageObject) {
|
|
|
824
824
|
}
|
|
825
825
|
}
|
|
826
826
|
|
|
827
|
+
function getPanelGroupKey(autoSaveId) {
|
|
828
|
+
return `react-resizable-panels:${autoSaveId}`;
|
|
829
|
+
}
|
|
830
|
+
|
|
827
831
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
828
832
|
// so they should not be used as part of the serialization key.
|
|
829
833
|
// Using the min/max size attributes should work well enough as a backup.
|
|
830
834
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
831
|
-
function
|
|
835
|
+
function getPanelKey(panels) {
|
|
832
836
|
return panels.map(panel => {
|
|
833
837
|
const {
|
|
834
838
|
constraints,
|
|
@@ -839,13 +843,14 @@ function getSerializationKey(panels) {
|
|
|
839
843
|
if (idIsFromProps) {
|
|
840
844
|
return id;
|
|
841
845
|
} else {
|
|
842
|
-
return `${order}:${JSON.stringify(constraints)}
|
|
846
|
+
return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
|
|
843
847
|
}
|
|
844
848
|
}).sort((a, b) => a.localeCompare(b)).join(",");
|
|
845
849
|
}
|
|
846
850
|
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
847
851
|
try {
|
|
848
|
-
const
|
|
852
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
853
|
+
const serialized = storage.getItem(panelGroupKey);
|
|
849
854
|
if (serialized) {
|
|
850
855
|
const parsed = JSON.parse(serialized);
|
|
851
856
|
if (typeof parsed === "object" && parsed != null) {
|
|
@@ -855,12 +860,17 @@ function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
|
855
860
|
} catch (error) {}
|
|
856
861
|
return null;
|
|
857
862
|
}
|
|
858
|
-
function
|
|
859
|
-
|
|
860
|
-
const
|
|
861
|
-
|
|
863
|
+
function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
|
|
864
|
+
var _loadSerializedPanelG2;
|
|
865
|
+
const panelGroupKey = getPanelGroupKey(autoSaveId);
|
|
866
|
+
const panelKey = getPanelKey(panels);
|
|
867
|
+
const state = (_loadSerializedPanelG2 = loadSerializedPanelGroupState(autoSaveId, storage)) !== null && _loadSerializedPanelG2 !== void 0 ? _loadSerializedPanelG2 : {};
|
|
868
|
+
state[panelKey] = {
|
|
869
|
+
expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
|
|
870
|
+
layout: sizes
|
|
871
|
+
};
|
|
862
872
|
try {
|
|
863
|
-
storage.setItem(
|
|
873
|
+
storage.setItem(panelGroupKey, JSON.stringify(state));
|
|
864
874
|
} catch (error) {
|
|
865
875
|
console.error(error);
|
|
866
876
|
}
|
|
@@ -957,7 +967,6 @@ function PanelGroupWithForwardedRef({
|
|
|
957
967
|
const groupId = useUniqueId(idFromProps);
|
|
958
968
|
const [dragState, setDragState] = useState(null);
|
|
959
969
|
const [layout, setLayout] = useState([]);
|
|
960
|
-
useState([]);
|
|
961
970
|
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
962
971
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
963
972
|
const prevDeltaRef = useRef(0);
|
|
@@ -1032,13 +1041,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1032
1041
|
|
|
1033
1042
|
// Limit the frequency of localStorage updates.
|
|
1034
1043
|
if (debouncedSave == null) {
|
|
1035
|
-
debouncedSave = debounce(
|
|
1044
|
+
debouncedSave = debounce(savePanelGroupState, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1036
1045
|
debounceMap[autoSaveId] = debouncedSave;
|
|
1037
1046
|
}
|
|
1038
1047
|
|
|
1039
|
-
// Clone
|
|
1040
|
-
//
|
|
1041
|
-
|
|
1048
|
+
// Clone mutable data before passing to the debounced function,
|
|
1049
|
+
// else we run the risk of saving an incorrect combination of mutable and immutable values to state.
|
|
1050
|
+
const clonedPanelDataArray = [...panelDataArray];
|
|
1051
|
+
const clonedPanelSizesBeforeCollapse = new Map(panelSizeBeforeCollapseRef.current);
|
|
1052
|
+
debouncedSave(autoSaveId, clonedPanelDataArray, clonedPanelSizesBeforeCollapse, layout, storage);
|
|
1042
1053
|
}
|
|
1043
1054
|
}, [autoSaveId, layout, storage]);
|
|
1044
1055
|
|