Skip to content

Commit d2fcc09

Browse files
authored
Remove reverse prop (#774)
1 parent a0bf981 commit d2fcc09

File tree

11 files changed

+448
-426
lines changed

11 files changed

+448
-426
lines changed

e2e/VList.spec.ts

Lines changed: 1 addition & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,9 @@ import {
2727
getStyleValue,
2828
findFirstVisibleItem,
2929
findLastVisibleItem,
30+
isVerticalScrollBarVisible,
3031
} from "./utils";
3132

32-
const isVerticalScrollBarVisible = async (e: Locator) => {
33-
return e.evaluate((e) => e.scrollHeight > (e as HTMLElement).offsetHeight);
34-
};
35-
3633
test.describe("smoke", () => {
3734
test("vertically scrollable", async ({ page }) => {
3835
await page.goto(storyUrl("basics-vlist--default"));
@@ -112,39 +109,6 @@ test.describe("smoke", () => {
112109
).toBeVisible();
113110
});
114111

115-
test("reverse", async ({ page }) => {
116-
await page.goto(storyUrl("basics-vlist--reverse"), {
117-
waitUntil: "domcontentloaded",
118-
});
119-
await page.evaluate(() => {
120-
(window as any)._displayed = false;
121-
const mo = new MutationObserver((entries) => {
122-
for (const e of entries) {
123-
for (const n of [...e.addedNodes]) {
124-
const walker = document.createTreeWalker(n, NodeFilter.SHOW_TEXT);
125-
let node: Node;
126-
while ((node = walker.nextNode()!)) {
127-
if (node.textContent === "0") {
128-
(window as any)._displayed = true;
129-
return;
130-
}
131-
}
132-
}
133-
}
134-
});
135-
mo.observe(document.body, { childList: true, subtree: true });
136-
});
137-
138-
const component = await getScrollable(page);
139-
140-
// check if last is displayed
141-
const last = component.getByText("999", { exact: true });
142-
await expect(last).toBeVisible();
143-
expect(await relativeBottom(component, last)).toEqual(0);
144-
// check if start is not displayed
145-
expect(await page.evaluate(() => (window as any)._displayed)).toBe(false);
146-
});
147-
148112
test("display: none", async ({ page }) => {
149113
await page.goto(storyUrl("basics-vlist--default"));
150114

@@ -1324,123 +1288,6 @@ test.describe("check if item shift compensation works", () => {
13241288
expect(i).toBeGreaterThanOrEqual(8);
13251289
});
13261290

1327-
test("prepending when total height is lower than viewport height and reverse:true", async ({
1328-
page,
1329-
browserName,
1330-
}) => {
1331-
const [component, container] = await Promise.all([
1332-
getScrollable(page),
1333-
getVirtualizer(page),
1334-
]);
1335-
1336-
await page.getByRole("checkbox", { name: "reverse" }).click();
1337-
1338-
await page.getByRole("checkbox", { name: "prepend" }).click();
1339-
const decreaseRadio = page.getByRole("radio", { name: "decrease" });
1340-
const increaseRadio = page.getByRole("radio", { name: "increase" });
1341-
const valueInput = page.getByRole("spinbutton");
1342-
const updateButton = page.getByRole("button", { name: "update" });
1343-
1344-
const initialLength = await getItems(container).count();
1345-
expect(initialLength).toBeGreaterThan(1);
1346-
1347-
let i = 0;
1348-
while (true) {
1349-
i++;
1350-
await valueInput.clear();
1351-
await valueInput.fill(String(i));
1352-
1353-
// preprend
1354-
await increaseRadio.click();
1355-
await updateButton.click();
1356-
1357-
const items = getItems(container);
1358-
1359-
// Check if all items are visible
1360-
await expect(items).toHaveCount(i + initialLength);
1361-
1362-
const isScrollBarVisible = await isVerticalScrollBarVisible(component);
1363-
const itemBottom = await relativeBottom(component, items.last());
1364-
1365-
if (isScrollBarVisible) {
1366-
// Check if sticked to bottom
1367-
expectInRange(itemBottom, {
1368-
min: -0.1,
1369-
max: browserName === "firefox" ? 0.45 : 0.1,
1370-
});
1371-
break;
1372-
} else {
1373-
// Check if bottom is always visible and on bottom
1374-
expectInRange(itemBottom, { min: -0.1, max: 0.1 });
1375-
}
1376-
1377-
// remove
1378-
await decreaseRadio.click();
1379-
await updateButton.click();
1380-
}
1381-
1382-
expect(i).toBeGreaterThanOrEqual(8);
1383-
});
1384-
1385-
test("stick to bottom even if many items are removed from top", async ({
1386-
page,
1387-
browserName,
1388-
}) => {
1389-
await page.goto(storyUrl("basics-vlist--increasing-items"));
1390-
const [component, container] = await Promise.all([
1391-
getScrollable(page),
1392-
getVirtualizer(page),
1393-
]);
1394-
1395-
await page.getByRole("checkbox", { name: "reverse" }).click();
1396-
1397-
await page.getByRole("checkbox", { name: "prepend" }).click();
1398-
const decreaseRadio = page.getByRole("radio", { name: "decrease" });
1399-
const increaseRadio = page.getByRole("radio", { name: "increase" });
1400-
const valueInput = page.getByRole("spinbutton");
1401-
const updateButton = page.getByRole("button", { name: "update" });
1402-
1403-
// preprend many
1404-
await valueInput.clear();
1405-
await valueInput.fill("50");
1406-
await increaseRadio.click();
1407-
await updateButton.click();
1408-
1409-
// scroll to bottom
1410-
await scrollToBottom(component);
1411-
1412-
// remove many
1413-
await valueInput.clear();
1414-
await valueInput.fill("1");
1415-
await decreaseRadio.click();
1416-
let i = 0;
1417-
while (true) {
1418-
i++;
1419-
await updateButton.click();
1420-
1421-
const isScrollBarVisible = await isVerticalScrollBarVisible(component);
1422-
const itemBottom = await relativeBottom(
1423-
component,
1424-
getItems(container).last()
1425-
);
1426-
1427-
// Check if bottom is always visible and on bottom
1428-
expectInRange(itemBottom, {
1429-
min: browserName === "firefox" ? -0.6 : -0.5,
1430-
max: 0.5,
1431-
});
1432-
1433-
if (!isScrollBarVisible) {
1434-
break;
1435-
} else {
1436-
// may have subpixel error so scroll to bottom again
1437-
await component.evaluate((e) => (e.scrollTop += e.scrollHeight));
1438-
}
1439-
}
1440-
1441-
expect(i).toBeGreaterThanOrEqual(30);
1442-
});
1443-
14441291
test("check if prepending cancels imperative scroll", async ({ page }) => {
14451292
await page.goto(storyUrl("advanced-chat--default"));
14461293
await page.getByRole("checkbox", { name: "auto update" }).click();

e2e/Virtualizer.spec.ts

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
relativeBottom,
1111
relativeTop,
1212
scrollBy,
13+
isVerticalScrollBarVisible,
1314
} from "./utils";
1415

1516
test("header and footer", async ({ page }) => {
@@ -136,3 +137,154 @@ test("overflow", async ({ page }) => {
136137
).toBe(true);
137138
}
138139
});
140+
141+
test.describe("aligned to bottom", () => {
142+
test("reverse", async ({ page }) => {
143+
await page.goto(storyUrl("basics-virtualizer--reverse"), {
144+
waitUntil: "domcontentloaded",
145+
});
146+
await page.evaluate(() => {
147+
(window as any)._displayed = false;
148+
const mo = new MutationObserver((entries) => {
149+
for (const e of entries) {
150+
for (const n of [...e.addedNodes]) {
151+
const walker = document.createTreeWalker(n, NodeFilter.SHOW_TEXT);
152+
let node: Node;
153+
while ((node = walker.nextNode()!)) {
154+
if (node.textContent === "0") {
155+
(window as any)._displayed = true;
156+
return;
157+
}
158+
}
159+
}
160+
}
161+
});
162+
mo.observe(document.body, { childList: true, subtree: true });
163+
});
164+
165+
const component = await getScrollable(page);
166+
167+
// check if last is displayed
168+
const last = component.getByText("999", { exact: true });
169+
await expect(last).toBeVisible();
170+
expect(await relativeBottom(component, last)).toEqual(0);
171+
// check if start is not displayed
172+
expect(await page.evaluate(() => (window as any)._displayed)).toBe(false);
173+
});
174+
175+
test("prepending when total height is lower than viewport height", async ({
176+
page,
177+
browserName,
178+
}) => {
179+
await page.goto(storyUrl("basics-virtualizer--align-bottom"));
180+
181+
const [component, container] = await Promise.all([
182+
getScrollable(page),
183+
getVirtualizer(page),
184+
]);
185+
186+
await page.getByRole("checkbox", { name: "prepend" }).click();
187+
const decreaseRadio = page.getByRole("radio", { name: "decrease" });
188+
const increaseRadio = page.getByRole("radio", { name: "increase" });
189+
const valueInput = page.getByRole("spinbutton");
190+
const updateButton = page.getByRole("button", { name: "update" });
191+
192+
const initialLength = await getItems(container).count();
193+
expect(initialLength).toBeGreaterThan(1);
194+
195+
let i = 0;
196+
while (true) {
197+
i++;
198+
await valueInput.clear();
199+
await valueInput.fill(String(i));
200+
201+
// preprend
202+
await increaseRadio.click();
203+
await updateButton.click();
204+
205+
const items = getItems(container);
206+
207+
// Check if all items are visible
208+
await expect(items).toHaveCount(i + initialLength);
209+
210+
const isScrollBarVisible = await isVerticalScrollBarVisible(component);
211+
const itemBottom = await relativeBottom(component, items.last());
212+
213+
if (isScrollBarVisible) {
214+
// Check if sticked to bottom
215+
expectInRange(itemBottom, {
216+
min: -0.1,
217+
max: browserName === "firefox" ? 0.45 : 0.1,
218+
});
219+
break;
220+
} else {
221+
// Check if bottom is always visible and on bottom
222+
expectInRange(itemBottom, { min: -0.1, max: 0.1 });
223+
}
224+
225+
// remove
226+
await decreaseRadio.click();
227+
await updateButton.click();
228+
}
229+
230+
expect(i).toBeGreaterThanOrEqual(8);
231+
});
232+
233+
test("stick to bottom even if many items are removed from top", async ({
234+
page,
235+
browserName,
236+
}) => {
237+
await page.goto(storyUrl("basics-virtualizer--align-bottom"));
238+
239+
const [component, container] = await Promise.all([
240+
getScrollable(page),
241+
getVirtualizer(page),
242+
]);
243+
244+
await page.getByRole("checkbox", { name: "prepend" }).click();
245+
const decreaseRadio = page.getByRole("radio", { name: "decrease" });
246+
const increaseRadio = page.getByRole("radio", { name: "increase" });
247+
const valueInput = page.getByRole("spinbutton");
248+
const updateButton = page.getByRole("button", { name: "update" });
249+
250+
// preprend many
251+
await valueInput.clear();
252+
await valueInput.fill("50");
253+
await increaseRadio.click();
254+
await updateButton.click();
255+
256+
// scroll to bottom
257+
await scrollToBottom(component);
258+
259+
// remove many
260+
await valueInput.clear();
261+
await valueInput.fill("1");
262+
await decreaseRadio.click();
263+
let i = 0;
264+
while (true) {
265+
i++;
266+
await updateButton.click();
267+
268+
const isScrollBarVisible = await isVerticalScrollBarVisible(component);
269+
const itemBottom = await relativeBottom(
270+
component,
271+
getItems(container).last()
272+
);
273+
274+
// Check if bottom is always visible and on bottom
275+
expectInRange(itemBottom, {
276+
min: browserName === "firefox" ? -0.6 : -0.5,
277+
max: 0.5,
278+
});
279+
280+
if (!isScrollBarVisible) {
281+
break;
282+
} else {
283+
// may have subpixel error so scroll to bottom again
284+
await component.evaluate((e) => (e.scrollTop += e.scrollHeight));
285+
}
286+
}
287+
288+
expect(i).toBeGreaterThanOrEqual(30);
289+
});
290+
});

e2e/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ export const getWindowScrollRight = (page: Page) => {
165165
return page.evaluate(() => document.body.scrollWidth - window.scrollX);
166166
};
167167

168+
export const isVerticalScrollBarVisible = async (e: Locator) => {
169+
return e.evaluate((e) => e.scrollHeight > (e as HTMLElement).offsetHeight);
170+
};
171+
168172
export const scrollTo = (
169173
scrollable: ScrollableLocator,
170174
offset: number,

src/react/VList.spec.tsx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -287,16 +287,3 @@ describe("horizontal", async () => {
287287
expect(asFragment()).toMatchSnapshot();
288288
});
289289
});
290-
291-
describe("reverse", async () => {
292-
it("should render many items", async () => {
293-
const { asFragment } = await render(
294-
<VList reverse>
295-
{Array.from({ length: 100 }).map((_, i) => (
296-
<div key={i}>{i}</div>
297-
))}
298-
</VList>
299-
);
300-
expect(asFragment()).toMatchSnapshot();
301-
});
302-
});

0 commit comments

Comments
 (0)