react-resizable-panels 1.0.7 → 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.
Files changed (60) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +16 -15
  3. package/dist/declarations/src/Panel.d.ts +3 -3
  4. package/dist/declarations/src/PanelGroup.d.ts +2 -2
  5. package/dist/declarations/src/PanelResizeHandle.d.ts +2 -2
  6. package/dist/declarations/src/index.d.ts +1 -3
  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 +114 -84
  16. package/dist/react-resizable-panels.browser.cjs.mjs +0 -2
  17. package/dist/react-resizable-panels.browser.development.cjs.js +116 -85
  18. package/dist/react-resizable-panels.browser.development.cjs.mjs +0 -2
  19. package/dist/react-resizable-panels.browser.development.esm.js +117 -84
  20. package/dist/react-resizable-panels.browser.esm.js +115 -83
  21. package/dist/react-resizable-panels.cjs.js +114 -84
  22. package/dist/react-resizable-panels.cjs.mjs +0 -2
  23. package/dist/react-resizable-panels.development.cjs.js +116 -85
  24. package/dist/react-resizable-panels.development.cjs.mjs +0 -2
  25. package/dist/react-resizable-panels.development.esm.js +117 -84
  26. package/dist/react-resizable-panels.development.node.cjs.js +102 -83
  27. package/dist/react-resizable-panels.development.node.cjs.mjs +0 -2
  28. package/dist/react-resizable-panels.development.node.esm.js +103 -82
  29. package/dist/react-resizable-panels.esm.js +115 -83
  30. package/dist/react-resizable-panels.node.cjs.js +100 -82
  31. package/dist/react-resizable-panels.node.cjs.mjs +0 -2
  32. package/dist/react-resizable-panels.node.esm.js +101 -81
  33. package/package.json +1 -1
  34. package/src/Panel.test.tsx +137 -2
  35. package/src/Panel.ts +16 -2
  36. package/src/PanelGroup.test.tsx +3 -2
  37. package/src/PanelGroup.ts +95 -35
  38. package/src/PanelGroupContext.ts +9 -3
  39. package/src/PanelResizeHandle.test.tsx +3 -3
  40. package/src/PanelResizeHandle.ts +4 -2
  41. package/src/hooks/useWindowSplitterBehavior.ts +14 -5
  42. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +23 -7
  43. package/src/index.ts +0 -4
  44. package/src/utils/calculateDeltaPercentage.ts +4 -2
  45. package/src/utils/calculateDragOffsetPercentage.ts +4 -3
  46. package/src/utils/determinePivotIndices.ts +7 -2
  47. package/src/utils/dom/getPanelElement.ts +5 -2
  48. package/src/utils/dom/getPanelElementsForGroup.ts +5 -2
  49. package/src/utils/dom/getPanelGroupElement.ts +14 -2
  50. package/src/utils/dom/getResizeHandleElement.ts +5 -4
  51. package/src/utils/dom/getResizeHandleElementIndex.ts +3 -2
  52. package/src/utils/dom/getResizeHandleElementsForGroup.ts +3 -2
  53. package/src/utils/dom/getResizeHandlePanelIds.ts +4 -3
  54. package/src/utils/validatePanelConstraints.test.ts +45 -0
  55. package/src/utils/validatePanelConstraints.ts +5 -1
  56. package/src/vendor/react.ts +2 -0
  57. package/dist/declarations/src/utils/dom/calculateAvailablePanelSizeInPixels.d.ts +0 -1
  58. package/dist/declarations/src/utils/dom/getAvailableGroupSizePixels.d.ts +0 -1
  59. package/src/utils/dom/calculateAvailablePanelSizeInPixels.ts +0 -29
  60. package/src/utils/dom/getAvailableGroupSizePixels.ts +0 -29
package/src/PanelGroup.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import { isDevelopment } from "#is-development";
2
- import { PanelData } from "./Panel";
3
- import { DragState, PanelGroupContext, ResizeEvent } from "./PanelGroupContext";
2
+ import { PanelConstraints, PanelData } from "./Panel";
3
+ import {
4
+ DragState,
5
+ PanelGroupContext,
6
+ ResizeEvent,
7
+ TPanelGroupContext,
8
+ } from "./PanelGroupContext";
4
9
  import useIsomorphicLayoutEffect from "./hooks/useIsomorphicEffect";
5
10
  import useUniqueId from "./hooks/useUniqueId";
