Skip to content

Commit d1aa733

Browse files
committed
Add onLayoutChanged prop to Group
1 parent a8dcf7a commit d1aa733

File tree

14 files changed

+269
-108
lines changed

14 files changed

+269
-108
lines changed

integrations/tests/src/components/Decoder.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ export function Decoder({
6464
imperativeGroupApiLayout: Layout | undefined;
6565
imperativePanelApiSize: PanelSize | undefined;
6666
layout: Layout;
67-
onLayoutCount: number;
67+
onLayoutChangeCount: number;
68+
onLayoutChangedCount: number;
6869
panels: {
6970
[id: number | string]: {
7071
onResizeCount: number;
@@ -75,7 +76,8 @@ export function Decoder({
7576
imperativeGroupApiLayout: undefined,
7677
imperativePanelApiSize: undefined,
7778
layout: {},
78-
onLayoutCount: 0,
79+
onLayoutChangeCount: 0,
80+
onLayoutChangedCount: 0,
7981
panels: {}
8082
});
8183

@@ -94,7 +96,14 @@ export function Decoder({
9496

9597
setState((prev) => ({
9698
...prev,
97-
onLayoutCount: prev.onLayoutCount + 1,
99+
onLayoutChangeCount: prev.onLayoutChangeCount + 1,
100+
layout
101+
}));
102+
},
103+
onLayoutChanged: (layout) => {
104+
setState((prev) => ({
105+
...prev,
106+
onLayoutChangedCount: prev.onLayoutChangedCount + 1,
98107
layout
99108
}));
100109
}
@@ -153,7 +162,8 @@ export function Decoder({
153162
<DebugData
154163
data={{
155164
layout: state.layout,
156-
onLayoutCount: state.onLayoutCount
165+
onLayoutChangeCount: state.onLayoutChangeCount,
166+
onLayoutChangedCount: state.onLayoutChangedCount
157167
}}
158168
/>
159169
{Array.from(Object.keys(state.panels)).map((panelId) => (
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { expect, type Page } from "@playwright/test";
2+
3+
export async function assertLayoutChangeCounts(
4+
page: Page,
5+
layoutChangeCount: number,
6+
layoutChangedCount: number | undefined = layoutChangeCount
7+
) {
8+
await expect(
9+
page.getByText(`"onLayoutChangeCount": ${layoutChangeCount}`)
10+
).toBeVisible();
11+
await expect(
12+
page.getByText(`"onLayoutChangedCount": ${layoutChangedCount}`)
13+
).toBeVisible();
14+
}

integrations/tests/src/utils/expectLayout.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@ import type { Layout } from "react-resizable-panels";
44
export async function expectLayout({
55
layout,
66
mainPage,
7-
onLayoutCount
7+
onLayoutChangeCount,
8+
onLayoutChangedCount
89
}: {
910
layout: Layout;
1011
mainPage: Page;
11-
onLayoutCount: number;
12+
onLayoutChangeCount: number;
13+
onLayoutChangedCount: number;
1214
}) {
1315
await expect(mainPage.getByText('"layout"')).toHaveText(
1416
JSON.stringify(
1517
{
1618
layout,
17-
onLayoutCount
19+
onLayoutChangeCount,
20+
onLayoutChangedCount
1821
},
1922
null,
2023
2

integrations/tests/tests/fixed-size-elements.spec.tsx

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ test.describe("fixed size elements", () => {
2323
{ usePopUpWindow }
2424
);
2525

26-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
26+
await expect(
27+
mainPage.getByText('"onLayoutChangeCount": 1')
28+
).toBeVisible();
2729

2830
for (const text of ["foo+bar", "bar+baz", "baz+qux"]) {
2931
const box = (await page.getByText(text).boundingBox())!;
@@ -34,7 +36,9 @@ test.describe("fixed size elements", () => {
3436
await page.mouse.up();
3537
}
3638

37-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
39+
await expect(
40+
mainPage.getByText('"onLayoutChangeCount": 1')
41+
).toBeVisible();
3842
});
3943

4044
test("should work without an explicit separator", async ({
@@ -57,7 +61,9 @@ test.describe("fixed size elements", () => {
5761
{ usePopUpWindow }
5862
);
5963

60-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
64+
await expect(
65+
mainPage.getByText('"onLayoutChangeCount": 1')
66+
).toBeVisible();
6167

6268
const boxFoo = (await page.getByText("id: foo").boundingBox())!;
6369

@@ -66,7 +72,9 @@ test.describe("fixed size elements", () => {
6672
await page.mouse.move(0, 0);
6773
await page.mouse.up();
6874

69-
await expect(mainPage.getByText('"onLayoutCount": 2')).toBeVisible();
75+
await expect(
76+
mainPage.getByText('"onLayoutChangeCount": 2')
77+
).toBeVisible();
7078

7179
const boxBar = (await page.getByText("id: bar").boundingBox())!;
7280

@@ -75,7 +83,9 @@ test.describe("fixed size elements", () => {
7583
await page.mouse.move(1000, 0);
7684
await page.mouse.up();
7785

78-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
86+
await expect(
87+
mainPage.getByText('"onLayoutChangeCount": 3')
88+
).toBeVisible();
7989
});
8090

8191
test("should work with an explicit separator", async ({
@@ -105,7 +115,9 @@ test.describe("fixed size elements", () => {
105115
await page.mouse.move(0, 0);
106116
await page.mouse.up();
107117

108-
await expect(mainPage.getByText('"onLayoutCount": 2')).toBeVisible();
118+
await expect(
119+
mainPage.getByText('"onLayoutChangeCount": 2')
120+
).toBeVisible();
109121

110122
const boxBaz = (await page.getByText("id: baz").boundingBox())!;
111123

@@ -114,7 +126,9 @@ test.describe("fixed size elements", () => {
114126
await page.mouse.move(1000, 0);
115127
await page.mouse.up();
116128

117-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
129+
await expect(
130+
mainPage.getByText('"onLayoutChangeCount": 3')
131+
).toBeVisible();
118132
});
119133

120134
test("should work with two explicit separators", async ({
@@ -146,7 +160,9 @@ test.describe("fixed size elements", () => {
146160
await page.mouse.move(0, 0);
147161
await page.mouse.up();
148162

149-
await expect(mainPage.getByText('"onLayoutCount": 2')).toBeVisible();
163+
await expect(
164+
mainPage.getByText('"onLayoutChangeCount": 2')
165+
).toBeVisible();
150166

151167
separatorBox = (await page.getByTestId("baz+qux+right").boundingBox())!;
152168

@@ -155,7 +171,9 @@ test.describe("fixed size elements", () => {
155171
await page.mouse.move(1000, 0);
156172
await page.mouse.up();
157173

158-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
174+
await expect(
175+
mainPage.getByText('"onLayoutChangeCount": 3')
176+
).toBeVisible();
159177
});
160178
});
161179
}

integrations/tests/tests/keyboard-interactions.spec.tsx

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { expect, test } from "@playwright/test";
22
import { Group, Panel, Separator } from "react-resizable-panels";
3+
import { assertLayoutChangeCounts } from "../src/utils/assertLayoutChangeCounts";
34
import { getSeparatorAriaAttributes } from "../src/utils/getSeparatorAriaAttributes";
45
import { goToUrl } from "../src/utils/goToUrl";
56

@@ -21,7 +22,7 @@ test.describe("keyboard interactions: window splitter api", () => {
2122
{ usePopUpWindow }
2223
);
2324

24-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
25+
await assertLayoutChangeCounts(mainPage, 1);
2526
await expect(mainPage.getByText('"left": 30')).toBeVisible();
2627

2728
await expect(await getSeparatorAriaAttributes(page)).toEqual({
@@ -36,7 +37,7 @@ test.describe("keyboard interactions: window splitter api", () => {
3637
await separator.focus();
3738
await page.keyboard.press("ArrowLeft");
3839

39-
await expect(mainPage.getByText('"onLayoutCount": 2')).toBeVisible();
40+
await assertLayoutChangeCounts(mainPage, 2);
4041
await expect(mainPage.getByText('"left": 25')).toBeVisible();
4142

4243
await expect(await getSeparatorAriaAttributes(page)).toEqual({
@@ -48,7 +49,7 @@ test.describe("keyboard interactions: window splitter api", () => {
4849

4950
await page.keyboard.press("ArrowRight");
5051

51-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
52+
await assertLayoutChangeCounts(mainPage, 3);
5253
await expect(mainPage.getByText('"left": 30')).toBeVisible();
5354

5455
await expect(await getSeparatorAriaAttributes(page)).toEqual({
@@ -61,7 +62,7 @@ test.describe("keyboard interactions: window splitter api", () => {
6162
// Up/down are no-ops
6263
await page.keyboard.press("ArrowUp");
6364
await page.keyboard.press("ArrowDown");
64-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
65+
await assertLayoutChangeCounts(mainPage, 3);
6566
});
6667

6768
test("vertical: arrow keys", async ({ page: mainPage }) => {
@@ -75,7 +76,7 @@ test.describe("keyboard interactions: window splitter api", () => {
7576
{ usePopUpWindow }
7677
);
7778

78-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
79+
await assertLayoutChangeCounts(mainPage, 1);
7980
await expect(mainPage.getByText('"top": 30')).toBeVisible();
8081

8182
await expect(await getSeparatorAriaAttributes(page)).toEqual({
@@ -90,7 +91,7 @@ test.describe("keyboard interactions: window splitter api", () => {
9091
await separator.focus();
9192
await page.keyboard.press("ArrowDown");
9293

93-
await expect(mainPage.getByText('"onLayoutCount": 2')).toBeVisible();
94+
await assertLayoutChangeCounts(mainPage, 2);
9495
await expect(mainPage.getByText('"top": 35')).toBeVisible();
9596

9697
await expect(await getSeparatorAriaAttributes(page)).toEqual({
@@ -102,7 +103,7 @@ test.describe("keyboard interactions: window splitter api", () => {
102103

103104
await page.keyboard.press("ArrowUp");
104105

105-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
106+
await assertLayoutChangeCounts(mainPage, 3);
106107
await expect(mainPage.getByText('"top": 30')).toBeVisible();
107108

108109
await expect(await getSeparatorAriaAttributes(page)).toEqual({
@@ -115,7 +116,7 @@ test.describe("keyboard interactions: window splitter api", () => {
115116
// Left/right are no-ops
116117
await page.keyboard.press("ArrowLeft");
117118
await page.keyboard.press("ArrowRight");
118-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
119+
await assertLayoutChangeCounts(mainPage, 3);
119120
});
120121

121122
test("enter key and collapsible panel", async ({ page: mainPage }) => {
@@ -129,7 +130,7 @@ test.describe("keyboard interactions: window splitter api", () => {
129130
{ usePopUpWindow }
130131
);
131132

132-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
133+
await assertLayoutChangeCounts(mainPage, 1);
133134
await expect(mainPage.getByText('"left": 50')).toBeVisible();
134135
await expect(mainPage.getByText('"right": 50')).toBeVisible();
135136

@@ -144,7 +145,7 @@ test.describe("keyboard interactions: window splitter api", () => {
144145
await separator.focus();
145146
await page.keyboard.press("Enter");
146147

147-
await expect(mainPage.getByText('"onLayoutCount": 2')).toBeVisible();
148+
await assertLayoutChangeCounts(mainPage, 2);
148149
await expect(mainPage.getByText('"left": 5')).toBeVisible();
149150
await expect(mainPage.getByText('"right": 95')).toBeVisible();
150151

@@ -157,7 +158,7 @@ test.describe("keyboard interactions: window splitter api", () => {
157158

158159
await page.keyboard.press("Enter");
159160

160-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
161+
await assertLayoutChangeCounts(mainPage, 3);
161162
await expect(mainPage.getByText('"left": 50')).toBeVisible();
162163
await expect(mainPage.getByText('"right": 50')).toBeVisible();
163164

@@ -170,7 +171,7 @@ test.describe("keyboard interactions: window splitter api", () => {
170171

171172
await page.keyboard.press("ArrowLeft");
172173

173-
await expect(mainPage.getByText('"onLayoutCount": 4')).toBeVisible();
174+
await assertLayoutChangeCounts(mainPage, 4);
174175
await expect(mainPage.getByText('"left": 45')).toBeVisible();
175176
await expect(mainPage.getByText('"right": 55')).toBeVisible();
176177

@@ -183,7 +184,7 @@ test.describe("keyboard interactions: window splitter api", () => {
183184

184185
await page.keyboard.press("Enter");
185186

186-
await expect(mainPage.getByText('"onLayoutCount": 5')).toBeVisible();
187+
await assertLayoutChangeCounts(mainPage, 5);
187188
await expect(mainPage.getByText('"left": 5')).toBeVisible();
188189
await expect(mainPage.getByText('"right": 95')).toBeVisible();
189190

@@ -196,7 +197,7 @@ test.describe("keyboard interactions: window splitter api", () => {
196197

197198
await page.keyboard.press("Enter");
198199

199-
await expect(mainPage.getByText('"onLayoutCount": 6')).toBeVisible();
200+
await assertLayoutChangeCounts(mainPage, 6);
200201
await expect(mainPage.getByText('"left": 45')).toBeVisible();
201202
await expect(mainPage.getByText('"right": 55')).toBeVisible();
202203

@@ -221,15 +222,15 @@ test.describe("keyboard interactions: window splitter api", () => {
221222
{ usePopUpWindow }
222223
);
223224

224-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
225+
await assertLayoutChangeCounts(mainPage, 1);
225226
await expect(mainPage.getByText('"left": 50')).toBeVisible();
226227
await expect(mainPage.getByText('"right": 50')).toBeVisible();
227228

228229
const separator = page.getByRole("separator");
229230
await separator.focus();
230231
await page.keyboard.press("Enter");
231232

232-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
233+
await assertLayoutChangeCounts(mainPage, 1);
233234
});
234235

235236
test("home and end keys", async ({ page: mainPage }) => {
@@ -243,7 +244,7 @@ test.describe("keyboard interactions: window splitter api", () => {
243244
{ usePopUpWindow }
244245
);
245246

246-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
247+
await assertLayoutChangeCounts(mainPage, 1);
247248
await expect(mainPage.getByText('"left": 50')).toBeVisible();
248249
await expect(mainPage.getByText('"right": 50')).toBeVisible();
249250

@@ -252,13 +253,13 @@ test.describe("keyboard interactions: window splitter api", () => {
252253
await separator.focus();
253254
await page.keyboard.press("Home");
254255

255-
await expect(mainPage.getByText('"onLayoutCount": 2')).toBeVisible();
256+
await assertLayoutChangeCounts(mainPage, 2);
256257
await expect(mainPage.getByText('"left": 20')).toBeVisible();
257258
await expect(mainPage.getByText('"right": 80')).toBeVisible();
258259

259260
await page.keyboard.press("End");
260261

261-
await expect(mainPage.getByText('"onLayoutCount": 3')).toBeVisible();
262+
await assertLayoutChangeCounts(mainPage, 3);
262263
await expect(mainPage.getByText('"left": 95')).toBeVisible();
263264
await expect(mainPage.getByText('"right": 5')).toBeVisible();
264265
});
@@ -307,7 +308,7 @@ test.describe("keyboard interactions: window splitter api", () => {
307308
{ usePopUpWindow }
308309
);
309310

310-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
311+
await assertLayoutChangeCounts(mainPage, 1);
311312
await expect(mainPage.getByText('"left": 30')).toBeVisible();
312313

313314
const separator = page.getByRole("separator");
@@ -320,7 +321,7 @@ test.describe("keyboard interactions: window splitter api", () => {
320321
await page.keyboard.press("Enter");
321322
await page.keyboard.press("Home");
322323

323-
await expect(mainPage.getByText('"onLayoutCount": 1')).toBeVisible();
324+
await assertLayoutChangeCounts(mainPage, 1);
324325
await expect(mainPage.getByText('"left": 30')).toBeVisible();
325326
});
326327
});

0 commit comments

Comments
 (0)