react-resizable-panels 0.0.51 → 0.0.53
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 +7 -0
- package/README.md +15 -14
- package/dist/declarations/src/Panel.d.ts +1 -0
- package/dist/declarations/src/types.d.ts +2 -1
- package/dist/react-resizable-panels.cjs.js +77 -42
- package/dist/react-resizable-panels.development.cjs.js +77 -42
- package/dist/react-resizable-panels.development.esm.js +77 -42
- package/dist/react-resizable-panels.esm.js +77 -42
- package/package.json +1 -1
- package/src/Panel.ts +5 -0
- package/src/PanelGroup.ts +47 -35
- package/src/types.ts +2 -1
- package/src/utils/group.ts +26 -16
|
@@ -45,6 +45,7 @@ PanelGroupContext.displayName = "PanelGroupContext";
|
|
|
45
45
|
function PanelWithForwardedRef({
|
|
46
46
|
children = null,
|
|
47
47
|
className: classNameFromProps = "",
|
|
48
|
+
collapsedSize = 0,
|
|
48
49
|
collapsible = false,
|
|
49
50
|
defaultSize = null,
|
|
50
51
|
forwardedRef,
|
|
@@ -102,6 +103,7 @@ function PanelWithForwardedRef({
|
|
|
102
103
|
});
|
|
103
104
|
const panelDataRef = useRef({
|
|
104
105
|
callbacksRef,
|
|
106
|
+
collapsedSize,
|
|
105
107
|
collapsible,
|
|
106
108
|
defaultSize,
|
|
107
109
|
id: panelId,
|
|
@@ -112,6 +114,7 @@ function PanelWithForwardedRef({
|
|
|
112
114
|
useIsomorphicLayoutEffect(() => {
|
|
113
115
|
committedValuesRef.current.size = parseSizeFromStyle(style);
|
|
114
116
|
panelDataRef.current.callbacksRef = callbacksRef;
|
|
117
|
+
panelDataRef.current.collapsedSize = collapsedSize;
|
|
115
118
|
panelDataRef.current.collapsible = collapsible;
|
|
116
119
|
panelDataRef.current.defaultSize = defaultSize;
|
|
117
120
|
panelDataRef.current.id = panelId;
|
|
@@ -259,11 +262,18 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
259
262
|
}
|
|
260
263
|
function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
261
264
|
sizes.forEach((size, index) => {
|
|
265
|
+
const panelRef = panelsArray[index];
|
|
266
|
+
if (!panelRef) {
|
|
267
|
+
// Handle initial mount (when panels are registered too late to be in the panels array)
|
|
268
|
+
// The subsequent render+effects will handle the resize notification
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
262
271
|
const {
|
|
263
272
|
callbacksRef,
|
|
273
|
+
collapsedSize,
|
|
264
274
|
collapsible,
|
|
265
275
|
id
|
|
266
|
-
} =
|
|
276
|
+
} = panelRef.current;
|
|
267
277
|
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[id];
|
|
268
278
|
if (lastNotifiedSize !== size) {
|
|
269
279
|
panelIdToLastNotifiedSizeMap[id] = size;
|
|
@@ -272,14 +282,12 @@ function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
|
272
282
|
onResize
|
|
273
283
|
} = callbacksRef.current;
|
|
274
284
|
if (onResize) {
|
|
275
|
-
onResize(size);
|
|
285
|
+
onResize(size, lastNotifiedSize);
|
|
276
286
|
}
|
|
277
287
|
if (collapsible && onCollapse) {
|
|
278
|
-
|
|
279
|
-
// and initial size of undefined (when mounting)
|
|
280
|
-
if (!lastNotifiedSize && size !== 0) {
|
|
288
|
+
if ((lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
281
289
|
onCollapse(false);
|
|
282
|
-
} else if (lastNotifiedSize !==
|
|
290
|
+
} else if (lastNotifiedSize !== collapsedSize && size === collapsedSize) {
|
|
283
291
|
onCollapse(true);
|
|
284
292
|
}
|
|
285
293
|
}
|
|
@@ -371,11 +379,17 @@ function panelsMapToSortedArray(panels) {
|
|
|
371
379
|
}
|
|
372
380
|
function safeResizePanel(panel, delta, prevSize, event) {
|
|
373
381
|
const nextSizeUnsafe = prevSize + delta;
|
|
374
|
-
|
|
375
|
-
|
|
382
|
+
const {
|
|
383
|
+
collapsedSize,
|
|
384
|
+
collapsible,
|
|
385
|
+
maxSize,
|
|
386
|
+
minSize
|
|
387
|
+
} = panel.current;
|
|
388
|
+
if (collapsible) {
|
|
389
|
+
if (prevSize > collapsedSize) {
|
|
376
390
|
// Mimic VS COde behavior; collapse a panel if it's smaller than half of its min-size
|
|
377
|
-
if (nextSizeUnsafe <=
|
|
378
|
-
return
|
|
391
|
+
if (nextSizeUnsafe <= minSize / 2 + collapsedSize) {
|
|
392
|
+
return collapsedSize;
|
|
379
393
|
}
|
|
380
394
|
} else {
|
|
381
395
|
const isKeyboardEvent = event?.type?.startsWith("key");
|
|
@@ -383,13 +397,13 @@ function safeResizePanel(panel, delta, prevSize, event) {
|
|
|
383
397
|
// Keyboard events should expand a collapsed panel to the min size,
|
|
384
398
|
// but mouse events should wait until the panel has reached its min size
|
|
385
399
|
// to avoid a visual flickering when dragging between collapsed and min size.
|
|
386
|
-
if (nextSizeUnsafe <
|
|
387
|
-
return
|
|
400
|
+
if (nextSizeUnsafe < minSize) {
|
|
401
|
+
return collapsedSize;
|
|
388
402
|
}
|
|
389
403
|
}
|
|
390
404
|
}
|
|
391
405
|
}
|
|
392
|
-
const nextSize = Math.min(
|
|
406
|
+
const nextSize = Math.min(maxSize, Math.max(minSize, nextSizeUnsafe));
|
|
393
407
|
return nextSize;
|
|
394
408
|
}
|
|
395
409
|
|
|
@@ -852,8 +866,8 @@ function PanelGroupWithForwardedRef({
|
|
|
852
866
|
} = committedValuesRef.current;
|
|
853
867
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
854
868
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
855
|
-
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
856
869
|
setSizes(sizes);
|
|
870
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
857
871
|
}
|
|
858
872
|
}), []);
|
|
859
873
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -875,25 +889,25 @@ function PanelGroupWithForwardedRef({
|
|
|
875
889
|
const {
|
|
876
890
|
onLayout
|
|
877
891
|
} = callbacksRef.current;
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
} = committedValuesRef.current;
|
|
892
|
+
const {
|
|
893
|
+
panels,
|
|
894
|
+
sizes
|
|
895
|
+
} = committedValuesRef.current;
|
|
883
896
|
|
|
884
|
-
|
|
885
|
-
|
|
897
|
+
// Don't commit layout until all panels have registered and re-rendered with their actual sizes.
|
|
898
|
+
if (sizes.length > 0) {
|
|
899
|
+
if (onLayout) {
|
|
886
900
|
onLayout(sizes);
|
|
887
|
-
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
888
|
-
|
|
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
901
|
}
|
|
902
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
903
|
+
|
|
904
|
+
// When possible, we notify before the next render so that rendering work can be batched together.
|
|
905
|
+
// Some cases are difficult to detect though,
|
|
906
|
+
// for example– panels that are conditionally rendered can affect the size of neighboring panels.
|
|
907
|
+
// In this case, the best we can do is notify on commit.
|
|
908
|
+
// The callPanelCallbacks() uses its own memoization to avoid notifying panels twice in these cases.
|
|
909
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
910
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
897
911
|
}
|
|
898
912
|
}, [sizes]);
|
|
899
913
|
|
|
@@ -1063,10 +1077,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1063
1077
|
}
|
|
1064
1078
|
if (sizesChanged) {
|
|
1065
1079
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1080
|
+
setSizes(nextSizes);
|
|
1066
1081
|
|
|
1067
1082
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1083
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1068
1084
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1069
|
-
setSizes(nextSizes);
|
|
1070
1085
|
}
|
|
1071
1086
|
prevDeltaRef.current = delta;
|
|
1072
1087
|
};
|
|
@@ -1088,7 +1103,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1088
1103
|
sizes: prevSizes
|
|
1089
1104
|
} = committedValuesRef.current;
|
|
1090
1105
|
const panel = panels.get(id);
|
|
1091
|
-
if (panel == null
|
|
1106
|
+
if (panel == null) {
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
const {
|
|
1110
|
+
collapsedSize,
|
|
1111
|
+
collapsible
|
|
1112
|
+
} = panel.current;
|
|
1113
|
+
if (!collapsible) {
|
|
1092
1114
|
return;
|
|
1093
1115
|
}
|
|
1094
1116
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
@@ -1097,7 +1119,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1097
1119
|
return;
|
|
1098
1120
|
}
|
|
1099
1121
|
const currentSize = prevSizes[index];
|
|
1100
|
-
if (currentSize ===
|
|
1122
|
+
if (currentSize === collapsedSize) {
|
|
1101
1123
|
// Panel is already collapsed.
|
|
1102
1124
|
return;
|
|
1103
1125
|
}
|
|
@@ -1107,14 +1129,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1107
1129
|
return;
|
|
1108
1130
|
}
|
|
1109
1131
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1110
|
-
const delta = isLastPanel ? currentSize :
|
|
1132
|
+
const delta = isLastPanel ? currentSize : collapsedSize - currentSize;
|
|
1111
1133
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1112
1134
|
if (prevSizes !== nextSizes) {
|
|
1113
1135
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1136
|
+
setSizes(nextSizes);
|
|
1114
1137
|
|
|
1115
1138
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1139
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1116
1140
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1117
|
-
setSizes(nextSizes);
|
|
1118
1141
|
}
|
|
1119
1142
|
}, []);
|
|
1120
1143
|
const expandPanel = useCallback(id => {
|
|
@@ -1126,7 +1149,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1126
1149
|
if (panel == null) {
|
|
1127
1150
|
return;
|
|
1128
1151
|
}
|
|
1129
|
-
const
|
|
1152
|
+
const {
|
|
1153
|
+
collapsedSize,
|
|
1154
|
+
minSize
|
|
1155
|
+
} = panel.current;
|
|
1156
|
+
const sizeBeforeCollapse = panelSizeBeforeCollapse.current.get(id) || minSize;
|
|
1130
1157
|
if (!sizeBeforeCollapse) {
|
|
1131
1158
|
return;
|
|
1132
1159
|
}
|
|
@@ -1136,7 +1163,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1136
1163
|
return;
|
|
1137
1164
|
}
|
|
1138
1165
|
const currentSize = prevSizes[index];
|
|
1139
|
-
if (currentSize !==
|
|
1166
|
+
if (currentSize !== collapsedSize) {
|
|
1140
1167
|
// Panel is already expanded.
|
|
1141
1168
|
return;
|
|
1142
1169
|
}
|
|
@@ -1145,14 +1172,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1145
1172
|
return;
|
|
1146
1173
|
}
|
|
1147
1174
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1148
|
-
const delta = isLastPanel ?
|
|
1175
|
+
const delta = isLastPanel ? collapsedSize - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1149
1176
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1150
1177
|
if (prevSizes !== nextSizes) {
|
|
1151
1178
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1179
|
+
setSizes(nextSizes);
|
|
1152
1180
|
|
|
1153
1181
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1182
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1154
1183
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1155
|
-
setSizes(nextSizes);
|
|
1156
1184
|
}
|
|
1157
1185
|
}, []);
|
|
1158
1186
|
const resizePanel = useCallback((id, nextSize) => {
|
|
@@ -1164,6 +1192,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1164
1192
|
if (panel == null) {
|
|
1165
1193
|
return;
|
|
1166
1194
|
}
|
|
1195
|
+
const {
|
|
1196
|
+
collapsedSize,
|
|
1197
|
+
collapsible,
|
|
1198
|
+
maxSize,
|
|
1199
|
+
minSize
|
|
1200
|
+
} = panel.current;
|
|
1167
1201
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
1168
1202
|
const index = panelsArray.indexOf(panel);
|
|
1169
1203
|
if (index < 0) {
|
|
@@ -1173,8 +1207,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1173
1207
|
if (currentSize === nextSize) {
|
|
1174
1208
|
return;
|
|
1175
1209
|
}
|
|
1176
|
-
if (
|
|
1177
|
-
nextSize = Math.min(
|
|
1210
|
+
if (collapsible && nextSize === collapsedSize) ; else {
|
|
1211
|
+
nextSize = Math.min(maxSize, Math.max(minSize, nextSize));
|
|
1178
1212
|
}
|
|
1179
1213
|
const [idBefore, idAfter] = getBeforeAndAfterIds(id, panelsArray);
|
|
1180
1214
|
if (idBefore == null || idAfter == null) {
|
|
@@ -1185,10 +1219,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1185
1219
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1186
1220
|
if (prevSizes !== nextSizes) {
|
|
1187
1221
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1222
|
+
setSizes(nextSizes);
|
|
1188
1223
|
|
|
1189
1224
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1225
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1190
1226
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1191
|
-
setSizes(nextSizes);
|
|
1192
1227
|
}
|
|
1193
1228
|
}, []);
|
|
1194
1229
|
const context = useMemo(() => ({
|
|
@@ -45,6 +45,7 @@ PanelGroupContext.displayName = "PanelGroupContext";
|
|
|
45
45
|
function PanelWithForwardedRef({
|
|
46
46
|
children = null,
|
|
47
47
|
className: classNameFromProps = "",
|
|
48
|
+
collapsedSize = 0,
|
|
48
49
|
collapsible = false,
|
|
49
50
|
defaultSize = null,
|
|
50
51
|
forwardedRef,
|
|
@@ -102,6 +103,7 @@ function PanelWithForwardedRef({
|
|
|
102
103
|
});
|
|
103
104
|
const panelDataRef = useRef({
|
|
104
105
|
callbacksRef,
|
|
106
|
+
collapsedSize,
|
|
105
107
|
collapsible,
|
|
106
108
|
defaultSize,
|
|
107
109
|
id: panelId,
|
|
@@ -112,6 +114,7 @@ function PanelWithForwardedRef({
|
|
|
112
114
|
useIsomorphicLayoutEffect(() => {
|
|
113
115
|
committedValuesRef.current.size = parseSizeFromStyle(style);
|
|
114
116
|
panelDataRef.current.callbacksRef = callbacksRef;
|
|
117
|
+
panelDataRef.current.collapsedSize = collapsedSize;
|
|
115
118
|
panelDataRef.current.collapsible = collapsible;
|
|
116
119
|
panelDataRef.current.defaultSize = defaultSize;
|
|
117
120
|
panelDataRef.current.id = panelId;
|
|
@@ -259,11 +262,18 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
259
262
|
}
|
|
260
263
|
function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
261
264
|
sizes.forEach((size, index) => {
|
|
265
|
+
const panelRef = panelsArray[index];
|
|
266
|
+
if (!panelRef) {
|
|
267
|
+
// Handle initial mount (when panels are registered too late to be in the panels array)
|
|
268
|
+
// The subsequent render+effects will handle the resize notification
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
262
271
|
const {
|
|
263
272
|
callbacksRef,
|
|
273
|
+
collapsedSize,
|
|
264
274
|
collapsible,
|
|
265
275
|
id
|
|
266
|
-
} =
|
|
276
|
+
} = panelRef.current;
|
|
267
277
|
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[id];
|
|
268
278
|
if (lastNotifiedSize !== size) {
|
|
269
279
|
panelIdToLastNotifiedSizeMap[id] = size;
|
|
@@ -272,14 +282,12 @@ function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
|
272
282
|
onResize
|
|
273
283
|
} = callbacksRef.current;
|
|
274
284
|
if (onResize) {
|
|
275
|
-
onResize(size);
|
|
285
|
+
onResize(size, lastNotifiedSize);
|
|
276
286
|
}
|
|
277
287
|
if (collapsible && onCollapse) {
|
|
278
|
-
|
|
279
|
-
// and initial size of undefined (when mounting)
|
|
280
|
-
if (!lastNotifiedSize && size !== 0) {
|
|
288
|
+
if ((lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
281
289
|
onCollapse(false);
|
|
282
|
-
} else if (lastNotifiedSize !==
|
|
290
|
+
} else if (lastNotifiedSize !== collapsedSize && size === collapsedSize) {
|
|
283
291
|
onCollapse(true);
|
|
284
292
|
}
|
|
285
293
|
}
|
|
@@ -371,11 +379,17 @@ function panelsMapToSortedArray(panels) {
|
|
|
371
379
|
}
|
|
372
380
|
function safeResizePanel(panel, delta, prevSize, event) {
|
|
373
381
|
const nextSizeUnsafe = prevSize + delta;
|
|
374
|
-
|
|
375
|
-
|
|
382
|
+
const {
|
|
383
|
+
collapsedSize,
|
|
384
|
+
collapsible,
|
|
385
|
+
maxSize,
|
|
386
|
+
minSize
|
|
387
|
+
} = panel.current;
|
|
388
|
+
if (collapsible) {
|
|
389
|
+
if (prevSize > collapsedSize) {
|
|
376
390
|
// Mimic VS COde behavior; collapse a panel if it's smaller than half of its min-size
|
|
377
|
-
if (nextSizeUnsafe <=
|
|
378
|
-
return
|
|
391
|
+
if (nextSizeUnsafe <= minSize / 2 + collapsedSize) {
|
|
392
|
+
return collapsedSize;
|
|
379
393
|
}
|
|
380
394
|
} else {
|
|
381
395
|
const isKeyboardEvent = event?.type?.startsWith("key");
|
|
@@ -383,13 +397,13 @@ function safeResizePanel(panel, delta, prevSize, event) {
|
|
|
383
397
|
// Keyboard events should expand a collapsed panel to the min size,
|
|
384
398
|
// but mouse events should wait until the panel has reached its min size
|
|
385
399
|
// to avoid a visual flickering when dragging between collapsed and min size.
|
|
386
|
-
if (nextSizeUnsafe <
|
|
387
|
-
return
|
|
400
|
+
if (nextSizeUnsafe < minSize) {
|
|
401
|
+
return collapsedSize;
|
|
388
402
|
}
|
|
389
403
|
}
|
|
390
404
|
}
|
|
391
405
|
}
|
|
392
|
-
const nextSize = Math.min(
|
|
406
|
+
const nextSize = Math.min(maxSize, Math.max(minSize, nextSizeUnsafe));
|
|
393
407
|
return nextSize;
|
|
394
408
|
}
|
|
395
409
|
|
|
@@ -845,8 +859,8 @@ function PanelGroupWithForwardedRef({
|
|
|
845
859
|
} = committedValuesRef.current;
|
|
846
860
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
847
861
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
848
|
-
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
849
862
|
setSizes(sizes);
|
|
863
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
850
864
|
}
|
|
851
865
|
}), []);
|
|
852
866
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -868,25 +882,25 @@ function PanelGroupWithForwardedRef({
|
|
|
868
882
|
const {
|
|
869
883
|
onLayout
|
|
870
884
|
} = callbacksRef.current;
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
} = committedValuesRef.current;
|
|
885
|
+
const {
|
|
886
|
+
panels,
|
|
887
|
+
sizes
|
|
888
|
+
} = committedValuesRef.current;
|
|
876
889
|
|
|
877
|
-
|
|
878
|
-
|
|
890
|
+
// Don't commit layout until all panels have registered and re-rendered with their actual sizes.
|
|
891
|
+
if (sizes.length > 0) {
|
|
892
|
+
if (onLayout) {
|
|
879
893
|
onLayout(sizes);
|
|
880
|
-
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
881
|
-
|
|
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
894
|
}
|
|
895
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
896
|
+
|
|
897
|
+
// When possible, we notify before the next render so that rendering work can be batched together.
|
|
898
|
+
// Some cases are difficult to detect though,
|
|
899
|
+
// for example– panels that are conditionally rendered can affect the size of neighboring panels.
|
|
900
|
+
// In this case, the best we can do is notify on commit.
|
|
901
|
+
// The callPanelCallbacks() uses its own memoization to avoid notifying panels twice in these cases.
|
|
902
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
903
|
+
callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
|
|
890
904
|
}
|
|
891
905
|
}, [sizes]);
|
|
892
906
|
|
|
@@ -1051,10 +1065,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1051
1065
|
}
|
|
1052
1066
|
if (sizesChanged) {
|
|
1053
1067
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1068
|
+
setSizes(nextSizes);
|
|
1054
1069
|
|
|
1055
1070
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1071
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1056
1072
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1057
|
-
setSizes(nextSizes);
|
|
1058
1073
|
}
|
|
1059
1074
|
prevDeltaRef.current = delta;
|
|
1060
1075
|
};
|
|
@@ -1076,7 +1091,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1076
1091
|
sizes: prevSizes
|
|
1077
1092
|
} = committedValuesRef.current;
|
|
1078
1093
|
const panel = panels.get(id);
|
|
1079
|
-
if (panel == null
|
|
1094
|
+
if (panel == null) {
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
const {
|
|
1098
|
+
collapsedSize,
|
|
1099
|
+
collapsible
|
|
1100
|
+
} = panel.current;
|
|
1101
|
+
if (!collapsible) {
|
|
1080
1102
|
return;
|
|
1081
1103
|
}
|
|
1082
1104
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
@@ -1085,7 +1107,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1085
1107
|
return;
|
|
1086
1108
|
}
|
|
1087
1109
|
const currentSize = prevSizes[index];
|
|
1088
|
-
if (currentSize ===
|
|
1110
|
+
if (currentSize === collapsedSize) {
|
|
1089
1111
|
// Panel is already collapsed.
|
|
1090
1112
|
return;
|
|
1091
1113
|
}
|
|
@@ -1095,14 +1117,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1095
1117
|
return;
|
|
1096
1118
|
}
|
|
1097
1119
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1098
|
-
const delta = isLastPanel ? currentSize :
|
|
1120
|
+
const delta = isLastPanel ? currentSize : collapsedSize - currentSize;
|
|
1099
1121
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1100
1122
|
if (prevSizes !== nextSizes) {
|
|
1101
1123
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1124
|
+
setSizes(nextSizes);
|
|
1102
1125
|
|
|
1103
1126
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1127
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1104
1128
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1105
|
-
setSizes(nextSizes);
|
|
1106
1129
|
}
|
|
1107
1130
|
}, []);
|
|
1108
1131
|
const expandPanel = useCallback(id => {
|
|
@@ -1114,7 +1137,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1114
1137
|
if (panel == null) {
|
|
1115
1138
|
return;
|
|
1116
1139
|
}
|
|
1117
|
-
const
|
|
1140
|
+
const {
|
|
1141
|
+
collapsedSize,
|
|
1142
|
+
minSize
|
|
1143
|
+
} = panel.current;
|
|
1144
|
+
const sizeBeforeCollapse = panelSizeBeforeCollapse.current.get(id) || minSize;
|
|
1118
1145
|
if (!sizeBeforeCollapse) {
|
|
1119
1146
|
return;
|
|
1120
1147
|
}
|
|
@@ -1124,7 +1151,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1124
1151
|
return;
|
|
1125
1152
|
}
|
|
1126
1153
|
const currentSize = prevSizes[index];
|
|
1127
|
-
if (currentSize !==
|
|
1154
|
+
if (currentSize !== collapsedSize) {
|
|
1128
1155
|
// Panel is already expanded.
|
|
1129
1156
|
return;
|
|
1130
1157
|
}
|
|
@@ -1133,14 +1160,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1133
1160
|
return;
|
|
1134
1161
|
}
|
|
1135
1162
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1136
|
-
const delta = isLastPanel ?
|
|
1163
|
+
const delta = isLastPanel ? collapsedSize - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1137
1164
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1138
1165
|
if (prevSizes !== nextSizes) {
|
|
1139
1166
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1167
|
+
setSizes(nextSizes);
|
|
1140
1168
|
|
|
1141
1169
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1170
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1142
1171
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1143
|
-
setSizes(nextSizes);
|
|
1144
1172
|
}
|
|
1145
1173
|
}, []);
|
|
1146
1174
|
const resizePanel = useCallback((id, nextSize) => {
|
|
@@ -1152,6 +1180,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1152
1180
|
if (panel == null) {
|
|
1153
1181
|
return;
|
|
1154
1182
|
}
|
|
1183
|
+
const {
|
|
1184
|
+
collapsedSize,
|
|
1185
|
+
collapsible,
|
|
1186
|
+
maxSize,
|
|
1187
|
+
minSize
|
|
1188
|
+
} = panel.current;
|
|
1155
1189
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
1156
1190
|
const index = panelsArray.indexOf(panel);
|
|
1157
1191
|
if (index < 0) {
|
|
@@ -1161,8 +1195,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1161
1195
|
if (currentSize === nextSize) {
|
|
1162
1196
|
return;
|
|
1163
1197
|
}
|
|
1164
|
-
if (
|
|
1165
|
-
nextSize = Math.min(
|
|
1198
|
+
if (collapsible && nextSize === collapsedSize) ; else {
|
|
1199
|
+
nextSize = Math.min(maxSize, Math.max(minSize, nextSize));
|
|
1166
1200
|
}
|
|
1167
1201
|
const [idBefore, idAfter] = getBeforeAndAfterIds(id, panelsArray);
|
|
1168
1202
|
if (idBefore == null || idAfter == null) {
|
|
@@ -1173,10 +1207,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1173
1207
|
const nextSizes = adjustByDelta(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1174
1208
|
if (prevSizes !== nextSizes) {
|
|
1175
1209
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1210
|
+
setSizes(nextSizes);
|
|
1176
1211
|
|
|
1177
1212
|
// If resize change handlers have been declared, this is the time to call them.
|
|
1213
|
+
// Trigger user callbacks after updating state, so that user code can override the sizes.
|
|
1178
1214
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1179
|
-
setSizes(nextSizes);
|
|
1180
1215
|
}
|
|
1181
1216
|
}, []);
|
|
1182
1217
|
const context = useMemo(() => ({
|
package/package.json
CHANGED
package/src/Panel.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
export type PanelProps = {
|
|
25
25
|
children?: ReactNode;
|
|
26
26
|
className?: string;
|
|
27
|
+
collapsedSize?: number;
|
|
27
28
|
collapsible?: boolean;
|
|
28
29
|
defaultSize?: number | null;
|
|
29
30
|
id?: string | null;
|
|
@@ -47,6 +48,7 @@ export type ImperativePanelHandle = {
|
|
|
47
48
|
function PanelWithForwardedRef({
|
|
48
49
|
children = null,
|
|
49
50
|
className: classNameFromProps = "",
|
|
51
|
+
collapsedSize = 0,
|
|
50
52
|
collapsible = false,
|
|
51
53
|
defaultSize = null,
|
|
52
54
|
forwardedRef,
|
|
@@ -119,6 +121,7 @@ function PanelWithForwardedRef({
|
|
|
119
121
|
});
|
|
120
122
|
const panelDataRef = useRef<{
|
|
121
123
|
callbacksRef: PanelCallbackRef;
|
|
124
|
+
collapsedSize: number;
|
|
122
125
|
collapsible: boolean;
|
|
123
126
|
defaultSize: number | null;
|
|
124
127
|
id: string;
|
|
@@ -127,6 +130,7 @@ function PanelWithForwardedRef({
|
|
|
127
130
|
order: number | null;
|
|
128
131
|
}>({
|
|
129
132
|
callbacksRef,
|
|
133
|
+
collapsedSize,
|
|
130
134
|
collapsible,
|
|
131
135
|
defaultSize,
|
|
132
136
|
id: panelId,
|
|
@@ -138,6 +142,7 @@ function PanelWithForwardedRef({
|
|
|
138
142
|
committedValuesRef.current.size = parseSizeFromStyle(style);
|
|
139
143
|
|
|
140
144
|
panelDataRef.current.callbacksRef = callbacksRef;
|
|
145
|
+
panelDataRef.current.collapsedSize = collapsedSize;
|
|
141
146
|
panelDataRef.current.collapsible = collapsible;
|
|
142
147
|
panelDataRef.current.defaultSize = defaultSize;
|
|
143
148
|
panelDataRef.current.id = panelId;
|