react-resizable-panels 1.0.7 → 1.0.8

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 (51) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/declarations/src/Panel.d.ts +3 -3
  3. package/dist/declarations/src/PanelGroup.d.ts +2 -2
  4. package/dist/declarations/src/PanelResizeHandle.d.ts +2 -2
  5. package/dist/declarations/src/utils/dom/calculateAvailablePanelSizeInPixels.d.ts +1 -1
  6. package/dist/declarations/src/utils/dom/getAvailableGroupSizePixels.d.ts +1 -1
  7. package/dist/declarations/src/utils/dom/getPanelElement.d.ts +1 -1
  8. package/dist/declarations/src/utils/dom/getPanelElementsForGroup.d.ts +1 -1
  9. package/dist/declarations/src/utils/dom/getPanelGroupElement.d.ts +1 -1
  10. package/dist/declarations/src/utils/dom/getResizeHandleElement.d.ts +1 -1
  11. package/dist/declarations/src/utils/dom/getResizeHandleElementIndex.d.ts +1 -1
  12. package/dist/declarations/src/utils/dom/getResizeHandleElementsForGroup.d.ts +1 -1
  13. package/dist/declarations/src/utils/dom/getResizeHandlePanelIds.d.ts +1 -1
  14. package/dist/declarations/src/vendor/react.d.ts +2 -2
  15. package/dist/react-resizable-panels.browser.cjs.js +74 -51
  16. package/dist/react-resizable-panels.browser.development.cjs.js +76 -52
  17. package/dist/react-resizable-panels.browser.development.esm.js +76 -52
  18. package/dist/react-resizable-panels.browser.esm.js +74 -51
  19. package/dist/react-resizable-panels.cjs.js +74 -51
  20. package/dist/react-resizable-panels.development.cjs.js +76 -52
  21. package/dist/react-resizable-panels.development.esm.js +76 -52
  22. package/dist/react-resizable-panels.development.node.cjs.js +71 -50
  23. package/dist/react-resizable-panels.development.node.esm.js +71 -50
  24. package/dist/react-resizable-panels.esm.js +74 -51
  25. package/dist/react-resizable-panels.node.cjs.js +69 -49
  26. package/dist/react-resizable-panels.node.esm.js +69 -49
  27. package/package.json +1 -1
  28. package/src/Panel.test.tsx +3 -2
  29. package/src/Panel.ts +2 -2
  30. package/src/PanelGroup.test.tsx +3 -2
  31. package/src/PanelGroup.ts +48 -28
  32. package/src/PanelGroupContext.ts +4 -2
  33. package/src/PanelResizeHandle.test.tsx +3 -3
  34. package/src/PanelResizeHandle.ts +4 -2
  35. package/src/hooks/useWindowSplitterBehavior.ts +14 -5
  36. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +23 -7
  37. package/src/utils/calculateDeltaPercentage.ts +4 -2
  38. package/src/utils/calculateDragOffsetPercentage.ts +4 -3
  39. package/src/utils/determinePivotIndices.ts +7 -2
  40. package/src/utils/dom/calculateAvailablePanelSizeInPixels.ts +8 -3
  41. package/src/utils/dom/getAvailableGroupSizePixels.ts +8 -7
  42. package/src/utils/dom/getPanelElement.ts +5 -2
  43. package/src/utils/dom/getPanelElementsForGroup.ts +7 -2
  44. package/src/utils/dom/getPanelGroupElement.ts +14 -2
  45. package/src/utils/dom/getResizeHandleElement.ts +5 -2
  46. package/src/utils/dom/getResizeHandleElementIndex.ts +3 -2
  47. package/src/utils/dom/getResizeHandleElementsForGroup.ts +3 -2
  48. package/src/utils/dom/getResizeHandlePanelIds.ts +4 -3
  49. package/src/utils/validatePanelConstraints.test.ts +45 -0
  50. package/src/utils/validatePanelConstraints.ts +5 -1
  51. package/src/vendor/react.ts +2 -0
