Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions __tests__/core/calculateItemsInView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,22 @@ describe("calculateItemsInView", () => {
}
});

it("applies a deferred item-size MVCP correction in the next pass that repositions items", () => {
setupFixedSizeItems(30, 10);
const deferredPass = mock(() => {});
mockState.scheduledWork.frame(deferredPass, "mvcpRecalculate");
const prepareMVCPSpy = spyOn(mvcpModule, "prepareMVCP").mockImplementation(() => undefined);
try {
// A scroll-driven pass runs before the deferred frame.
calculateItemsInView(mockCtx, { scrollVelocity: 0 });

expect(prepareMVCPSpy).toHaveBeenCalledWith(mockCtx, undefined, "item-size");
expect(mockState.scheduledWork.has("mvcpRecalculate")).toBe(false);
} finally {
prepareMVCPSpy.mockRestore();
}
});

it("limits cold assignments to the current buffer and header-corrected animated target union", () => {
setupFixedSizeItems(120, 64);
mockState.props.estimatedItemSize = 64;
Expand Down
10 changes: 9 additions & 1 deletion src/core/calculateItemsInView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,8 @@ export function calculateItemsInView(
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || new Set<number>();
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
const { dataChanged, doMVCP, forceFullItemPositions, mvcpAdjustmentSource } = params;
const { dataChanged, forceFullItemPositions } = params;
let { doMVCP, mvcpAdjustmentSource } = params;
const bootstrapInitialScrollState =
state.initialScrollSession?.kind === "bootstrap" ? state.initialScrollSession.bootstrap : undefined;
const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
Expand Down Expand Up @@ -503,6 +504,13 @@ export function calculateItemsInView(
}
}

// A deferred item-size correction must land in any pass that repositions items, or they move without it.
if (!doMVCP && state.scheduledWork.has("mvcpRecalculate")) {
state.scheduledWork.cancel("mvcpRecalculate");
doMVCP = true;
mvcpAdjustmentSource = "item-size";
}

////// Update item positions and do MVCP
// Handle maintainVisibleContentPosition adjustment early
const checkMVCP =
Expand Down