6
11
  import { useWindowSplitterPanelGroupBehavior } from "./hooks/useWindowSplitterPanelGroupBehavior";
@@ -31,7 +36,7 @@ import {
31
36
  ForwardedRef,
32
37
  HTMLAttributes,
33
38
  PropsWithChildren,
34
- ReactNode,
39
+ ReactElement,
35
40
  createElement,
36
41
  forwardRef,
37
42
  useCallback,
@@ -103,9 +108,9 @@ function PanelGroupWithForwardedRef({
103
108
  ...rest
104
109
  }: PanelGroupProps & {
105
110
  forwardedRef: ForwardedRef<ImperativePanelGroupHandle>;
106
- }): ReactNode {
111
+ }): ReactElement {
107
112
  const groupId = useUniqueId(idFromProps);
108
-
113
+ const panelGroupElementRef = useRef<HTMLDivElement | null>(null);
109
114
  const [dragState, setDragState] = useState<DragState | null>(null);
110
115
  const [layout, setLayout] = useState<number[]>([]);
111
116
 
@@ -207,6 +212,7 @@ function PanelGroupWithForwardedRef({
207
212
  layout,
208
213
  panelDataArray: eagerValuesRef.current.panelDataArray,
209
214
  setLayout,
215
+ panelGroupElement: panelGroupElementRef.current,
210
216
  });
211
217
 
212
218
  useEffect(() => {
@@ -561,7 +567,10 @@ function PanelGroupWithForwardedRef({
561
567
  const registerResizeHandle = useCallback((dragHandleId: string) => {
562
568
  return function resizeHandler(event: ResizeEvent) {
563
569
  event.preventDefault();
564
-
570
+ const panelGroupElement = panelGroupElementRef.current;
571
+ if (!panelGroupElement) {
572
+ return () => null;
573
+ }
565
574
  const {
566
575
  direction,
567
576
  dragState,
@@ -573,14 +582,19 @@ function PanelGroupWithForwardedRef({
573
582
 
574
583
  const { initialLayout } = dragState ?? {};
575
584
 
576
- const pivotIndices = determinePivotIndices(groupId, dragHandleId);
585
+ const pivotIndices = determinePivotIndices(
586
+ groupId,
587
+ dragHandleId,
588
+ panelGroupElement
589
+ );
577
590
 
578
591
  let delta = calculateDeltaPercentage(
579
592
  event,
580
593
  dragHandleId,
581
594
  direction,
582
595
  dragState,
583
- keyboardResizeBy
596
+ keyboardResizeBy,
597
+ panelGroupElement
584
598
  );
585
599
  if (delta === 0) {
586
600
  return;
@@ -705,12 +719,60 @@ function PanelGroupWithForwardedRef({
705
719
  []
706
720
  );
707
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
+
708
765
  const startDragging = useCallback(
709
766
  (dragHandleId: string, event: ResizeEvent) => {
710
767
  const { direction } = committedValuesRef.current;
711
768
  const { layout } = eagerValuesRef.current;
712
-
713
- const handleElement = getResizeHandleElement(dragHandleId);
769
+ if (!panelGroupElementRef.current) {
770
+ return;
771
+ }
772
+ const handleElement = getResizeHandleElement(
773
+ dragHandleId,
774
+ panelGroupElementRef.current
775
+ );
714
776
  assert(handleElement);
715
777
 
716
778
  const initialCursorPosition = getResizeEventCursorPosition(
@@ -751,23 +813,26 @@ function PanelGroupWithForwardedRef({
751
813
  }, []);
752
814
 
753
815
  const context = useMemo(
754
- () => ({
755
- collapsePanel,
756
- direction,
757
- dragState,
758
- expandPanel,
759
- getPanelSize,
760
- getPanelStyle,
761
- groupId,
762
- isPanelCollapsed,
763
- isPanelExpanded,
764
- registerPanel,
765
- registerResizeHandle,
766
- resizePanel,
767
- startDragging,
768
- stopDragging,
769
- unregisterPanel,
770
- }),
816
+ () =>
817
+ ({
818
+ collapsePanel,
819
+ direction,
820
+ dragState,
821
+ expandPanel,
822
+ getPanelSize,
823
+ getPanelStyle,
824
+ groupId,
825
+ isPanelCollapsed,
826
+ isPanelExpanded,
827
+ reevaluatePanelConstraints,
828
+ registerPanel,
829
+ registerResizeHandle,
830
+ resizePanel,
831
+ startDragging,
832
+ stopDragging,
833
+ unregisterPanel,
834
+ panelGroupElement: panelGroupElementRef.current,
835
+ }) satisfies TPanelGroupContext,
771
836
  [
772
837
  collapsePanel,
773
838
  dragState,
@@ -778,6 +843,7 @@ function PanelGroupWithForwardedRef({
778
843
  groupId,
779
844
  isPanelCollapsed,
780
845
  isPanelExpanded,
846
+ reevaluatePanelConstraints,
781
847
  registerPanel,
782
848
  registerResizeHandle,
783
849
  resizePanel,
@@ -800,14 +866,13 @@ function PanelGroupWithForwardedRef({
800
866
  { value: context },
801
867
  createElement(Type, {
802
868
  ...rest,
803
-
804
869
  children,
805
870
  className: classNameFromProps,
806
871
  style: {
807
872
  ...style,
808
873
  ...styleFromProps,
809
874
  },
810
-
875
+ ref: panelGroupElementRef,
811
876
  // CSS selectors
812
877
  "data-panel-group": "",
813
878
  "data-panel-group-direction": direction,
@@ -838,12 +903,7 @@ function panelDataHelper(
838
903
  panelData: PanelData,
839
904
  layout: number[]
840
905
  ) {
841
- const panelConstraintsArray = panelDataArray.map(
842
- (panelData) => panelData.constraints
843
- );
844
-
845
906
  const panelIndex = findPanelDataIndex(panelDataArray, panelData);
846
- const panelConstraints = panelConstraintsArray[panelIndex];
847
907
 
848
908
  const isLastPanel = panelIndex === panelDataArray.length - 1;
849
909
  const pivotIndices = isLastPanel
@@ -853,7 +913,7 @@ function panelDataHelper(
853
913
  const panelSize = layout[panelIndex];
854
914
 
855
915
  return {
856
- ...panelConstraints,
916
+ ...panelData.constraints,
857
917
  panelSize,
858
918
  pivotIndices,
859
919
  };
@@ -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;
@@ -11,7 +11,7 @@ export type DragState = {
11
11
  initialLayout: number[];
12
12
  };
13
13
 
14
- export const PanelGroupContext = createContext<{
14
+ export type TPanelGroupContext = {
15
15
  collapsePanel: (panelData: PanelData) => void;
16
16
  direction: "horizontal" | "vertical";
17
17
  dragState: DragState | null;
@@ -24,12 +24,18 @@ export const PanelGroupContext = createContext<{
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;
30
34
  startDragging: (dragHandleId: string, event: ResizeEvent) => void;
31
35
  stopDragging: () => void;
32
36
  unregisterPanel: (panelData: PanelData) => void;
33
- } | null>(null);
37
+ panelGroupElement: ParentNode | null;
38
+ };
39
+ export const PanelGroupContext = createContext<TPanelGroupContext | null>(null);
34
40
 
35
41
  PanelGroupContext.displayName = "PanelGroupContext";
@@ -7,12 +7,12 @@ import { getResizeHandleElement } from "./utils/dom/getResizeHandleElement";
7
7
  describe("PanelResizeHandle", () => {
8
8
  let expectedWarnings: string[] = [];
9
9
  let root: Root;
10
+ let container: HTMLElement;
10
11
 
11
12
  beforeEach(() => {
12
13
  // @ts-expect-error
13
14
  global.IS_REACT_ACT_ENVIRONMENT = true;
14
-
15
- const container = document.createElement("div");
15
+ container = document.createElement("div");
16
16
  document.body.appendChild(container);
17
17
 
18
18
  expectedWarnings = [];
@@ -59,7 +59,7 @@ describe("PanelResizeHandle", () => {
59
59
  );
60
60
  });
61
61
 
62
- const element = getResizeHandleElement("handle");
62
+ const element = getResizeHandleElement("handle", container);
63
63
  assert(element);
64
64
  expect(element.tabIndex).toBe(123);
65
65
  expect(element.getAttribute("data-test-name")).toBe("foo");
@@ -4,8 +4,8 @@ import {
4
4
  CSSProperties,
5
5
  HTMLAttributes,
6
6
  PropsWithChildren,
7
+ ReactElement,
7
8
  MouseEvent as ReactMouseEvent,
8
- ReactNode,
9
9
  TouchEvent,
10
10
  useCallback,
11
11
  useContext,
@@ -49,7 +49,7 @@ export function PanelResizeHandle({
49
49
  tabIndex = 0,
50
50
  tagName: Type = "div",
51
51
  ...rest
52
- }: PanelResizeHandleProps): ReactNode {
52
+ }: PanelResizeHandleProps): ReactElement {
53
53
  const elementRef = useRef<HTMLElement>(null);
54
54
 
55
55
  // Use a ref to guard against users passing inline props
@@ -74,6 +74,7 @@ export function PanelResizeHandle({
74
74
  registerResizeHandle,
75
75
  startDragging,
76
76
  stopDragging,
77
+ panelGroupElement,
77
78
  } = panelGroupContext;
78
79
 
79
80
  const resizeHandleId = useUniqueId(idFromProps);
@@ -151,6 +152,7 @@ export function PanelResizeHandle({
151
152
  disabled,
152
153
  handleId: resizeHandleId,
153
154
  resizeHandler,
155
+ panelGroupElement,
154
156
  });
155
157
 
156
158
  const style: CSSProperties = {
@@ -11,17 +11,19 @@ export function useWindowSplitterResizeHandlerBehavior({
11
11
  disabled,
12
12
  handleId,
13
13
  resizeHandler,
14
+ panelGroupElement,
14
15
  }: {
15
16
  disabled: boolean;
16
17
  handleId: string;
17
18
  resizeHandler: ResizeHandler | null;
19
+ panelGroupElement: ParentNode | null;
18
20
  }): void {
19
21
  useEffect(() => {
20
- if (disabled || resizeHandler == null) {
22
+ if (disabled || resizeHandler == null || panelGroupElement == null) {
21
23
  return;
22
24
  }
23
25
 
24
- const handleElement = getResizeHandleElement(handleId);
26
+ const handleElement = getResizeHandleElement(handleId, panelGroupElement);
25
27
  if (handleElement == null) {
26
28
  return;
27
29
  }
@@ -49,8 +51,15 @@ export function useWindowSplitterResizeHandlerBehavior({
49
51
  const groupId = handleElement.getAttribute("data-panel-group-id");
50
52
  assert(groupId);
51
53
 
52
- const handles = getResizeHandleElementsForGroup(groupId);
53
- const index = getResizeHandleElementIndex(groupId, handleId);
54
+ const handles = getResizeHandleElementsForGroup(
55
+ groupId,
56
+ panelGroupElement
57
+ );
58
+ const index = getResizeHandleElementIndex(
59
+ groupId,
60
+ handleId,
61
+ panelGroupElement
62
+ );
54
63
 
55
64
  assert(index !== null);
56
65
 
@@ -74,5 +83,5 @@ export function useWindowSplitterResizeHandlerBehavior({
74
83
  return () => {
75
84
  handleElement.removeEventListener("keydown", onKeyDown);
76
85
  };
77
- }, [disabled, handleId, resizeHandler]);
86
+ }, [panelGroupElement, disabled, handleId, resizeHandler]);
78
87
  }
@@ -20,6 +20,7 @@ export function useWindowSplitterPanelGroupBehavior({
20
20
  groupId,
21
21
  layout,
22
22
  panelDataArray,
23
+ panelGroupElement,
23
24
  setLayout,
24
25
  }: {
25
26
  committedValuesRef: RefObject<{
@@ -31,6 +32,7 @@ export function useWindowSplitterPanelGroupBehavior({
31
32
  groupId: string;
32
33
  layout: number[];
33
34
  panelDataArray: PanelData[];
35
+ panelGroupElement: ParentNode | null;
34
36
  setLayout: (sizes: number[]) => void;
35
37
  }): void {
36
38
  const devWarningsRef = useRef<{
@@ -40,7 +42,13 @@ export function useWindowSplitterPanelGroupBehavior({
40
42
  });
41
43
 
42
44
  useIsomorphicLayoutEffect(() => {
43
- const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
45
+ if (!panelGroupElement) {
46
+ return;
47
+ }
48
+ const resizeHandleElements = getResizeHandleElementsForGroup(
49
+ groupId,
50
+ panelGroupElement
51
+ );
44
52
 
45
53
  for (let index = 0; index < panelDataArray.length - 1; index++) {
46
54
  const { valueMax, valueMin, valueNow } = calculateAriaValues({
@@ -90,18 +98,20 @@ export function useWindowSplitterPanelGroupBehavior({
90
98
  resizeHandleElement.removeAttribute("aria-valuenow");
91
99
  });
92
100
  };
93
- }, [groupId, layout, panelDataArray]);
101
+ }, [groupId, layout, panelDataArray, panelGroupElement]);
94
102
 
95
103
  useEffect(() => {
104
+ if (!panelGroupElement) {
105
+ return;
106
+ }
96
107
  const eagerValues = eagerValuesRef.current;
97
108
  assert(eagerValues);
98
109
 
99
110
  const { panelDataArray } = eagerValues;
100
-
101
- const groupElement = getPanelGroupElement(groupId);
111
+ const groupElement = getPanelGroupElement(groupId, panelGroupElement);
102
112
  assert(groupElement != null, `No group found for id "${groupId}"`);
103
113
 
104
- const handles = getResizeHandleElementsForGroup(groupId);
114
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
105
115
  assert(handles);
106
116
 
107
117
  const cleanupFunctions = handles.map((handle) => {
@@ -111,7 +121,8 @@ export function useWindowSplitterPanelGroupBehavior({
111
121
  const [idBefore, idAfter] = getResizeHandlePanelIds(
112
122
  groupId,
113
123
  handleId,
114
- panelDataArray
124
+ panelDataArray,
125
+ panelGroupElement
115
126
  );
116
127
  if (idBefore == null || idAfter == null) {
117
128
  return () => {};
@@ -150,7 +161,11 @@ export function useWindowSplitterPanelGroupBehavior({
150
161
  panelConstraints: panelDataArray.map(
151
162
  (panelData) => panelData.constraints
152
163
  ),
153
- pivotIndices: determinePivotIndices(groupId, handleId),
164
+ pivotIndices: determinePivotIndices(
165
+ groupId,
166
+ handleId,
167
+ panelGroupElement
168
+ ),
154
169
  trigger: "keyboard",
155
170
  });
156
171
  if (layout !== nextLayout) {
@@ -174,6 +189,7 @@ export function useWindowSplitterPanelGroupBehavior({
174
189
  cleanupFunctions.forEach((cleanupFunction) => cleanupFunction());
175
190
  };
176
191
  }, [
192
+ panelGroupElement,
177
193
  committedValuesRef,
178
194
  eagerValuesRef,
179
195
  groupId,
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,
@@ -9,7 +9,8 @@ export function calculateDeltaPercentage(
9
9
  dragHandleId: string,
10
10
  direction: Direction,
11
11
  initialDragState: DragState | null,
12
- keyboardResizeBy: number | null
12
+ keyboardResizeBy: number | null,
13
+ panelGroupElement: HTMLElement
13
14
  ): number {
14
15
  if (isKeyDown(event)) {
15
16
  const isHorizontal = direction === "horizontal";
@@ -55,7 +56,8 @@ export function calculateDeltaPercentage(
55
56
  event,
56
57
  dragHandleId,
57
58
  direction,
58
- initialDragState
59
+ initialDragState,
60
+ panelGroupElement
59
61
  );
60
62
  }
61
63
  }
@@ -9,11 +9,12 @@ export function calculateDragOffsetPercentage(
9
9
  event: ResizeEvent,
10
10
  dragHandleId: string,
11
11
  direction: Direction,
12
- initialDragState: DragState
12
+ initialDragState: DragState,
13
+ panelGroupElement: HTMLElement
13
14
  ): number {
14
15
  const isHorizontal = direction === "horizontal";
15
16
 
16
- const handleElement = getResizeHandleElement(dragHandleId);
17
+ const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
17
18
  assert(handleElement);
18
19
 
19
20
  const groupId = handleElement.getAttribute("data-panel-group-id");
@@ -23,7 +24,7 @@ export function calculateDragOffsetPercentage(
23
24
 
24
25
  const cursorPosition = getResizeEventCursorPosition(direction, event);
25
26
 
26
- const groupElement = getPanelGroupElement(groupId);
27
+ const groupElement = getPanelGroupElement(groupId, panelGroupElement);
27
28
  assert(groupElement);
28
29
 
29
30
  const groupRect = groupElement.getBoundingClientRect();
@@ -2,9 +2,14 @@ import { getResizeHandleElementIndex } from "../utils/dom/getResizeHandleElement
2
2
 
3
3
  export function determinePivotIndices(
4
4
  groupId: string,
5
- dragHandleId: string
5
+ dragHandleId: string,
6
+ panelGroupElement: ParentNode
6
7
  ): [indexBefore: number, indexAfter: number] {
7
- const index = getResizeHandleElementIndex(groupId, dragHandleId);
8
+ const index = getResizeHandleElementIndex(
9
+ groupId,
10
+ dragHandleId,
11
+ panelGroupElement
12
+ );
8
13
 
9
14
  return index != null ? [index, index + 1] : [-1, -1];
10
15
  }
@@ -1,5 +1,8 @@
1
- export function getPanelElement(id: string): HTMLElement | null {
2
- const element = document.querySelector(`[data-panel-id="${id}"]`);
1
+ export function getPanelElement(
2
+ id: string,
3
+ scope: ParentNode | HTMLElement = document
4
+ ): HTMLElement | null {
5
+ const element = scope.querySelector(`[data-panel-id="${id}"]`);
3
6
  if (element) {
4
7
  return element as HTMLElement;
5
8
  }
@@ -1,5 +1,8 @@
1
- export function getPanelElementsForGroup(groupId: string): HTMLElement[] {
1
+ export function getPanelElementsForGroup(
2
+ groupId: string,
3
+ scope: ParentNode | HTMLElement = document
4
+ ): HTMLElement[] {
2
5
  return Array.from(
3
- document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`)
6
+ scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`)
4
7
  );
5
8
  }
@@ -1,5 +1,17 @@
1
- export function getPanelGroupElement(id: string): HTMLElement | null {
2
- const element = document.querySelector(
1
+ export function getPanelGroupElement(
2
+ id: string,
3
+ rootElement: ParentNode | HTMLElement = document
4
+ ): HTMLElement | null {
5
+ //If the root element is the PanelGroup
6
+ if (
7
+ rootElement instanceof HTMLElement &&
8
+ (rootElement as HTMLElement)?.dataset?.panelGroupId == id
9
+ ) {
10
+ return rootElement as HTMLElement;
11
+ }
12
+
13
+ //Else query children
14
+ const element = rootElement.querySelector(
3
15
  `[data-panel-group][data-panel-group-id="${id}"]`
4
16
  );
5
17
  if (element) {
@@ -1,7 +1,8 @@
1
- export function getResizeHandleElement(id: string): HTMLElement | null {
2
- const element = document.querySelector(
3
- `[data-panel-resize-handle-id="${id}"]`
4
- );
1
+ export function getResizeHandleElement(
2
+ id: string,
3
+ scope: ParentNode | HTMLElement = document
4
+ ): HTMLElement | null {
5
+ const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
5
6
  if (element) {
6
7
  return element as HTMLElement;
7
8
  }
@@ -2,9 +2,10 @@ import { getResizeHandleElementsForGroup } from "./getResizeHandleElementsForGro
2
2
 
3
3
  export function getResizeHandleElementIndex(
4
4
  groupId: string,
5
- id: string
5
+ id: string,
6
+ scope: ParentNode | HTMLElement = document
6
7
  ): number | null {
7
- const handles = getResizeHandleElementsForGroup(groupId);
8
+ const handles = getResizeHandleElementsForGroup(groupId, scope);
8
9
  const index = handles.findIndex(
9
10
  (handle) => handle.getAttribute("data-panel-resize-handle-id") === id
10
11
  );
@@ -1,8 +1,9 @@
1
1
  export function getResizeHandleElementsForGroup(
2
- groupId: string
2
+ groupId: string,
3
+ scope: ParentNode | HTMLElement = document
3
4
  ): HTMLElement[] {
4
5
  return Array.from(
5
- document.querySelectorAll(
6
+ scope.querySelectorAll(
6
7
  `[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`
7
8
  )
8
9
  );
@@ -5,10 +5,11 @@ import { getResizeHandleElementsForGroup } from "./getResizeHandleElementsForGro
5
5
  export function getResizeHandlePanelIds(
6
6
  groupId: string,
7
7
  handleId: string,
8
- panelsArray: PanelData[]
8
+ panelsArray: PanelData[],
9
+ scope: ParentNode | HTMLElement = document
9
10
  ): [idBefore: string | null, idAfter: string | null] {
10
- const handle = getResizeHandleElement(handleId);
11
- const handles = getResizeHandleElementsForGroup(groupId);
11
+ const handle = getResizeHandleElement(handleId, scope);
12
+ const handles = getResizeHandleElementsForGroup(groupId, scope);
12
13
  const index = handle ? handles.indexOf(handle) : -1;
13
14
 
14
15
  const idBefore: string | null = panelsArray[index]?.id ?? null;