react-resizable-panels 2.0.3 → 2.0.4
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.
- package/CHANGELOG.md +4 -0
- package/dist/declarations/src/PanelResizeHandle.d.ts +1 -0
- package/dist/declarations/src/PanelResizeHandleRegistry.d.ts +1 -2
- package/dist/react-resizable-panels.browser.cjs.js +55 -52
- package/dist/react-resizable-panels.browser.development.cjs.js +55 -52
- package/dist/react-resizable-panels.browser.development.esm.js +55 -52
- package/dist/react-resizable-panels.browser.esm.js +55 -52
- package/dist/react-resizable-panels.cjs.js +55 -52
- package/dist/react-resizable-panels.development.cjs.js +55 -52
- package/dist/react-resizable-panels.development.esm.js +55 -52
- package/dist/react-resizable-panels.development.node.cjs.js +55 -52
- package/dist/react-resizable-panels.development.node.esm.js +55 -52
- package/dist/react-resizable-panels.esm.js +55 -52
- package/dist/react-resizable-panels.node.cjs.js +55 -52
- package/dist/react-resizable-panels.node.esm.js +55 -52
- package/package.json +1 -1
- package/src/Panel.test.tsx +63 -0
- package/src/PanelGroup.test.tsx +21 -1
- package/src/PanelResizeHandle.test.tsx +181 -22
- package/src/PanelResizeHandle.ts +44 -24
- package/src/PanelResizeHandleRegistry.ts +13 -23
- package/src/utils/test-utils.ts +39 -0
package/src/PanelGroup.test.tsx
CHANGED
|
@@ -13,7 +13,10 @@ import {
|
|
|
13
13
|
} from ".";
|
|
14
14
|
import { assert } from "./utils/assert";
|
|
15
15
|
import { getPanelGroupElement } from "./utils/dom/getPanelGroupElement";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
mockPanelGroupOffsetWidthAndHeight,
|
|
18
|
+
verifyAttribute,
|
|
19
|
+
} from "./utils/test-utils";
|
|
17
20
|
import { createRef } from "./vendor/react";
|
|
18
21
|
|
|
19
22
|
describe("PanelGroup", () => {
|
|
@@ -256,6 +259,23 @@ describe("PanelGroup", () => {
|
|
|
256
259
|
});
|
|
257
260
|
});
|
|
258
261
|
|
|
262
|
+
describe("data attributes", () => {
|
|
263
|
+
it("should initialize with the correct props based attributes", () => {
|
|
264
|
+
act(() => {
|
|
265
|
+
root.render(
|
|
266
|
+
<PanelGroup direction="horizontal" id="test-group"></PanelGroup>
|
|
267
|
+
);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const element = getPanelGroupElement("test-group", container);
|
|
271
|
+
assert(element);
|
|
272
|
+
|
|
273
|
+
verifyAttribute(element, "data-panel-group", "");
|
|
274
|
+
verifyAttribute(element, "data-panel-group-direction", "horizontal");
|
|
275
|
+
verifyAttribute(element, "data-panel-group-id", "test-group");
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
259
279
|
describe("DEV warnings", () => {
|
|
260
280
|
it("should warn about unstable layouts without id and order props", () => {
|
|
261
281
|
act(() => {
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Root, createRoot } from "react-dom/client";
|
|
2
2
|
import { act } from "react-dom/test-utils";
|
|
3
|
+
import type { PanelResizeHandleProps } from "react-resizable-panels";
|
|
3
4
|
import { Panel, PanelGroup, PanelResizeHandle } from ".";
|
|
4
5
|
import { assert } from "./utils/assert";
|
|
5
6
|
import { getResizeHandleElement } from "./utils/dom/getResizeHandleElement";
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
dispatchPointerEvent,
|
|
9
|
+
mockBoundingClientRect,
|
|
10
|
+
verifyAttribute,
|
|
11
|
+
} from "./utils/test-utils";
|
|
7
12
|
|
|
8
13
|
describe("PanelResizeHandle", () => {
|
|
9
14
|
let expectedWarnings: string[] = [];
|
|
@@ -67,47 +72,201 @@ describe("PanelResizeHandle", () => {
|
|
|
67
72
|
expect(element.title).toBe("bar");
|
|
68
73
|
});
|
|
69
74
|
|
|
75
|
+
function setupMockedGroup({
|
|
76
|
+
leftProps = {},
|
|
77
|
+
rightProps = {},
|
|
78
|
+
}: {
|
|
79
|
+
leftProps?: Partial<PanelResizeHandleProps>;
|
|
80
|
+
rightProps?: Partial<PanelResizeHandleProps>;
|
|
81
|
+
} = {}) {
|
|
82
|
+
act(() => {
|
|
83
|
+
root.render(
|
|
84
|
+
<PanelGroup direction="horizontal" id="test-group">
|
|
85
|
+
<Panel />
|
|
86
|
+
<PanelResizeHandle id="handle-left" tabIndex={1} {...leftProps} />
|
|
87
|
+
<Panel />
|
|
88
|
+
<PanelResizeHandle id="handle-right" tabIndex={2} {...rightProps} />
|
|
89
|
+
<Panel />
|
|
90
|
+
</PanelGroup>
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const leftElement = getResizeHandleElement("handle-left", container);
|
|
95
|
+
const rightElement = getResizeHandleElement("handle-right", container);
|
|
96
|
+
|
|
97
|
+
assert(leftElement);
|
|
98
|
+
assert(rightElement);
|
|
99
|
+
|
|
100
|
+
// JSDom doesn't properly handle bounding rects
|
|
101
|
+
mockBoundingClientRect(leftElement, {
|
|
102
|
+
x: 50,
|
|
103
|
+
y: 0,
|
|
104
|
+
height: 50,
|
|
105
|
+
width: 2,
|
|
106
|
+
});
|
|
107
|
+
mockBoundingClientRect(rightElement, {
|
|
108
|
+
x: 100,
|
|
109
|
+
y: 0,
|
|
110
|
+
height: 50,
|
|
111
|
+
width: 2,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
leftElement,
|
|
116
|
+
rightElement,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
70
120
|
describe("callbacks", () => {
|
|
71
121
|
describe("onDragging", () => {
|
|
72
|
-
it("should fire when dragging starts/stops",
|
|
122
|
+
it("should fire when dragging starts/stops", () => {
|
|
73
123
|
const onDragging = jest.fn();
|
|
74
124
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<PanelGroup direction="horizontal">
|
|
78
|
-
<Panel />
|
|
79
|
-
<PanelResizeHandle
|
|
80
|
-
id="handle"
|
|
81
|
-
onDragging={onDragging}
|
|
82
|
-
tabIndex={123}
|
|
83
|
-
title="bar"
|
|
84
|
-
/>
|
|
85
|
-
<Panel />
|
|
86
|
-
</PanelGroup>
|
|
87
|
-
);
|
|
125
|
+
const { leftElement } = setupMockedGroup({
|
|
126
|
+
leftProps: { onDragging },
|
|
88
127
|
});
|
|
89
128
|
|
|
90
|
-
const handleElement = container.querySelector(
|
|
91
|
-
'[data-panel-resize-handle-id="handle"]'
|
|
92
|
-
) as HTMLElement;
|
|
93
|
-
|
|
94
129
|
act(() => {
|
|
95
|
-
dispatchPointerEvent("
|
|
130
|
+
dispatchPointerEvent("mousemove", leftElement);
|
|
96
131
|
});
|
|
97
132
|
expect(onDragging).not.toHaveBeenCalled();
|
|
98
133
|
|
|
99
134
|
act(() => {
|
|
100
|
-
dispatchPointerEvent("mousedown",
|
|
135
|
+
dispatchPointerEvent("mousedown", leftElement);
|
|
101
136
|
});
|
|
102
137
|
expect(onDragging).toHaveBeenCalledTimes(1);
|
|
103
138
|
expect(onDragging).toHaveBeenCalledWith(true);
|
|
104
139
|
|
|
105
140
|
act(() => {
|
|
106
|
-
dispatchPointerEvent("mouseup",
|
|
141
|
+
dispatchPointerEvent("mouseup", leftElement);
|
|
107
142
|
});
|
|
108
143
|
expect(onDragging).toHaveBeenCalledTimes(2);
|
|
109
144
|
expect(onDragging).toHaveBeenCalledWith(false);
|
|
110
145
|
});
|
|
146
|
+
|
|
147
|
+
it("should only fire for the handle that has been dragged", () => {
|
|
148
|
+
const onDraggingLeft = jest.fn();
|
|
149
|
+
const onDraggingRight = jest.fn();
|
|
150
|
+
|
|
151
|
+
const { leftElement } = setupMockedGroup({
|
|
152
|
+
leftProps: { onDragging: onDraggingLeft },
|
|
153
|
+
rightProps: { onDragging: onDraggingRight },
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
act(() => {
|
|
157
|
+
dispatchPointerEvent("mousemove", leftElement);
|
|
158
|
+
});
|
|
159
|
+
expect(onDraggingLeft).not.toHaveBeenCalled();
|
|
160
|
+
expect(onDraggingRight).not.toHaveBeenCalled();
|
|
161
|
+
|
|
162
|
+
act(() => {
|
|
163
|
+
dispatchPointerEvent("mousedown", leftElement);
|
|
164
|
+
});
|
|
165
|
+
expect(onDraggingLeft).toHaveBeenCalledTimes(1);
|
|
166
|
+
expect(onDraggingLeft).toHaveBeenCalledWith(true);
|
|
167
|
+
expect(onDraggingRight).not.toHaveBeenCalled();
|
|
168
|
+
|
|
169
|
+
act(() => {
|
|
170
|
+
dispatchPointerEvent("mouseup", leftElement);
|
|
171
|
+
});
|
|
172
|
+
expect(onDraggingLeft).toHaveBeenCalledTimes(2);
|
|
173
|
+
expect(onDraggingLeft).toHaveBeenCalledWith(false);
|
|
174
|
+
expect(onDraggingRight).not.toHaveBeenCalled();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
describe("data attributes", () => {
|
|
180
|
+
it("should initialize with the correct props based attributes", () => {
|
|
181
|
+
const { leftElement, rightElement } = setupMockedGroup();
|
|
182
|
+
|
|
183
|
+
verifyAttribute(leftElement, "data-panel-group-id", "test-group");
|
|
184
|
+
verifyAttribute(leftElement, "data-resize-handle", "");
|
|
185
|
+
verifyAttribute(leftElement, "data-panel-group-direction", "horizontal");
|
|
186
|
+
verifyAttribute(leftElement, "data-panel-resize-handle-enabled", "true");
|
|
187
|
+
verifyAttribute(
|
|
188
|
+
leftElement,
|
|
189
|
+
"data-panel-resize-handle-id",
|
|
190
|
+
"handle-left"
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
verifyAttribute(rightElement, "data-panel-group-id", "test-group");
|
|
194
|
+
verifyAttribute(rightElement, "data-resize-handle", "");
|
|
195
|
+
verifyAttribute(rightElement, "data-panel-group-direction", "horizontal");
|
|
196
|
+
verifyAttribute(rightElement, "data-panel-resize-handle-enabled", "true");
|
|
197
|
+
verifyAttribute(
|
|
198
|
+
rightElement,
|
|
199
|
+
"data-panel-resize-handle-id",
|
|
200
|
+
"handle-right"
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("should update data-resize-handle-active and data-resize-handle-state when dragging starts/stops", () => {
|
|
205
|
+
const { leftElement, rightElement } = setupMockedGroup();
|
|
206
|
+
verifyAttribute(leftElement, "data-resize-handle-active", null);
|
|
207
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
208
|
+
verifyAttribute(leftElement, "data-resize-handle-state", "inactive");
|
|
209
|
+
verifyAttribute(rightElement, "data-resize-handle-state", "inactive");
|
|
210
|
+
|
|
211
|
+
act(() => {
|
|
212
|
+
dispatchPointerEvent("mousemove", leftElement);
|
|
213
|
+
});
|
|
214
|
+
verifyAttribute(leftElement, "data-resize-handle-active", null);
|
|
215
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
216
|
+
verifyAttribute(leftElement, "data-resize-handle-state", "hover");
|
|
217
|
+
verifyAttribute(rightElement, "data-resize-handle-state", "inactive");
|
|
218
|
+
|
|
219
|
+
act(() => {
|
|
220
|
+
dispatchPointerEvent("mousedown", leftElement);
|
|
221
|
+
});
|
|
222
|
+
verifyAttribute(leftElement, "data-resize-handle-active", "pointer");
|
|
223
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
224
|
+
verifyAttribute(leftElement, "data-resize-handle-state", "drag");
|
|
225
|
+
verifyAttribute(rightElement, "data-resize-handle-state", "inactive");
|
|
226
|
+
|
|
227
|
+
act(() => {
|
|
228
|
+
dispatchPointerEvent("mousemove", leftElement);
|
|
229
|
+
});
|
|
230
|
+
verifyAttribute(leftElement, "data-resize-handle-active", "pointer");
|
|
231
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
232
|
+
verifyAttribute(leftElement, "data-resize-handle-state", "drag");
|
|
233
|
+
verifyAttribute(rightElement, "data-resize-handle-state", "inactive");
|
|
234
|
+
|
|
235
|
+
act(() => {
|
|
236
|
+
dispatchPointerEvent("mouseup", leftElement);
|
|
237
|
+
});
|
|
238
|
+
verifyAttribute(leftElement, "data-resize-handle-active", null);
|
|
239
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
240
|
+
verifyAttribute(leftElement, "data-resize-handle-state", "hover");
|
|
241
|
+
verifyAttribute(rightElement, "data-resize-handle-state", "inactive");
|
|
242
|
+
|
|
243
|
+
act(() => {
|
|
244
|
+
dispatchPointerEvent("mousemove", rightElement);
|
|
245
|
+
});
|
|
246
|
+
verifyAttribute(leftElement, "data-resize-handle-active", null);
|
|
247
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
248
|
+
verifyAttribute(leftElement, "data-resize-handle-state", "inactive");
|
|
249
|
+
verifyAttribute(rightElement, "data-resize-handle-state", "hover");
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("should update data-resize-handle-active when focused", () => {
|
|
253
|
+
const { leftElement, rightElement } = setupMockedGroup();
|
|
254
|
+
verifyAttribute(leftElement, "data-resize-handle-active", null);
|
|
255
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
256
|
+
|
|
257
|
+
act(() => {
|
|
258
|
+
leftElement.focus();
|
|
259
|
+
});
|
|
260
|
+
expect(document.activeElement).toBe(leftElement);
|
|
261
|
+
verifyAttribute(leftElement, "data-resize-handle-active", "keyboard");
|
|
262
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
263
|
+
|
|
264
|
+
act(() => {
|
|
265
|
+
leftElement.blur();
|
|
266
|
+
});
|
|
267
|
+
expect(document.activeElement).not.toBe(leftElement);
|
|
268
|
+
verifyAttribute(leftElement, "data-resize-handle-active", null);
|
|
269
|
+
verifyAttribute(rightElement, "data-resize-handle-active", null);
|
|
111
270
|
});
|
|
112
271
|
});
|
|
113
272
|
});
|
package/src/PanelResizeHandle.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ReactElement,
|
|
8
8
|
useContext,
|
|
9
9
|
useEffect,
|
|
10
|
+
useLayoutEffect,
|
|
10
11
|
useRef,
|
|
11
12
|
useState,
|
|
12
13
|
} from "./vendor/react";
|
|
@@ -21,11 +22,11 @@ import {
|
|
|
21
22
|
PointerHitAreaMargins,
|
|
22
23
|
registerResizeHandle,
|
|
23
24
|
ResizeHandlerAction,
|
|
24
|
-
ResizeHandlerState,
|
|
25
25
|
} from "./PanelResizeHandleRegistry";
|
|
26
26
|
import { assert } from "./utils/assert";
|
|
27
27
|
|
|
28
28
|
export type PanelResizeHandleOnDragging = (isDragging: boolean) => void;
|
|
29
|
+
export type ResizeHandlerState = "drag" | "hover" | "inactive";
|
|
29
30
|
|
|
30
31
|
export type PanelResizeHandleProps = Omit<
|
|
31
32
|
HTMLAttributes<keyof HTMLElementTagNameMap>,
|
|
@@ -90,6 +91,16 @@ export function PanelResizeHandle({
|
|
|
90
91
|
null
|
|
91
92
|
);
|
|
92
93
|
|
|
94
|
+
const committedValuesRef = useRef<{
|
|
95
|
+
state: ResizeHandlerState;
|
|
96
|
+
}>({
|
|
97
|
+
state,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
useLayoutEffect(() => {
|
|
101
|
+
committedValuesRef.current.state = state;
|
|
102
|
+
});
|
|
103
|
+
|
|
93
104
|
useEffect(() => {
|
|
94
105
|
if (disabled) {
|
|
95
106
|
setResizeHandler(null);
|
|
@@ -109,37 +120,46 @@ export function PanelResizeHandle({
|
|
|
109
120
|
|
|
110
121
|
const setResizeHandlerState = (
|
|
111
122
|
action: ResizeHandlerAction,
|
|
112
|
-
|
|
123
|
+
isActive: boolean,
|
|
113
124
|
event: ResizeEvent
|
|
114
125
|
) => {
|
|
115
|
-
|
|
126
|
+
if (isActive) {
|
|
127
|
+
switch (action) {
|
|
128
|
+
case "down": {
|
|
129
|
+
setState("drag");
|
|
130
|
+
|
|
131
|
+
startDragging(resizeHandleId, event);
|
|
132
|
+
|
|
133
|
+
const { onDragging } = callbacksRef.current;
|
|
134
|
+
if (onDragging) {
|
|
135
|
+
onDragging(true);
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case "move": {
|
|
140
|
+
const { state } = committedValuesRef.current;
|
|
116
141
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
142
|
+
if (state !== "drag") {
|
|
143
|
+
setState("hover");
|
|
144
|
+
}
|
|
120
145
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
onDragging(true);
|
|
146
|
+
resizeHandler(event);
|
|
147
|
+
break;
|
|
124
148
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
case "up": {
|
|
128
|
-
stopDragging();
|
|
149
|
+
case "up": {
|
|
150
|
+
setState("hover");
|
|
129
151
|
|
|
130
|
-
|
|
131
|
-
if (onDragging) {
|
|
132
|
-
onDragging(false);
|
|
133
|
-
}
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
152
|
+
stopDragging();
|
|
137
153
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
154
|
+
const { onDragging } = callbacksRef.current;
|
|
155
|
+
if (onDragging) {
|
|
156
|
+
onDragging(false);
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
142
160
|
}
|
|
161
|
+
} else {
|
|
162
|
+
setState("inactive");
|
|
143
163
|
}
|
|
144
164
|
};
|
|
145
165
|
|
|
@@ -4,10 +4,9 @@ import { getResizeEventCoordinates } from "./utils/events/getResizeEventCoordina
|
|
|
4
4
|
import { getInputType } from "./utils/getInputType";
|
|
5
5
|
|
|
6
6
|
export type ResizeHandlerAction = "down" | "move" | "up";
|
|
7
|
-
export type ResizeHandlerState = "drag" | "hover" | "inactive";
|
|
8
7
|
export type SetResizeHandlerState = (
|
|
9
8
|
action: ResizeHandlerAction,
|
|
10
|
-
|
|
9
|
+
isActive: boolean,
|
|
11
10
|
event: ResizeEvent
|
|
12
11
|
) => void;
|
|
13
12
|
|
|
@@ -93,21 +92,18 @@ function handlePointerDown(event: ResizeEvent) {
|
|
|
93
92
|
function handlePointerMove(event: ResizeEvent) {
|
|
94
93
|
const { x, y } = getResizeEventCoordinates(event);
|
|
95
94
|
|
|
96
|
-
if (isPointerDown) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
setResizeHandlerState("move", "drag", event);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Update cursor based on return value(s) from active handles
|
|
104
|
-
updateCursor();
|
|
105
|
-
} else {
|
|
95
|
+
if (!isPointerDown) {
|
|
96
|
+
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
97
|
+
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
98
|
+
// but the same set of active handles should be locked until the pointer is released
|
|
106
99
|
recalculateIntersectingHandles({ x, y });
|
|
107
|
-
updateResizeHandlerStates("move", event);
|
|
108
|
-
updateCursor();
|
|
109
100
|
}
|
|
110
101
|
|
|
102
|
+
updateResizeHandlerStates("move", event);
|
|
103
|
+
|
|
104
|
+
// Update cursor based on return value(s) from active handles
|
|
105
|
+
updateCursor();
|
|
106
|
+
|
|
111
107
|
if (intersectingHandles.length > 0) {
|
|
112
108
|
event.preventDefault();
|
|
113
109
|
}
|
|
@@ -250,14 +246,8 @@ function updateResizeHandlerStates(
|
|
|
250
246
|
registeredResizeHandlers.forEach((data) => {
|
|
251
247
|
const { setResizeHandlerState } = data;
|
|
252
248
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
} else {
|
|
257
|
-
setResizeHandlerState(action, "hover", event);
|
|
258
|
-
}
|
|
259
|
-
} else {
|
|
260
|
-
setResizeHandlerState(action, "inactive", event);
|
|
261
|
-
}
|
|
249
|
+
const isActive = intersectingHandles.includes(data);
|
|
250
|
+
|
|
251
|
+
setResizeHandlerState(action, isActive, event);
|
|
262
252
|
});
|
|
263
253
|
}
|
package/src/utils/test-utils.ts
CHANGED
|
@@ -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[]
|