Skip to content

Commit

Permalink
Merge pull request #386 from inokawa/resize-jump-on-idle
Browse files Browse the repository at this point in the history
Fix regression related to resizing when its top is out of viewport
  • Loading branch information
inokawa authored Feb 19, 2024
2 parents f1cfffa + 76317c5 commit 9bad093
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 103 deletions.
55 changes: 55 additions & 0 deletions e2e/VList.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,61 @@ test.describe("check if scroll jump compensation works", () => {
await expect(prev).toBeGreaterThan(initial + min);
});

test("resize when its top is out of viewport", async ({ page }) => {
await page.goto(storyUrl("advanced-collapse-and-scroll--default"));
const component = await getScrollable(page);
const container = await getVirtualizer(page);
await component.waitForElementState("stable");

expect(
await container.evaluate((e) => e.children.length)
).toBeGreaterThanOrEqual(3);

const targetIndex = 1;
const marginTop = 100;

const getTargetItem = () => {
return container.evaluateHandle((e, i) => {
return Array.from(e.children).find((c) =>
c.textContent!.startsWith(String(i) + "Resize")
)!;
}, targetIndex);
};

const getResizeButton = async () => {
const target = await getTargetItem();
const button = await target.evaluateHandle((e) => {
const buttons = e.querySelectorAll("button");
return buttons[0];
});
expect(await button.textContent()).toBe("Resize");
return button;
};

const getTargetTop = async () => {
const target = await getTargetItem();
return target.evaluate((e) => {
return (e as HTMLElement).offsetTop;
});
};

// resize and check if jump compensation doesn't work
// collapse -> expand
for (let i = 0; i <= 1; i++) {
await scrollTo(component, (await getTargetTop()) + marginTop);
const initialItem = await getFirstItem(component);
expect(initialItem.top).toBeLessThan(0);
expect(initialItem.text).toContain(String(targetIndex));

await page.waitForTimeout(200);
await (await getResizeButton()).click();
await (await getTargetItem()).waitForElementState("stable");
const updatedItem = await getFirstItem(component);
expect(updatedItem.top).toEqual(initialItem.top);
expect(updatedItem.text).toContain(String(targetIndex));
}
});

test("resize with smooth scroll", async ({ page }) => {
await page.goto(storyUrl("advanced-collapse-and-scroll--default"));
const component = await getScrollable(page);
Expand Down
8 changes: 7 additions & 1 deletion src/core/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,13 @@ export const createVirtualStore = (
(_frozenRange
? // https://github.com/inokawa/virtua/issues/380
index < _frozenRange[0]
: getItemOffset(index) < scrollOffset)
: getItemOffset(index) +
// https://github.com/inokawa/virtua/issues/385
(_scrollDirection === SCROLL_IDLE &&
_scrollMode === SCROLL_BY_NATIVE
? getItemSize(cache, index)
: 0) <
scrollOffset)
) {
const diff = size - getItemSize(cache, index);
if (!shouldStickToEnd || diff > 0) {
Expand Down
2 changes: 1 addition & 1 deletion stories/react/advanced/Collapse and scroll.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const Collapser = ({
<div
style={{
transition: "height 250ms linear",
height: isCollapsed ? 200 : 800,
height: isCollapsed ? 200 : 600,
background: "#ccc",
display: "flex",
flexDirection: "column",
Expand Down
101 changes: 0 additions & 101 deletions stories/react/advanced/Collapse nested.stories.tsx

This file was deleted.

0 comments on commit 9bad093

Please sign in to comment.