react-resizable-panels 0.0.56 → 0.0.57
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.browser.cjs.js +57 -30
- package/dist/react-resizable-panels.browser.development.cjs.js +57 -30
- package/dist/react-resizable-panels.browser.development.esm.js +57 -30
- package/dist/react-resizable-panels.browser.esm.js +57 -30
- package/dist/react-resizable-panels.cjs.js +57 -30
- package/dist/react-resizable-panels.cjs.js.map +1 -1
- package/dist/react-resizable-panels.development.cjs.js +57 -30
- package/dist/react-resizable-panels.development.esm.js +57 -30
- package/dist/react-resizable-panels.development.node.cjs.js +46 -25
- package/dist/react-resizable-panels.development.node.esm.js +46 -25
- package/dist/react-resizable-panels.esm.js +57 -30
- package/dist/react-resizable-panels.esm.js.map +1 -1
- package/dist/react-resizable-panels.node.cjs.js +46 -25
- package/dist/react-resizable-panels.node.esm.js +46 -25
- package/package.json +3 -1
- package/src/Panel.ts +1 -1
- package/src/PanelGroup.ts +6 -4
- package/src/PanelResizeHandle.ts +12 -13
- package/src/utils/adjustLayoutByDelta.ts +1 -1
- package/src/utils/computePercentagePanelConstraints.test.ts +27 -0
- package/src/utils/convertPixelConstraintsToPercentages.test.ts +47 -0
- package/src/utils/convertPixelConstraintsToPercentages.ts +17 -0
- package/src/utils/dom/getPanelGroupElement.ts +3 -1
- package/src/utils/resizePanel.test.ts +45 -0
- package/src/utils/resizePanel.ts +19 -0
|
@@ -57,7 +57,7 @@ function useUniqueId(idFromParams = null) {
|
|
|
57
57
|
if (idRef.current === null) {
|
|
58
58
|
idRef.current = "" + counter++;
|
|
59
59
|
}
|
|
60
|
-
return idFromParams
|
|
60
|
+
return idFromParams !== null && idFromParams !== void 0 ? idFromParams : idRef.current;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
function PanelWithForwardedRef({
|
|
@@ -153,9 +153,9 @@ function PanelWithForwardedRef({
|
|
|
153
153
|
},
|
|
154
154
|
// CSS selectors
|
|
155
155
|
"data-panel": "",
|
|
156
|
+
"data-panel-id": panelId,
|
|
156
157
|
// e2e test attributes
|
|
157
158
|
"data-panel-collapsible": undefined,
|
|
158
|
-
"data-panel-id": undefined,
|
|
159
159
|
"data-panel-size": undefined
|
|
160
160
|
});
|
|
161
161
|
}
|
|
@@ -183,6 +183,16 @@ function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels)
|
|
|
183
183
|
minSizePercentage = 0,
|
|
184
184
|
minSizePixels
|
|
185
185
|
} = panelConstraints;
|
|
186
|
+
const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
|
|
187
|
+
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
188
|
+
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
189
|
+
return {
|
|
190
|
+
collapsedSizePercentage: 0,
|
|
191
|
+
defaultSizePercentage,
|
|
192
|
+
maxSizePercentage: 0,
|
|
193
|
+
minSizePercentage: 0
|
|
194
|
+
};
|
|
195
|
+
}
|
|
186
196
|
if (collapsedSizePixels != null) {
|
|
187
197
|
collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
|
|
188
198
|
}
|
|
@@ -257,6 +267,16 @@ function resizePanel({
|
|
|
257
267
|
panelIndex,
|
|
258
268
|
size
|
|
259
269
|
}) {
|
|
270
|
+
const hasPixelConstraints = panelConstraints.some(({
|
|
271
|
+
collapsedSizePixels,
|
|
272
|
+
defaultSizePixels,
|
|
273
|
+
minSizePixels,
|
|
274
|
+
maxSizePixels
|
|
275
|
+
}) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
|
|
276
|
+
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
277
|
+
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
278
|
+
return 0;
|
|
279
|
+
}
|
|
260
280
|
let {
|
|
261
281
|
collapsible
|
|
262
282
|
} = panelConstraints[panelIndex];
|
|
@@ -313,7 +333,6 @@ function adjustLayoutByDelta({
|
|
|
313
333
|
} = panelConstraints[pivotIndex];
|
|
314
334
|
const {
|
|
315
335
|
collapsedSizePercentage,
|
|
316
|
-
maxSizePercentage,
|
|
317
336
|
minSizePercentage
|
|
318
337
|
} = computePercentagePanelConstraints(panelConstraints, pivotIndex, groupSizePixels);
|
|
319
338
|
const isCollapsed = collapsible && fuzzyNumbersEqual(initialSize, collapsedSizePercentage);
|
|
@@ -469,7 +488,7 @@ function getResizeHandleElementsForGroup(groupId) {
|
|
|
469
488
|
function getResizeHandleElementIndex(groupId, id) {
|
|
470
489
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
471
490
|
const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
|
|
472
|
-
return index
|
|
491
|
+
return index !== null && index !== void 0 ? index : null;
|
|
473
492
|
}
|
|
474
493
|
|
|
475
494
|
function determinePivotIndices(groupId, dragHandleId) {
|
|
@@ -478,7 +497,7 @@ function determinePivotIndices(groupId, dragHandleId) {
|
|
|
478
497
|
}
|
|
479
498
|
|
|
480
499
|
function getPanelGroupElement(id) {
|
|
481
|
-
const element = document.querySelector(`[data-panel-group-id="${id}"]`);
|
|
500
|
+
const element = document.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
|
|
482
501
|
if (element) {
|
|
483
502
|
return element;
|
|
484
503
|
}
|
|
@@ -530,11 +549,12 @@ function getResizeHandleElement(id) {
|
|
|
530
549
|
}
|
|
531
550
|
|
|
532
551
|
function getResizeHandlePanelIds(groupId, handleId, panelsArray) {
|
|
552
|
+
var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
|
|
533
553
|
const handle = getResizeHandleElement(handleId);
|
|
534
554
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
535
555
|
const index = handle ? handles.indexOf(handle) : -1;
|
|
536
|
-
const idBefore = panelsArray[index]
|
|
537
|
-
const idAfter = panelsArray[index + 1]
|
|
556
|
+
const idBefore = (_panelsArray$index$id = (_panelsArray$index = panelsArray[index]) === null || _panelsArray$index === void 0 ? void 0 : _panelsArray$index.id) !== null && _panelsArray$index$id !== void 0 ? _panelsArray$index$id : null;
|
|
557
|
+
const idAfter = (_panelsArray$id = (_panelsArray = panelsArray[index + 1]) === null || _panelsArray === void 0 ? void 0 : _panelsArray.id) !== null && _panelsArray$id !== void 0 ? _panelsArray$id : null;
|
|
538
558
|
return [idBefore, idAfter];
|
|
539
559
|
}
|
|
540
560
|
|
|
@@ -581,11 +601,12 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
581
601
|
const panelData = panelDataArray[index];
|
|
582
602
|
const size = layout[index];
|
|
583
603
|
if (size != null) {
|
|
604
|
+
var _getPercentageSizeFro;
|
|
584
605
|
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
585
|
-
const minSize = getPercentageSizeFromMixedSizes({
|
|
606
|
+
const minSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
586
607
|
sizePercentage: panelData.constraints.minSizePercentage,
|
|
587
608
|
sizePixels: panelData.constraints.minSizePixels
|
|
588
|
-
}, groupSizePixels)
|
|
609
|
+
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
589
610
|
let delta = 0;
|
|
590
611
|
if (size.toPrecision(PRECISION) <= minSize.toPrecision(PRECISION)) {
|
|
591
612
|
delta = direction === "horizontal" ? width : height;
|
|
@@ -752,10 +773,11 @@ function callPanelCallbacks(groupId, panelsArray, layout, panelIdToLastNotifiedM
|
|
|
752
773
|
onResize(mixedSizes, lastNotifiedMixedSizes);
|
|
753
774
|
}
|
|
754
775
|
if (collapsible && (onCollapse || onExpand)) {
|
|
755
|
-
|
|
776
|
+
var _getPercentageSizeFro;
|
|
777
|
+
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
756
778
|
sizePercentage: constraints.collapsedSizePercentage,
|
|
757
779
|
sizePixels: constraints.collapsedSizePixels
|
|
758
|
-
}, groupSizePixels)
|
|
780
|
+
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
759
781
|
const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
|
|
760
782
|
if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
|
|
761
783
|
onExpand();
|
|
@@ -1273,7 +1295,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1273
1295
|
} = committedValuesRef.current;
|
|
1274
1296
|
const {
|
|
1275
1297
|
initialLayout
|
|
1276
|
-
} = dragState
|
|
1298
|
+
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1277
1299
|
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1278
1300
|
let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
|
|
1279
1301
|
percentage: keyboardResizeByPercentage,
|
|
@@ -1293,7 +1315,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1293
1315
|
const nextLayout = adjustLayoutByDelta({
|
|
1294
1316
|
delta,
|
|
1295
1317
|
groupSizePixels,
|
|
1296
|
-
layout: initialLayout
|
|
1318
|
+
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1297
1319
|
panelConstraints,
|
|
1298
1320
|
pivotIndices,
|
|
1299
1321
|
trigger: isKeyDown(event) ? "keyboard" : "mouse-or-touch"
|
|
@@ -1436,9 +1458,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1436
1458
|
},
|
|
1437
1459
|
// CSS selectors
|
|
1438
1460
|
"data-panel-group": "",
|
|
1439
|
-
|
|
1440
|
-
"data-panel-group-
|
|
1441
|
-
"data-panel-group-id": undefined
|
|
1461
|
+
"data-panel-group-direction": direction,
|
|
1462
|
+
"data-panel-group-id": groupId
|
|
1442
1463
|
}));
|
|
1443
1464
|
}
|
|
1444
1465
|
const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
|
|
@@ -1550,7 +1571,7 @@ function PanelResizeHandle({
|
|
|
1550
1571
|
stopDragging
|
|
1551
1572
|
} = panelGroupContext;
|
|
1552
1573
|
const resizeHandleId = useUniqueId(idFromProps);
|
|
1553
|
-
const isDragging = dragState
|
|
1574
|
+
const isDragging = (dragState === null || dragState === void 0 ? void 0 : dragState.dragHandleId) === resizeHandleId;
|
|
1554
1575
|
const [isFocused, setIsFocused] = useState(false);
|
|
1555
1576
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
1556
1577
|
const stopDraggingAndBlur = useCallback(() => {
|
|
@@ -1614,13 +1635,6 @@ function PanelResizeHandle({
|
|
|
1614
1635
|
return createElement(Type, {
|
|
1615
1636
|
children,
|
|
1616
1637
|
className: classNameFromProps,
|
|
1617
|
-
// CSS selectors
|
|
1618
|
-
"data-resize-handle": "",
|
|
1619
|
-
"data-resize-handle-active": isDragging ? "pointer" : isFocused ? "keyboard" : undefined,
|
|
1620
|
-
"data-panel-group-direction": direction,
|
|
1621
|
-
"data-panel-group-id": groupId,
|
|
1622
|
-
"data-panel-resize-handle-enabled": !disabled,
|
|
1623
|
-
"data-panel-resize-handle-id": resizeHandleId,
|
|
1624
1638
|
onBlur: () => setIsFocused(false),
|
|
1625
1639
|
onFocus: () => setIsFocused(true),
|
|
1626
1640
|
onMouseDown: event => {
|
|
@@ -1650,7 +1664,14 @@ function PanelResizeHandle({
|
|
|
1650
1664
|
...style,
|
|
1651
1665
|
...styleFromProps
|
|
1652
1666
|
},
|
|
1653
|
-
tabIndex: 0
|
|
1667
|
+
tabIndex: 0,
|
|
1668
|
+
// CSS selectors
|
|
1669
|
+
"data-panel-group-direction": direction,
|
|
1670
|
+
"data-panel-group-id": groupId,
|
|
1671
|
+
"data-resize-handle": "",
|
|
1672
|
+
"data-resize-handle-active": isDragging ? "pointer" : isFocused ? "keyboard" : undefined,
|
|
1673
|
+
"data-panel-resize-handle-enabled": !disabled,
|
|
1674
|
+
"data-panel-resize-handle-id": resizeHandleId
|
|
1654
1675
|
});
|
|
1655
1676
|
}
|
|
1656
1677
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
@@ -33,7 +33,7 @@ function useUniqueId(idFromParams = null) {
|
|
|
33
33
|
if (idRef.current === null) {
|
|
34
34
|
idRef.current = "" + counter++;
|
|
35
35
|
}
|
|
36
|
-
return idFromParams
|
|
36
|
+
return idFromParams !== null && idFromParams !== void 0 ? idFromParams : idRef.current;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
function PanelWithForwardedRef({
|
|
@@ -129,9 +129,9 @@ function PanelWithForwardedRef({
|
|
|
129
129
|
},
|
|
130
130
|
// CSS selectors
|
|
131
131
|
"data-panel": "",
|
|
132
|
+
"data-panel-id": panelId,
|
|
132
133
|
// e2e test attributes
|
|
133
134
|
"data-panel-collapsible": undefined,
|
|
134
|
-
"data-panel-id": undefined,
|
|
135
135
|
"data-panel-size": undefined
|
|
136
136
|
});
|
|
137
137
|
}
|
|
@@ -159,6 +159,16 @@ function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels)
|
|
|
159
159
|
minSizePercentage = 0,
|
|
160
160
|
minSizePixels
|
|
161
161
|
} = panelConstraints;
|
|
162
|
+
const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
|
|
163
|
+
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
164
|
+
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
165
|
+
return {
|
|
166
|
+
collapsedSizePercentage: 0,
|
|
167
|
+
defaultSizePercentage,
|
|
168
|
+
maxSizePercentage: 0,
|
|
169
|
+
minSizePercentage: 0
|
|
170
|
+
};
|
|
171
|
+
}
|
|
162
172
|
if (collapsedSizePixels != null) {
|
|
163
173
|
collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
|
|
164
174
|
}
|
|
@@ -233,6 +243,16 @@ function resizePanel({
|
|
|
233
243
|
panelIndex,
|
|
234
244
|
size
|
|
235
245
|
}) {
|
|
246
|
+
const hasPixelConstraints = panelConstraints.some(({
|
|
247
|
+
collapsedSizePixels,
|
|
248
|
+
defaultSizePixels,
|
|
249
|
+
minSizePixels,
|
|
250
|
+
maxSizePixels
|
|
251
|
+
}) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
|
|
252
|
+
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
253
|
+
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
254
|
+
return 0;
|
|
255
|
+
}
|
|
236
256
|
let {
|
|
237
257
|
collapsible
|
|
238
258
|
} = panelConstraints[panelIndex];
|
|
@@ -289,7 +309,6 @@ function adjustLayoutByDelta({
|
|
|
289
309
|
} = panelConstraints[pivotIndex];
|
|
290
310
|
const {
|
|
291
311
|
collapsedSizePercentage,
|
|
292
|
-
maxSizePercentage,
|
|
293
312
|
minSizePercentage
|
|
294
313
|
} = computePercentagePanelConstraints(panelConstraints, pivotIndex, groupSizePixels);
|
|
295
314
|
const isCollapsed = collapsible && fuzzyNumbersEqual(initialSize, collapsedSizePercentage);
|
|
@@ -445,7 +464,7 @@ function getResizeHandleElementsForGroup(groupId) {
|
|
|
445
464
|
function getResizeHandleElementIndex(groupId, id) {
|
|
446
465
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
447
466
|
const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
|
|
448
|
-
return index
|
|
467
|
+
return index !== null && index !== void 0 ? index : null;
|
|
449
468
|
}
|
|
450
469
|
|
|
451
470
|
function determinePivotIndices(groupId, dragHandleId) {
|
|
@@ -454,7 +473,7 @@ function determinePivotIndices(groupId, dragHandleId) {
|
|
|
454
473
|
}
|
|
455
474
|
|
|
456
475
|
function getPanelGroupElement(id) {
|
|
457
|
-
const element = document.querySelector(`[data-panel-group-id="${id}"]`);
|
|
476
|
+
const element = document.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
|
|
458
477
|
if (element) {
|
|
459
478
|
return element;
|
|
460
479
|
}
|
|
@@ -506,11 +525,12 @@ function getResizeHandleElement(id) {
|
|
|
506
525
|
}
|
|
507
526
|
|
|
508
527
|
function getResizeHandlePanelIds(groupId, handleId, panelsArray) {
|
|
528
|
+
var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
|
|
509
529
|
const handle = getResizeHandleElement(handleId);
|
|
510
530
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
511
531
|
const index = handle ? handles.indexOf(handle) : -1;
|
|
512
|
-
const idBefore = panelsArray[index]
|
|
513
|
-
const idAfter = panelsArray[index + 1]
|
|
532
|
+
const idBefore = (_panelsArray$index$id = (_panelsArray$index = panelsArray[index]) === null || _panelsArray$index === void 0 ? void 0 : _panelsArray$index.id) !== null && _panelsArray$index$id !== void 0 ? _panelsArray$index$id : null;
|
|
533
|
+
const idAfter = (_panelsArray$id = (_panelsArray = panelsArray[index + 1]) === null || _panelsArray === void 0 ? void 0 : _panelsArray.id) !== null && _panelsArray$id !== void 0 ? _panelsArray$id : null;
|
|
514
534
|
return [idBefore, idAfter];
|
|
515
535
|
}
|
|
516
536
|
|
|
@@ -557,11 +577,12 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
557
577
|
const panelData = panelDataArray[index];
|
|
558
578
|
const size = layout[index];
|
|
559
579
|
if (size != null) {
|
|
580
|
+
var _getPercentageSizeFro;
|
|
560
581
|
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
561
|
-
const minSize = getPercentageSizeFromMixedSizes({
|
|
582
|
+
const minSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
562
583
|
sizePercentage: panelData.constraints.minSizePercentage,
|
|
563
584
|
sizePixels: panelData.constraints.minSizePixels
|
|
564
|
-
}, groupSizePixels)
|
|
585
|
+
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
565
586
|
let delta = 0;
|
|
566
587
|
if (size.toPrecision(PRECISION) <= minSize.toPrecision(PRECISION)) {
|
|
567
588
|
delta = direction === "horizontal" ? width : height;
|
|
@@ -728,10 +749,11 @@ function callPanelCallbacks(groupId, panelsArray, layout, panelIdToLastNotifiedM
|
|
|
728
749
|
onResize(mixedSizes, lastNotifiedMixedSizes);
|
|
729
750
|
}
|
|
730
751
|
if (collapsible && (onCollapse || onExpand)) {
|
|
731
|
-
|
|
752
|
+
var _getPercentageSizeFro;
|
|
753
|
+
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
732
754
|
sizePercentage: constraints.collapsedSizePercentage,
|
|
733
755
|
sizePixels: constraints.collapsedSizePixels
|
|
734
|
-
}, groupSizePixels)
|
|
756
|
+
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
735
757
|
const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
|
|
736
758
|
if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
|
|
737
759
|
onExpand();
|
|
@@ -1249,7 +1271,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1249
1271
|
} = committedValuesRef.current;
|
|
1250
1272
|
const {
|
|
1251
1273
|
initialLayout
|
|
1252
|
-
} = dragState
|
|
1274
|
+
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1253
1275
|
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1254
1276
|
let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
|
|
1255
1277
|
percentage: keyboardResizeByPercentage,
|
|
@@ -1269,7 +1291,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1269
1291
|
const nextLayout = adjustLayoutByDelta({
|
|
1270
1292
|
delta,
|
|
1271
1293
|
groupSizePixels,
|
|
1272
|
-
layout: initialLayout
|
|
1294
|
+
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1273
1295
|
panelConstraints,
|
|
1274
1296
|
pivotIndices,
|
|
1275
1297
|
trigger: isKeyDown(event) ? "keyboard" : "mouse-or-touch"
|
|
@@ -1412,9 +1434,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1412
1434
|
},
|
|
1413
1435
|
// CSS selectors
|
|
1414
1436
|
"data-panel-group": "",
|
|
1415
|
-
|
|
1416
|
-
"data-panel-group-
|
|
1417
|
-
"data-panel-group-id": undefined
|
|
1437
|
+
"data-panel-group-direction": direction,
|
|
1438
|
+
"data-panel-group-id": groupId
|
|
1418
1439
|
}));
|
|
1419
1440
|
}
|
|
1420
1441
|
const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
|
|
@@ -1526,7 +1547,7 @@ function PanelResizeHandle({
|
|
|
1526
1547
|
stopDragging
|
|
1527
1548
|
} = panelGroupContext;
|
|
1528
1549
|
const resizeHandleId = useUniqueId(idFromProps);
|
|
1529
|
-
const isDragging = dragState
|
|
1550
|
+
const isDragging = (dragState === null || dragState === void 0 ? void 0 : dragState.dragHandleId) === resizeHandleId;
|
|
1530
1551
|
const [isFocused, setIsFocused] = useState(false);
|
|
1531
1552
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
1532
1553
|
const stopDraggingAndBlur = useCallback(() => {
|
|
@@ -1590,13 +1611,6 @@ function PanelResizeHandle({
|
|
|
1590
1611
|
return createElement(Type, {
|
|
1591
1612
|
children,
|
|
1592
1613
|
className: classNameFromProps,
|
|
1593
|
-
// CSS selectors
|
|
1594
|
-
"data-resize-handle": "",
|
|
1595
|
-
"data-resize-handle-active": isDragging ? "pointer" : isFocused ? "keyboard" : undefined,
|
|
1596
|
-
"data-panel-group-direction": direction,
|
|
1597
|
-
"data-panel-group-id": groupId,
|
|
1598
|
-
"data-panel-resize-handle-enabled": !disabled,
|
|
1599
|
-
"data-panel-resize-handle-id": resizeHandleId,
|
|
1600
1614
|
onBlur: () => setIsFocused(false),
|
|
1601
1615
|
onFocus: () => setIsFocused(true),
|
|
1602
1616
|
onMouseDown: event => {
|
|
@@ -1626,7 +1640,14 @@ function PanelResizeHandle({
|
|
|
1626
1640
|
...style,
|
|
1627
1641
|
...styleFromProps
|
|
1628
1642
|
},
|
|
1629
|
-
tabIndex: 0
|
|
1643
|
+
tabIndex: 0,
|
|
1644
|
+
// CSS selectors
|
|
1645
|
+
"data-panel-group-direction": direction,
|
|
1646
|
+
"data-panel-group-id": groupId,
|
|
1647
|
+
"data-resize-handle": "",
|
|
1648
|
+
"data-resize-handle-active": isDragging ? "pointer" : isFocused ? "keyboard" : undefined,
|
|
1649
|
+
"data-panel-resize-handle-enabled": !disabled,
|
|
1650
|
+
"data-panel-resize-handle-id": resizeHandleId
|
|
1630
1651
|
});
|
|
1631
1652
|
}
|
|
1632
1653
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-resizable-panels",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.57",
|
|
4
4
|
"description": "React components for resizable panel groups/layouts",
|
|
5
5
|
"author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -67,6 +67,8 @@
|
|
|
67
67
|
"watch": "parcel watch --port=2345"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
+
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
|
|
71
|
+
"@babel/plugin-proposal-optional-chaining": "7.21.0",
|
|
70
72
|
"eslint": "^8.37.0",
|
|
71
73
|
"eslint-plugin-no-restricted-imports": "^0.0.0",
|
|
72
74
|
"eslint-plugin-react-hooks": "^4.6.0",
|
package/src/Panel.ts
CHANGED
|
@@ -243,12 +243,12 @@ export function PanelWithForwardedRef({
|
|
|
243
243
|
|
|
244
244
|
// CSS selectors
|
|
245
245
|
"data-panel": "",
|
|
246
|
+
"data-panel-id": panelId,
|
|
246
247
|
|
|
247
248
|
// e2e test attributes
|
|
248
249
|
"data-panel-collapsible": isDevelopment
|
|
249
250
|
? collapsible || undefined
|
|
250
251
|
: undefined,
|
|
251
|
-
"data-panel-id": isDevelopment ? panelId : undefined,
|
|
252
252
|
"data-panel-size": isDevelopment
|
|
253
253
|
? parseFloat("" + style.flexGrow).toFixed(1)
|
|
254
254
|
: undefined,
|
package/src/PanelGroup.ts
CHANGED
|
@@ -266,6 +266,10 @@ function PanelGroupWithForwardedRef({
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
269
|
+
if (groupSizePixels <= 0) {
|
|
270
|
+
// Wait until the group has rendered a non-zero size before computing layout.
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
269
273
|
|
|
270
274
|
if (unsafeLayout == null) {
|
|
271
275
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -925,10 +929,8 @@ function PanelGroupWithForwardedRef({
|
|
|
925
929
|
|
|
926
930
|
// CSS selectors
|
|
927
931
|
"data-panel-group": "",
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
"data-panel-group-direction": isDevelopment ? direction : undefined,
|
|
931
|
-
"data-panel-group-id": isDevelopment ? groupId : undefined,
|
|
932
|
+
"data-panel-group-direction": direction,
|
|
933
|
+
"data-panel-group-id": groupId,
|
|
932
934
|
})
|
|
933
935
|
);
|
|
934
936
|
}
|
package/src/PanelResizeHandle.ts
CHANGED
|
@@ -151,19 +151,6 @@ export function PanelResizeHandle({
|
|
|
151
151
|
return createElement(Type, {
|
|
152
152
|
children,
|
|
153
153
|
className: classNameFromProps,
|
|
154
|
-
|
|
155
|
-
// CSS selectors
|
|
156
|
-
"data-resize-handle": "",
|
|
157
|
-
|
|
158
|
-
"data-resize-handle-active": isDragging
|
|
159
|
-
? "pointer"
|
|
160
|
-
: isFocused
|
|
161
|
-
? "keyboard"
|
|
162
|
-
: undefined,
|
|
163
|
-
"data-panel-group-direction": direction,
|
|
164
|
-
"data-panel-group-id": groupId,
|
|
165
|
-
"data-panel-resize-handle-enabled": !disabled,
|
|
166
|
-
"data-panel-resize-handle-id": resizeHandleId,
|
|
167
154
|
onBlur: () => setIsFocused(false),
|
|
168
155
|
onFocus: () => setIsFocused(true),
|
|
169
156
|
onMouseDown: (event: ReactMouseEvent) => {
|
|
@@ -192,6 +179,18 @@ export function PanelResizeHandle({
|
|
|
192
179
|
...styleFromProps,
|
|
193
180
|
},
|
|
194
181
|
tabIndex: 0,
|
|
182
|
+
|
|
183
|
+
// CSS selectors
|
|
184
|
+
"data-panel-group-direction": direction,
|
|
185
|
+
"data-panel-group-id": groupId,
|
|
186
|
+
"data-resize-handle": "",
|
|
187
|
+
"data-resize-handle-active": isDragging
|
|
188
|
+
? "pointer"
|
|
189
|
+
: isFocused
|
|
190
|
+
? "keyboard"
|
|
191
|
+
: undefined,
|
|
192
|
+
"data-panel-resize-handle-enabled": !disabled,
|
|
193
|
+
"data-panel-resize-handle-id": resizeHandleId,
|
|
195
194
|
});
|
|
196
195
|
}
|
|
197
196
|
|
|
@@ -44,7 +44,7 @@ export function adjustLayoutByDelta({
|
|
|
44
44
|
const initialSize = nextLayout[pivotIndex]!;
|
|
45
45
|
|
|
46
46
|
const { collapsible } = panelConstraints[pivotIndex]!;
|
|
47
|
-
const { collapsedSizePercentage,
|
|
47
|
+
const { collapsedSizePercentage, minSizePercentage } =
|
|
48
48
|
computePercentagePanelConstraints(
|
|
49
49
|
panelConstraints,
|
|
50
50
|
pivotIndex,
|
|
@@ -68,4 +68,31 @@ describe("computePercentagePanelConstraints", () => {
|
|
|
68
68
|
}
|
|
69
69
|
`);
|
|
70
70
|
});
|
|
71
|
+
|
|
72
|
+
it("should compute reasonable percentage based constraints from pixels if group size is negative", () => {
|
|
73
|
+
jest.spyOn(console, "warn").mockImplementation(() => {});
|
|
74
|
+
|
|
75
|
+
expect(
|
|
76
|
+
computePercentagePanelConstraints(
|
|
77
|
+
[
|
|
78
|
+
{
|
|
79
|
+
minSizePixels: 25,
|
|
80
|
+
maxSizePixels: 100,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
|
|
84
|
+
0,
|
|
85
|
+
-100
|
|
86
|
+
)
|
|
87
|
+
).toMatchInlineSnapshot(`
|
|
88
|
+
{
|
|
89
|
+
"collapsedSizePercentage": 0,
|
|
90
|
+
"defaultSizePercentage": undefined,
|
|
91
|
+
"maxSizePercentage": 0,
|
|
92
|
+
"minSizePercentage": 0,
|
|
93
|
+
}
|
|
94
|
+
`);
|
|
95
|
+
|
|
96
|
+
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
97
|
+
});
|
|
71
98
|
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { convertPixelConstraintsToPercentages } from "./convertPixelConstraintsToPercentages";
|
|
2
|
+
|
|
3
|
+
describe("convertPixelConstraintsToPercentages", () => {
|
|
4
|
+
it("should respect percentage panel constraints if group size is negative", () => {
|
|
5
|
+
jest.spyOn(console, "warn").mockImplementation(() => {});
|
|
6
|
+
|
|
7
|
+
expect(
|
|
8
|
+
convertPixelConstraintsToPercentages(
|
|
9
|
+
{
|
|
10
|
+
minSizePercentage: 25,
|
|
11
|
+
defaultSizePercentage: 50,
|
|
12
|
+
maxSizePercentage: 75,
|
|
13
|
+
},
|
|
14
|
+
-100
|
|
15
|
+
)
|
|
16
|
+
).toEqual({
|
|
17
|
+
collapsedSizePercentage: 0,
|
|
18
|
+
defaultSizePercentage: 50,
|
|
19
|
+
maxSizePercentage: 75,
|
|
20
|
+
minSizePercentage: 25,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(console.warn).toHaveBeenCalledTimes(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Edge case test (issues/206)
|
|
27
|
+
it("should ignore pixel panel constraints if group size is negative", () => {
|
|
28
|
+
jest.spyOn(console, "warn").mockImplementation(() => {});
|
|
29
|
+
|
|
30
|
+
expect(
|
|
31
|
+
convertPixelConstraintsToPercentages(
|
|
32
|
+
{
|
|
33
|
+
minSizePixels: 25,
|
|
34
|
+
maxSizePixels: 75,
|
|
35
|
+
},
|
|
36
|
+
-100
|
|
37
|
+
)
|
|
38
|
+
).toEqual({
|
|
39
|
+
collapsedSizePercentage: 0,
|
|
40
|
+
defaultSizePercentage: undefined,
|
|
41
|
+
maxSizePercentage: 0,
|
|
42
|
+
minSizePercentage: 0,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -21,6 +21,23 @@ export function convertPixelConstraintsToPercentages(
|
|
|
21
21
|
minSizePixels,
|
|
22
22
|
} = panelConstraints;
|
|
23
23
|
|
|
24
|
+
const hasPixelConstraints =
|
|
25
|
+
collapsedSizePixels != null ||
|
|
26
|
+
defaultSizePixels != null ||
|
|
27
|
+
minSizePixels != null ||
|
|
28
|
+
maxSizePixels != null;
|
|
29
|
+
|
|
30
|
+
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
31
|
+
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
collapsedSizePercentage: 0,
|
|
35
|
+
defaultSizePercentage,
|
|
36
|
+
maxSizePercentage: 0,
|
|
37
|
+
minSizePercentage: 0,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
24
41
|
if (collapsedSizePixels != null) {
|
|
25
42
|
collapsedSizePercentage = convertPixelsToPercentage(
|
|
26
43
|
collapsedSizePixels,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export function getPanelGroupElement(id: string): HTMLDivElement | null {
|
|
2
|
-
const element = document.querySelector(
|
|
2
|
+
const element = document.querySelector(
|
|
3
|
+
`[data-panel-group][data-panel-group-id="${id}"]`
|
|
4
|
+
);
|
|
3
5
|
if (element) {
|
|
4
6
|
return element as HTMLDivElement;
|
|
5
7
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { resizePanel } from "./resizePanel";
|
|
2
|
+
|
|
3
|
+
describe("resizePanel", () => {
|
|
4
|
+
// Edge case test (issues/206)
|
|
5
|
+
fit("should respect percentage panel constraints if group size is negative", () => {
|
|
6
|
+
jest.spyOn(console, "warn").mockImplementation(() => {});
|
|
7
|
+
|
|
8
|
+
expect(
|
|
9
|
+
resizePanel({
|
|
10
|
+
groupSizePixels: -100,
|
|
11
|
+
panelConstraints: [
|
|
12
|
+
{
|
|
13
|
+
minSizePercentage: 25,
|
|
14
|
+
maxSizePercentage: 75,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
panelIndex: 0,
|
|
18
|
+
size: 50,
|
|
19
|
+
})
|
|
20
|
+
).toBe(50);
|
|
21
|
+
|
|
22
|
+
expect(console.warn).toHaveBeenCalledTimes(0);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Edge case test (issues/206)
|
|
26
|
+
it("should handle pixel panel constraints if group size is negative", () => {
|
|
27
|
+
jest.spyOn(console, "warn").mockImplementation(() => {});
|
|
28
|
+
|
|
29
|
+
expect(
|
|
30
|
+
resizePanel({
|
|
31
|
+
groupSizePixels: -100,
|
|
32
|
+
panelConstraints: [
|
|
33
|
+
{
|
|
34
|
+
minSizePixels: 25,
|
|
35
|
+
maxSizePixels: 75,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
panelIndex: 0,
|
|
39
|
+
size: 50,
|
|
40
|
+
})
|
|
41
|
+
).toBe(0);
|
|
42
|
+
|
|
43
|
+
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
44
|
+
});
|
|
45
|
+
});
|
package/src/utils/resizePanel.ts
CHANGED
|
@@ -14,6 +14,25 @@ export function resizePanel({
|
|
|
14
14
|
panelIndex: number;
|
|
15
15
|
size: number;
|
|
16
16
|
}) {
|
|
17
|
+
const hasPixelConstraints = panelConstraints.some(
|
|
18
|
+
({
|
|
19
|
+
collapsedSizePixels,
|
|
20
|
+
defaultSizePixels,
|
|
21
|
+
minSizePixels,
|
|
22
|
+
maxSizePixels,
|
|
23
|
+
}) =>
|
|
24
|
+
collapsedSizePixels != null ||
|
|
25
|
+
defaultSizePixels != null ||
|
|
26
|
+
minSizePixels != null ||
|
|
27
|
+
maxSizePixels != null
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
31
|
+
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
32
|
+
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
17
36
|
let { collapsible } = panelConstraints[panelIndex]!;
|
|
18
37
|
|
|
19
38
|
const { collapsedSizePercentage, maxSizePercentage, minSizePercentage } =
|