react-resizable-panels 1.0.8 → 1.0.9
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 +5 -0
- package/README.md +16 -15
- package/dist/declarations/src/index.d.ts +1 -3
- package/dist/declarations/src/utils/dom/getPanelElement.d.ts +1 -1
- package/dist/declarations/src/utils/dom/getPanelElementsForGroup.d.ts +1 -1
- package/dist/declarations/src/utils/dom/getPanelGroupElement.d.ts +1 -1
- package/dist/declarations/src/utils/dom/getResizeHandleElement.d.ts +1 -1
- package/dist/declarations/src/utils/dom/getResizeHandleElementIndex.d.ts +1 -1
- package/dist/declarations/src/utils/dom/getResizeHandleElementsForGroup.d.ts +1 -1
- package/dist/declarations/src/utils/dom/getResizeHandlePanelIds.d.ts +1 -1
- package/dist/react-resizable-panels.browser.cjs.js +58 -51
- package/dist/react-resizable-panels.browser.cjs.mjs +0 -2
- package/dist/react-resizable-panels.browser.development.cjs.js +58 -51
- package/dist/react-resizable-panels.browser.development.cjs.mjs +0 -2
- package/dist/react-resizable-panels.browser.development.esm.js +59 -50
- package/dist/react-resizable-panels.browser.esm.js +59 -50
- package/dist/react-resizable-panels.cjs.js +58 -51
- package/dist/react-resizable-panels.cjs.mjs +0 -2
- package/dist/react-resizable-panels.development.cjs.js +58 -51
- package/dist/react-resizable-panels.development.cjs.mjs +0 -2
- package/dist/react-resizable-panels.development.esm.js +59 -50
- package/dist/react-resizable-panels.development.node.cjs.js +49 -51
- package/dist/react-resizable-panels.development.node.cjs.mjs +0 -2
- package/dist/react-resizable-panels.development.node.esm.js +50 -50
- package/dist/react-resizable-panels.esm.js +59 -50
- package/dist/react-resizable-panels.node.cjs.js +49 -51
- package/dist/react-resizable-panels.node.cjs.mjs +0 -2
- package/dist/react-resizable-panels.node.esm.js +50 -50
- package/package.json +1 -1
- package/src/Panel.test.tsx +134 -0
- package/src/Panel.ts +14 -0
- package/src/PanelGroup.ts +47 -7
- package/src/PanelGroupContext.ts +5 -1
- package/src/index.ts +0 -4
- package/src/utils/dom/getPanelElement.ts +2 -2
- package/src/utils/dom/getPanelElementsForGroup.ts +2 -4
- package/src/utils/dom/getPanelGroupElement.ts +1 -1
- package/src/utils/dom/getResizeHandleElement.ts +2 -4
- package/src/utils/dom/getResizeHandleElementIndex.ts +2 -2
- package/src/utils/dom/getResizeHandleElementsForGroup.ts +2 -2
- package/src/utils/dom/getResizeHandlePanelIds.ts +3 -3
- package/dist/declarations/src/utils/dom/calculateAvailablePanelSizeInPixels.d.ts +0 -1
- package/dist/declarations/src/utils/dom/getAvailableGroupSizePixels.d.ts +0 -1
- package/src/utils/dom/calculateAvailablePanelSizeInPixels.ts +0 -34
- package/src/utils/dom/getAvailableGroupSizePixels.ts +0 -30
|
@@ -65,6 +65,7 @@ function PanelWithForwardedRef({
|
|
|
65
65
|
getPanelStyle,
|
|
66
66
|
groupId,
|
|
67
67
|
isPanelCollapsed,
|
|
68
|
+
reevaluatePanelConstraints,
|
|
68
69
|
registerPanel,
|
|
69
70
|
resizePanel,
|
|
70
71
|
unregisterPanel
|
|
@@ -430,12 +431,12 @@ function adjustLayoutByDelta({
|
|
|
430
431
|
return nextLayout;
|
|
431
432
|
}
|
|
432
433
|
|
|
433
|
-
function getResizeHandleElementsForGroup(groupId,
|
|
434
|
-
return Array.from(
|
|
434
|
+
function getResizeHandleElementsForGroup(groupId, scope = document) {
|
|
435
|
+
return Array.from(scope.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
|
|
435
436
|
}
|
|
436
437
|
|
|
437
|
-
function getResizeHandleElementIndex(groupId, id,
|
|
438
|
-
const handles = getResizeHandleElementsForGroup(groupId,
|
|
438
|
+
function getResizeHandleElementIndex(groupId, id, scope = document) {
|
|
439
|
+
const handles = getResizeHandleElementsForGroup(groupId, scope);
|
|
439
440
|
const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
|
|
440
441
|
return index !== null && index !== void 0 ? index : null;
|
|
441
442
|
}
|
|
@@ -445,7 +446,7 @@ function determinePivotIndices(groupId, dragHandleId, panelGroupElement) {
|
|
|
445
446
|
return index != null ? [index, index + 1] : [-1, -1];
|
|
446
447
|
}
|
|
447
448
|
|
|
448
|
-
function getPanelGroupElement(id, rootElement) {
|
|
449
|
+
function getPanelGroupElement(id, rootElement = document) {
|
|
449
450
|
var _dataset;
|
|
450
451
|
//If the root element is the PanelGroup
|
|
451
452
|
if (rootElement instanceof HTMLElement && (rootElement === null || rootElement === void 0 ? void 0 : (_dataset = rootElement.dataset) === null || _dataset === void 0 ? void 0 : _dataset.panelGroupId) == id) {
|
|
@@ -460,18 +461,18 @@ function getPanelGroupElement(id, rootElement) {
|
|
|
460
461
|
return null;
|
|
461
462
|
}
|
|
462
463
|
|
|
463
|
-
function getResizeHandleElement(id,
|
|
464
|
-
const element =
|
|
464
|
+
function getResizeHandleElement(id, scope = document) {
|
|
465
|
+
const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
465
466
|
if (element) {
|
|
466
467
|
return element;
|
|
467
468
|
}
|
|
468
469
|
return null;
|
|
469
470
|
}
|
|
470
471
|
|
|
471
|
-
function getResizeHandlePanelIds(groupId, handleId, panelsArray,
|
|
472
|
+
function getResizeHandlePanelIds(groupId, handleId, panelsArray, scope = document) {
|
|
472
473
|
var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
|
|
473
|
-
const handle = getResizeHandleElement(handleId,
|
|
474
|
-
const handles = getResizeHandleElementsForGroup(groupId,
|
|
474
|
+
const handle = getResizeHandleElement(handleId, scope);
|
|
475
|
+
const handles = getResizeHandleElementsForGroup(groupId, scope);
|
|
475
476
|
const index = handle ? handles.indexOf(handle) : -1;
|
|
476
477
|
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;
|
|
477
478
|
const idAfter = (_panelsArray$id = (_panelsArray = panelsArray[index + 1]) === null || _panelsArray === void 0 ? void 0 : _panelsArray.id) !== null && _panelsArray$id !== void 0 ? _panelsArray$id : null;
|
|
@@ -1319,6 +1320,37 @@ function PanelGroupWithForwardedRef({
|
|
|
1319
1320
|
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1320
1321
|
}
|
|
1321
1322
|
}, []);
|
|
1323
|
+
const reevaluatePanelConstraints = useCallback((panelData, prevConstraints) => {
|
|
1324
|
+
const {
|
|
1325
|
+
layout,
|
|
1326
|
+
panelDataArray
|
|
1327
|
+
} = eagerValuesRef.current;
|
|
1328
|
+
const {
|
|
1329
|
+
collapsedSize: prevCollapsedSize = 0,
|
|
1330
|
+
collapsible: prevCollapsible,
|
|
1331
|
+
defaultSize: prevDefaultSize,
|
|
1332
|
+
maxSize: prevMaxSize = 100,
|
|
1333
|
+
minSize: prevMinSize = 0
|
|
1334
|
+
} = prevConstraints;
|
|
1335
|
+
const {
|
|
1336
|
+
collapsedSize: nextCollapsedSize = 0,
|
|
1337
|
+
collapsible: nextCollapsible,
|
|
1338
|
+
defaultSize: nextDefaultSize,
|
|
1339
|
+
maxSize: nextMaxSize = 100,
|
|
1340
|
+
minSize: nextMinSize = 0
|
|
1341
|
+
} = panelData.constraints;
|
|
1342
|
+
const {
|
|
1343
|
+
panelSize: prevPanelSize
|
|
1344
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1345
|
+
assert(prevPanelSize != null);
|
|
1346
|
+
if (prevCollapsible && nextCollapsible && prevCollapsedSize !== nextCollapsedSize && prevPanelSize === prevCollapsedSize) {
|
|
1347
|
+
resizePanel(panelData, nextCollapsedSize);
|
|
1348
|
+
} else if (prevPanelSize < nextMinSize) {
|
|
1349
|
+
resizePanel(panelData, nextMinSize);
|
|
1350
|
+
} else if (prevPanelSize > nextMaxSize) {
|
|
1351
|
+
resizePanel(panelData, nextMaxSize);
|
|
1352
|
+
}
|
|
1353
|
+
}, [resizePanel]);
|
|
1322
1354
|
const startDragging = useCallback((dragHandleId, event) => {
|
|
1323
1355
|
const {
|
|
1324
1356
|
direction
|
|
@@ -1369,6 +1401,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1369
1401
|
groupId,
|
|
1370
1402
|
isPanelCollapsed,
|
|
1371
1403
|
isPanelExpanded,
|
|
1404
|
+
reevaluatePanelConstraints,
|
|
1372
1405
|
registerPanel,
|
|
1373
1406
|
registerResizeHandle,
|
|
1374
1407
|
resizePanel,
|
|
@@ -1376,7 +1409,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1376
1409
|
stopDragging,
|
|
1377
1410
|
unregisterPanel,
|
|
1378
1411
|
panelGroupElement: panelGroupElementRef.current
|
|
1379
|
-
}), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
|
|
1412
|
+
}), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, reevaluatePanelConstraints, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
|
|
1380
1413
|
const style = {
|
|
1381
1414
|
display: "flex",
|
|
1382
1415
|
flexDirection: direction === "horizontal" ? "row" : "column",
|
|
@@ -1411,14 +1444,12 @@ function findPanelDataIndex(panelDataArray, panelData) {
|
|
|
1411
1444
|
return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
|
|
1412
1445
|
}
|
|
1413
1446
|
function panelDataHelper(panelDataArray, panelData, layout) {
|
|
1414
|
-
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1415
1447
|
const panelIndex = findPanelDataIndex(panelDataArray, panelData);
|
|
1416
|
-
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
1417
1448
|
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
1418
1449
|
const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
|
|
1419
1450
|
const panelSize = layout[panelIndex];
|
|
1420
1451
|
return {
|
|
1421
|
-
...
|
|
1452
|
+
...panelData.constraints,
|
|
1422
1453
|
panelSize,
|
|
1423
1454
|
pivotIndices
|
|
1424
1455
|
};
|
|
@@ -1625,47 +1656,16 @@ function PanelResizeHandle({
|
|
|
1625
1656
|
}
|
|
1626
1657
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
1627
1658
|
|
|
1628
|
-
function
|
|
1629
|
-
|
|
1630
|
-
return NaN;
|
|
1631
|
-
}
|
|
1632
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
1633
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
|
|
1634
|
-
if (direction === "horizontal") {
|
|
1635
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
1636
|
-
return accumulated + handle.offsetWidth;
|
|
1637
|
-
}, 0);
|
|
1638
|
-
} else {
|
|
1639
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
1640
|
-
return accumulated + handle.offsetHeight;
|
|
1641
|
-
}, 0);
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
function getAvailableGroupSizePixels(groupId, panelGroupElement) {
|
|
1646
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
1647
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
|
|
1648
|
-
if (direction === "horizontal") {
|
|
1649
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
1650
|
-
return accumulated + handle.offsetWidth;
|
|
1651
|
-
}, 0);
|
|
1652
|
-
} else {
|
|
1653
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
1654
|
-
return accumulated + handle.offsetHeight;
|
|
1655
|
-
}, 0);
|
|
1656
|
-
}
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1659
|
-
function getPanelElement(id, panelGroupElement) {
|
|
1660
|
-
const element = panelGroupElement.querySelector(`[data-panel-id="${id}"]`);
|
|
1659
|
+
function getPanelElement(id, scope = document) {
|
|
1660
|
+
const element = scope.querySelector(`[data-panel-id="${id}"]`);
|
|
1661
1661
|
if (element) {
|
|
1662
1662
|
return element;
|
|
1663
1663
|
}
|
|
1664
1664
|
return null;
|
|
1665
1665
|
}
|
|
1666
1666
|
|
|
1667
|
-
function getPanelElementsForGroup(groupId,
|
|
1668
|
-
return Array.from(
|
|
1667
|
+
function getPanelElementsForGroup(groupId, scope = document) {
|
|
1668
|
+
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
1669
1669
|
}
|
|
1670
1670
|
|
|
1671
|
-
export { Panel, PanelGroup, PanelResizeHandle, assert,
|
|
1671
|
+
export { Panel, PanelGroup, PanelResizeHandle, assert, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds };
|
package/package.json
CHANGED
package/src/Panel.test.tsx
CHANGED
|
@@ -266,6 +266,140 @@ describe("PanelGroup", () => {
|
|
|
266
266
|
expect(element.title).toBe("bar");
|
|
267
267
|
});
|
|
268
268
|
|
|
269
|
+
describe("constraints", () => {
|
|
270
|
+
it("should resize a collapsed panel if the collapsedSize prop changes", () => {
|
|
271
|
+
act(() => {
|
|
272
|
+
root.render(
|
|
273
|
+
<PanelGroup direction="horizontal">
|
|
274
|
+
<Panel
|
|
275
|
+
id="left"
|
|
276
|
+
collapsedSize={10}
|
|
277
|
+
collapsible
|
|
278
|
+
defaultSize={10}
|
|
279
|
+
minSize={25}
|
|
280
|
+
/>
|
|
281
|
+
<PanelResizeHandle />
|
|
282
|
+
<Panel id="middle" />
|
|
283
|
+
<PanelResizeHandle />
|
|
284
|
+
<Panel
|
|
285
|
+
id="right"
|
|
286
|
+
collapsedSize={10}
|
|
287
|
+
collapsible
|
|
288
|
+
defaultSize={10}
|
|
289
|
+
minSize={25}
|
|
290
|
+
/>
|
|
291
|
+
</PanelGroup>
|
|
292
|
+
);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
let leftElement = getPanelElement("left", container);
|
|
296
|
+
let middleElement = getPanelElement("middle", container);
|
|
297
|
+
let rightElement = getPanelElement("right", container);
|
|
298
|
+
assert(leftElement);
|
|
299
|
+
assert(middleElement);
|
|
300
|
+
assert(rightElement);
|
|
301
|
+
expect(leftElement.getAttribute("data-panel-size")).toBe("10.0");
|
|
302
|
+
expect(middleElement.getAttribute("data-panel-size")).toBe("80.0");
|
|
303
|
+
expect(rightElement.getAttribute("data-panel-size")).toBe("10.0");
|
|
304
|
+
|
|
305
|
+
act(() => {
|
|
306
|
+
root.render(
|
|
307
|
+
<PanelGroup direction="horizontal">
|
|
308
|
+
<Panel id="left" collapsedSize={5} collapsible minSize={25} />
|
|
309
|
+
<PanelResizeHandle />
|
|
310
|
+
<Panel id="middle" />
|
|
311
|
+
<PanelResizeHandle />
|
|
312
|
+
<Panel id="right" collapsedSize={5} collapsible minSize={25} />
|
|
313
|
+
</PanelGroup>
|
|
314
|
+
);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
expect(leftElement.getAttribute("data-panel-size")).toBe("5.0");
|
|
318
|
+
expect(middleElement.getAttribute("data-panel-size")).toBe("90.0");
|
|
319
|
+
expect(rightElement.getAttribute("data-panel-size")).toBe("5.0");
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it("should resize a panel if the minSize prop changes", () => {
|
|
323
|
+
act(() => {
|
|
324
|
+
root.render(
|
|
325
|
+
<PanelGroup direction="horizontal">
|
|
326
|
+
<Panel id="left" defaultSize={15} minSize={10} />
|
|
327
|
+
<PanelResizeHandle />
|
|
328
|
+
<Panel id="middle" />
|
|
329
|
+
<PanelResizeHandle />
|
|
330
|
+
<Panel id="right" defaultSize={15} minSize={10} />
|
|
331
|
+
</PanelGroup>
|
|
332
|
+
);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
let leftElement = getPanelElement("left", container);
|
|
336
|
+
let middleElement = getPanelElement("middle", container);
|
|
337
|
+
let rightElement = getPanelElement("right", container);
|
|
338
|
+
assert(leftElement);
|
|
339
|
+
assert(middleElement);
|
|
340
|
+
assert(rightElement);
|
|
341
|
+
expect(leftElement.getAttribute("data-panel-size")).toBe("15.0");
|
|
342
|
+
expect(middleElement.getAttribute("data-panel-size")).toBe("70.0");
|
|
343
|
+
expect(rightElement.getAttribute("data-panel-size")).toBe("15.0");
|
|
344
|
+
|
|
345
|
+
act(() => {
|
|
346
|
+
root.render(
|
|
347
|
+
<PanelGroup direction="horizontal">
|
|
348
|
+
<Panel id="left" minSize={20} />
|
|
349
|
+
<PanelResizeHandle />
|
|
350
|
+
<Panel id="middle" />
|
|
351
|
+
<PanelResizeHandle />
|
|
352
|
+
<Panel id="right" minSize={20} />
|
|
353
|
+
</PanelGroup>
|
|
354
|
+
);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
expect(leftElement.getAttribute("data-panel-size")).toBe("20.0");
|
|
358
|
+
expect(middleElement.getAttribute("data-panel-size")).toBe("60.0");
|
|
359
|
+
expect(rightElement.getAttribute("data-panel-size")).toBe("20.0");
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("should resize a panel if the maxSize prop changes", () => {
|
|
363
|
+
act(() => {
|
|
364
|
+
root.render(
|
|
365
|
+
<PanelGroup direction="horizontal">
|
|
366
|
+
<Panel id="left" defaultSize={25} maxSize={30} />
|
|
367
|
+
<PanelResizeHandle />
|
|
368
|
+
<Panel id="middle" />
|
|
369
|
+
<PanelResizeHandle />
|
|
370
|
+
<Panel id="right" defaultSize={25} maxSize={30} />
|
|
371
|
+
</PanelGroup>
|
|
372
|
+
);
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
let leftElement = getPanelElement("left", container);
|
|
376
|
+
let middleElement = getPanelElement("middle", container);
|
|
377
|
+
let rightElement = getPanelElement("right", container);
|
|
378
|
+
assert(leftElement);
|
|
379
|
+
assert(middleElement);
|
|
380
|
+
assert(rightElement);
|
|
381
|
+
expect(leftElement.getAttribute("data-panel-size")).toBe("25.0");
|
|
382
|
+
expect(middleElement.getAttribute("data-panel-size")).toBe("50.0");
|
|
383
|
+
expect(rightElement.getAttribute("data-panel-size")).toBe("25.0");
|
|
384
|
+
|
|
385
|
+
act(() => {
|
|
386
|
+
root.render(
|
|
387
|
+
<PanelGroup direction="horizontal">
|
|
388
|
+
<Panel id="left" maxSize={20} />
|
|
389
|
+
<PanelResizeHandle />
|
|
390
|
+
<Panel id="middle" />
|
|
391
|
+
<PanelResizeHandle />
|
|
392
|
+
<Panel id="right" maxSize={20} />
|
|
393
|
+
</PanelGroup>
|
|
394
|
+
);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
expect(leftElement.getAttribute("data-panel-size")).toBe("20.0");
|
|
398
|
+
expect(middleElement.getAttribute("data-panel-size")).toBe("60.0");
|
|
399
|
+
expect(rightElement.getAttribute("data-panel-size")).toBe("20.0");
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
|
|
269
403
|
describe("callbacks", () => {
|
|
270
404
|
describe("onCollapse", () => {
|
|
271
405
|
it("should be called on mount if a panels initial size is 0", () => {
|
package/src/Panel.ts
CHANGED
|
@@ -108,6 +108,7 @@ export function PanelWithForwardedRef({
|
|
|
108
108
|
getPanelStyle,
|
|
109
109
|
groupId,
|
|
110
110
|
isPanelCollapsed,
|
|
111
|
+
reevaluatePanelConstraints,
|
|
111
112
|
registerPanel,
|
|
112
113
|
resizePanel,
|
|
113
114
|
unregisterPanel,
|
|
@@ -155,6 +156,8 @@ export function PanelWithForwardedRef({
|
|
|
155
156
|
useIsomorphicLayoutEffect(() => {
|
|
156
157
|
const { callbacks, constraints } = panelDataRef.current;
|
|
157
158
|
|
|
159
|
+
const prevConstraints = { ...constraints };
|
|
160
|
+
|
|
158
161
|
panelDataRef.current.id = panelId;
|
|
159
162
|
panelDataRef.current.idIsFromProps = idFromProps !== undefined;
|
|
160
163
|
panelDataRef.current.order = order;
|
|
@@ -168,6 +171,17 @@ export function PanelWithForwardedRef({
|
|
|
168
171
|
constraints.defaultSize = defaultSize;
|
|
169
172
|
constraints.maxSize = maxSize;
|
|
170
173
|
constraints.minSize = minSize;
|
|
174
|
+
|
|
175
|
+
// If constraints have changed, we should revisit panel sizes.
|
|
176
|
+
// This is uncommon but may happen if people are trying to implement pixel based constraints.
|
|
177
|
+
if (
|
|
178
|
+
prevConstraints.collapsedSize !== constraints.collapsedSize ||
|
|
179
|
+
prevConstraints.collapsible !== constraints.collapsible ||
|
|
180
|
+
prevConstraints.maxSize !== constraints.maxSize ||
|
|
181
|
+
prevConstraints.minSize !== constraints.minSize
|
|
182
|
+
) {
|
|
183
|
+
reevaluatePanelConstraints(panelDataRef.current, prevConstraints);
|
|
184
|
+
}
|
|
171
185
|
});
|
|
172
186
|
|
|
173
187
|
useIsomorphicLayoutEffect(() => {
|
package/src/PanelGroup.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isDevelopment } from "#is-development";
|
|
2
|
-
import { PanelData } from "./Panel";
|
|
2
|
+
import { PanelConstraints, PanelData } from "./Panel";
|
|
3
3
|
import {
|
|
4
4
|
DragState,
|
|
5
5
|
PanelGroupContext,
|
|
@@ -719,6 +719,49 @@ function PanelGroupWithForwardedRef({
|
|
|
719
719
|
[]
|
|
720
720
|
);
|
|
721
721
|
|
|
722
|
+
const reevaluatePanelConstraints = useCallback(
|
|
723
|
+
(panelData: PanelData, prevConstraints: PanelConstraints) => {
|
|
724
|
+
const { layout, panelDataArray } = eagerValuesRef.current;
|
|
725
|
+
|
|
726
|
+
const {
|
|
727
|
+
collapsedSize: prevCollapsedSize = 0,
|
|
728
|
+
collapsible: prevCollapsible,
|
|
729
|
+
defaultSize: prevDefaultSize,
|
|
730
|
+
maxSize: prevMaxSize = 100,
|
|
731
|
+
minSize: prevMinSize = 0,
|
|
732
|
+
} = prevConstraints;
|
|
733
|
+
|
|
734
|
+
const {
|
|
735
|
+
collapsedSize: nextCollapsedSize = 0,
|
|
736
|
+
collapsible: nextCollapsible,
|
|
737
|
+
defaultSize: nextDefaultSize,
|
|
738
|
+
maxSize: nextMaxSize = 100,
|
|
739
|
+
minSize: nextMinSize = 0,
|
|
740
|
+
} = panelData.constraints;
|
|
741
|
+
|
|
742
|
+
const { panelSize: prevPanelSize } = panelDataHelper(
|
|
743
|
+
panelDataArray,
|
|
744
|
+
panelData,
|
|
745
|
+
layout
|
|
746
|
+
);
|
|
747
|
+
assert(prevPanelSize != null);
|
|
748
|
+
|
|
749
|
+
if (
|
|
750
|
+
prevCollapsible &&
|
|
751
|
+
nextCollapsible &&
|
|
752
|
+
prevCollapsedSize !== nextCollapsedSize &&
|
|
753
|
+
prevPanelSize === prevCollapsedSize
|
|
754
|
+
) {
|
|
755
|
+
resizePanel(panelData, nextCollapsedSize);
|
|
756
|
+
} else if (prevPanelSize < nextMinSize) {
|
|
757
|
+
resizePanel(panelData, nextMinSize);
|
|
758
|
+
} else if (prevPanelSize > nextMaxSize) {
|
|
759
|
+
resizePanel(panelData, nextMaxSize);
|
|
760
|
+
}
|
|
761
|
+
},
|
|
762
|
+
[resizePanel]
|
|
763
|
+
);
|
|
764
|
+
|
|
722
765
|
const startDragging = useCallback(
|
|
723
766
|
(dragHandleId: string, event: ResizeEvent) => {
|
|
724
767
|
const { direction } = committedValuesRef.current;
|
|
@@ -781,6 +824,7 @@ function PanelGroupWithForwardedRef({
|
|
|
781
824
|
groupId,
|
|
782
825
|
isPanelCollapsed,
|
|
783
826
|
isPanelExpanded,
|
|
827
|
+
reevaluatePanelConstraints,
|
|
784
828
|
registerPanel,
|
|
785
829
|
registerResizeHandle,
|
|
786
830
|
resizePanel,
|
|
@@ -799,6 +843,7 @@ function PanelGroupWithForwardedRef({
|
|
|
799
843
|
groupId,
|
|
800
844
|
isPanelCollapsed,
|
|
801
845
|
isPanelExpanded,
|
|
846
|
+
reevaluatePanelConstraints,
|
|
802
847
|
registerPanel,
|
|
803
848
|
registerResizeHandle,
|
|
804
849
|
resizePanel,
|
|
@@ -858,12 +903,7 @@ function panelDataHelper(
|
|
|
858
903
|
panelData: PanelData,
|
|
859
904
|
layout: number[]
|
|
860
905
|
) {
|
|
861
|
-
const panelConstraintsArray = panelDataArray.map(
|
|
862
|
-
(panelData) => panelData.constraints
|
|
863
|
-
);
|
|
864
|
-
|
|
865
906
|
const panelIndex = findPanelDataIndex(panelDataArray, panelData);
|
|
866
|
-
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
867
907
|
|
|
868
908
|
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
869
909
|
const pivotIndices = isLastPanel
|
|
@@ -873,7 +913,7 @@ function panelDataHelper(
|
|
|
873
913
|
const panelSize = layout[panelIndex];
|
|
874
914
|
|
|
875
915
|
return {
|
|
876
|
-
...
|
|
916
|
+
...panelData.constraints,
|
|
877
917
|
panelSize,
|
|
878
918
|
pivotIndices,
|
|
879
919
|
};
|
package/src/PanelGroupContext.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PanelData } from "./Panel";
|
|
1
|
+
import { PanelConstraints, PanelData } from "./Panel";
|
|
2
2
|
import { CSSProperties, createContext } from "./vendor/react";
|
|
3
3
|
|
|
4
4
|
export type ResizeEvent = KeyboardEvent | MouseEvent | TouchEvent;
|
|
@@ -24,6 +24,10 @@ export type TPanelGroupContext = {
|
|
|
24
24
|
groupId: string;
|
|
25
25
|
isPanelCollapsed: (panelData: PanelData) => boolean;
|
|
26
26
|
isPanelExpanded: (panelData: PanelData) => boolean;
|
|
27
|
+
reevaluatePanelConstraints: (
|
|
28
|
+
panelData: PanelData,
|
|
29
|
+
prevConstraints: PanelConstraints
|
|
30
|
+
) => void;
|
|
27
31
|
registerPanel: (panelData: PanelData) => void;
|
|
28
32
|
registerResizeHandle: (dragHandleId: string) => ResizeHandler;
|
|
29
33
|
resizePanel: (panelData: PanelData, size: number) => void;
|
package/src/index.ts
CHANGED
|
@@ -2,8 +2,6 @@ import { Panel } from "./Panel";
|
|
|
2
2
|
import { PanelGroup } from "./PanelGroup";
|
|
3
3
|
import { PanelResizeHandle } from "./PanelResizeHandle";
|
|
4
4
|
import { assert } from "./utils/assert";
|
|
5
|
-
import { calculateAvailablePanelSizeInPixels } from "./utils/dom/calculateAvailablePanelSizeInPixels";
|
|
6
|
-
import { getAvailableGroupSizePixels } from "./utils/dom/getAvailableGroupSizePixels";
|
|
7
5
|
import { getPanelElement } from "./utils/dom/getPanelElement";
|
|
8
6
|
import { getPanelElementsForGroup } from "./utils/dom/getPanelElementsForGroup";
|
|
9
7
|
import { getPanelGroupElement } from "./utils/dom/getPanelGroupElement";
|
|
@@ -53,8 +51,6 @@ export {
|
|
|
53
51
|
assert,
|
|
54
52
|
|
|
55
53
|
// DOM helpers
|
|
56
|
-
calculateAvailablePanelSizeInPixels,
|
|
57
|
-
getAvailableGroupSizePixels,
|
|
58
54
|
getPanelElement,
|
|
59
55
|
getPanelElementsForGroup,
|
|
60
56
|
getPanelGroupElement,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export function getPanelElement(
|
|
2
2
|
id: string,
|
|
3
|
-
|
|
3
|
+
scope: ParentNode | HTMLElement = document
|
|
4
4
|
): HTMLElement | null {
|
|
5
|
-
const element =
|
|
5
|
+
const element = scope.querySelector(`[data-panel-id="${id}"]`);
|
|
6
6
|
if (element) {
|
|
7
7
|
return element as HTMLElement;
|
|
8
8
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export function getPanelElementsForGroup(
|
|
2
2
|
groupId: string,
|
|
3
|
-
|
|
3
|
+
scope: ParentNode | HTMLElement = document
|
|
4
4
|
): HTMLElement[] {
|
|
5
5
|
return Array.from(
|
|
6
|
-
|
|
7
|
-
`[data-panel][data-panel-group-id="${groupId}"]`
|
|
8
|
-
)
|
|
6
|
+
scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`)
|
|
9
7
|
);
|
|
10
8
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export function getResizeHandleElement(
|
|
2
2
|
id: string,
|
|
3
|
-
|
|
3
|
+
scope: ParentNode | HTMLElement = document
|
|
4
4
|
): HTMLElement | null {
|
|
5
|
-
const element =
|
|
6
|
-
`[data-panel-resize-handle-id="${id}"]`
|
|
7
|
-
);
|
|
5
|
+
const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
8
6
|
if (element) {
|
|
9
7
|
return element as HTMLElement;
|
|
10
8
|
}
|
|
@@ -3,9 +3,9 @@ import { getResizeHandleElementsForGroup } from "./getResizeHandleElementsForGro
|
|
|
3
3
|
export function getResizeHandleElementIndex(
|
|
4
4
|
groupId: string,
|
|
5
5
|
id: string,
|
|
6
|
-
|
|
6
|
+
scope: ParentNode | HTMLElement = document
|
|
7
7
|
): number | null {
|
|
8
|
-
const handles = getResizeHandleElementsForGroup(groupId,
|
|
8
|
+
const handles = getResizeHandleElementsForGroup(groupId, scope);
|
|
9
9
|
const index = handles.findIndex(
|
|
10
10
|
(handle) => handle.getAttribute("data-panel-resize-handle-id") === id
|
|
11
11
|
);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export function getResizeHandleElementsForGroup(
|
|
2
2
|
groupId: string,
|
|
3
|
-
|
|
3
|
+
scope: ParentNode | HTMLElement = document
|
|
4
4
|
): HTMLElement[] {
|
|
5
5
|
return Array.from(
|
|
6
|
-
|
|
6
|
+
scope.querySelectorAll(
|
|
7
7
|
`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`
|
|
8
8
|
)
|
|
9
9
|
);
|
|
@@ -6,10 +6,10 @@ export function getResizeHandlePanelIds(
|
|
|
6
6
|
groupId: string,
|
|
7
7
|
handleId: string,
|
|
8
8
|
panelsArray: PanelData[],
|
|
9
|
-
|
|
9
|
+
scope: ParentNode | HTMLElement = document
|
|
10
10
|
): [idBefore: string | null, idAfter: string | null] {
|
|
11
|
-
const handle = getResizeHandleElement(handleId,
|
|
12
|
-
const handles = getResizeHandleElementsForGroup(groupId,
|
|
11
|
+
const handle = getResizeHandleElement(handleId, scope);
|
|
12
|
+
const handles = getResizeHandleElementsForGroup(groupId, scope);
|
|
13
13
|
const index = handle ? handles.indexOf(handle) : -1;
|
|
14
14
|
|
|
15
15
|
const idBefore: string | null = panelsArray[index]?.id ?? null;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function calculateAvailablePanelSizeInPixels(groupId: string, panelGroupElement: HTMLElement): number;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function getAvailableGroupSizePixels(groupId: string, panelGroupElement: HTMLElement): number;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { getPanelGroupElement } from "./getPanelGroupElement";
|
|
2
|
-
import { getResizeHandleElementsForGroup } from "./getResizeHandleElementsForGroup";
|
|
3
|
-
|
|
4
|
-
export function calculateAvailablePanelSizeInPixels(
|
|
5
|
-
groupId: string,
|
|
6
|
-
panelGroupElement: HTMLElement
|
|
7
|
-
): number {
|
|
8
|
-
if (panelGroupElement == null) {
|
|
9
|
-
return NaN;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const direction = panelGroupElement.getAttribute(
|
|
13
|
-
"data-panel-group-direction"
|
|
14
|
-
);
|
|
15
|
-
const resizeHandles = getResizeHandleElementsForGroup(
|
|
16
|
-
groupId,
|
|
17
|
-
panelGroupElement
|
|
18
|
-
);
|
|
19
|
-
if (direction === "horizontal") {
|
|
20
|
-
return (
|
|
21
|
-
panelGroupElement.offsetWidth -
|
|
22
|
-
resizeHandles.reduce((accumulated, handle) => {
|
|
23
|
-
return accumulated + handle.offsetWidth;
|
|
24
|
-
}, 0)
|
|
25
|
-
);
|
|
26
|
-
} else {
|
|
27
|
-
return (
|
|
28
|
-
panelGroupElement.offsetHeight -
|
|
29
|
-
resizeHandles.reduce((accumulated, handle) => {
|
|
30
|
-
return accumulated + handle.offsetHeight;
|
|
31
|
-
}, 0)
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { getPanelGroupElement } from "./getPanelGroupElement";
|
|
2
|
-
import { getResizeHandleElementsForGroup } from "./getResizeHandleElementsForGroup";
|
|
3
|
-
|
|
4
|
-
export function getAvailableGroupSizePixels(
|
|
5
|
-
groupId: string,
|
|
6
|
-
panelGroupElement: HTMLElement
|
|
7
|
-
): number {
|
|
8
|
-
const direction = panelGroupElement.getAttribute(
|
|
9
|
-
"data-panel-group-direction"
|
|
10
|
-
);
|
|
11
|
-
const resizeHandles = getResizeHandleElementsForGroup(
|
|
12
|
-
groupId,
|
|
13
|
-
panelGroupElement
|
|
14
|
-
);
|
|
15
|
-
if (direction === "horizontal") {
|
|
16
|
-
return (
|
|
17
|
-
panelGroupElement.offsetWidth -
|
|
18
|
-
resizeHandles.reduce((accumulated, handle) => {
|
|
19
|
-
return accumulated + handle.offsetWidth;
|
|
20
|
-
}, 0)
|
|
21
|
-
);
|
|
22
|
-
} else {
|
|
23
|
-
return (
|
|
24
|
-
panelGroupElement.offsetHeight -
|
|
25
|
-
resizeHandles.reduce((accumulated, handle) => {
|
|
26
|
-
return accumulated + handle.offsetHeight;
|
|
27
|
-
}, 0)
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
}
|