|
1 | 1 | import { expect, test } from "bun:test" |
2 | | -import { createVirtualizer, defaultRangeExtractor } from "@tanstack/solid-virtual" |
| 2 | +import { createVirtualizer, defaultRangeExtractor, Virtualizer } from "@tanstack/solid-virtual" |
3 | 3 | import { createRoot, createSignal } from "solid-js" |
4 | 4 | import { filterVirtualIndexes } from "@/pages/session/timeline/virtual-items" |
5 | 5 |
|
| 6 | +test("end anchoring survives consecutive resizes when the first scroll write is clamped", () => { |
| 7 | + const writes: { offset: number; adjustments?: number }[] = [] |
| 8 | + const virtualizer = new Virtualizer<HTMLDivElement, HTMLDivElement>({ |
| 9 | + count: 5, |
| 10 | + estimateSize: () => 50, |
| 11 | + initialOffset: 50, |
| 12 | + initialRect: { width: 400, height: 200 }, |
| 13 | + anchorTo: "end", |
| 14 | + scrollEndThreshold: 1, |
| 15 | + getScrollElement: () => null, |
| 16 | + scrollToFn: (offset, options) => writes.push({ offset, adjustments: options.adjustments }), |
| 17 | + observeElementRect: () => {}, |
| 18 | + observeElementOffset: () => {}, |
| 19 | + }) |
| 20 | + |
| 21 | + virtualizer.getTotalSize() |
| 22 | + virtualizer.resizeItem(4, 120) |
| 23 | + expect(writes).toEqual([{ offset: 50, adjustments: 70 }]) |
| 24 | + writes.length = 0 |
| 25 | + |
| 26 | + virtualizer.resizeItem(4, 200) |
| 27 | + expect(writes).toEqual([{ offset: 120, adjustments: 80 }]) |
| 28 | +}) |
| 29 | + |
6 | 30 | test("reactive count updates preserve measured row sizes", () => { |
7 | 31 | createRoot((dispose) => { |
8 | 32 | const [count, setCount] = createSignal(2) |
@@ -42,23 +66,26 @@ test("initial rect projects rows before a scroll element connects", () => { |
42 | 66 | }) |
43 | 67 | }) |
44 | 68 |
|
45 | | -test("logical scroll offset includes pending measurement adjustments", () => { |
46 | | - createRoot((dispose) => { |
47 | | - const virtualizer = createVirtualizer<HTMLDivElement, HTMLDivElement>({ |
48 | | - count: 2, |
49 | | - getScrollElement: () => null, |
50 | | - estimateSize: () => 60, |
51 | | - initialOffset: 100, |
52 | | - initialRect: { width: 800, height: 60 }, |
53 | | - }) |
| 69 | +test("clamps oversized offsets with scroll margin and padding changes", () => { |
| 70 | + const options = (paddingEnd: number) => ({ |
| 71 | + count: 20, |
| 72 | + estimateSize: () => 60, |
| 73 | + initialOffset: Number.MAX_SAFE_INTEGER, |
| 74 | + initialRect: { width: 800, height: 600 }, |
| 75 | + scrollMargin: 64, |
| 76 | + paddingEnd, |
| 77 | + overscan: 1, |
| 78 | + getScrollElement: () => null, |
| 79 | + scrollToFn: () => {}, |
| 80 | + observeElementRect: () => {}, |
| 81 | + observeElementOffset: () => {}, |
| 82 | + }) |
| 83 | + const virtualizer = new Virtualizer<HTMLDivElement, HTMLDivElement>(options(64)) |
54 | 84 |
|
55 | | - virtualizer.getTotalSize() |
56 | | - virtualizer.resizeItem(0, 100) |
| 85 | + expect(virtualizer.getVirtualItems().map((item) => item.index)).toEqual([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) |
57 | 86 |
|
58 | | - expect(virtualizer.scrollOffset).toBe(100) |
59 | | - expect(virtualizer.getLogicalScrollOffset()).toBe(140) |
60 | | - dispose() |
61 | | - }) |
| 87 | + virtualizer.setOptions(options(600)) |
| 88 | + expect(virtualizer.getVirtualItems().map((item) => item.index)).toEqual([18, 19]) |
62 | 89 | }) |
63 | 90 |
|
64 | 91 | test("stale pinned indexes do not produce missing virtual items after count shrinks", () => { |
|
0 commit comments