react-resizable-panels 0.0.50 → 0.0.51
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 +4 -0
- package/dist/react-resizable-panels.cjs.js +42 -33
- package/dist/react-resizable-panels.development.cjs.js +42 -33
- package/dist/react-resizable-panels.development.esm.js +42 -33
- package/dist/react-resizable-panels.esm.js +42 -33
- package/package.json +1 -1
- package/src/PanelGroup.ts +40 -21
- package/src/utils/group.ts +12 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.51
|
|
4
|
+
* [154](https://github.com/bvaughn/react-resizable-panels/issues/154): `onResize` and `onCollapse` props are called in response to `PanelGroup.setLayout`
|
|
5
|
+
* [123](https://github.com/bvaughn/react-resizable-panels/issues/123): `onResize` called when number of panels in a group change due to conditional rendering
|
|
6
|
+
|
|
3
7
|
## 0.0.50
|
|
4
8
|
* Improved panel size validation in `PanelGroup`.
|
|
5
9
|
|
|
@@ -281,27 +281,29 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
281
281
|
nextSizes[index] = baseSizes[index] + deltaApplied;
|
|
282
282
|
return nextSizes;
|
|
283
283
|
}
|
|
284
|
-
function callPanelCallbacks(panelsArray,
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
284
|
+
function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
285
|
+
sizes.forEach((size, index) => {
|
|
286
|
+
const {
|
|
287
|
+
callbacksRef,
|
|
288
|
+
collapsible,
|
|
289
|
+
id
|
|
290
|
+
} = panelsArray[index].current;
|
|
291
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[id];
|
|
292
|
+
if (lastNotifiedSize !== size) {
|
|
293
|
+
panelIdToLastNotifiedSizeMap[id] = size;
|
|
292
294
|
const {
|
|
293
295
|
onCollapse,
|
|
294
296
|
onResize
|
|
295
297
|
} = callbacksRef.current;
|
|
296
298
|
if (onResize) {
|
|
297
|
-
onResize(
|
|
299
|
+
onResize(size);
|
|
298
300
|
}
|
|
299
301
|
if (collapsible && onCollapse) {
|
|
300
302
|
// Falsy check handles both previous size of 0
|
|
301
303
|
// and initial size of undefined (when mounting)
|
|
302
|
-
if (!
|
|
304
|
+
if (!lastNotifiedSize && size !== 0) {
|
|
303
305
|
onCollapse(false);
|
|
304
|
-
} else if (
|
|
306
|
+
} else if (lastNotifiedSize !== 0 && size === 0) {
|
|
305
307
|
onCollapse(true);
|
|
306
308
|
}
|
|
307
309
|
}
|
|
@@ -837,6 +839,7 @@ function PanelGroupWithForwardedRef({
|
|
|
837
839
|
useEffect(() => {
|
|
838
840
|
callbacksRef.current.onLayout = onLayout;
|
|
839
841
|
});
|
|
842
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
840
843
|
|
|
841
844
|
// 0-1 values representing the relative size of each panel.
|
|
842
845
|
const [sizes, setSizes] = useState([]);
|
|
@@ -861,6 +864,12 @@ function PanelGroupWithForwardedRef({
|
|
|
861
864
|
setLayout: sizes => {
|
|
862
865
|
const total = sizes.reduce((accumulated, current) => accumulated + current, 0);
|
|
863
866
|
assert(total === 100, "Panel sizes must add up to 100%");
|
|
867
|
+
const {
|
|
868
|
+
panels
|
|
869
|
+
} = committedValuesRef.current;
|
|
870
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
871
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
872
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
864
873
|
setSizes(sizes);
|
|
865
874
|
}
|
|
866
875
|
}), []);
|
|
@@ -885,31 +894,23 @@ function PanelGroupWithForwardedRef({
|
|
|
885
894
|
} = callbacksRef.current;
|
|
886
895
|
if (onLayout) {
|
|
887
896
|
const {
|
|
897
|
+
panels,
|
|
888
898
|
sizes
|
|
889
899
|
} = committedValuesRef.current;
|
|
890
900
|
|
|
891
901
|
// Don't commit layout until all panels have registered and re-rendered with their actual sizes.
|
|
892
902
|
if (sizes.length > 0) {
|
|
893
903
|
onLayout(sizes);
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
}, [sizes]);
|
|
904
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
897
905
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
panels,
|
|
907
|
-
sizes
|
|
908
|
-
} = committedValuesRef.current;
|
|
909
|
-
if (sizes.length > 0) {
|
|
910
|
-
didNotifyCallbacksAfterMountRef.current = true;
|
|
911
|
-
const panelsArray = panelsMapToSortedArray(panels);
|
|
912
|
-
callPanelCallbacks(panelsArray, [], sizes);
|
|
906
|
+
// When possible, we notify before the next render so that rendering work can be batched together.
|
|
907
|
+
// Some cases are difficult to detect though,
|
|
908
|
+
// for example– panels that are conditionally rendered can affect the size of neighboring panels.
|
|
909
|
+
// In this case, the best we can do is notify on commit.
|
|
910
|
+
// The callPanelCallbacks() uses its own memoization to avoid notifying panels twice in these cases.
|
|
911
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
912
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
913
|
+
}
|
|
913
914
|
}
|
|
914
915
|
}, [sizes]);
|
|
915
916
|
|
|
@@ -1073,8 +1074,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1073
1074
|
}
|
|
1074
1075
|
}
|
|
1075
1076
|
if (sizesChanged) {
|
|
1077
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1078
|
+
|
|
1076
1079
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1077
|
-
callPanelCallbacks(panelsArray,
|
|
1080
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1078
1081
|
setSizes(nextSizes);
|
|
1079
1082
|
}
|
|
1080
1083
|
prevDeltaRef.current = delta;
|
|
@@ -1119,8 +1122,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1119
1122
|
const delta = isLastPanel ? currentSize : 0 - currentSize;
|
|
1120
1123
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1121
1124
|
if (prevSizes !== nextSizes) {
|
|
1125
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1126
|
+
|
|
1122
1127
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1123
|
-
callPanelCallbacks(panelsArray,
|
|
1128
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1124
1129
|
setSizes(nextSizes);
|
|
1125
1130
|
}
|
|
1126
1131
|
}, []);
|
|
@@ -1155,8 +1160,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1155
1160
|
const delta = isLastPanel ? 0 - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1156
1161
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1157
1162
|
if (prevSizes !== nextSizes) {
|
|
1163
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1164
|
+
|
|
1158
1165
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1159
|
-
callPanelCallbacks(panelsArray,
|
|
1166
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1160
1167
|
setSizes(nextSizes);
|
|
1161
1168
|
}
|
|
1162
1169
|
}, []);
|
|
@@ -1189,8 +1196,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1189
1196
|
const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
|
|
1190
1197
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1191
1198
|
if (prevSizes !== nextSizes) {
|
|
1199
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1200
|
+
|
|
1192
1201
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1193
|
-
callPanelCallbacks(panelsArray,
|
|
1202
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1194
1203
|
setSizes(nextSizes);
|
|
1195
1204
|
}
|
|
1196
1205
|
}, []);
|
|
@@ -281,27 +281,29 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
281
281
|
nextSizes[index] = baseSizes[index] + deltaApplied;
|
|
282
282
|
return nextSizes;
|
|
283
283
|
}
|
|
284
|
-
function callPanelCallbacks(panelsArray,
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
284
|
+
function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
285
|
+
sizes.forEach((size, index) => {
|
|
286
|
+
const {
|
|
287
|
+
callbacksRef,
|
|
288
|
+
collapsible,
|
|
289
|
+
id
|
|
290
|
+
} = panelsArray[index].current;
|
|
291
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[id];
|
|
292
|
+
if (lastNotifiedSize !== size) {
|
|
293
|
+
panelIdToLastNotifiedSizeMap[id] = size;
|
|
292
294
|
const {
|
|
293
295
|
onCollapse,
|
|
294
296
|
onResize
|
|
295
297
|
} = callbacksRef.current;
|
|
296
298
|
if (onResize) {
|
|
297
|
-
onResize(
|
|
299
|
+
onResize(size);
|
|
298
300
|
}
|
|
299
301
|
if (collapsible && onCollapse) {
|
|
300
302
|
// Falsy check handles both previous size of 0
|
|
301
303
|
// and initial size of undefined (when mounting)
|
|
302
|
-
if (!
|
|
304
|
+
if (!lastNotifiedSize && size !== 0) {
|
|
303
305
|
onCollapse(false);
|
|
304
|
-
} else if (
|
|
306
|
+
} else if (lastNotifiedSize !== 0 && size === 0) {
|
|
305
307
|
onCollapse(true);
|
|
306
308
|
}
|
|
307
309
|
}
|
|
@@ -844,6 +846,7 @@ function PanelGroupWithForwardedRef({
|
|
|
844
846
|
useEffect(() => {
|
|
845
847
|
callbacksRef.current.onLayout = onLayout;
|
|
846
848
|
});
|
|
849
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
847
850
|
|
|
848
851
|
// 0-1 values representing the relative size of each panel.
|
|
849
852
|
const [sizes, setSizes] = useState([]);
|
|
@@ -868,6 +871,12 @@ function PanelGroupWithForwardedRef({
|
|
|
868
871
|
setLayout: sizes => {
|
|
869
872
|
const total = sizes.reduce((accumulated, current) => accumulated + current, 0);
|
|
870
873
|
assert(total === 100, "Panel sizes must add up to 100%");
|
|
874
|
+
const {
|
|
875
|
+
panels
|
|
876
|
+
} = committedValuesRef.current;
|
|
877
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
878
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
879
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
871
880
|
setSizes(sizes);
|
|
872
881
|
}
|
|
873
882
|
}), []);
|
|
@@ -892,31 +901,23 @@ function PanelGroupWithForwardedRef({
|
|
|
892
901
|
} = callbacksRef.current;
|
|
893
902
|
if (onLayout) {
|
|
894
903
|
const {
|
|
904
|
+
panels,
|
|
895
905
|
sizes
|
|
896
906
|
} = committedValuesRef.current;
|
|
897
907
|
|
|
898
908
|
// Don't commit layout until all panels have registered and re-rendered with their actual sizes.
|
|
899
909
|
if (sizes.length > 0) {
|
|
900
910
|
onLayout(sizes);
|
|
901
|
-
|
|
902
|
-
}
|
|
903
|
-
}, [sizes]);
|
|
911
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
904
912
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
panels,
|
|
914
|
-
sizes
|
|
915
|
-
} = committedValuesRef.current;
|
|
916
|
-
if (sizes.length > 0) {
|
|
917
|
-
didNotifyCallbacksAfterMountRef.current = true;
|
|
918
|
-
const panelsArray = panelsMapToSortedArray(panels);
|
|
919
|
-
callPanelCallbacks(panelsArray, [], sizes);
|
|
913
|
+
// When possible, we notify before the next render so that rendering work can be batched together.
|
|
914
|
+
// Some cases are difficult to detect though,
|
|
915
|
+
// for example– panels that are conditionally rendered can affect the size of neighboring panels.
|
|
916
|
+
// In this case, the best we can do is notify on commit.
|
|
917
|
+
// The callPanelCallbacks() uses its own memoization to avoid notifying panels twice in these cases.
|
|
918
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
919
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
920
|
+
}
|
|
920
921
|
}
|
|
921
922
|
}, [sizes]);
|
|
922
923
|
|
|
@@ -1085,8 +1086,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1085
1086
|
}
|
|
1086
1087
|
}
|
|
1087
1088
|
if (sizesChanged) {
|
|
1089
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1090
|
+
|
|
1088
1091
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1089
|
-
callPanelCallbacks(panelsArray,
|
|
1092
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1090
1093
|
setSizes(nextSizes);
|
|
1091
1094
|
}
|
|
1092
1095
|
prevDeltaRef.current = delta;
|
|
@@ -1131,8 +1134,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1131
1134
|
const delta = isLastPanel ? currentSize : 0 - currentSize;
|
|
1132
1135
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1133
1136
|
if (prevSizes !== nextSizes) {
|
|
1137
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1138
|
+
|
|
1134
1139
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1135
|
-
callPanelCallbacks(panelsArray,
|
|
1140
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1136
1141
|
setSizes(nextSizes);
|
|
1137
1142
|
}
|
|
1138
1143
|
}, []);
|
|
@@ -1167,8 +1172,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1167
1172
|
const delta = isLastPanel ? 0 - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1168
1173
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1169
1174
|
if (prevSizes !== nextSizes) {
|
|
1175
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1176
|
+
|
|
1170
1177
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1171
|
-
callPanelCallbacks(panelsArray,
|
|
1178
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1172
1179
|
setSizes(nextSizes);
|
|
1173
1180
|
}
|
|
1174
1181
|
}, []);
|
|
@@ -1201,8 +1208,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1201
1208
|
const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
|
|
1202
1209
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1203
1210
|
if (prevSizes !== nextSizes) {
|
|
1211
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1212
|
+
|
|
1204
1213
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1205
|
-
callPanelCallbacks(panelsArray,
|
|
1214
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1206
1215
|
setSizes(nextSizes);
|
|
1207
1216
|
}
|
|
1208
1217
|
}, []);
|
|
@@ -257,27 +257,29 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
257
257
|
nextSizes[index] = baseSizes[index] + deltaApplied;
|
|
258
258
|
return nextSizes;
|
|
259
259
|
}
|
|
260
|
-
function callPanelCallbacks(panelsArray,
|
|
261
|
-
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
260
|
+
function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
261
|
+
sizes.forEach((size, index) => {
|
|
262
|
+
const {
|
|
263
|
+
callbacksRef,
|
|
264
|
+
collapsible,
|
|
265
|
+
id
|
|
266
|
+
} = panelsArray[index].current;
|
|
267
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[id];
|
|
268
|
+
if (lastNotifiedSize !== size) {
|
|
269
|
+
panelIdToLastNotifiedSizeMap[id] = size;
|
|
268
270
|
const {
|
|
269
271
|
onCollapse,
|
|
270
272
|
onResize
|
|
271
273
|
} = callbacksRef.current;
|
|
272
274
|
if (onResize) {
|
|
273
|
-
onResize(
|
|
275
|
+
onResize(size);
|
|
274
276
|
}
|
|
275
277
|
if (collapsible && onCollapse) {
|
|
276
278
|
// Falsy check handles both previous size of 0
|
|
277
279
|
// and initial size of undefined (when mounting)
|
|
278
|
-
if (!
|
|
280
|
+
if (!lastNotifiedSize && size !== 0) {
|
|
279
281
|
onCollapse(false);
|
|
280
|
-
} else if (
|
|
282
|
+
} else if (lastNotifiedSize !== 0 && size === 0) {
|
|
281
283
|
onCollapse(true);
|
|
282
284
|
}
|
|
283
285
|
}
|
|
@@ -820,6 +822,7 @@ function PanelGroupWithForwardedRef({
|
|
|
820
822
|
useEffect(() => {
|
|
821
823
|
callbacksRef.current.onLayout = onLayout;
|
|
822
824
|
});
|
|
825
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
823
826
|
|
|
824
827
|
// 0-1 values representing the relative size of each panel.
|
|
825
828
|
const [sizes, setSizes] = useState([]);
|
|
@@ -844,6 +847,12 @@ function PanelGroupWithForwardedRef({
|
|
|
844
847
|
setLayout: sizes => {
|
|
845
848
|
const total = sizes.reduce((accumulated, current) => accumulated + current, 0);
|
|
846
849
|
assert(total === 100, "Panel sizes must add up to 100%");
|
|
850
|
+
const {
|
|
851
|
+
panels
|
|
852
|
+
} = committedValuesRef.current;
|
|
853
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
854
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
855
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
847
856
|
setSizes(sizes);
|
|
848
857
|
}
|
|
849
858
|
}), []);
|
|
@@ -868,31 +877,23 @@ function PanelGroupWithForwardedRef({
|
|
|
868
877
|
} = callbacksRef.current;
|
|
869
878
|
if (onLayout) {
|
|
870
879
|
const {
|
|
880
|
+
panels,
|
|
871
881
|
sizes
|
|
872
882
|
} = committedValuesRef.current;
|
|
873
883
|
|
|
874
884
|
// Don't commit layout until all panels have registered and re-rendered with their actual sizes.
|
|
875
885
|
if (sizes.length > 0) {
|
|
876
886
|
onLayout(sizes);
|
|
877
|
-
|
|
878
|
-
}
|
|
879
|
-
}, [sizes]);
|
|
887
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
880
888
|
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
panels,
|
|
890
|
-
sizes
|
|
891
|
-
} = committedValuesRef.current;
|
|
892
|
-
if (sizes.length > 0) {
|
|
893
|
-
didNotifyCallbacksAfterMountRef.current = true;
|
|
894
|
-
const panelsArray = panelsMapToSortedArray(panels);
|
|
895
|
-
callPanelCallbacks(panelsArray, [], sizes);
|
|
889
|
+
// When possible, we notify before the next render so that rendering work can be batched together.
|
|
890
|
+
// Some cases are difficult to detect though,
|
|
891
|
+
// for example– panels that are conditionally rendered can affect the size of neighboring panels.
|
|
892
|
+
// In this case, the best we can do is notify on commit.
|
|
893
|
+
// The callPanelCallbacks() uses its own memoization to avoid notifying panels twice in these cases.
|
|
894
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
895
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
896
|
+
}
|
|
896
897
|
}
|
|
897
898
|
}, [sizes]);
|
|
898
899
|
|
|
@@ -1061,8 +1062,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1061
1062
|
}
|
|
1062
1063
|
}
|
|
1063
1064
|
if (sizesChanged) {
|
|
1065
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1066
|
+
|
|
1064
1067
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1065
|
-
callPanelCallbacks(panelsArray,
|
|
1068
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1066
1069
|
setSizes(nextSizes);
|
|
1067
1070
|
}
|
|
1068
1071
|
prevDeltaRef.current = delta;
|
|
@@ -1107,8 +1110,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1107
1110
|
const delta = isLastPanel ? currentSize : 0 - currentSize;
|
|
1108
1111
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1109
1112
|
if (prevSizes !== nextSizes) {
|
|
1113
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1114
|
+
|
|
1110
1115
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1111
|
-
callPanelCallbacks(panelsArray,
|
|
1116
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1112
1117
|
setSizes(nextSizes);
|
|
1113
1118
|
}
|
|
1114
1119
|
}, []);
|
|
@@ -1143,8 +1148,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1143
1148
|
const delta = isLastPanel ? 0 - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1144
1149
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1145
1150
|
if (prevSizes !== nextSizes) {
|
|
1151
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1152
|
+
|
|
1146
1153
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1147
|
-
callPanelCallbacks(panelsArray,
|
|
1154
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1148
1155
|
setSizes(nextSizes);
|
|
1149
1156
|
}
|
|
1150
1157
|
}, []);
|
|
@@ -1177,8 +1184,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1177
1184
|
const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
|
|
1178
1185
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1179
1186
|
if (prevSizes !== nextSizes) {
|
|
1187
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1188
|
+
|
|
1180
1189
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1181
|
-
callPanelCallbacks(panelsArray,
|
|
1190
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1182
1191
|
setSizes(nextSizes);
|
|
1183
1192
|
}
|
|
1184
1193
|
}, []);
|
|
@@ -257,27 +257,29 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
257
257
|
nextSizes[index] = baseSizes[index] + deltaApplied;
|
|
258
258
|
return nextSizes;
|
|
259
259
|
}
|
|
260
|
-
function callPanelCallbacks(panelsArray,
|
|
261
|
-
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
260
|
+
function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
261
|
+
sizes.forEach((size, index) => {
|
|
262
|
+
const {
|
|
263
|
+
callbacksRef,
|
|
264
|
+
collapsible,
|
|
265
|
+
id
|
|
266
|
+
} = panelsArray[index].current;
|
|
267
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[id];
|
|
268
|
+
if (lastNotifiedSize !== size) {
|
|
269
|
+
panelIdToLastNotifiedSizeMap[id] = size;
|
|
268
270
|
const {
|
|
269
271
|
onCollapse,
|
|
270
272
|
onResize
|
|
271
273
|
} = callbacksRef.current;
|
|
272
274
|
if (onResize) {
|
|
273
|
-
onResize(
|
|
275
|
+
onResize(size);
|
|
274
276
|
}
|
|
275
277
|
if (collapsible && onCollapse) {
|
|
276
278
|
// Falsy check handles both previous size of 0
|
|
277
279
|
// and initial size of undefined (when mounting)
|
|
278
|
-
if (!
|
|
280
|
+
if (!lastNotifiedSize && size !== 0) {
|
|
279
281
|
onCollapse(false);
|
|
280
|
-
} else if (
|
|
282
|
+
} else if (lastNotifiedSize !== 0 && size === 0) {
|
|
281
283
|
onCollapse(true);
|
|
282
284
|
}
|
|
283
285
|
}
|
|
@@ -813,6 +815,7 @@ function PanelGroupWithForwardedRef({
|
|
|
813
815
|
useEffect(() => {
|
|
814
816
|
callbacksRef.current.onLayout = onLayout;
|
|
815
817
|
});
|
|
818
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
816
819
|
|
|
817
820
|
// 0-1 values representing the relative size of each panel.
|
|
818
821
|
const [sizes, setSizes] = useState([]);
|
|
@@ -837,6 +840,12 @@ function PanelGroupWithForwardedRef({
|
|
|
837
840
|
setLayout: sizes => {
|
|
838
841
|
const total = sizes.reduce((accumulated, current) => accumulated + current, 0);
|
|
839
842
|
assert(total === 100, "Panel sizes must add up to 100%");
|
|
843
|
+
const {
|
|
844
|
+
panels
|
|
845
|
+
} = committedValuesRef.current;
|
|
846
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
847
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
848
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
840
849
|
setSizes(sizes);
|
|
841
850
|
}
|
|
842
851
|
}), []);
|
|
@@ -861,31 +870,23 @@ function PanelGroupWithForwardedRef({
|
|
|
861
870
|
} = callbacksRef.current;
|
|
862
871
|
if (onLayout) {
|
|
863
872
|
const {
|
|
873
|
+
panels,
|
|
864
874
|
sizes
|
|
865
875
|
} = committedValuesRef.current;
|
|
866
876
|
|
|
867
877
|
// Don't commit layout until all panels have registered and re-rendered with their actual sizes.
|
|
868
878
|
if (sizes.length > 0) {
|
|
869
879
|
onLayout(sizes);
|
|
870
|
-
|
|
871
|
-
}
|
|
872
|
-
}, [sizes]);
|
|
880
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
873
881
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
panels,
|
|
883
|
-
sizes
|
|
884
|
-
} = committedValuesRef.current;
|
|
885
|
-
if (sizes.length > 0) {
|
|
886
|
-
didNotifyCallbacksAfterMountRef.current = true;
|
|
887
|
-
const panelsArray = panelsMapToSortedArray(panels);
|
|
888
|
-
callPanelCallbacks(panelsArray, [], sizes);
|
|
882
|
+
// When possible, we notify before the next render so that rendering work can be batched together.
|
|
883
|
+
// Some cases are difficult to detect though,
|
|
884
|
+
// for example– panels that are conditionally rendered can affect the size of neighboring panels.
|
|
885
|
+
// In this case, the best we can do is notify on commit.
|
|
886
|
+
// The callPanelCallbacks() uses its own memoization to avoid notifying panels twice in these cases.
|
|
887
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
888
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
889
|
+
}
|
|
889
890
|
}
|
|
890
891
|
}, [sizes]);
|
|
891
892
|
|
|
@@ -1049,8 +1050,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1049
1050
|
}
|
|
1050
1051
|
}
|
|
1051
1052
|
if (sizesChanged) {
|
|
1053
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1054
|
+
|
|
1052
1055
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1053
|
-
callPanelCallbacks(panelsArray,
|
|
1056
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1054
1057
|
setSizes(nextSizes);
|
|
1055
1058
|
}
|
|
1056
1059
|
prevDeltaRef.current = delta;
|
|
@@ -1095,8 +1098,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1095
1098
|
const delta = isLastPanel ? currentSize : 0 - currentSize;
|
|
1096
1099
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1097
1100
|
if (prevSizes !== nextSizes) {
|
|
1101
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1102
|
+
|
|
1098
1103
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1099
|
-
callPanelCallbacks(panelsArray,
|
|
1104
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1100
1105
|
setSizes(nextSizes);
|
|
1101
1106
|
}
|
|
1102
1107
|
}, []);
|
|
@@ -1131,8 +1136,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1131
1136
|
const delta = isLastPanel ? 0 - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1132
1137
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1133
1138
|
if (prevSizes !== nextSizes) {
|
|
1139
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1140
|
+
|
|
1134
1141
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1135
|
-
callPanelCallbacks(panelsArray,
|
|
1142
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1136
1143
|
setSizes(nextSizes);
|
|
1137
1144
|
}
|
|
1138
1145
|
}, []);
|
|
@@ -1165,8 +1172,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1165
1172
|
const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
|
|
1166
1173
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1167
1174
|
if (prevSizes !== nextSizes) {
|
|
1175
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1176
|
+
|
|
1168
1177
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1169
|
-
callPanelCallbacks(panelsArray,
|
|
1178
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1170
1179
|
setSizes(nextSizes);
|
|
1171
1180
|
}
|
|
1172
1181
|
}, []);
|
package/package.json
CHANGED
package/src/PanelGroup.ts
CHANGED
|
@@ -169,6 +169,8 @@ function PanelGroupWithForwardedRef({
|
|
|
169
169
|
callbacksRef.current.onLayout = onLayout;
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
+
const panelIdToLastNotifiedSizeMapRef = useRef<Record<string, number>>({});
|
|
173
|
+
|
|
172
174
|
// 0-1 values representing the relative size of each panel.
|
|
173
175
|
const [sizes, setSizes] = useState<number[]>([]);
|
|
174
176
|
|
|
@@ -199,6 +201,13 @@ function PanelGroupWithForwardedRef({
|
|
|
199
201
|
|
|
200
202
|
assert(total === 100, "Panel sizes must add up to 100%");
|
|
201
203
|
|
|
204
|
+
const { panels } = committedValuesRef.current;
|
|
205
|
+
const panelIdToLastNotifiedSizeMap =
|
|
206
|
+
panelIdToLastNotifiedSizeMapRef.current;
|
|
207
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
208
|
+
|
|
209
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
210
|
+
|
|
202
211
|
setSizes(sizes);
|
|
203
212
|
},
|
|
204
213
|
}),
|
|
@@ -224,29 +233,23 @@ function PanelGroupWithForwardedRef({
|
|
|
224
233
|
useEffect(() => {
|
|
225
234
|
const { onLayout } = callbacksRef.current!;
|
|
226
235
|
if (onLayout) {
|
|
227
|
-
const { sizes } = committedValuesRef.current;
|
|
236
|
+
const { panels, sizes } = committedValuesRef.current;
|
|
228
237
|
|
|
229
238
|
// Don't commit layout until all panels have registered and re-rendered with their actual sizes.
|
|
230
239
|
if (sizes.length > 0) {
|
|
231
240
|
onLayout(sizes);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}, [sizes]);
|
|
235
|
-
|
|
236
|
-
// Notify Panel listeners about their initial sizes and collapsed state after mount.
|
|
237
|
-
// Subsequent changes will be called by the resizeHandler.
|
|
238
|
-
const didNotifyCallbacksAfterMountRef = useRef(false);
|
|
239
|
-
useIsomorphicLayoutEffect(() => {
|
|
240
|
-
if (didNotifyCallbacksAfterMountRef.current) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
241
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
didNotifyCallbacksAfterMountRef.current = true;
|
|
242
|
+
const panelIdToLastNotifiedSizeMap =
|
|
243
|
+
panelIdToLastNotifiedSizeMapRef.current;
|
|
247
244
|
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
// When possible, we notify before the next render so that rendering work can be batched together.
|
|
246
|
+
// Some cases are difficult to detect though,
|
|
247
|
+
// for example– panels that are conditionally rendered can affect the size of neighboring panels.
|
|
248
|
+
// In this case, the best we can do is notify on commit.
|
|
249
|
+
// The callPanelCallbacks() uses its own memoization to avoid notifying panels twice in these cases.
|
|
250
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
251
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
252
|
+
}
|
|
250
253
|
}
|
|
251
254
|
}, [sizes]);
|
|
252
255
|
|
|
@@ -481,8 +484,15 @@ function PanelGroupWithForwardedRef({
|
|
|
481
484
|
}
|
|
482
485
|
|
|
483
486
|
if (sizesChanged) {
|
|
487
|
+
const panelIdToLastNotifiedSizeMap =
|
|
488
|
+
panelIdToLastNotifiedSizeMapRef.current;
|
|
489
|
+
|
|
484
490
|
// If resize change handlers have been declared, this is the time to call them.
|
|
485
|
-
callPanelCallbacks(
|
|
491
|
+
callPanelCallbacks(
|
|
492
|
+
panelsArray,
|
|
493
|
+
nextSizes,
|
|
494
|
+
panelIdToLastNotifiedSizeMap
|
|
495
|
+
);
|
|
486
496
|
|
|
487
497
|
setSizes(nextSizes);
|
|
488
498
|
}
|
|
@@ -550,8 +560,11 @@ function PanelGroupWithForwardedRef({
|
|
|
550
560
|
null
|
|
551
561
|
);
|
|
552
562
|
if (prevSizes !== nextSizes) {
|
|
563
|
+
const panelIdToLastNotifiedSizeMap =
|
|
564
|
+
panelIdToLastNotifiedSizeMapRef.current;
|
|
565
|
+
|
|
553
566
|
// If resize change handlers have been declared, this is the time to call them.
|
|
554
|
-
callPanelCallbacks(panelsArray,
|
|
567
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
555
568
|
|
|
556
569
|
setSizes(nextSizes);
|
|
557
570
|
}
|
|
@@ -603,8 +616,11 @@ function PanelGroupWithForwardedRef({
|
|
|
603
616
|
null
|
|
604
617
|
);
|
|
605
618
|
if (prevSizes !== nextSizes) {
|
|
619
|
+
const panelIdToLastNotifiedSizeMap =
|
|
620
|
+
panelIdToLastNotifiedSizeMapRef.current;
|
|
621
|
+
|
|
606
622
|
// If resize change handlers have been declared, this is the time to call them.
|
|
607
|
-
callPanelCallbacks(panelsArray,
|
|
623
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
608
624
|
|
|
609
625
|
setSizes(nextSizes);
|
|
610
626
|
}
|
|
@@ -658,8 +674,11 @@ function PanelGroupWithForwardedRef({
|
|
|
658
674
|
null
|
|
659
675
|
);
|
|
660
676
|
if (prevSizes !== nextSizes) {
|
|
677
|
+
const panelIdToLastNotifiedSizeMap =
|
|
678
|
+
panelIdToLastNotifiedSizeMapRef.current;
|
|
679
|
+
|
|
661
680
|
// If resize change handlers have been declared, this is the time to call them.
|
|
662
|
-
callPanelCallbacks(panelsArray,
|
|
681
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
663
682
|
|
|
664
683
|
setSizes(nextSizes);
|
|
665
684
|
}
|
package/src/utils/group.ts
CHANGED
|
@@ -119,25 +119,28 @@ export function adjustByDelta(
|
|
|
119
119
|
|
|
120
120
|
export function callPanelCallbacks(
|
|
121
121
|
panelsArray: PanelData[],
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
sizes: number[],
|
|
123
|
+
panelIdToLastNotifiedSizeMap: Record<string, number>
|
|
124
124
|
) {
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
sizes.forEach((size, index) => {
|
|
126
|
+
const { callbacksRef, collapsible, id } = panelsArray[index].current;
|
|
127
|
+
|
|
128
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[id];
|
|
129
|
+
if (lastNotifiedSize !== size) {
|
|
130
|
+
panelIdToLastNotifiedSizeMap[id] = size;
|
|
131
|
+
|
|
129
132
|
const { onCollapse, onResize } = callbacksRef.current!;
|
|
130
133
|
|
|
131
134
|
if (onResize) {
|
|
132
|
-
onResize(
|
|
135
|
+
onResize(size);
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
if (collapsible && onCollapse) {
|
|
136
139
|
// Falsy check handles both previous size of 0
|
|
137
140
|
// and initial size of undefined (when mounting)
|
|
138
|
-
if (!
|
|
141
|
+
if (!lastNotifiedSize && size !== 0) {
|
|
139
142
|
onCollapse(false);
|
|
140
|
-
} else if (
|
|
143
|
+
} else if (lastNotifiedSize !== 0 && size === 0) {
|
|
141
144
|
onCollapse(true);
|
|
142
145
|
}
|
|
143
146
|
}
|