react-resizable-panels 2.0.3 → 2.0.5

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 (38) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/declarations/src/PanelResizeHandle.d.ts +1 -0
  3. package/dist/declarations/src/PanelResizeHandleRegistry.d.ts +1 -2
  4. package/dist/declarations/src/index.d.ts +3 -1
  5. package/dist/declarations/src/utils/rects/getIntersectingRectangle.d.ts +2 -0
  6. package/dist/declarations/src/utils/rects/intersects.d.ts +2 -0
  7. package/dist/declarations/src/utils/rects/types.d.ts +6 -0
  8. package/dist/react-resizable-panels.browser.cjs.js +138 -56
  9. package/dist/react-resizable-panels.browser.cjs.mjs +3 -1
  10. package/dist/react-resizable-panels.browser.development.cjs.js +138 -56
  11. package/dist/react-resizable-panels.browser.development.cjs.mjs +3 -1
  12. package/dist/react-resizable-panels.browser.development.esm.js +137 -57
  13. package/dist/react-resizable-panels.browser.esm.js +137 -57
  14. package/dist/react-resizable-panels.cjs.js +138 -56
  15. package/dist/react-resizable-panels.cjs.mjs +3 -1
  16. package/dist/react-resizable-panels.development.cjs.js +138 -56
  17. package/dist/react-resizable-panels.development.cjs.mjs +3 -1
  18. package/dist/react-resizable-panels.development.esm.js +137 -57
  19. package/dist/react-resizable-panels.development.node.cjs.js +138 -56
  20. package/dist/react-resizable-panels.development.node.cjs.mjs +3 -1
  21. package/dist/react-resizable-panels.development.node.esm.js +137 -57
  22. package/dist/react-resizable-panels.esm.js +137 -57
  23. package/dist/react-resizable-panels.node.cjs.js +138 -56
  24. package/dist/react-resizable-panels.node.cjs.mjs +3 -1
  25. package/dist/react-resizable-panels.node.esm.js +137 -57
  26. package/package.json +4 -1
  27. package/src/Panel.test.tsx +63 -0
  28. package/src/PanelGroup.test.tsx +21 -1
  29. package/src/PanelResizeHandle.test.tsx +181 -22
  30. package/src/PanelResizeHandle.ts +44 -24
  31. package/src/PanelResizeHandleRegistry.ts +87 -30
  32. package/src/index.ts +4 -0
  33. package/src/utils/rects/getIntersectingRectangle.test.ts +198 -0
  34. package/src/utils/rects/getIntersectingRectangle.ts +28 -0
  35. package/src/utils/rects/intersects.test.ts +197 -0
  36. package/src/utils/rects/intersects.ts +23 -0
  37. package/src/utils/rects/types.ts +6 -0
  38. package/src/utils/test-utils.ts +39 -0