@@ -441,41 +441,48 @@ function adjustLayoutByDelta({
441
441
  return nextLayout;
442
442
  }
443
443
 
444
- function getResizeHandleElementsForGroup(groupId) {
445
- return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
444
+ function getResizeHandleElementsForGroup(groupId, panelGroupElement) {
445
+ return Array.from(panelGroupElement.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
446
446
  }
447
447
 
448
- function getResizeHandleElementIndex(groupId, id) {
449
- const handles = getResizeHandleElementsForGroup(groupId);
448
+ function getResizeHandleElementIndex(groupId, id, panelGroupElement) {
449
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
450
450
  const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
451
451
  return index !== null && index !== void 0 ? index : null;
452
452
  }
453
453
 
454
- function determinePivotIndices(groupId, dragHandleId) {
455
- const index = getResizeHandleElementIndex(groupId, dragHandleId);
454
+ function determinePivotIndices(groupId, dragHandleId, panelGroupElement) {
455
+ const index = getResizeHandleElementIndex(groupId, dragHandleId, panelGroupElement);
456
456
  return index != null ? [index, index + 1] : [-1, -1];
457
457
  }
458
458
 
459
- function getPanelGroupElement(id) {
460
- const element = document.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
459
+ function getPanelGroupElement(id, rootElement) {
460
+ var _dataset;
461
+ //If the root element is the PanelGroup
462
+ if (rootElement instanceof HTMLElement && (rootElement === null || rootElement === void 0 ? void 0 : (_dataset = rootElement.dataset) === null || _dataset === void 0 ? void 0 : _dataset.panelGroupId) == id) {
463
+ return rootElement;
464
+ }
465
+
466
+ //Else query children
467
+ const element = rootElement.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
461
468
  if (element) {
462
469
  return element;
463
470
  }
464
471
  return null;
465
472
  }
466
473
 
467
- function getResizeHandleElement(id) {
468
- const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
474
+ function getResizeHandleElement(id, panelGroupElement) {
475
+ const element = panelGroupElement.querySelector(`[data-panel-resize-handle-id="${id}"]`);
469
476
  if (element) {
470
477
  return element;
471
478
  }
472
479
  return null;
473
480
  }
474
481
 
475
- function getResizeHandlePanelIds(groupId, handleId, panelsArray) {
482
+ function getResizeHandlePanelIds(groupId, handleId, panelsArray, panelGroupElement) {
476
483
  var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
477
- const handle = getResizeHandleElement(handleId);
478
- const handles = getResizeHandleElementsForGroup(groupId);
484
+ const handle = getResizeHandleElement(handleId, panelGroupElement);
485
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
479
486
  const index = handle ? handles.indexOf(handle) : -1;
480
487
  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;
481
488
  const idAfter = (_panelsArray$id = (_panelsArray = panelsArray[index + 1]) === null || _panelsArray === void 0 ? void 0 : _panelsArray.id) !== null && _panelsArray$id !== void 0 ? _panelsArray$id : null;
@@ -490,25 +497,29 @@ function useWindowSplitterPanelGroupBehavior({
490
497
  groupId,
491
498
  layout,
492
499
  panelDataArray,
500
+ panelGroupElement,
493
501
  setLayout
494
502
  }) {
495
503
  useRef({
496
504
  didWarnAboutMissingResizeHandle: false
497
505
  });
498
506
  useEffect(() => {
507
+ if (!panelGroupElement) {
508
+ return;
509
+ }
499
510
  const eagerValues = eagerValuesRef.current;
500
511
  assert(eagerValues);
501
512
  const {
502
513
  panelDataArray
503
514
  } = eagerValues;
504
- const groupElement = getPanelGroupElement(groupId);
515
+ const groupElement = getPanelGroupElement(groupId, panelGroupElement);
505
516
  assert(groupElement != null, `No group found for id "${groupId}"`);
506
- const handles = getResizeHandleElementsForGroup(groupId);
517
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
507
518
  assert(handles);
508
519
  const cleanupFunctions = handles.map(handle => {
509
520
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
510
521
  assert(handleId);
511
- const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
522
+ const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
512
523
  if (idBefore == null || idAfter == null) {
513
524
  return () => {};
514
525
  }
@@ -535,7 +546,7 @@ function useWindowSplitterPanelGroupBehavior({
535
546
  delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
536
547
  layout,
537
548
  panelConstraints: panelDataArray.map(panelData => panelData.constraints),
538
- pivotIndices: determinePivotIndices(groupId, handleId),
549
+ pivotIndices: determinePivotIndices(groupId, handleId, panelGroupElement),
539
550
  trigger: "keyboard"
540
551
  });
541
552
  if (layout !== nextLayout) {
@@ -555,7 +566,7 @@ function useWindowSplitterPanelGroupBehavior({
555
566
  return () => {
556
567
  cleanupFunctions.forEach(cleanupFunction => cleanupFunction());
557
568
  };
558
- }, [committedValuesRef, eagerValuesRef, groupId, layout, panelDataArray, setLayout]);
569
+ }, [panelGroupElement, committedValuesRef, eagerValuesRef, groupId, layout, panelDataArray, setLayout]);
559
570
  }
560
571
 
561
572
  function areEqual(arrayA, arrayB) {
@@ -593,9 +604,9 @@ function getResizeEventCursorPosition(direction, event) {
593
604
  }
594
605
  }
595
606
 
596
- function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
607
+ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement) {
597
608
  const isHorizontal = direction === "horizontal";
598
- const handleElement = getResizeHandleElement(dragHandleId);
609
+ const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
599
610
  assert(handleElement);
600
611
  const groupId = handleElement.getAttribute("data-panel-group-id");
601
612
  assert(groupId);
@@ -603,7 +614,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
603
614
  initialCursorPosition
604
615
  } = initialDragState;
605
616
  const cursorPosition = getResizeEventCursorPosition(direction, event);
606
- const groupElement = getPanelGroupElement(groupId);
617
+ const groupElement = getPanelGroupElement(groupId, panelGroupElement);
607
618
  assert(groupElement);
608
619
  const groupRect = groupElement.getBoundingClientRect();
609
620
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
@@ -613,7 +624,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
613
624
  }
614
625
 
615
626
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
616
- function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
627
+ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy, panelGroupElement) {
617
628
  if (isKeyDown(event)) {
618
629
  const isHorizontal = direction === "horizontal";
619
630
  let delta = 0;
@@ -650,7 +661,7 @@ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragSta
650
661
  if (initialDragState == null) {
651
662
  return 0;
652
663
  }
653
- return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
664
+ return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement);
654
665
  }
655
666
  }
656
667
 
@@ -877,6 +888,7 @@ function validatePanelConstraints({
877
888
  assert(panelConstraints);
878
889
  const {
879
890
  collapsedSize = 0,
891
+ collapsible = false,
880
892
  defaultSize,
881
893
  maxSize = 100,
882
894
  minSize = 0
@@ -887,7 +899,7 @@ function validatePanelConstraints({
887
899
  if (defaultSize != null) {
888
900
  if (defaultSize < 0) {
889
901
  warnings.push("default size should not be less than 0");
890
- } else if (defaultSize < minSize) {
902
+ } else if (defaultSize < minSize && (!collapsible || defaultSize !== collapsedSize)) {
891
903
  warnings.push("default size should not be less than min size");
892
904
  }
893
905
  if (defaultSize > 100) {
@@ -1002,6 +1014,7 @@ function PanelGroupWithForwardedRef({
1002
1014
  ...rest
1003
1015
  }) {
1004
1016
  const groupId = useUniqueId(idFromProps);
1017
+ const panelGroupElementRef = useRef(null);
1005
1018
  const [dragState, setDragState] = useState(null);
1006
1019
  const [layout, setLayout] = useState([]);
1007
1020
  const panelIdToLastNotifiedSizeMapRef = useRef({});
@@ -1062,7 +1075,8 @@ function PanelGroupWithForwardedRef({
1062
1075
  groupId,
1063
1076
  layout,
1064
1077
  panelDataArray: eagerValuesRef.current.panelDataArray,
1065
- setLayout
1078
+ setLayout,
1079
+ panelGroupElement: panelGroupElementRef.current
1066
1080
  });
1067
1081
  useEffect(() => {
1068
1082
  const {
@@ -1299,6 +1313,10 @@ function PanelGroupWithForwardedRef({
1299
1313
  const registerResizeHandle = useCallback(dragHandleId => {
1300
1314
  return function resizeHandler(event) {
1301
1315
  event.preventDefault();
1316
+ const panelGroupElement = panelGroupElementRef.current;
1317
+ if (!panelGroupElement) {
1318
+ return () => null;
1319
+ }
1302
1320
  const {
1303
1321
  direction,
1304
1322
  dragState,
@@ -1313,8 +1331,8 @@ function PanelGroupWithForwardedRef({
1313
1331
  const {
1314
1332
  initialLayout
1315
1333
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1316
- const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1317
- let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1334
+ const pivotIndices = determinePivotIndices(groupId, dragHandleId, panelGroupElement);
1335
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy, panelGroupElement);
1318
1336
  if (delta === 0) {
1319
1337
  return;
1320
1338
  }
@@ -1409,7 +1427,10 @@ function PanelGroupWithForwardedRef({
1409
1427
  const {
1410
1428
  layout
1411
1429
  } = eagerValuesRef.current;
1412
- const handleElement = getResizeHandleElement(dragHandleId);
1430
+ if (!panelGroupElementRef.current) {
1431
+ return;
1432
+ }
1433
+ const handleElement = getResizeHandleElement(dragHandleId, panelGroupElementRef.current);
1413
1434
  assert(handleElement);
1414
1435
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1415
1436
  setDragState({
@@ -1454,7 +1475,8 @@ function PanelGroupWithForwardedRef({
1454
1475
  resizePanel,
1455
1476
  startDragging,
1456
1477
  stopDragging,
1457
- unregisterPanel
1478
+ unregisterPanel,
1479
+ panelGroupElement: panelGroupElementRef.current
1458
1480
  }), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
1459
1481
  const style = {
1460
1482
  display: "flex",
@@ -1473,6 +1495,7 @@ function PanelGroupWithForwardedRef({
1473
1495
  ...style,
1474
1496
  ...styleFromProps
1475
1497
  },
1498
+ ref: panelGroupElementRef,
1476
1499
  // CSS selectors
1477
1500
  "data-panel-group": "",
1478
1501
  "data-panel-group-direction": direction,
@@ -1507,13 +1530,14 @@ function panelDataHelper(panelDataArray, panelData, layout) {
1507
1530
  function useWindowSplitterResizeHandlerBehavior({
1508
1531
  disabled,
1509
1532
  handleId,
1510
- resizeHandler
1533
+ resizeHandler,
1534
+ panelGroupElement
1511
1535
  }) {
1512
1536
  useEffect(() => {
1513
- if (disabled || resizeHandler == null) {
1537
+ if (disabled || resizeHandler == null || panelGroupElement == null) {
1514
1538
  return;
1515
1539
  }
1516
- const handleElement = getResizeHandleElement(handleId);
1540
+ const handleElement = getResizeHandleElement(handleId, panelGroupElement);
1517
1541
  if (handleElement == null) {
1518
1542
  return;
1519
1543
  }
@@ -1538,8 +1562,8 @@ function useWindowSplitterResizeHandlerBehavior({
1538
1562
  event.preventDefault();
1539
1563
  const groupId = handleElement.getAttribute("data-panel-group-id");
1540
1564
  assert(groupId);
1541
- const handles = getResizeHandleElementsForGroup(groupId);
1542
- const index = getResizeHandleElementIndex(groupId, handleId);
1565
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1566
+ const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
1543
1567
  assert(index !== null);
1544
1568
  const nextIndex = event.shiftKey ? index > 0 ? index - 1 : handles.length - 1 : index + 1 < handles.length ? index + 1 : 0;
1545
1569
  const nextHandle = handles[nextIndex];
@@ -1552,7 +1576,7 @@ function useWindowSplitterResizeHandlerBehavior({
1552
1576
  return () => {
1553
1577
  handleElement.removeEventListener("keydown", onKeyDown);
1554
1578
  };
1555
- }, [disabled, handleId, resizeHandler]);
1579
+ }, [panelGroupElement, disabled, handleId, resizeHandler]);
1556
1580
  }
1557
1581
 
1558
1582
  function PanelResizeHandle({
@@ -1585,7 +1609,8 @@ function PanelResizeHandle({
1585
1609
  groupId,
1586
1610
  registerResizeHandle,
1587
1611
  startDragging,
1588
- stopDragging
1612
+ stopDragging,
1613
+ panelGroupElement
1589
1614
  } = panelGroupContext;
1590
1615
  const resizeHandleId = useUniqueId(idFromProps);
1591
1616
  const isDragging = (dragState === null || dragState === void 0 ? void 0 : dragState.dragHandleId) === resizeHandleId;
@@ -1644,7 +1669,8 @@ function PanelResizeHandle({
1644
1669
  useWindowSplitterResizeHandlerBehavior({
1645
1670
  disabled,
1646
1671
  handleId: resizeHandleId,
1647
- resizeHandler
1672
+ resizeHandler,
1673
+ panelGroupElement
1648
1674
  });
1649
1675
  const style = {
1650
1676
  cursor: getCursorStyle(direction),
@@ -1700,13 +1726,12 @@ function PanelResizeHandle({
1700
1726
  }
1701
1727
  PanelResizeHandle.displayName = "PanelResizeHandle";
1702
1728
 
1703
- function calculateAvailablePanelSizeInPixels(groupId) {
1704
- const panelGroupElement = getPanelGroupElement(groupId);
1729
+ function calculateAvailablePanelSizeInPixels(groupId, panelGroupElement) {
1705
1730
  if (panelGroupElement == null) {
1706
1731
  return NaN;
1707
1732
  }
1708
1733
  const direction = panelGroupElement.getAttribute("data-panel-group-direction");
1709
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
1734
+ const resizeHandles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1710
1735
  if (direction === "horizontal") {
1711
1736
  return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
1712
1737
  return accumulated + handle.offsetWidth;
@@ -1718,13 +1743,9 @@ function calculateAvailablePanelSizeInPixels(groupId) {
1718
1743
  }
1719
1744
  }
1720
1745
 
1721
- function getAvailableGroupSizePixels(groupId) {
1722
- const panelGroupElement = getPanelGroupElement(groupId);
1723
- if (panelGroupElement == null) {
1724
- return NaN;
1725
- }
1746
+ function getAvailableGroupSizePixels(groupId, panelGroupElement) {
1726
1747
  const direction = panelGroupElement.getAttribute("data-panel-group-direction");
1727
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
1748
+ const resizeHandles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1728
1749
  if (direction === "horizontal") {
1729
1750
  return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
1730
1751
  return accumulated + handle.offsetWidth;
@@ -1736,16 +1757,16 @@ function getAvailableGroupSizePixels(groupId) {
1736
1757
  }
1737
1758
  }
1738
1759
 
1739
- function getPanelElement(id) {
1740
- const element = document.querySelector(`[data-panel-id="${id}"]`);
1760
+ function getPanelElement(id, panelGroupElement) {
1761
+ const element = panelGroupElement.querySelector(`[data-panel-id="${id}"]`);
1741
1762
  if (element) {
1742
1763
  return element;
1743
1764
  }
1744
1765
  return null;
1745
1766
  }
1746
1767
 
1747
- function getPanelElementsForGroup(groupId) {
1748
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
1768
+ function getPanelElementsForGroup(groupId, panelGroupElement) {
1769
+ return Array.from(panelGroupElement.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
1749
1770
  }
1750
1771
 
1751
1772
  export { Panel, PanelGroup, PanelResizeHandle, assert, calculateAvailablePanelSizeInPixels, getAvailableGroupSizePixels, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds };