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