@@ -0,0 +1,197 @@
1
+ import { intersects } from "./intersects";
2
+ import { Rectangle } from "./types";
3
+
4
+ const emptyRect = { x: 0, y: 0, width: 0, height: 0 };
5
+ const rect = { x: 25, y: 25, width: 50, height: 50 };
6
+
7
+ function forkRect(partial: Partial<Rectangle>, baseRect: Rectangle = rect) {
8
+ return { ...rect, ...partial };
9
+ }
10
+
11
+ describe("intersects", () => {
12
+ let strict: boolean = false;
13
+
14
+ function verify(rectOne: Rectangle, rectTwo: Rectangle, expected: boolean) {
15
+ const actual = intersects(rectOne, rectTwo, strict);
16
+
17
+ try {
18
+ expect(actual).toBe(expected);
19
+ } catch (thrown) {
20
+ console.log(
21
+ "Expected",
22
+ rectOne,
23
+ "to",
24
+ expected ? "intersect" : "not intersect",
25
+ rectTwo,
26
+ strict ? "in strict mode" : "in loose mode"
27
+ );
28
+
29
+ throw thrown;
30
+ }
31
+ }
32
+
33
+ describe("loose", () => {
34
+ beforeEach(() => {
35
+ strict = false;
36
+ });
37
+
38
+ it("should handle empty rects", () => {
39
+ verify(emptyRect, emptyRect, true);
40
+ });
41
+
42
+ it("should support fully overlapping rects", () => {
43
+ verify(rect, rect, true);
44
+
45
+ verify(rect, forkRect({ x: 35, width: 30 }), true);
46
+ verify(rect, forkRect({ y: 35, height: 30 }), true);
47
+ verify(
48
+ rect,
49
+ forkRect({
50
+ x: 35,
51
+ y: 35,
52
+ width: 30,
53
+ height: 30,
54
+ }),
55
+ true
56
+ );
57
+
58
+ verify(rect, forkRect({ x: 10, width: 100 }), true);
59
+ verify(rect, forkRect({ y: 10, height: 100 }), true);
60
+ verify(
61
+ rect,
62
+ forkRect({
63
+ x: 10,
64
+ y: 10,
65
+ width: 100,
66
+ height: 100,
67
+ }),
68
+ true
69
+ );
70
+ });
71
+
72
+ it("should support partially overlapping rects", () => {
73
+ const cases: Partial<Rectangle>[] = [
74
+ { x: 0 },
75
+ { y: 0 },
76
+
77
+ // Loose mode only
78
+ { x: -25 },
79
+ { x: 75 },
80
+ { y: -25 },
81
+ { y: 75 },
82
+ { x: -25, y: -25 },
83
+ { x: 75, y: 75 },
84
+ ];
85
+
86
+ cases.forEach((partial) => {
87
+ verify(forkRect(partial), rect, true);
88
+ });
89
+ });
90
+
91
+ it("should support non-overlapping rects", () => {
92
+ const cases: Partial<Rectangle>[] = [
93
+ { x: 100 },
94
+ { x: -100 },
95
+ { y: 100 },
96
+ { y: -100 },
97
+ { x: -100, y: -100 },
98
+ { x: 100, y: 100 },
99
+ ];
100
+
101
+ cases.forEach((partial) => {
102
+ verify(forkRect(partial), rect, false);
103
+ });
104
+ });
105
+
106
+ it("should support all negative coordinates", () => {
107
+ expect(
108
+ intersects(
109
+ { x: -100, y: -100, width: 50, height: 50 },
110
+ { x: -110, y: -90, width: 50, height: 50 },
111
+ false
112
+ )
113
+ ).toBe(true);
114
+ });
115
+ });
116
+
117
+ describe("strict", () => {
118
+ beforeEach(() => {
119
+ strict = true;
120
+ });
121
+
122
+ it("should handle empty rects", () => {
123
+ verify(emptyRect, emptyRect, false);
124
+ });
125
+
126
+ it("should support fully overlapping rects", () => {
127
+ verify(rect, rect, true);
128
+
129
+ verify(rect, forkRect({ x: 35, width: 30 }), true);
130
+ verify(rect, forkRect({ y: 35, height: 30 }), true);
131
+ verify(
132
+ rect,
133
+ forkRect({
134
+ x: 35,
135
+ y: 35,
136
+ width: 30,
137
+ height: 30,
138
+ }),
139
+ true
140
+ );
141
+
142
+ verify(rect, forkRect({ x: 10, width: 100 }), true);
143
+ verify(rect, forkRect({ y: 10, height: 100 }), true);
144
+ verify(
145
+ rect,
146
+ forkRect({
147
+ x: 10,
148
+ y: 10,
149
+ width: 100,
150
+ height: 100,
151
+ }),
152
+ true
153
+ );
154
+ });
155
+
156
+ it("should support partially overlapping rects", () => {
157
+ const cases: Partial<Rectangle>[] = [{ x: 0 }, { y: 0 }];
158
+
159
+ cases.forEach((partial) => {
160
+ verify(forkRect(partial), rect, true);
161
+ });
162
+ });
163
+
164
+ it("should support non-overlapping rects", () => {
165
+ const cases: Partial<Rectangle>[] = [
166
+ { x: 100 },
167
+ { x: -100 },
168
+ { y: 100 },
169
+ { y: -100 },
170
+ { x: -100, y: -100 },
171
+ { x: 100, y: 100 },
172
+
173
+ // Strict mode only
174
+ { x: -25 },
175
+ { x: 75 },
176
+ { y: -25 },
177
+ { y: 75 },
178
+ { x: -25, y: -25 },
179
+ { x: 75, y: 75 },
180
+ ];
181
+
182
+ cases.forEach((partial) => {
183
+ verify(forkRect(partial), rect, false);
184
+ });
185
+ });
186
+
187
+ it("should support all negative coordinates", () => {
188
+ expect(
189
+ intersects(
190
+ { x: -100, y: -100, width: 50, height: 50 },
191
+ { x: -110, y: -90, width: 50, height: 50 },
192
+ true
193
+ )
194
+ ).toBe(true);
195
+ });
196
+ });
197
+ });
@@ -0,0 +1,23 @@
1
+ import { Rectangle } from "./types";
2
+
3
+ export function intersects(
4
+ rectOne: Rectangle,
5
+ rectTwo: Rectangle,
6
+ strict: boolean
7
+ ): boolean {
8
+ if (strict) {
9
+ return (
10
+ rectOne.x < rectTwo.x + rectTwo.width &&
11
+ rectOne.x + rectOne.width > rectTwo.x &&
12
+ rectOne.y < rectTwo.y + rectTwo.height &&
13
+ rectOne.y + rectOne.height > rectTwo.y
14
+ );
15
+ } else {
16
+ return (
17
+ rectOne.x <= rectTwo.x + rectTwo.width &&
18
+ rectOne.x + rectOne.width >= rectTwo.x &&
19
+ rectOne.y <= rectTwo.y + rectTwo.height &&
20
+ rectOne.y + rectOne.height >= rectTwo.y
21
+ );
22
+ }
23
+ }
@@ -0,0 +1,6 @@
1
+ export interface Rectangle {
2
+ x: number;
3
+ y: number;
4
+ width: number;
5
+ height: number;
6
+ }
@@ -47,6 +47,36 @@ export function expectToBeCloseToArray(
47
47
  }
48
48
  }
49
49
 
50
+ export function mockBoundingClientRect(
51
+ element: HTMLElement,
52
+ rect: {
53
+ height: number;
54
+ width: number;
55
+ x: number;
56
+ y: number;
57
+ }
58
+ ) {
59
+ const { height, width, x, y } = rect;
60
+
61
+ Object.defineProperty(element, "getBoundingClientRect", {
62
+ configurable: true,
63
+ value: () =>
64
+ ({
65
+ bottom: y + height,
66
+ height,
67
+ left: x,
68
+ right: x + width,
69
+ toJSON() {
70
+ return "";
71
+ },
72
+ top: y,
73
+ width,
74
+ x,
75
+ y,
76
+ }) satisfies DOMRect,
77
+ });
78
+ }
79
+
50
80
  export function mockPanelGroupOffsetWidthAndHeight(
51
81
  mockWidth = 1_000,
52
82
  mockHeight = 1_000
@@ -102,6 +132,15 @@ export function mockPanelGroupOffsetWidthAndHeight(
102
132
  };
103
133
  }
104
134
 
135
+ export function verifyAttribute(
136
+ element: HTMLElement,
137
+ attributeName: string,
138
+ expectedValue: string | null
139
+ ) {
140
+ const actualValue = element.getAttribute(attributeName);
141
+ expect(actualValue).toBe(expectedValue);
142
+ }
143
+
105
144
  export function verifyExpandedPanelGroupLayout(
106
145
  actualLayout: number[],
107
146
  expectedLayout: number[]