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
@@ -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,
@@ -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,8 +1,10 @@
1
1
  import { getPanelGroupElement } from "./getPanelGroupElement";
2
2
  import { getResizeHandleElementsForGroup } from "./getResizeHandleElementsForGroup";
3
3
 
4
- export function calculateAvailablePanelSizeInPixels(groupId: string): number {
5
- const panelGroupElement = getPanelGroupElement(groupId);
4
+ export function calculateAvailablePanelSizeInPixels(
5
+ groupId: string,
6
+ panelGroupElement: HTMLElement
7
+ ): number {
6
8
  if (panelGroupElement == null) {
7
9
  return NaN;
8
10
  }
@@ -10,7 +12,10 @@ export function calculateAvailablePanelSizeInPixels(groupId: string): number {
10
12
  const direction = panelGroupElement.getAttribute(
11
13
  "data-panel-group-direction"
12
14
  );
13
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
15
+ const resizeHandles = getResizeHandleElementsForGroup(
16
+ groupId,
17
+ panelGroupElement
18
+ );
14
19
  if (direction === "horizontal") {
15
20
  return (
16
21
  panelGroupElement.offsetWidth -
@@ -1,16 +1,17 @@
1
1
  import { getPanelGroupElement } from "./getPanelGroupElement";
2
2
  import { getResizeHandleElementsForGroup } from "./getResizeHandleElementsForGroup";
3
3
 
4
- export function getAvailableGroupSizePixels(groupId: string): number {
5
- const panelGroupElement = getPanelGroupElement(groupId);
6
- if (panelGroupElement == null) {
7
- return NaN;
8
- }
9
-
4
+ export function getAvailableGroupSizePixels(
5
+ groupId: string,
6
+ panelGroupElement: HTMLElement
7
+ ): number {
10
8
  const direction = panelGroupElement.getAttribute(
11
9
  "data-panel-group-direction"
12
10
  );
13
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
11
+ const resizeHandles = getResizeHandleElementsForGroup(
12
+ groupId,
13
+ panelGroupElement
14
+ );
14
15
  if (direction === "horizontal") {
15
16
  return (
16
17
  panelGroupElement.offsetWidth -
@@ -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
+ panelGroupElement: HTMLElement
4
+ ): HTMLElement | null {
5
+ const element = panelGroupElement.querySelector(`[data-panel-id="${id}"]`);
3
6
  if (element) {
4
7
  return element as HTMLElement;
5
8
  }
@@ -1,5 +1,10 @@
1
- export function getPanelElementsForGroup(groupId: string): HTMLElement[] {
1
+ export function getPanelElementsForGroup(
2
+ groupId: string,
3
+ panelGroupElement: HTMLElement
4
+ ): HTMLElement[] {
2
5
  return Array.from(
3
- document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`)
6
+ panelGroupElement.querySelectorAll(
7
+ `[data-panel][data-panel-group-id="${groupId}"]`
8
+ )
4
9
  );
5
10
  }
@@ -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
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,5 +1,8 @@
1
- export function getResizeHandleElement(id: string): HTMLElement | null {
2
- const element = document.querySelector(
1
+ export function getResizeHandleElement(
2
+ id: string,
3
+ panelGroupElement: ParentNode
4
+ ): HTMLElement | null {
5
+ const element = panelGroupElement.querySelector(
3
6
  `[data-panel-resize-handle-id="${id}"]`
4
7
  );
5
8
  if (element) {
@@ -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
+ panelGroupElement: ParentNode
6
7
  ): number | null {
7
- const handles = getResizeHandleElementsForGroup(groupId);
8
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
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
+ panelGroupElement: ParentNode
3
4
  ): HTMLElement[] {
4
5
  return Array.from(
5
- document.querySelectorAll(
6
+ panelGroupElement.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
+ panelGroupElement: ParentNode
9
10
  ): [idBefore: string | null, idAfter: string | null] {
10
- const handle = getResizeHandleElement(handleId);
11
- const handles = getResizeHandleElementsForGroup(groupId);
11
+ const handle = getResizeHandleElement(handleId, panelGroupElement);
12
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
12
13
  const index = handle ? handles.indexOf(handle) : -1;
13
14
 
14
15
  const idBefore: string | null = panelsArray[index]?.id ?? null;
@@ -69,6 +69,51 @@ describe("validatePanelConstraints", () => {
69
69
  });
70
70
  }, "default size should not be less than min size");
71
71
 
72
+ verifyExpectedWarnings(() => {
73
+ validatePanelConstraints({
74
+ panelConstraints: [
75
+ {
76
+ collapsedSize: 5,
77
+ collapsible: true,
78
+ defaultSize: 5,
79
+ minSize: 10,
80
+ },
81
+ ],
82
+ panelIndex: 0,
83
+ panelId: "test",
84
+ });
85
+ });
86
+
87
+ verifyExpectedWarnings(() => {
88
+ validatePanelConstraints({
89
+ panelConstraints: [
90
+ {
91
+ collapsedSize: 7,
92
+ collapsible: true,
93
+ defaultSize: 5,
94
+ minSize: 10,
95
+ },
96
+ ],
97
+ panelIndex: 0,
98
+ panelId: "test",
99
+ });
100
+ }, "default size should not be less than min size");
101
+
102
+ verifyExpectedWarnings(() => {
103
+ validatePanelConstraints({
104
+ panelConstraints: [
105
+ {
106
+ collapsedSize: 5,
107
+ collapsible: false,
108
+ defaultSize: 5,
109
+ minSize: 10,
110
+ },
111
+ ],
112
+ panelIndex: 0,
113
+ panelId: "test",
114
+ });
115
+ }, "default size should not be less than min size");
116
+
72
117
  verifyExpectedWarnings(() => {
73
118
  validatePanelConstraints({
74
119
  panelConstraints: [
@@ -19,6 +19,7 @@ export function validatePanelConstraints({
19
19
 
20
20
  const {
21
21
  collapsedSize = 0,
22
+ collapsible = false,
22
23
  defaultSize,
23
24
  maxSize = 100,
24
25
  minSize = 0,
@@ -33,7 +34,10 @@ export function validatePanelConstraints({
33
34
  if (defaultSize != null) {
34
35
  if (defaultSize < 0) {
35
36
  warnings.push("default size should not be less than 0");
36
- } else if (defaultSize < minSize) {
37
+ } else if (
38
+ defaultSize < minSize &&
39
+ (!collapsible || defaultSize !== collapsedSize)
40
+ ) {
37
41
  warnings.push("default size should not be less than min size");
38
42
  }
39
43
 
@@ -15,6 +15,7 @@ import type {
15
15
  HTMLAttributes,
16
16
  MouseEvent,
17
17
  PropsWithChildren,
18
+ ReactElement,
18
19
  ReactNode,
19
20
  RefObject,
20
21
  TouchEvent,
@@ -61,6 +62,7 @@ export type {
61
62
  HTMLAttributes,
62
63
  MouseEvent,
63
64
  PropsWithChildren,
65
+ ReactElement,
64
66
  ReactNode,
65
67
  RefObject,
66
68
  TouchEvent,