react-resizable-panels 2.0.2 → 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 +8 -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 +57 -42
- package/dist/react-resizable-panels.browser.development.cjs.js +57 -42
- package/dist/react-resizable-panels.browser.development.esm.js +57 -42
- package/dist/react-resizable-panels.browser.esm.js +57 -42
- package/dist/react-resizable-panels.cjs.js +57 -42
- package/dist/react-resizable-panels.development.cjs.js +57 -42
- package/dist/react-resizable-panels.development.esm.js +57 -42
- package/dist/react-resizable-panels.development.node.cjs.js +57 -42
- package/dist/react-resizable-panels.development.node.esm.js +57 -42
- package/dist/react-resizable-panels.esm.js +57 -42
- package/dist/react-resizable-panels.node.cjs.js +57 -42
- package/dist/react-resizable-panels.node.esm.js +57 -42
- package/package.json +3 -1
- package/src/Panel.test.tsx +63 -0
- package/src/PanelGroup.test.tsx +21 -1
- package/src/PanelResizeHandle.test.tsx +199 -1
- package/src/PanelResizeHandle.ts +49 -19
- package/src/PanelResizeHandleRegistry.ts +13 -23
- package/src/hooks/useWindowSplitterBehavior.ts +2 -2
- package/src/utils/test-utils.ts +66 -0
|
@@ -1,8 +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";
|
|
7
|
+
import {
|
|
8
|
+
dispatchPointerEvent,
|
|
9
|
+
mockBoundingClientRect,
|
|
10
|
+
verifyAttribute,
|
|
11
|
+
} from "./utils/test-utils";
|
|
6
12
|
|
|
7
13
|
describe("PanelResizeHandle", () => {
|
|
8
14
|
let expectedWarnings: string[] = [];
|
|
@@ -66,9 +72,201 @@ describe("PanelResizeHandle", () => {
|
|
|
66
72
|
expect(element.title).toBe("bar");
|
|
67
73
|
});
|
|
68
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
|
+
|
|
69
120
|
describe("callbacks", () => {
|
|
70
121
|
describe("onDragging", () => {
|
|
71
|
-
|
|
122
|
+
it("should fire when dragging starts/stops", () => {
|
|
123
|
+
const onDragging = jest.fn();
|
|
124
|
+
|
|
125
|
+
const { leftElement } = setupMockedGroup({
|
|
126
|
+
leftProps: { onDragging },
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
act(() => {
|
|
130
|
+
dispatchPointerEvent("mousemove", leftElement);
|
|
131
|
+
});
|
|
132
|
+
expect(onDragging).not.toHaveBeenCalled();
|
|
133
|
+
|
|
134
|
+
act(() => {
|
|
135
|
+
dispatchPointerEvent("mousedown", leftElement);
|
|
136
|
+
});
|
|
137
|
+
expect(onDragging).toHaveBeenCalledTimes(1);
|
|
138
|
+
expect(onDragging).toHaveBeenCalledWith(true);
|
|
139
|
+
|
|
140
|
+
act(() => {
|
|
141
|
+
dispatchPointerEvent("mouseup", leftElement);
|
|
142
|
+
});
|
|
143
|
+
expect(onDragging).toHaveBeenCalledTimes(2);
|
|
144
|
+
expect(onDragging).toHaveBeenCalledWith(false);
|
|
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);
|
|
72
270
|
});
|
|
73
271
|
});
|
|
74
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,27 +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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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;
|
|
141
|
+
|
|
142
|
+
if (state !== "drag") {
|
|
143
|
+
setState("hover");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
resizeHandler(event);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case "up": {
|
|
150
|
+
setState("hover");
|
|
151
|
+
|
|
152
|
+
stopDragging();
|
|
153
|
+
|
|
154
|
+
const { onDragging } = callbacksRef.current;
|
|
155
|
+
if (onDragging) {
|
|
156
|
+
onDragging(false);
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
132
160
|
}
|
|
161
|
+
} else {
|
|
162
|
+
setState("inactive");
|
|
133
163
|
}
|
|
134
164
|
};
|
|
135
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
|
}
|
|
@@ -68,8 +68,8 @@ export function useWindowSplitterResizeHandlerBehavior({
|
|
|
68
68
|
? index - 1
|
|
69
69
|
: handles.length - 1
|
|
70
70
|
: index + 1 < handles.length
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
? index + 1
|
|
72
|
+
: 0;
|
|
73
73
|
|
|
74
74
|
const nextHandle = handles[nextIndex] as HTMLElement;
|
|
75
75
|
nextHandle.focus();
|
package/src/utils/test-utils.ts
CHANGED
|
@@ -2,6 +2,33 @@ import { assert } from "./assert";
|
|
|
2
2
|
|
|
3
3
|
const util = require("util");
|
|
4
4
|
|
|
5
|
+
export function dispatchPointerEvent(type: string, target: HTMLElement) {
|
|
6
|
+
const rect = target.getBoundingClientRect();
|
|
7
|
+
|
|
8
|
+
const clientX = rect.left + rect.width / 2;
|
|
9
|
+
const clientY = rect.top + rect.height / 2;
|
|
10
|
+
|
|
11
|
+
const event = new MouseEvent(type, {
|
|
12
|
+
bubbles: true,
|
|
13
|
+
clientX,
|
|
14
|
+
clientY,
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperties(event, {
|
|
17
|
+
pageX: {
|
|
18
|
+
get() {
|
|
19
|
+
return clientX;
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
pageY: {
|
|
23
|
+
get() {
|
|
24
|
+
return clientY;
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
target.dispatchEvent(event);
|
|
30
|
+
}
|
|
31
|
+
|
|
5
32
|
export function expectToBeCloseToArray(
|
|
6
33
|
actualNumbers: number[],
|
|
7
34
|
expectedNumbers: number[]
|
|
@@ -20,6 +47,36 @@ export function expectToBeCloseToArray(
|
|
|
20
47
|
}
|
|
21
48
|
}
|
|
22
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
|
+
|
|
23
80
|
export function mockPanelGroupOffsetWidthAndHeight(
|
|
24
81
|
mockWidth = 1_000,
|
|
25
82
|
mockHeight = 1_000
|
|
@@ -75,6 +132,15 @@ export function mockPanelGroupOffsetWidthAndHeight(
|
|
|
75
132
|
};
|
|
76
133
|
}
|
|
77
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
|
+
|
|
78
144
|
export function verifyExpandedPanelGroupLayout(
|
|
79
145
|
actualLayout: number[],
|
|
80
146
|
expectedLayout: number[]
|