react-resizable-panels 1.0.8 → 1.0.10

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +16 -15
  3. package/dist/declarations/src/index.d.ts +1 -3
  4. package/dist/declarations/src/utils/dom/getPanelElement.d.ts +1 -1
  5. package/dist/declarations/src/utils/dom/getPanelElementsForGroup.d.ts +1 -1
  6. package/dist/declarations/src/utils/dom/getPanelGroupElement.d.ts +1 -1
  7. package/dist/declarations/src/utils/dom/getResizeHandleElement.d.ts +1 -1
  8. package/dist/declarations/src/utils/dom/getResizeHandleElementIndex.d.ts +1 -1
  9. package/dist/declarations/src/utils/dom/getResizeHandleElementsForGroup.d.ts +1 -1
  10. package/dist/declarations/src/utils/dom/getResizeHandlePanelIds.d.ts +1 -1
  11. package/dist/react-resizable-panels.browser.cjs.js +56 -51
  12. package/dist/react-resizable-panels.browser.cjs.mjs +0 -2
  13. package/dist/react-resizable-panels.browser.development.cjs.js +56 -51
  14. package/dist/react-resizable-panels.browser.development.cjs.mjs +0 -2
  15. package/dist/react-resizable-panels.browser.development.esm.js +57 -50
  16. package/dist/react-resizable-panels.browser.esm.js +57 -50
  17. package/dist/react-resizable-panels.cjs.js +56 -51
  18. package/dist/react-resizable-panels.cjs.mjs +0 -2
  19. package/dist/react-resizable-panels.development.cjs.js +56 -51
  20. package/dist/react-resizable-panels.development.cjs.mjs +0 -2
  21. package/dist/react-resizable-panels.development.esm.js +57 -50
  22. package/dist/react-resizable-panels.development.node.cjs.js +47 -51
  23. package/dist/react-resizable-panels.development.node.cjs.mjs +0 -2
  24. package/dist/react-resizable-panels.development.node.esm.js +48 -50
  25. package/dist/react-resizable-panels.esm.js +57 -50
  26. package/dist/react-resizable-panels.node.cjs.js +47 -51
  27. package/dist/react-resizable-panels.node.cjs.mjs +0 -2
  28. package/dist/react-resizable-panels.node.esm.js +48 -50
  29. package/package.json +1 -1
  30. package/src/Panel.test.tsx +186 -0
  31. package/src/Panel.ts +14 -0
  32. package/src/PanelGroup.ts +46 -7
  33. package/src/PanelGroupContext.ts +5 -1
  34. package/src/index.ts +0 -4
  35. package/src/utils/dom/getPanelElement.ts +2 -2
  36. package/src/utils/dom/getPanelElementsForGroup.ts +2 -4
  37. package/src/utils/dom/getPanelGroupElement.ts +1 -1
  38. package/src/utils/dom/getResizeHandleElement.ts +2 -4
  39. package/src/utils/dom/getResizeHandleElementIndex.ts +2 -2
  40. package/src/utils/dom/getResizeHandleElementsForGroup.ts +2 -2
  41. package/src/utils/dom/getResizeHandlePanelIds.ts +3 -3
  42. package/dist/declarations/src/utils/dom/calculateAvailablePanelSizeInPixels.d.ts +0 -1
  43. package/dist/declarations/src/utils/dom/getAvailableGroupSizePixels.d.ts +0 -1
  44. package/src/utils/dom/calculateAvailablePanelSizeInPixels.ts +0 -34
  45. 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, panelGroupElement) {
434
- return Array.from(panelGroupElement.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
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, panelGroupElement) {
438
- const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
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, panelGroupElement) {
464
- const element = panelGroupElement.querySelector(`[data-panel-resize-handle-id="${id}"]`);
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, panelGroupElement) {
472
+ function getResizeHandlePanelIds(groupId, handleId, panelsArray, scope = document) {
472
473
  var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
473
- const handle = getResizeHandleElement(handleId, panelGroupElement);
474
- const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
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,35 @@ 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
+ } = prevConstraints;
1332
+ const {
1333
+ collapsedSize: nextCollapsedSize = 0,
1334
+ collapsible: nextCollapsible,
1335
+ maxSize: nextMaxSize = 100,
1336
+ minSize: nextMinSize = 0
1337
+ } = panelData.constraints;
1338
+ const {
1339
+ panelSize: prevPanelSize
1340
+ } = panelDataHelper(panelDataArray, panelData, layout);
1341
+ assert(prevPanelSize != null);
1342
+ if (prevCollapsible && nextCollapsible && prevPanelSize === prevCollapsedSize) {
1343
+ if (prevCollapsedSize !== nextCollapsedSize) {
1344
+ resizePanel(panelData, nextCollapsedSize);
1345
+ }
1346
+ } else if (prevPanelSize < nextMinSize) {
1347
+ resizePanel(panelData, nextMinSize);
1348
+ } else if (prevPanelSize > nextMaxSize) {
1349
+ resizePanel(panelData, nextMaxSize);
1350
+ }
1351
+ }, [resizePanel]);
1322
1352
  const startDragging = useCallback((dragHandleId, event) => {
1323
1353
  const {
1324
1354
  direction
@@ -1369,6 +1399,7 @@ function PanelGroupWithForwardedRef({
1369
1399
  groupId,
1370
1400
  isPanelCollapsed,
1371
1401
  isPanelExpanded,
1402
+ reevaluatePanelConstraints,
1372
1403
  registerPanel,
1373
1404
  registerResizeHandle,
1374
1405
  resizePanel,
@@ -1376,7 +1407,7 @@ function PanelGroupWithForwardedRef({
1376
1407
  stopDragging,
1377
1408
  unregisterPanel,
1378
1409
  panelGroupElement: panelGroupElementRef.current
1379
- }), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
1410
+ }), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, reevaluatePanelConstraints, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
1380
1411
  const style = {
1381
1412
  display: "flex",
1382
1413
  flexDirection: direction === "horizontal" ? "row" : "column",
@@ -1411,14 +1442,12 @@ function findPanelDataIndex(panelDataArray, panelData) {
1411
1442
  return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1412
1443
  }
1413
1444
  function panelDataHelper(panelDataArray, panelData, layout) {
1414
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1415
1445
  const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1416
- const panelConstraints = panelConstraintsArray[panelIndex];
1417
1446
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1418
1447
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
1419
1448
  const panelSize = layout[panelIndex];
1420
1449
  return {
1421
- ...panelConstraints,
1450
+ ...panelData.constraints,
1422
1451
  panelSize,
1423
1452
  pivotIndices
1424
1453
  };
@@ -1625,47 +1654,16 @@ function PanelResizeHandle({
1625
1654
  }
1626
1655
  PanelResizeHandle.displayName = "PanelResizeHandle";
1627
1656
 
1628
- function calculateAvailablePanelSizeInPixels(groupId, panelGroupElement) {
1629
- if (panelGroupElement == null) {
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}"]`);
1657
+ function getPanelElement(id, scope = document) {
1658
+ const element = scope.querySelector(`[data-panel-id="${id}"]`);
1661
1659
  if (element) {
1662
1660
  return element;
1663
1661
  }
1664
1662
  return null;
1665
1663
  }
1666
1664
 
1667
- function getPanelElementsForGroup(groupId, panelGroupElement) {
1668
- return Array.from(panelGroupElement.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
1665
+ function getPanelElementsForGroup(groupId, scope = document) {
1666
+ return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
1669
1667
  }
1670
1668
 
1671
- export { Panel, PanelGroup, PanelResizeHandle, assert, calculateAvailablePanelSizeInPixels, getAvailableGroupSizePixels, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds };
1669
+ export { Panel, PanelGroup, PanelResizeHandle, assert, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-resizable-panels",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "React components for resizable panel groups/layouts",
5
5
  "author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
6
6
  "license": "MIT",
@@ -266,6 +266,192 @@ 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("it should not expand a collapsed panel if other constraints change", () => {
323
+ act(() => {
324
+ root.render(
325
+ <PanelGroup direction="horizontal">
326
+ <Panel
327
+ id="left"
328
+ collapsedSize={10}
329
+ collapsible
330
+ defaultSize={10}
331
+ minSize={25}
332
+ />
333
+ <PanelResizeHandle />
334
+ <Panel id="middle" />
335
+ <PanelResizeHandle />
336
+ <Panel
337
+ id="right"
338
+ collapsedSize={10}
339
+ collapsible
340
+ defaultSize={10}
341
+ minSize={25}
342
+ />
343
+ </PanelGroup>
344
+ );
345
+ });
346
+
347
+ let leftElement = getPanelElement("left", container);
348
+ let middleElement = getPanelElement("middle", container);
349
+ let rightElement = getPanelElement("right", container);
350
+ assert(leftElement);
351
+ assert(middleElement);
352
+ assert(rightElement);
353
+ expect(leftElement.getAttribute("data-panel-size")).toBe("10.0");
354
+ expect(middleElement.getAttribute("data-panel-size")).toBe("80.0");
355
+ expect(rightElement.getAttribute("data-panel-size")).toBe("10.0");
356
+
357
+ act(() => {
358
+ root.render(
359
+ <PanelGroup direction="horizontal">
360
+ <Panel id="left" collapsedSize={10} collapsible minSize={20} />
361
+ <PanelResizeHandle />
362
+ <Panel id="middle" />
363
+ <PanelResizeHandle />
364
+ <Panel id="right" collapsedSize={10} collapsible minSize={20} />
365
+ </PanelGroup>
366
+ );
367
+ });
368
+
369
+ expect(leftElement.getAttribute("data-panel-size")).toBe("10.0");
370
+ expect(middleElement.getAttribute("data-panel-size")).toBe("80.0");
371
+ expect(rightElement.getAttribute("data-panel-size")).toBe("10.0");
372
+ });
373
+
374
+ it("should resize a panel if the minSize prop changes", () => {
375
+ act(() => {
376
+ root.render(
377
+ <PanelGroup direction="horizontal">
378
+ <Panel id="left" defaultSize={15} minSize={10} />
379
+ <PanelResizeHandle />
380
+ <Panel id="middle" />
381
+ <PanelResizeHandle />
382
+ <Panel id="right" defaultSize={15} minSize={10} />
383
+ </PanelGroup>
384
+ );
385
+ });
386
+
387
+ let leftElement = getPanelElement("left", container);
388
+ let middleElement = getPanelElement("middle", container);
389
+ let rightElement = getPanelElement("right", container);
390
+ assert(leftElement);
391
+ assert(middleElement);
392
+ assert(rightElement);
393
+ expect(leftElement.getAttribute("data-panel-size")).toBe("15.0");
394
+ expect(middleElement.getAttribute("data-panel-size")).toBe("70.0");
395
+ expect(rightElement.getAttribute("data-panel-size")).toBe("15.0");
396
+
397
+ act(() => {
398
+ root.render(
399
+ <PanelGroup direction="horizontal">
400
+ <Panel id="left" minSize={20} />
401
+ <PanelResizeHandle />
402
+ <Panel id="middle" />
403
+ <PanelResizeHandle />
404
+ <Panel id="right" minSize={20} />
405
+ </PanelGroup>
406
+ );
407
+ });
408
+
409
+ expect(leftElement.getAttribute("data-panel-size")).toBe("20.0");
410
+ expect(middleElement.getAttribute("data-panel-size")).toBe("60.0");
411
+ expect(rightElement.getAttribute("data-panel-size")).toBe("20.0");
412
+ });
413
+
414
+ it("should resize a panel if the maxSize prop changes", () => {
415
+ act(() => {
416
+ root.render(
417
+ <PanelGroup direction="horizontal">
418
+ <Panel id="left" defaultSize={25} maxSize={30} />
419
+ <PanelResizeHandle />
420
+ <Panel id="middle" />
421
+ <PanelResizeHandle />
422
+ <Panel id="right" defaultSize={25} maxSize={30} />
423
+ </PanelGroup>
424
+ );
425
+ });
426
+
427
+ let leftElement = getPanelElement("left", container);
428
+ let middleElement = getPanelElement("middle", container);
429
+ let rightElement = getPanelElement("right", container);
430
+ assert(leftElement);
431
+ assert(middleElement);
432
+ assert(rightElement);
433
+ expect(leftElement.getAttribute("data-panel-size")).toBe("25.0");
434
+ expect(middleElement.getAttribute("data-panel-size")).toBe("50.0");
435
+ expect(rightElement.getAttribute("data-panel-size")).toBe("25.0");
436
+
437
+ act(() => {
438
+ root.render(
439
+ <PanelGroup direction="horizontal">
440
+ <Panel id="left" maxSize={20} />
441
+ <PanelResizeHandle />
442
+ <Panel id="middle" />
443
+ <PanelResizeHandle />
444
+ <Panel id="right" maxSize={20} />
445
+ </PanelGroup>
446
+ );
447
+ });
448
+
449
+ expect(leftElement.getAttribute("data-panel-size")).toBe("20.0");
450
+ expect(middleElement.getAttribute("data-panel-size")).toBe("60.0");
451
+ expect(rightElement.getAttribute("data-panel-size")).toBe("20.0");
452
+ });
453
+ });
454
+
269
455
  describe("callbacks", () => {
270
456
  describe("onCollapse", () => {
271
457
  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,48 @@ 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
+ } = prevConstraints;
730
+
731
+ const {
732
+ collapsedSize: nextCollapsedSize = 0,
733
+ collapsible: nextCollapsible,
734
+ maxSize: nextMaxSize = 100,
735
+ minSize: nextMinSize = 0,
736
+ } = panelData.constraints;
737
+
738
+ const { panelSize: prevPanelSize } = panelDataHelper(
739
+ panelDataArray,
740
+ panelData,
741
+ layout
742
+ );
743
+ assert(prevPanelSize != null);
744
+
745
+ if (
746
+ prevCollapsible &&
747
+ nextCollapsible &&
748
+ prevPanelSize === prevCollapsedSize
749
+ ) {
750
+ if (prevCollapsedSize !== nextCollapsedSize) {
751
+ resizePanel(panelData, nextCollapsedSize);
752
+ } else {
753
+ // Stay collapsed
754
+ }
755
+ } else if (prevPanelSize < nextMinSize) {
756
+ resizePanel(panelData, nextMinSize);
757
+ } else if (prevPanelSize > nextMaxSize) {
758
+ resizePanel(panelData, nextMaxSize);
759
+ }
760
+ },
761
+ [resizePanel]
762
+ );
763
+
722
764
  const startDragging = useCallback(
723
765
  (dragHandleId: string, event: ResizeEvent) => {
724
766
  const { direction } = committedValuesRef.current;
@@ -781,6 +823,7 @@ function PanelGroupWithForwardedRef({
781
823
  groupId,
782
824
  isPanelCollapsed,
783
825
  isPanelExpanded,
826
+ reevaluatePanelConstraints,
784
827
  registerPanel,
785
828
  registerResizeHandle,
786
829
  resizePanel,
@@ -799,6 +842,7 @@ function PanelGroupWithForwardedRef({
799
842
  groupId,
800
843
  isPanelCollapsed,
801
844
  isPanelExpanded,
845
+ reevaluatePanelConstraints,
802
846
  registerPanel,
803
847
  registerResizeHandle,
804
848
  resizePanel,
@@ -858,12 +902,7 @@ function panelDataHelper(
858
902
  panelData: PanelData,
859
903
  layout: number[]
860
904
  ) {
861
- const panelConstraintsArray = panelDataArray.map(
862
- (panelData) => panelData.constraints
863
- );
864
-
865
905
  const panelIndex = findPanelDataIndex(panelDataArray, panelData);
866
- const panelConstraints = panelConstraintsArray[panelIndex];
867
906
 
868
907
  const isLastPanel = panelIndex === panelDataArray.length - 1;
869
908
  const pivotIndices = isLastPanel
@@ -873,7 +912,7 @@ function panelDataHelper(
873
912
  const panelSize = layout[panelIndex];
874
913
 
875
914
  return {
876
- ...panelConstraints,
915
+ ...panelData.constraints,
877
916
  panelSize,
878
917
  pivotIndices,
879
918
  };
@@ -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
- panelGroupElement: HTMLElement
3
+ scope: ParentNode | HTMLElement = document
4
4
  ): HTMLElement | null {
5
- const element = panelGroupElement.querySelector(`[data-panel-id="${id}"]`);
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
- panelGroupElement: HTMLElement
3
+ scope: ParentNode | HTMLElement = document
4
4
  ): HTMLElement[] {
5
5
  return Array.from(
6
- panelGroupElement.querySelectorAll(
7
- `[data-panel][data-panel-group-id="${groupId}"]`
8
- )
6
+ scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`)
9
7
  );
10
8
  }
@@ -1,6 +1,6 @@
1
1
  export function getPanelGroupElement(
2
2
  id: string,
3
- rootElement: ParentNode | HTMLElement
3
+ rootElement: ParentNode | HTMLElement = document
4
4
  ): HTMLElement | null {
5
5
  //If the root element is the PanelGroup
6
6
  if (
@@ -1,10 +1,8 @@
1
1
  export function getResizeHandleElement(
2
2
  id: string,
3
- panelGroupElement: ParentNode
3
+ scope: ParentNode | HTMLElement = document
4
4
  ): HTMLElement | null {
5
- const element = panelGroupElement.querySelector(
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
- panelGroupElement: ParentNode
6
+ scope: ParentNode | HTMLElement = document
7
7
  ): number | null {
8
- const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
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
- panelGroupElement: ParentNode
3
+ scope: ParentNode | HTMLElement = document
4
4
  ): HTMLElement[] {
5
5
  return Array.from(
6
- panelGroupElement.querySelectorAll(
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
- panelGroupElement: ParentNode
9
+ scope: ParentNode | HTMLElement = document
10
10
  ): [idBefore: string | null, idAfter: string | null] {
11
- const handle = getResizeHandleElement(handleId, panelGroupElement);
12
- const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
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
- }